Browse Source

meta: built-in labels for meta data

skypjack 10 months ago
parent
commit
d775841457
3 changed files with 88 additions and 2 deletions
  1. 46 2
      src/entt/meta/factory.hpp
  2. 8 0
      src/entt/meta/meta.hpp
  3. 34 0
      test/entt/meta/meta_data.cpp

+ 46 - 2
src/entt/meta/factory.hpp

@@ -319,6 +319,27 @@ public:
         return *this;
     }
 
+    /**
+     * @brief Assigns a meta data to a meta type.
+     *
+     * Extended function for hashed string support.<br/>
+     * The identifier is used for the type, while the associated string is used
+     * as the name. The length is ignored.
+     *
+     * @warning
+     * The reflection system expects string literals, does not make copies, and
+     * is not in charge of freeing memory in any case.
+     *
+     * @tparam Data The actual variable to attach to the meta type.
+     * @tparam Policy Optional policy (no policy set by default).
+     * @param id A custom unique identifier.
+     * @return A meta factory for the given type.
+     */
+    template<auto Data, typename Policy = as_is_t>
+    meta_factory data(const hashed_string id) noexcept {
+        return data<Data, Policy>(id.value(), id.data());
+    }
+
     /**
      * @brief Assigns a meta data to a meta type.
      *
@@ -362,7 +383,7 @@ public:
             base_type::data(
                 internal::meta_data_node{
                     id,
-                    nullptr,
+                    label,
                     ((!std::is_pointer_v<decltype(Data)> || std::is_const_v<data_type>) ? internal::meta_traits::is_const : internal::meta_traits::is_none) | internal::meta_traits::is_static,
                     1u,
                     &internal::resolve<std::remove_cv_t<std::remove_reference_t<data_type>>>,
@@ -374,6 +395,29 @@ public:
         return *this;
     }
 
+    /**
+     * @brief Assigns a meta data to a meta type by means of its setter and
+     * getter.
+     *
+     * Extended function for hashed string support.<br/>
+     * The identifier is used for the type, while the associated string is used
+     * as the name. The length is ignored.
+     *
+     * @warning
+     * The reflection system expects string literals, does not make copies, and
+     * is not in charge of freeing memory in any case.
+     *
+     * @tparam Setter The actual function to use as a setter.
+     * @tparam Getter The actual function to use as a getter.
+     * @tparam Policy Optional policy (no policy set by default).
+     * @param id A custom unique identifier.
+     * @return A meta factory for the given type.
+     */
+    template<auto Setter, auto Getter, typename Policy = as_is_t>
+    meta_factory data(const hashed_string id) noexcept {
+        return data<Setter, Getter, Policy>(id.value(), id.data());
+    }
+
     /**
      * @brief Assigns a meta data to a meta type by means of its setter and
      * getter.
@@ -418,7 +462,7 @@ public:
             base_type::data(
                 internal::meta_data_node{
                     id,
-                    nullptr,
+                    label,
                     /* this is never static nor const */
                     internal::meta_traits::is_none,
                     1u,

+ 8 - 0
src/entt/meta/meta.hpp

@@ -832,6 +832,14 @@ struct meta_data {
         : node{std::move(curr)},
           ctx{&area} {}
 
+    /**
+     * @brief Returns the label assigned to a data member, if any.
+     * @return The label assigned to the data member, if any.
+     */
+    [[nodiscard]] const char *label() const noexcept {
+        return node.label;
+    }
+
     /**
      * @brief Returns the number of setters available.
      * @return The number of setters available.

+ 34 - 0
test/entt/meta/meta_data.cpp

@@ -184,6 +184,40 @@ ENTT_DEBUG_TEST_F(MetaDataDeathTest, Custom) {
     ASSERT_DEATH([[maybe_unused]] const char value = entt::resolve<clazz>().data("j"_hs).custom(), "");
 }
 
+TEST_F(MetaData, Label) {
+    using namespace entt::literals;
+
+    entt::meta_reset<clazz>();
+    entt::meta_reset<setter_getter>();
+
+    entt::meta_factory<clazz>{}
+        .data<&clazz::i, entt::as_ref_t>("i")
+        .data<&clazz::i, entt::as_cref_t>("ci"_hs)
+        .data<&clazz::j>(entt::hashed_string::value("j"))
+        .data<&clazz::h>("h"_hs, "hhh");
+
+    entt::meta_factory<setter_getter>{}
+        .data<&setter_getter::static_setter, &setter_getter::static_getter>("x")
+        .data<&setter_getter::setter, &setter_getter::getter>("y"_hs)
+        .data<nullptr, &setter_getter::getter>(entt::hashed_string::value("z"))
+        .data<&setter_getter::setter_with_ref, &setter_getter::getter_with_ref>("h"_hs, "hhh");
+
+    const entt::meta_type type = entt::resolve<clazz>();
+    const entt::meta_type other = entt::resolve<setter_getter>();
+
+    ASSERT_EQ(type.data("i"_hs).label(), std::string_view{"i"});
+    ASSERT_EQ(type.data("ci"_hs).label(), std::string_view{"ci"});
+    ASSERT_EQ(type.data("j"_hs).label(), nullptr);
+    ASSERT_EQ(type.data("k"_hs).label(), nullptr);
+    ASSERT_EQ(type.data("h"_hs).label(), std::string_view{"hhh"});
+
+    ASSERT_EQ(other.data("x"_hs).label(), std::string_view{"x"});
+    ASSERT_EQ(other.data("y"_hs).label(), std::string_view{"y"});
+    ASSERT_EQ(other.data("z"_hs).label(), nullptr);
+    ASSERT_EQ(other.data("v"_hs).label(), nullptr);
+    ASSERT_EQ(other.data("h"_hs).label(), std::string_view{"hhh"});
+}
+
 TEST_F(MetaData, Comparison) {
     using namespace entt::literals;