meta: reset is now part of meta_type

This commit is contained in:
Michele Caini
2020-08-10 17:23:45 +02:00
parent ead6cb9ca3
commit 0ac07e2e83
8 changed files with 71 additions and 85 deletions

View File

@@ -878,7 +878,7 @@ 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::meta<my_type>().reset();
entt::resolve<my_type>().reset();
```
The type can be re-registered later with a completely different name and form.

View File

@@ -4,7 +4,6 @@
#include "../core/attribute.h"
#include "../config/config.h"
#include "internal.hpp"
namespace entt {
@@ -19,6 +18,9 @@ namespace entt {
namespace internal {
struct meta_type_node;
struct ENTT_API meta_context {
// we could use the lines below but VS2017 returns with an ICE if combined with ENTT_API despite the code being valid C++
// inline static meta_type_node *local = nullptr;
@@ -33,18 +35,6 @@ struct ENTT_API meta_context {
static meta_type_node **chain = &local();
return chain;
}
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;
}
}
};

View File

@@ -12,7 +12,6 @@
#include "../core/fwd.hpp"
#include "../core/type_info.hpp"
#include "../core/type_traits.hpp"
#include "../core/utility.hpp"
#include "internal.hpp"
#include "meta.hpp"
#include "policy.hpp"
@@ -691,46 +690,6 @@ public:
return meta_factory<Type, std::integral_constant<decltype(Candidate), Candidate>>{&node.prop};
}
/**
* @brief Resets a meta type and all its parts.
*
* This function resets a meta type and all its data members, member
* functions and properties, as well as its constructors, destructors and
* conversion functions if any.<br/>
* Base classes aren't reset but the link between the two types is removed.
*
* @return An extended meta factory for the given type.
*/
auto reset() ENTT_NOEXCEPT {
auto * const node = internal::meta_info<Type>::resolve();
internal::meta_context::detach(node);
const auto unregister_all = y_combinator{
[](auto &&self, auto **curr, auto... member) {
while(*curr) {
auto *prev = *curr;
(self(&(prev->*member)), ...);
*curr = prev->next;
prev->next = nullptr;
}
}
};
unregister_all(&node->prop);
unregister_all(&node->base);
unregister_all(&node->conv);
unregister_all(&node->ctor, &internal::meta_ctor_node::prop);
unregister_all(&node->data, &internal::meta_data_node::prop);
unregister_all(&node->func, &internal::meta_func_node::prop);
node->id = {};
node->next = nullptr;
node->dtor = nullptr;
return meta_factory<Type, Type>{&node->prop};
}
};

View File

@@ -11,6 +11,7 @@
#include <utility>
#include "../config/config.h"
#include "../core/fwd.hpp"
#include "../core/utility.hpp"
#include "ctx.hpp"
#include "internal.hpp"
#include "range.hpp"
@@ -467,7 +468,7 @@ public:
private:
internal::meta_storage storage;
const internal::meta_type_node *node;
internal::meta_type_node *node;
dereference_operator_type *deref;
meta_sequence_container(* seq_factory)(void *);
meta_associative_container(* assoc_factory)(void *);
@@ -985,7 +986,7 @@ public:
using size_type = typename node_type::size_type;
/*! @copydoc meta_prop::meta_prop */
meta_type(const node_type *curr = nullptr) ENTT_NOEXCEPT
meta_type(node_type *curr = nullptr) ENTT_NOEXCEPT
: node{curr}
{}
@@ -1344,13 +1345,51 @@ 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_context::detach(node);
/**
* @brief Resets a meta type and all its parts.
*
* This function resets a meta type and all its data members, member
* functions and properties, as well as its constructors, destructors and
* conversion functions if any.<br/>
* Base classes aren't reset but the link between the two types is removed.
*
* The meta type is also removed from the list of searchable types.
*/
void reset() ENTT_NOEXCEPT {
auto** it = internal::meta_context::global();
while (*it && *it != node) {
it = &(*it)->next;
}
if(*it) {
*it = (*it)->next;
}
const auto unregister_all = y_combinator{
[](auto &&self, auto **curr, auto... member) {
while(*curr) {
auto *prev = *curr;
(self(&(prev->*member)), ...);
*curr = prev->next;
prev->next = nullptr;
}
}
};
unregister_all(&node->prop);
unregister_all(&node->base);
unregister_all(&node->conv);
unregister_all(&node->ctor, &internal::meta_ctor_node::prop);
unregister_all(&node->data, &internal::meta_data_node::prop);
unregister_all(&node->func, &internal::meta_func_node::prop);
node->id = {};
node->dtor = nullptr;
}
private:
const node_type *node;
node_type *node;
};

View File

@@ -308,20 +308,15 @@ TEST_F(MetaType, ConstructCastAndConvert) {
ASSERT_EQ(any.cast<clazz_t>().value, 42);
}
TEST_F(MetaType, Detach) {
TEST_F(MetaType, Reset) {
ASSERT_TRUE(entt::resolve_id("clazz"_hs));
for(auto curr: entt::resolve()) {
if(curr.id() == "clazz"_hs) {
curr.detach();
break;
}
}
entt::resolve_id("clazz"_hs).reset();
ASSERT_FALSE(entt::resolve_id("clazz"_hs));
ASSERT_EQ(entt::resolve<clazz_t>().id(), "clazz"_hs);
ASSERT_EQ(entt::resolve<clazz_t>().prop(property_t::value).value().cast<int>(), 42);
ASSERT_TRUE(entt::resolve<clazz_t>().data("value"_hs));
ASSERT_NE(entt::resolve<clazz_t>().id(), "clazz"_hs);
ASSERT_FALSE(entt::resolve<clazz_t>().prop(property_t::value));
ASSERT_FALSE(entt::resolve<clazz_t>().data("value"_hs));
entt::meta<clazz_t>().type("clazz"_hs);
@@ -413,14 +408,14 @@ TEST_F(MetaType, PropertiesAndCornerCases) {
TEST_F(MetaType, ResetAndReRegistrationAfterReset) {
ASSERT_NE(*entt::internal::meta_context::global(), nullptr);
entt::meta<double>().reset();
entt::meta<unsigned int>().reset();
entt::meta<base_t>().reset();
entt::meta<derived_t>().reset();
entt::meta<abstract_t>().reset();
entt::meta<concrete_t>().reset();
entt::meta<property_t>().reset();
entt::meta<clazz_t>().reset();
entt::resolve<double>().reset();
entt::resolve<unsigned int>().reset();
entt::resolve<base_t>().reset();
entt::resolve<derived_t>().reset();
entt::resolve<abstract_t>().reset();
entt::resolve<concrete_t>().reset();
entt::resolve<property_t>().reset();
entt::resolve<clazz_t>().reset();
ASSERT_FALSE(entt::resolve_id("double"_hs));
ASSERT_FALSE(entt::resolve_id("base"_hs));

View File

@@ -2,6 +2,7 @@
#include <entt/core/hashed_string.hpp>
#include <entt/meta/factory.hpp>
#include <entt/meta/meta.hpp>
#include <entt/meta/resolve.hpp>
#include "types.h"
position create_position(int x, int y) {
@@ -23,8 +24,8 @@ ENTT_API void set_up() {
}
ENTT_API void tear_down() {
entt::meta<position>().reset();
entt::meta<velocity>().reset();
entt::resolve<position>().reset();
entt::resolve<velocity>().reset();
}
ENTT_API entt::meta_any wrap_int(int value) {

View File

@@ -2,6 +2,7 @@
#include <entt/core/hashed_string.hpp>
#include <entt/meta/factory.hpp>
#include <entt/meta/meta.hpp>
#include <entt/meta/resolve.hpp>
#include "types.h"
position create_position(int x, int y) {
@@ -23,8 +24,8 @@ void set_up() {
}
void tear_down() {
entt::meta<position>().reset();
entt::meta<velocity>().reset();
entt::resolve<position>().reset();
entt::resolve<velocity>().reset();
}
CR_EXPORT int cr_main(cr_plugin *ctx, cr_op operation) {

View File

@@ -2,6 +2,7 @@
#include <entt/core/hashed_string.hpp>
#include <entt/meta/factory.hpp>
#include <entt/meta/meta.hpp>
#include <entt/meta/resolve.hpp>
#include "types.h"
position create_position(int x, int y) {
@@ -23,8 +24,8 @@ void set_up() {
}
void tear_down() {
entt::meta<position>().reset();
entt::meta<velocity>().reset();
entt::resolve<position>().reset();
entt::resolve<velocity>().reset();
}
CR_EXPORT int cr_main(cr_plugin *ctx, cr_op operation) {