소스 검색

meta: top-level only searches for data and functions

skypjack 4 달 전
부모
커밋
31d5d5ff1c
4개의 변경된 파일41개의 추가작업 그리고 10개의 파일을 삭제
  1. 1 1
      TODO
  2. 6 4
      src/entt/meta/meta.hpp
  3. 6 4
      src/entt/meta/node.hpp
  4. 28 1
      test/entt/meta/meta_type.cpp

+ 1 - 1
TODO

@@ -36,4 +36,4 @@ TODO:
 * find a way to test deleter and the absence of it in basic_any
 * archetype-like a-là EnTT support (see my own notes)
 * meta_factory: add a replace flag to traits to get around the |-only mechanism
-* support searching meta data and func only on top level types, no bases
+* propagate already loaded meta types from invoke/arg/whatever as much as possible to reduce lookups

+ 6 - 4
src/entt/meta/meta.hpp

@@ -1324,10 +1324,11 @@ public:
     /**
      * @brief Lookup utility for meta data (bases are also visited).
      * @param id Unique identifier.
+     * @param recursive True for a search in the base classes, false otherwise.
      * @return The registered meta data for the given identifier, if any.
      */
-    [[nodiscard]] meta_data data(const id_type id) const {
-        const auto *elem = internal::look_for<&internal::meta_type_descriptor::data>(internal::meta_context::from(*ctx), fetch_node(), id);
+    [[nodiscard]] meta_data data(const id_type id, const bool recursive = true) const {
+        const auto *elem = internal::look_for<&internal::meta_type_descriptor::data>(internal::meta_context::from(*ctx), fetch_node(), id, recursive);
         return (elem != nullptr) ? meta_data{*ctx, *elem} : meta_data{};
     }
 
@@ -1343,10 +1344,11 @@ public:
     /**
      * @brief Lookup utility for meta functions (bases are also visited).
      * @param id Unique identifier.
+     * @param recursive True for a search in the base classes, false otherwise.
      * @return The registered meta function for the given identifier, if any.
      */
-    [[nodiscard]] meta_func func(const id_type id) const {
-        const auto *elem = internal::look_for<&internal::meta_type_descriptor::func>(internal::meta_context::from(*ctx), fetch_node(), id);
+    [[nodiscard]] meta_func func(const id_type id, const bool recursive = true) const {
+        const auto *elem = internal::look_for<&internal::meta_type_descriptor::func>(internal::meta_context::from(*ctx), fetch_node(), id, recursive);
         return (elem != nullptr) ? meta_func{*ctx, *elem} : meta_func{};
     }
 

+ 6 - 4
src/entt/meta/node.hpp

@@ -166,7 +166,7 @@ template<auto Member, typename Type, typename Value>
 }
 
 template<auto Member>
-[[nodiscard]] auto *look_for(const meta_context &context, const meta_type_node &node, const id_type id) {
+[[nodiscard]] auto *look_for(const meta_context &context, const meta_type_node &node, const id_type id, bool recursive) {
     using value_type = typename std::remove_reference_t<decltype((node.details.get()->*Member))>::value_type;
 
     if(node.details) {
@@ -174,9 +174,11 @@ template<auto Member>
             return member;
         }
 
-        for(auto &&curr: node.details->base) {
-            if(auto *elem = look_for<Member>(context, curr.resolve(context), id); elem) {
-                return elem;
+        if(recursive) {
+            for(auto &&curr: node.details->base) {
+                if(auto *elem = look_for<Member>(context, curr.resolve(context), id, recursive); elem) {
+                    return elem;
+                }
             }
         }
     }

+ 28 - 1
test/entt/meta/meta_type.cpp

@@ -32,6 +32,10 @@ Type get(Type &elem) {
 
 struct base {
     char value{'c'};
+
+    static int f() {
+        return 0;
+    }
 };
 
 struct derived: base {
@@ -134,7 +138,8 @@ struct MetaType: ::testing::Test {
 
         entt::meta_factory<base>{}
             .type("base"_hs)
-            .data<&base::value>("value"_hs);
+            .data<&base::value>("value"_hs)
+            .func<&base::f>("func"_hs);
 
         entt::meta_factory<derived>{}
             .type("derived")
@@ -455,6 +460,17 @@ TEST_F(MetaType, Data) {
     ASSERT_EQ(type.data().cbegin(), type.data().cend());
 }
 
+TEST_F(MetaType, DataRecursive) {
+    using namespace entt::literals;
+
+    auto type = entt::resolve<derived>();
+    const derived instance{};
+
+    ASSERT_TRUE(type.data("value"_hs));
+    ASSERT_EQ('c', type.data("value"_hs).get(instance).cast<char>());
+    ASSERT_FALSE(type.data("value"_hs, false));
+}
+
 TEST_F(MetaType, Func) {
     using namespace entt::literals;
 
@@ -478,6 +494,17 @@ TEST_F(MetaType, Func) {
     ASSERT_EQ(type.func().cbegin(), type.func().cend());
 }
 
+TEST_F(MetaType, FuncRecursive) {
+    using namespace entt::literals;
+
+    auto type = entt::resolve<derived>();
+    const derived instance{};
+
+    ASSERT_TRUE(type.func("func"_hs));
+    ASSERT_EQ(0, type.func("func"_hs).invoke(instance).cast<int>());
+    ASSERT_FALSE(type.func("func"_hs, false));
+}
+
 TEST_F(MetaType, Invoke) {
     using namespace entt::literals;