diff --git a/TODO b/TODO index eb71cd852..313cfd88f 100644 --- a/TODO +++ b/TODO @@ -26,9 +26,8 @@ * Mission: get rid of named types - make it possible to use custom generators (eg for plugins) * dispatcher, emitter, registry - - generators as arguments to family::type overloads - - generators to constructors - - bind identifiers by name (as for meta) + * dispatcher/emitter: id shouldn't be part of the class (upcoming feature discard will create a hole otherwise) + * type_id_enabled and fallback on old-fashioned families otherwise - reintroduce old-fashion family and add a new family-like thing with generators - families should be defined as out-of-class to guarantee the same identifiers for the same types - update doc: family, dispatcher, emitter, registry, meta, across boundaries diff --git a/src/entt/signal/emitter.hpp b/src/entt/signal/emitter.hpp index c81bb7396..c3f24b055 100644 --- a/src/entt/signal/emitter.hpp +++ b/src/entt/signal/emitter.hpp @@ -10,8 +10,7 @@ #include #include #include "../config/config.h" -#include "../core/attribute.h" -#include "../core/family.hpp" +#include "../core/type_info.hpp" namespace entt { @@ -40,15 +39,11 @@ namespace entt { */ template class emitter { - struct ENTT_API emitter_event_family; - - template - using event_family = family; - struct basic_pool { virtual ~basic_pool() = default; virtual bool empty() const ENTT_NOEXCEPT = 0; virtual void clear() ENTT_NOEXCEPT = 0; + virtual ENTT_ID_TYPE id() const ENTT_NOEXCEPT = 0; }; template @@ -112,6 +107,10 @@ class emitter { on_list.remove_if([](auto &&element) { return element.first; }); } + ENTT_ID_TYPE id() const ENTT_NOEXCEPT override { + return type_id_v; + } + private: bool publishing{false}; container_type once_list{}; @@ -120,17 +119,19 @@ class emitter { template const pool_handler & assure() const { - const auto etype = event_family>::type(); + static const auto index = std::distance(pools.cbegin(), std::find_if(pools.cbegin(), pools.cend(), [](auto &&curr) { + return curr && curr->id() == type_id_v; + })); - if(!(etype < pools.size())) { - pools.resize(etype+1); + if(!(index < pools.size())) { + pools.resize(index+1); } - if(!pools[etype]) { - pools[etype] = std::make_unique>(); + if(!pools[index]) { + pools[index] = std::make_unique>(); } - return static_cast &>(*pools[etype]); + return static_cast &>(*pools[index]); } template diff --git a/test/lib/emitter/lib.cpp b/test/lib/emitter/lib.cpp index 692a502b4..e5c9b43d0 100644 --- a/test/lib/emitter/lib.cpp +++ b/test/lib/emitter/lib.cpp @@ -2,8 +2,6 @@ #include #include "types.h" -template struct entt::family; - ENTT_API void emit(int value, test_emitter &emitter) { emitter.publish(value); } diff --git a/test/lib/emitter/types.h b/test/lib/emitter/types.h index 3c5a05248..41274e899 100644 --- a/test/lib/emitter/types.h +++ b/test/lib/emitter/types.h @@ -1,18 +1,17 @@ #ifndef ENTT_LIB_EMITTER_TYPES_H #define ENTT_LIB_EMITTER_TYPES_H -#include #include -struct ENTT_API test_emitter +struct test_emitter : entt::emitter {}; -struct ENTT_API message { +struct message { int payload; }; -struct ENTT_API event { +struct event { int payload; }; diff --git a/test/plugin/emitter/main.cpp b/test/plugin/emitter/main.cpp index e69de29bb..7d09d6300 100644 --- a/test/plugin/emitter/main.cpp +++ b/test/plugin/emitter/main.cpp @@ -0,0 +1,26 @@ +#define CR_HOST + +#include +#include +#include +#include "types.h" + +TEST(Lib, Emitter) { + test_emitter emitter; + int value{}; + + emitter.once([&](event ev, test_emitter &) { value = ev.payload; }); + emitter.once([&](message msg, test_emitter &) { value = msg.payload; }); + emitter.publish(3); + + ASSERT_EQ(value, 3); + + cr_plugin ctx; + ctx.userdata = &emitter; + cr_plugin_load(ctx, PLUGIN); + cr_plugin_update(ctx); + + ASSERT_EQ(value, 42); + + cr_plugin_close(ctx); +} diff --git a/test/plugin/emitter/plugin.cpp b/test/plugin/emitter/plugin.cpp index e69de29bb..d37d47e00 100644 --- a/test/plugin/emitter/plugin.cpp +++ b/test/plugin/emitter/plugin.cpp @@ -0,0 +1,19 @@ +#include +#include +#include "types.h" + +CR_EXPORT int cr_main(cr_plugin *ctx, cr_op operation) { + switch (operation) { + case CR_STEP: + static_cast(ctx->userdata)->publish(42); + static_cast(ctx->userdata)->publish(3); + break; + case CR_LOAD: + case CR_UNLOAD: + case CR_CLOSE: + // nothing to do here, this is only a test. + break; + } + + return 0; +} diff --git a/test/plugin/emitter/types.h b/test/plugin/emitter/types.h index e69de29bb..dc1af255b 100644 --- a/test/plugin/emitter/types.h +++ b/test/plugin/emitter/types.h @@ -0,0 +1,18 @@ +#ifndef ENTT_PLUGIN_EMITTER_TYPES_H +#define ENTT_PLUGIN_EMITTER_TYPES_H + +#include + +struct test_emitter + : entt::emitter +{}; + +struct message { + int payload; +}; + +struct event { + int payload; +}; + +#endif // ENTT_PLUGIN_EMITTER_TYPES_H