From 4ffcf6bf3bece74c848acf6ecf0cdf5fa89739de Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Thu, 9 Apr 2020 00:26:02 +0200 Subject: [PATCH] meta: added the possibility to detach meta types from contexts --- TODO | 1 - src/entt/meta/factory.hpp | 9 +-------- src/entt/meta/meta.hpp | 17 +++++++++++++++++ test/entt/meta/meta.cpp | 21 +++++++++++++++++++-- 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/TODO b/TODO index 0d4fec5f2..d91f3a0b9 100644 --- a/TODO +++ b/TODO @@ -17,7 +17,6 @@ - get -> all, exclude -> none Next: -* meta, make it possible to reset nodes from meta types * replace observer class with observer functions * get(cmp, entity) -> void *, set(cmp, entity, void *) * review multi component views to reduce instantiations once empty types are gone... diff --git a/src/entt/meta/factory.hpp b/src/entt/meta/factory.hpp index ebd20fb77..ab60f52fb 100644 --- a/src/entt/meta/factory.hpp +++ b/src/entt/meta/factory.hpp @@ -778,15 +778,8 @@ public: */ auto reset() ENTT_NOEXCEPT { auto * const node = internal::meta_info::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{ [](auto &&self, auto **curr, auto... member) { diff --git a/src/entt/meta/meta.hpp b/src/entt/meta/meta.hpp index 5eea0472b..40fdedcf8 100644 --- a/src/entt/meta/meta.hpp +++ b/src/entt/meta/meta.hpp @@ -227,6 +227,18 @@ template<> struct meta_node<> { inline static meta_type_node *local = nullptr; 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); } + /*! @brief Removes a meta object from the list of searchable types. */ + void detach() ENTT_NOEXCEPT { + internal::meta_info<>::detach(node); + } + private: const internal::meta_type_node *node; }; diff --git a/test/entt/meta/meta.cpp b/test/entt/meta/meta.cpp index fa2d6b758..f5e3a052f 100644 --- a/test/entt/meta/meta.cpp +++ b/test/entt/meta/meta.cpp @@ -1718,6 +1718,25 @@ TEST_F(Meta, MetaTypeConstructCastAndConvert) { ASSERT_EQ(any.cast().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().alias(), "char"_hs); + ASSERT_EQ(entt::resolve().prop(props::prop_int).value().cast(), 42); + ASSERT_TRUE(entt::resolve().data("value"_hs)); + + entt::meta_factory().alias("char"_hs); + + ASSERT_TRUE(entt::resolve("char"_hs)); +} + TEST_F(Meta, MetaDataFromBase) { auto type = entt::resolve(); concrete_type instance; @@ -1874,8 +1893,6 @@ TEST_F(Meta, Reset) { entt::meta().reset(); entt::meta().reset(); - ASSERT_EQ(*entt::internal::meta_info<>::global, nullptr); - ASSERT_FALSE(entt::resolve("char"_hs)); ASSERT_FALSE(entt::resolve("base"_hs)); ASSERT_FALSE(entt::resolve("derived"_hs));