Просмотр исходного кода

dispatcher: uses type_id_v rather than a family

Michele Caini 6 лет назад
Родитель
Сommit
d1cdeb4a2d

+ 15 - 13
src/entt/signal/dispatcher.hpp

@@ -6,11 +6,11 @@
 #include <memory>
 #include <cstddef>
 #include <utility>
+#include <iterator>
 #include <algorithm>
 #include <type_traits>
 #include "../config/config.h"
-#include "../core/attribute.h"
-#include "../core/family.hpp"
+#include "../core/type_info.hpp"
 #include "sigh.hpp"
 
 
@@ -31,15 +31,11 @@ namespace entt {
  * crashes.
  */
 class dispatcher {
-    struct ENTT_API dispatcher_event_family;
-
-    template<typename Type>
-    using event_family = family<Type, dispatcher_event_family>;
-
     struct basic_pool {
         virtual ~basic_pool() = default;
         virtual void publish() = 0;
         virtual void clear() ENTT_NOEXCEPT = 0;
+        virtual ENTT_ID_TYPE id() const ENTT_NOEXCEPT = 0;
     };
 
     template<typename Event>
@@ -75,6 +71,10 @@ class dispatcher {
             events.emplace_back(std::forward<Args>(args)...);
         }
 
+        ENTT_ID_TYPE id() const ENTT_NOEXCEPT override {
+            return type_id_v<Event>;
+        }
+
     private:
         signal_type signal{};
         std::vector<Event> events;
@@ -82,17 +82,19 @@ class dispatcher {
 
     template<typename Event>
     pool_handler<Event> & assure() {
-        const auto etype = event_family<Event>::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<Event>;
+        }));
 
-        if(!(etype < pools.size())) {
-            pools.resize(etype+1);
+        if(!(index < pools.size())) {
+            pools.resize(index+1);
         }
 
-        if(!pools[etype]) {
-            pools[etype] = std::make_unique<pool_handler<Event>>();
+        if(!pools[index]) {
+            pools[index] = std::make_unique<pool_handler<Event>>();
         }
 
-        return static_cast<pool_handler<Event> &>(*pools[etype]);
+        return static_cast<pool_handler<Event> &>(*pools[index]);
     }
 
 public:

+ 0 - 2
test/lib/dispatcher/lib.cpp

@@ -2,8 +2,6 @@
 #include <entt/signal/dispatcher.hpp>
 #include "types.h"
 
-template struct entt::family<event, entt::dispatcher::dispatcher_event_family>;
-
 ENTT_API void trigger(int value, entt::dispatcher &dispatcher) {
     dispatcher.trigger<message>(value);
 }

+ 2 - 4
test/lib/dispatcher/types.h

@@ -1,13 +1,11 @@
 #ifndef ENTT_LIB_DISPATCHER_TYPES_H
 #define ENTT_LIB_DISPATCHER_TYPES_H
 
-#include <entt/core/attribute.h>
-
-struct ENTT_API message {
+struct message {
     int payload;
 };
 
-struct ENTT_API event {
+struct event {
     int payload;
 };
 

+ 33 - 0
test/plugin/dispatcher/main.cpp

@@ -0,0 +1,33 @@
+#define CR_HOST
+
+#include <cr.h>
+#include <gtest/gtest.h>
+#include <entt/core/utility.hpp>
+#include <entt/signal/dispatcher.hpp>
+#include "types.h"
+
+struct listener {
+    void on(event ev) { value = ev.payload; }
+    void on(message msg) { value = msg.payload; }
+    int value{};
+};
+
+TEST(Lib, Dispatcher) {
+    entt::dispatcher dispatcher;
+    listener listener;
+
+    dispatcher.sink<event>().connect<entt::overload<void(event)>(&listener::on)>(listener);
+    dispatcher.sink<message>().connect<entt::overload<void(message)>(&listener::on)>(listener);
+    dispatcher.trigger<event>(3);
+
+    ASSERT_EQ(listener.value, 3);
+
+    cr_plugin ctx;
+    ctx.userdata = &dispatcher;
+    cr_plugin_load(ctx, PLUGIN);
+    cr_plugin_update(ctx);
+
+    ASSERT_EQ(listener.value, 42);
+
+    cr_plugin_close(ctx);
+}

+ 18 - 0
test/plugin/dispatcher/plugin.cpp

@@ -0,0 +1,18 @@
+#include <cr.h>
+#include <entt/signal/dispatcher.hpp>
+#include "types.h"
+
+CR_EXPORT int cr_main(cr_plugin *ctx, cr_op operation) {
+    switch (operation) {
+    case CR_STEP:
+        static_cast<entt::dispatcher *>(ctx->userdata)->trigger<message>(42);
+        break;
+    case CR_LOAD:
+    case CR_UNLOAD:
+    case CR_CLOSE:
+        // nothing to do here, this is only a test.
+        break;
+    }
+
+    return 0;
+}

+ 12 - 0
test/plugin/dispatcher/types.h

@@ -0,0 +1,12 @@
+#ifndef ENTT_PLUGIN_DISPATCHER_TYPES_H
+#define ENTT_PLUGIN_DISPATCHER_TYPES_H
+
+struct message {
+    int payload;
+};
+
+struct event {
+    int payload;
+};
+
+#endif // ENTT_PLUGIN_DISPATCHER_TYPES_H