Kaynağa Gözat

meta: added the possibility to detach meta types from contexts

Michele Caini 5 yıl önce
ebeveyn
işleme
4ffcf6bf3b
4 değiştirilmiş dosya ile 37 ekleme ve 11 silme
  1. 0 1
      TODO
  2. 1 8
      src/entt/meta/factory.hpp
  3. 17 0
      src/entt/meta/meta.hpp
  4. 19 2
      test/entt/meta/meta.cpp

+ 0 - 1
TODO

@@ -17,7 +17,6 @@
   - get -> all, exclude -> none
   - get -> all, exclude -> none
 
 
 Next:
 Next:
-* meta, make it possible to reset nodes from meta types
 * replace observer class with observer functions
 * replace observer class with observer functions
 * get(cmp, entity) -> void *, set(cmp, entity, void *)
 * get(cmp, entity) -> void *, set(cmp, entity, void *)
 * review multi component views to reduce instantiations once empty types are gone...
 * review multi component views to reduce instantiations once empty types are gone...

+ 1 - 8
src/entt/meta/factory.hpp

@@ -778,15 +778,8 @@ public:
      */
      */
     auto reset() ENTT_NOEXCEPT {
     auto reset() ENTT_NOEXCEPT {
         auto * const node = internal::meta_info<Type>::resolve();
         auto * const node = internal::meta_info<Type>::resolve();
-        auto **it = internal::meta_info<>::global;
 
 
-        while(*it && *it != node) {
-            it = &(*it)->next;
-        }
-
-        if(*it) {
-            *it = (*it)->next;
-        }
+        internal::meta_info<>::detach(node);
 
 
         const auto unregister_all = y_combinator{
         const auto unregister_all = y_combinator{
             [](auto &&self, auto **curr, auto... member) {
             [](auto &&self, auto **curr, auto... member) {

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

@@ -227,6 +227,18 @@ template<>
 struct meta_node<> {
 struct meta_node<> {
     inline static meta_type_node *local = nullptr;
     inline static meta_type_node *local = nullptr;
     inline static meta_type_node **global = &local;
     inline static meta_type_node **global = &local;
+
+    inline static void detach(const meta_type_node *node) ENTT_NOEXCEPT {
+        auto **it = global;
+
+        while(*it && *it != node) {
+            it = &(*it)->next;
+        }
+
+        if(*it) {
+            *it = (*it)->next;
+        }
+    }
 };
 };
 
 
 
 
@@ -1473,6 +1485,11 @@ public:
         return (!node && !other.node) || (node && other.node && node->type_id == other.node->type_id);
         return (!node && !other.node) || (node && other.node && node->type_id == other.node->type_id);
     }
     }
 
 
+    /*! @brief Removes a meta object from the list of searchable types. */
+    void detach() ENTT_NOEXCEPT {
+        internal::meta_info<>::detach(node);
+    }
+
 private:
 private:
     const internal::meta_type_node *node;
     const internal::meta_type_node *node;
 };
 };

+ 19 - 2
test/entt/meta/meta.cpp

@@ -1718,6 +1718,25 @@ TEST_F(Meta, MetaTypeConstructCastAndConvert) {
     ASSERT_EQ(any.cast<derived_type>().c, 'c');
     ASSERT_EQ(any.cast<derived_type>().c, 'c');
 }
 }
 
 
+TEST_F(Meta, MetaTypeDetach) {
+    ASSERT_TRUE(entt::resolve("char"_hs));
+
+    entt::resolve([](auto type) {
+        if(type.alias() == "char"_hs) {
+            type.detach();
+        }
+    });
+
+    ASSERT_FALSE(entt::resolve("char"_hs));
+    ASSERT_EQ(entt::resolve<char>().alias(), "char"_hs);
+    ASSERT_EQ(entt::resolve<char>().prop(props::prop_int).value().cast<int>(), 42);
+    ASSERT_TRUE(entt::resolve<char>().data("value"_hs));
+
+    entt::meta_factory<char>().alias("char"_hs);
+
+    ASSERT_TRUE(entt::resolve("char"_hs));
+}
+
 TEST_F(Meta, MetaDataFromBase) {
 TEST_F(Meta, MetaDataFromBase) {
     auto type = entt::resolve<concrete_type>();
     auto type = entt::resolve<concrete_type>();
     concrete_type instance;
     concrete_type instance;
@@ -1874,8 +1893,6 @@ TEST_F(Meta, Reset) {
     entt::meta<another_abstract_type>().reset();
     entt::meta<another_abstract_type>().reset();
     entt::meta<unsigned int>().reset();
     entt::meta<unsigned int>().reset();
 
 
-    ASSERT_EQ(*entt::internal::meta_info<>::global, nullptr);
-
     ASSERT_FALSE(entt::resolve("char"_hs));
     ASSERT_FALSE(entt::resolve("char"_hs));
     ASSERT_FALSE(entt::resolve("base"_hs));
     ASSERT_FALSE(entt::resolve("base"_hs));
     ASSERT_FALSE(entt::resolve("derived"_hs));
     ASSERT_FALSE(entt::resolve("derived"_hs));