diff --git a/docs/md/meta.md b/docs/md/meta.md index 541300a8c..029144263 100644 --- a/docs/md/meta.md +++ b/docs/md/meta.md @@ -942,7 +942,21 @@ objects from it and making its identifier no longer visible. The underlying node will remain available though, as if it were implicitly generated: ```cpp -entt::resolve().reset(); +entt::meta_reset(); ``` -The type can be re-registered later with a completely different name and form. +It's also possible to reset types by their unique identifiers if required: + +```cpp +entt::meta_reset("my_type"_hs); +``` + +Finally, there exists a non-template overload of the `meta_reset` function that +doesn't accept argument and resets all searchable types (that is, all types that +were assigned an unique identifier): + +```cpp +entt::meta_reset(); +``` + +All types can be re-registered later with a completely different name and form. diff --git a/src/entt/meta/factory.hpp b/src/entt/meta/factory.hpp index d6b0e02b8..44be8738e 100644 --- a/src/entt/meta/factory.hpp +++ b/src/entt/meta/factory.hpp @@ -44,6 +44,30 @@ template } +template +void meta_reset(Node **curr) { + while(*curr) { + (meta_reset(&((*curr)->*Member)), ...); + *curr = std::exchange((*curr)->next, nullptr); + } +} + + +inline void meta_reset(internal::meta_type_node *node) ENTT_NOEXCEPT { + meta_reset(&node->prop); + meta_reset(&node->base); + meta_reset(&node->conv); + meta_reset<&internal::meta_ctor_node::prop>(&node->ctor); + meta_reset<&internal::meta_data_node::prop>(&node->data); + meta_reset<&internal::meta_func_node::prop>(&node->func); + + node->id = {}; + node->ctor = node->def_ctor; + node->dtor = nullptr; + node->next = nullptr; +} + + } @@ -570,6 +594,54 @@ template } +/** + * @brief Resets a type and all its parts. + * + * Resets a type and all its data members, member functions and properties, as + * well as its constructors, destructors and conversion functions if any.
+ * Base classes aren't reset but the link between the two types is removed. + * + * The type is also removed from the list of searchable types. + */ +template +void meta_reset() ENTT_NOEXCEPT { + meta_reset(internal::meta_info::resolve()->id); +} + + +/** + * @brief Resets a type and all its parts. + * + * @sa meta_reset + * + * @param id Unique identifier. + */ +inline void meta_reset(const id_type id) ENTT_NOEXCEPT { + for(auto** it = internal::meta_context::global(); *it; it = &(*it)->next) { + if((*it)->id == id) { + internal::meta_type_node *node = *it; + *it = (*it)->next; + internal::meta_reset(node); + break; + } + } +} + + +/** + * @brief Resets all searchable types. + * + * @sa meta_reset + */ +inline void meta_reset() ENTT_NOEXCEPT { + for(auto** it = internal::meta_context::global(); *it; it = &(*it)->next) { + internal::meta_reset(*it); + } + + *internal::meta_context::global() = nullptr; +} + + } diff --git a/src/entt/meta/meta.hpp b/src/entt/meta/meta.hpp index ef6af3dae..7fcccc6f1 100644 --- a/src/entt/meta/meta.hpp +++ b/src/entt/meta/meta.hpp @@ -1082,14 +1082,6 @@ class meta_type { return nullptr; } - template - void unregister_all(Node **curr) { - while(*curr) { - (unregister_all(&((*curr)->*Member)), ...); - *curr = std::exchange((*curr)->next, nullptr); - } - } - public: /*! @brief Node type. */ using node_type = internal::meta_type_node; @@ -1099,7 +1091,7 @@ public: using size_type = typename node_type::size_type; /*! @copydoc meta_prop::meta_prop */ - meta_type(node_type *curr = nullptr) ENTT_NOEXCEPT + meta_type(const node_type *curr = nullptr) ENTT_NOEXCEPT : node{curr} {} @@ -1107,7 +1099,7 @@ public: * @brief Constructs an instance from a given base node. * @param curr The base node with which to construct the instance. */ - meta_type(base_node_type *curr) ENTT_NOEXCEPT + meta_type(const base_node_type *curr) ENTT_NOEXCEPT : node{curr ? curr->type : nullptr} {} @@ -1567,38 +1559,8 @@ public: return (!node && !other.node) || (node && other.node && node->info == other.node->info); } - /** - * @brief Resets a type and all its parts. - * - * This function resets a type and all its data members, member functions - * and properties, as well as its constructors, destructors and conversion - * functions if any.
- * Base classes aren't reset but the link between the two types is removed. - * - * The type is also removed from the list of searchable types. - */ - void reset() ENTT_NOEXCEPT { - for(auto** it = internal::meta_context::global(); *it; it = &(*it)->next) { - if(*it == node) { - *it = (*it)->next; - break; - } - } - - unregister_all(&node->prop); - unregister_all(&node->base); - unregister_all(&node->conv); - unregister_all<&internal::meta_ctor_node::prop>(&node->ctor); - unregister_all<&internal::meta_data_node::prop>(&node->data); - unregister_all<&internal::meta_func_node::prop>(&node->func); - - node->id = {}; - node->ctor = node->def_ctor; - node->dtor = nullptr; - } - private: - node_type *node; + const node_type *node; }; diff --git a/test/entt/meta/meta_any.cpp b/test/entt/meta/meta_any.cpp index 233c8e492..351902c04 100644 --- a/test/entt/meta/meta_any.cpp +++ b/test/entt/meta/meta_any.cpp @@ -84,9 +84,7 @@ struct MetaAny: ::testing::Test { } void TearDown() override { - for(auto type: entt::resolve()) { - type.reset(); - } + entt::meta_reset(); } }; diff --git a/test/entt/meta/meta_base.cpp b/test/entt/meta/meta_base.cpp index b81e831ce..acadd0750 100644 --- a/test/entt/meta/meta_base.cpp +++ b/test/entt/meta/meta_base.cpp @@ -23,9 +23,7 @@ struct MetaBase: ::testing::Test { } void TearDown() override { - for(auto type: entt::resolve()) { - type.reset(); - } + entt::meta_reset(); } }; diff --git a/test/entt/meta/meta_container.cpp b/test/entt/meta/meta_container.cpp index c7345510c..c7aeada70 100644 --- a/test/entt/meta/meta_container.cpp +++ b/test/entt/meta/meta_container.cpp @@ -19,9 +19,7 @@ struct MetaContainer: ::testing::Test { } void TearDown() override { - for(auto type: entt::resolve()) { - type.reset(); - } + entt::meta_reset(); } }; diff --git a/test/entt/meta/meta_conv.cpp b/test/entt/meta/meta_conv.cpp index 72bd4347a..df5616d0b 100644 --- a/test/entt/meta/meta_conv.cpp +++ b/test/entt/meta/meta_conv.cpp @@ -26,9 +26,7 @@ struct MetaConv: ::testing::Test { } void TearDown() override { - for(auto type: entt::resolve()) { - type.reset(); - } + entt::meta_reset(); } }; diff --git a/test/entt/meta/meta_ctor.cpp b/test/entt/meta/meta_ctor.cpp index b3b4f22df..671720844 100644 --- a/test/entt/meta/meta_ctor.cpp +++ b/test/entt/meta/meta_ctor.cpp @@ -55,9 +55,7 @@ struct MetaCtor: ::testing::Test { } void TearDown() override { - for(auto type: entt::resolve()) { - type.reset(); - } + entt::meta_reset(); } }; diff --git a/test/entt/meta/meta_data.cpp b/test/entt/meta/meta_data.cpp index e577c6719..e4e087d21 100644 --- a/test/entt/meta/meta_data.cpp +++ b/test/entt/meta/meta_data.cpp @@ -118,9 +118,7 @@ struct MetaData: ::testing::Test { } void TearDown() override { - for(auto type: entt::resolve()) { - type.reset(); - } + entt::meta_reset(); } }; diff --git a/test/entt/meta/meta_dtor.cpp b/test/entt/meta/meta_dtor.cpp index f7f1776d9..e94eb349a 100644 --- a/test/entt/meta/meta_dtor.cpp +++ b/test/entt/meta/meta_dtor.cpp @@ -33,9 +33,7 @@ struct MetaDtor: ::testing::Test { } void TearDown() override { - for(auto type: entt::resolve()) { - type.reset(); - } + entt::meta_reset(); } }; diff --git a/test/entt/meta/meta_func.cpp b/test/entt/meta/meta_func.cpp index 01c72c49d..8cd7e0184 100644 --- a/test/entt/meta/meta_func.cpp +++ b/test/entt/meta/meta_func.cpp @@ -96,9 +96,7 @@ struct MetaFunc: ::testing::Test { } void TearDown() override { - for(auto type: entt::resolve()) { - type.reset(); - } + entt::meta_reset(); } }; diff --git a/test/entt/meta/meta_handle.cpp b/test/entt/meta/meta_handle.cpp index eff1c691c..01baba3be 100644 --- a/test/entt/meta/meta_handle.cpp +++ b/test/entt/meta/meta_handle.cpp @@ -22,9 +22,7 @@ struct MetaHandle: ::testing::Test { } void TearDown() override { - for(auto type: entt::resolve()) { - type.reset(); - } + entt::meta_reset(); } }; diff --git a/test/entt/meta/meta_prop.cpp b/test/entt/meta/meta_prop.cpp index 1028298b0..225e9e890 100644 --- a/test/entt/meta/meta_prop.cpp +++ b/test/entt/meta/meta_prop.cpp @@ -29,9 +29,7 @@ struct MetaProp: ::testing::Test { } void TearDown() override { - for(auto type: entt::resolve()) { - type.reset(); - } + entt::meta_reset(); } }; diff --git a/test/entt/meta/meta_range.cpp b/test/entt/meta/meta_range.cpp index 05ee55d8c..61f54a3f4 100644 --- a/test/entt/meta/meta_range.cpp +++ b/test/entt/meta/meta_range.cpp @@ -14,9 +14,7 @@ struct MetaRange: ::testing::Test { } void TearDown() override { - for(auto type: entt::resolve()) { - type.reset(); - } + entt::meta_reset(); } }; diff --git a/test/entt/meta/meta_type.cpp b/test/entt/meta/meta_type.cpp index 9c4fc85ff..d26a8a5bc 100644 --- a/test/entt/meta/meta_type.cpp +++ b/test/entt/meta/meta_type.cpp @@ -156,9 +156,7 @@ struct MetaType: ::testing::Test { } void TearDown() override { - for(auto type: entt::resolve()) { - type.reset(); - } + entt::meta_reset(); } }; @@ -488,7 +486,7 @@ TEST_F(MetaType, Reset) { // implicitly generated default constructor ASSERT_TRUE(entt::resolve().ctor<>()); - entt::resolve("clazz"_hs).reset(); + entt::meta_reset("clazz"_hs); ASSERT_FALSE(entt::resolve("clazz"_hs)); ASSERT_NE(entt::resolve().id(), "clazz"_hs); @@ -514,11 +512,7 @@ TEST_F(MetaType, ResetAll) { ASSERT_TRUE(entt::resolve("overloaded_func"_hs)); ASSERT_TRUE(entt::resolve("double"_hs)); - for(auto type: entt::resolve()) { - // we exploit the fact that the iterators aren't invalidated - // because EnTT leaves a dangling ::next in the underlying node - type.reset(); - } + entt::meta_reset(); ASSERT_FALSE(entt::resolve("clazz"_hs)); ASSERT_FALSE(entt::resolve("overloaded_func"_hs)); @@ -624,15 +618,15 @@ TEST_F(MetaType, ResetAndReRegistrationAfterReset) { ASSERT_NE(*entt::internal::meta_context::global(), nullptr); - entt::resolve().reset(); - entt::resolve().reset(); - entt::resolve().reset(); - entt::resolve().reset(); - entt::resolve().reset(); - entt::resolve().reset(); - entt::resolve ().reset (); - entt::resolve().reset(); - entt::resolve().reset(); + entt::meta_reset(); + entt::meta_reset(); + entt::meta_reset(); + entt::meta_reset(); + entt::meta_reset(); + entt::meta_reset(); + entt::meta_reset(); + entt::meta_reset(); + entt::meta_reset(); ASSERT_FALSE(entt::resolve("double"_hs)); ASSERT_FALSE(entt::resolve("base"_hs)); diff --git a/test/lib/meta/lib.cpp b/test/lib/meta/lib.cpp index e90378195..be4ff650b 100644 --- a/test/lib/meta/lib.cpp +++ b/test/lib/meta/lib.cpp @@ -26,8 +26,8 @@ ENTT_API void set_up() { } ENTT_API void tear_down() { - entt::resolve().reset(); - entt::resolve().reset(); + entt::meta_reset(); + entt::meta_reset(); } ENTT_API entt::meta_any wrap_int(int value) { diff --git a/test/lib/meta_plugin/plugin.cpp b/test/lib/meta_plugin/plugin.cpp index 46fd55cc4..d8b784b85 100644 --- a/test/lib/meta_plugin/plugin.cpp +++ b/test/lib/meta_plugin/plugin.cpp @@ -26,8 +26,8 @@ void set_up() { } void tear_down() { - entt::resolve().reset(); - entt::resolve().reset(); + entt::meta_reset(); + entt::meta_reset(); } CR_EXPORT int cr_main(cr_plugin *ctx, cr_op operation) { diff --git a/test/lib/meta_plugin_std/plugin.cpp b/test/lib/meta_plugin_std/plugin.cpp index 46fd55cc4..d8b784b85 100644 --- a/test/lib/meta_plugin_std/plugin.cpp +++ b/test/lib/meta_plugin_std/plugin.cpp @@ -26,8 +26,8 @@ void set_up() { } void tear_down() { - entt::resolve().reset(); - entt::resolve().reset(); + entt::meta_reset(); + entt::meta_reset(); } CR_EXPORT int cr_main(cr_plugin *ctx, cr_op operation) {