From acb70d4440881cbb3f77b1fd61104ef0b9d712a0 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Fri, 20 Dec 2019 14:12:16 +0100 Subject: [PATCH] meta: uses type_id_v rather than other techniques --- TODO | 2 -- src/entt/meta/factory.hpp | 32 ++++++------------------- src/entt/meta/meta.hpp | 47 +++++++++++++++++-------------------- test/entt/meta/meta.cpp | 6 ++--- test/lib/meta/lib.cpp | 5 +++- test/lib/meta/main.cpp | 15 ++++++++---- test/plugin/meta/main.cpp | 9 +++---- test/plugin/meta/plugin.cpp | 5 ---- 8 files changed, 49 insertions(+), 72 deletions(-) diff --git a/TODO b/TODO index 9eae31b2c..19297d89f 100644 --- a/TODO +++ b/TODO @@ -27,8 +27,6 @@ * Mission: get rid of named types - make it possible to use custom generators (eg for plugins) * ENTT_ID_TYPE id() (eg dispatcher) can be a data member rather than a virtual function - * meta: use type_id, remove import, everything should work transparently - * type_id_enabled and fallback on old-fashioned families otherwise * add discard pool functionality (+ test) - use type_id also for groups, get rid of extent and subfunctions, is it possible? - update doc: dispatcher, emitter, registry, meta, across boundaries diff --git a/src/entt/meta/factory.hpp b/src/entt/meta/factory.hpp index 9be727ce5..156e4e779 100644 --- a/src/entt/meta/factory.hpp +++ b/src/entt/meta/factory.hpp @@ -391,11 +391,11 @@ public: auto type(const ENTT_ID_TYPE identifier) ENTT_NOEXCEPT { auto * const node = internal::meta_info::resolve(); - ENTT_ASSERT(!exists(identifier, *internal::meta_info<>::context())); - ENTT_ASSERT(!exists(node, *internal::meta_info<>::context())); + ENTT_ASSERT(!exists(identifier, *internal::meta_info<>::global)); + ENTT_ASSERT(!exists(node, *internal::meta_info<>::global)); node->identifier = identifier; - node->next = *internal::meta_info<>::context(); - *internal::meta_info<>::context() = node; + node->next = *internal::meta_info<>::global; + *internal::meta_info<>::global = node; return meta_factory{&node->prop}; } @@ -777,7 +777,7 @@ public: */ auto reset() ENTT_NOEXCEPT { auto * const node = internal::meta_info::resolve(); - auto **it = internal::meta_info<>::context(); + auto **it = internal::meta_info<>::global; while(*it && *it != node) { it = &(*it)->next; @@ -811,24 +811,6 @@ public: return meta_factory{&node->prop}; } - - /** - * @brief Imports a meta type from another context. - * @param identifier Unique identifier. - * @return An extended meta factory for the given type. - */ - auto import(const ENTT_ID_TYPE identifier) ENTT_NOEXCEPT { - auto * const ctx = *internal::meta_info<>::context(); - - ENTT_ASSERT(exists(identifier, ctx)); - ENTT_ASSERT(!exists(internal::meta_info::resolve(), ctx)); - - internal::meta_info::alias = internal::find_if([identifier](const auto *curr) { - return curr->identifier == identifier; - }, ctx); - - return meta_factory{&internal::meta_info::resolve()->prop}; - } }; @@ -870,7 +852,7 @@ inline meta_type resolve() ENTT_NOEXCEPT { inline meta_type resolve(const ENTT_ID_TYPE identifier) ENTT_NOEXCEPT { return internal::find_if([identifier](const auto *curr) { return curr->identifier == identifier; - }, *internal::meta_info<>::context()); + }, *internal::meta_info<>::global); } @@ -882,7 +864,7 @@ inline meta_type resolve(const ENTT_ID_TYPE identifier) ENTT_NOEXCEPT { template inline std::enable_if_t, void> resolve(Op op) { - internal::visit(std::move(op), *internal::meta_info<>::context()); + internal::visit(std::move(op), *internal::meta_info<>::global); } diff --git a/src/entt/meta/meta.hpp b/src/entt/meta/meta.hpp index 3a9c6b753..2cd7ae159 100644 --- a/src/entt/meta/meta.hpp +++ b/src/entt/meta/meta.hpp @@ -7,7 +7,7 @@ #include #include #include "../config/config.h" -#include "../core/attribute.h" +#include "../core/type_info.hpp" #include "../core/type_traits.hpp" @@ -100,6 +100,7 @@ struct meta_func_node { struct meta_type_node { using size_type = std::size_t; + const ENTT_ID_TYPE id; ENTT_ID_TYPE identifier; meta_type_node * next; meta_prop_node * prop; @@ -190,12 +191,12 @@ bool compare(const void *lhs, const void *rhs) { template -struct ENTT_API meta_node { +struct meta_node { static_assert(std::is_same_v>...>); - inline static meta_type_node *alias = nullptr; inline static meta_type_node * resolve() ENTT_NOEXCEPT { static meta_type_node node{ + type_id_v, {}, nullptr, nullptr, @@ -216,19 +217,15 @@ struct ENTT_API meta_node { &meta_node>...>::resolve }; - return alias ? alias : &node; + return &node; } }; template<> -struct ENTT_API meta_node<> { - inline static meta_type_node **shared = nullptr; - - inline static meta_type_node ** context() ENTT_NOEXCEPT { - static meta_type_node *local = nullptr; - return shared ? shared : &local; - } +struct meta_node<> { + inline static meta_type_node *local = nullptr; + inline static meta_type_node **global = &local; }; @@ -252,12 +249,11 @@ struct meta_ctx { * @param other A valid context to which to bind. */ static void bind(meta_ctx other) ENTT_NOEXCEPT { - ENTT_ASSERT(!internal::meta_info<>::shared); - internal::meta_info<>::shared = other.ctx; + internal::meta_info<>::global = other.ctx; } private: - internal::meta_type_node **ctx{internal::meta_info<>::context()}; + internal::meta_type_node **ctx{&internal::meta_info<>::local}; }; @@ -464,9 +460,9 @@ public: const Type * try_cast() const { void *ret = nullptr; - if(const auto * const type = internal::meta_info::resolve(); type == node) { + if(const auto id = internal::meta_info::resolve()->id; node && node->id == id) { ret = instance; - } else if(const auto *base = internal::find_if<&internal::meta_type_node::base>([type](const auto *curr) { return curr->type() == type; }, node); base) { + } else if(const auto *base = internal::find_if<&internal::meta_type_node::base>([id](const auto *curr) { return curr->type()->id == id; }, node); base) { ret = base->cast(instance); } @@ -516,9 +512,9 @@ public: meta_any convert() const { meta_any any{}; - if(const auto * const type = internal::meta_info::resolve(); node == type) { + if(const auto id = internal::meta_info::resolve()->id; node && node->id == id) { any = *static_cast(instance); - } else if(const auto * const conv = internal::find_if<&internal::meta_type_node::conv>([type](const auto *curr) { return curr->type() == type; }, node); conv) { + } else if(const auto * const conv = internal::find_if<&internal::meta_type_node::conv>([id](const auto *curr) { return curr->type()->id == id; }, node); conv) { any = conv->conv(instance); } @@ -532,7 +528,7 @@ public: */ template bool convert() { - bool valid = (node == internal::meta_info::resolve()); + bool valid = (node && node->id == internal::meta_info::resolve()->id); if(!valid) { if(auto any = std::as_const(*this).convert(); (valid = static_cast(any))) { @@ -578,7 +574,7 @@ public: * otherwise. */ bool operator==(const meta_any &other) const { - return node == other.node && (!node || node->compare(instance, other.instance)); + return (!node && !other.node) || (node && other.node && node->id == other.node->id && node->compare(instance, other.instance)); } /** @@ -1115,8 +1111,9 @@ class meta_type { auto ctor(std::index_sequence) const { return internal::find_if([](const auto *candidate) { return candidate->size == sizeof...(Args) && ([](auto *from, auto *to) { - return (from == to) || internal::find_if<&internal::meta_type_node::base>([to](const auto *curr) { return curr->type() == to; }, from) - || internal::find_if<&internal::meta_type_node::conv>([to](const auto *curr) { return curr->type() == to; }, from); + return (from->id == to->id) + || internal::find_if<&internal::meta_type_node::base>([to](const auto *curr) { return curr->type()->id == to->id; }, from) + || internal::find_if<&internal::meta_type_node::conv>([to](const auto *curr) { return curr->type()->id == to->id; }, from); }(internal::meta_info::resolve(), candidate->arg(Indexes)) && ...); }, node->ctor); } @@ -1304,8 +1301,8 @@ public: */ template meta_conv conv() const { - return internal::find_if<&internal::meta_type_node::conv>([type = internal::meta_info::resolve()](const auto *curr) { - return curr->type() == type; + return internal::find_if<&internal::meta_type_node::conv>([id = internal::meta_info::resolve()->id](const auto *curr) { + return curr->type()->id == id; }, node); } @@ -1459,7 +1456,7 @@ public: * otherwise. */ bool operator==(const meta_type &other) const ENTT_NOEXCEPT { - return node == other.node; + return (!node && !other.node) || (node && other.node && node->id == other.node->id); } private: diff --git a/test/entt/meta/meta.cpp b/test/entt/meta/meta.cpp index b9b3c3275..7cc4da4db 100644 --- a/test/entt/meta/meta.cpp +++ b/test/entt/meta/meta.cpp @@ -1903,7 +1903,7 @@ TEST_F(Meta, PropertiesAndCornerCases) { } TEST_F(Meta, Reset) { - ASSERT_NE(*entt::internal::meta_info<>::context(), nullptr); + ASSERT_NE(*entt::internal::meta_info<>::global, nullptr); entt::meta().reset(); entt::meta().reset(); @@ -1921,7 +1921,7 @@ TEST_F(Meta, Reset) { entt::meta().reset(); entt::meta().reset(); - ASSERT_EQ(*entt::internal::meta_info<>::context(), nullptr); + ASSERT_EQ(*entt::internal::meta_info<>::global, nullptr); ASSERT_FALSE(entt::resolve("char"_hs)); ASSERT_FALSE(entt::resolve("base"_hs)); @@ -1935,7 +1935,7 @@ TEST_F(Meta, Reset) { ASSERT_FALSE(entt::resolve("another_abstract_type"_hs)); ASSERT_FALSE(entt::resolve("concrete"_hs)); - ASSERT_EQ(*entt::internal::meta_info<>::context(), nullptr); + ASSERT_EQ(*entt::internal::meta_info<>::global, nullptr); Meta::SetUpAfterUnregistration(); entt::meta_any any{42.}; diff --git a/test/lib/meta/lib.cpp b/test/lib/meta/lib.cpp index fbd7d8f67..af922c136 100644 --- a/test/lib/meta/lib.cpp +++ b/test/lib/meta/lib.cpp @@ -8,7 +8,9 @@ position create_position(int x, int y) { return position{x, y}; } -ENTT_API void set_up() { +ENTT_API void set_up(entt::meta_ctx ctx) { + entt::meta_ctx::bind(ctx); + entt::meta() .type("position"_hs) .ctor<&create_position>() @@ -16,6 +18,7 @@ ENTT_API void set_up() { .data<&position::y>("y"_hs); entt::meta() + .type("velocity"_hs) .ctor<>() .data<&velocity::dx>("dx"_hs) .data<&velocity::dy>("dy"_hs); diff --git a/test/lib/meta/main.cpp b/test/lib/meta/main.cpp index ae4a1da05..2b7fb3a00 100644 --- a/test/lib/meta/main.cpp +++ b/test/lib/meta/main.cpp @@ -4,20 +4,21 @@ #include #include "types.h" -ENTT_API void set_up(); +ENTT_API void set_up(entt::meta_ctx); ENTT_API void tear_down(); ENTT_API entt::meta_any wrap_int(int); TEST(Lib, Meta) { ASSERT_FALSE(entt::resolve("position"_hs)); - set_up(); + set_up(entt::meta_ctx{}); entt::meta().conv(); ASSERT_TRUE(entt::resolve("position"_hs)); + ASSERT_TRUE(entt::resolve("velocity"_hs)); auto pos = entt::resolve("position"_hs).construct(42., 3.); - auto vel = entt::resolve().ctor().invoke(); + auto vel = entt::resolve("velocity"_hs).ctor().invoke(); ASSERT_TRUE(pos && vel); @@ -27,11 +28,15 @@ TEST(Lib, Meta) { ASSERT_EQ(pos.type().data("y"_hs).get(*pos).cast(), 3); ASSERT_EQ(vel.type().data("dx"_hs).type(), entt::resolve()); - ASSERT_TRUE(vel.type().data("dy"_hs).get(*vel).convert()); + ASSERT_TRUE(vel.type().data("dy"_hs).get(*vel).convert()); ASSERT_EQ(vel.type().data("dx"_hs).get(*vel).cast(), 0.); ASSERT_EQ(vel.type().data("dy"_hs).get(*vel).cast(), 0.); - ASSERT_EQ(wrap_int(1).type(), entt::resolve()); + ASSERT_EQ(wrap_int(42).type(), entt::resolve()); + ASSERT_EQ(wrap_int(42).cast(), 42); tear_down(); + + ASSERT_FALSE(entt::resolve("position"_hs)); + ASSERT_FALSE(entt::resolve("velocity"_hs)); } diff --git a/test/plugin/meta/main.cpp b/test/plugin/meta/main.cpp index 771e1ed98..a91e1a097 100644 --- a/test/plugin/meta/main.cpp +++ b/test/plugin/meta/main.cpp @@ -7,11 +7,7 @@ #include "types.h" TEST(Lib, Meta) { - entt::meta().type("double"_hs); - entt::meta().type("int"_hs); - ASSERT_FALSE(entt::resolve("position"_hs)); - ASSERT_FALSE(entt::resolve().conv()); userdata ud{}; @@ -20,9 +16,10 @@ TEST(Lib, Meta) { cr_plugin_load(ctx, PLUGIN); cr_plugin_update(ctx); + entt::meta().conv(); + ASSERT_TRUE(entt::resolve("position"_hs)); ASSERT_TRUE(entt::resolve("velocity"_hs)); - ASSERT_TRUE(entt::resolve().conv()); auto pos = entt::resolve("position"_hs).construct(42., 3.); auto vel = entt::resolve("velocity"_hs).ctor().invoke(); @@ -35,7 +32,7 @@ TEST(Lib, Meta) { ASSERT_EQ(pos.type().data("y"_hs).get(*pos).cast(), 3); ASSERT_EQ(vel.type().data("dx"_hs).type(), entt::resolve()); - ASSERT_TRUE(vel.type().data("dy"_hs).get(*vel).convert()); + ASSERT_TRUE(vel.type().data("dy"_hs).get(*vel).convert()); ASSERT_EQ(vel.type().data("dx"_hs).get(*vel).cast(), 0.); ASSERT_EQ(vel.type().data("dy"_hs).get(*vel).cast(), 0.); diff --git a/test/plugin/meta/plugin.cpp b/test/plugin/meta/plugin.cpp index 939ef05d1..74dcb6160 100644 --- a/test/plugin/meta/plugin.cpp +++ b/test/plugin/meta/plugin.cpp @@ -9,11 +9,6 @@ position create_position(int x, int y) { } void set_up() { - entt::meta().import("double"_hs); - entt::meta().import("int"_hs); - - entt::meta().conv(); - entt::meta() .type("position"_hs) .ctor<&create_position>()