Răsfoiți Sursa

dispatcher: opaque disconnect (close #523)

Michele Caini 5 ani în urmă
părinte
comite
991244655a
2 a modificat fișierele cu 46 adăugiri și 0 ștergeri
  1. 31 0
      src/entt/signal/dispatcher.hpp
  2. 15 0
      test/entt/signal/dispatcher.cpp

+ 31 - 0
src/entt/signal/dispatcher.hpp

@@ -32,6 +32,7 @@ class dispatcher {
     struct basic_pool {
         virtual ~basic_pool() = default;
         virtual void publish() = 0;
+        virtual void disconnect(void *) = 0;
         virtual void clear() ENTT_NOEXCEPT = 0;
         [[nodiscard]] virtual id_type type_id() const ENTT_NOEXCEPT = 0;
     };
@@ -51,6 +52,10 @@ class dispatcher {
             events.erase(events.cbegin(), events.cbegin()+length);
         }
 
+        void disconnect(void *instance) override {
+            sink().disconnect(instance);
+        }
+
         void clear() ENTT_NOEXCEPT override {
             events.clear();
         }
@@ -185,6 +190,32 @@ public:
         assure<std::decay_t<Event>>().enqueue(std::forward<Event>(event));
     }
 
+    /**
+     * @brief Utility function to disconnect everything related to a given value
+     * or instance from a dispatcher.
+     * @tparam Type Type of class or type of payload.
+     * @param value_or_instance A valid object that fits the purpose.
+     */
+    template<typename Type>
+    void disconnect(Type &value_or_instance) {
+        disconnect(&value_or_instance);
+    }
+
+    /**
+     * @brief Utility function to disconnect everything related to a given value
+     * or instance from a dispatcher.
+     * @tparam Type Type of class or type of payload.
+     * @param value_or_instance A valid object that fits the purpose.
+     */
+    template<typename Type>
+    void disconnect(Type *value_or_instance) {
+        for(auto &&cpool: pools) {
+            if(cpool) {
+                cpool->disconnect(value_or_instance);
+            }
+        }
+    }
+
     /**
      * @brief Discards all the events queued so far.
      *

+ 15 - 0
test/entt/signal/dispatcher.cpp

@@ -81,3 +81,18 @@ TEST(Dispatcher, StopAndGo) {
 
     ASSERT_EQ(receiver.cnt, 2);
 }
+
+TEST(Dispatcher, OpaqueDisconnect) {
+    entt::dispatcher dispatcher;
+    receiver receiver;
+
+    dispatcher.sink<an_event>().connect<&receiver::receive>(receiver);
+    dispatcher.trigger<an_event>();
+
+    ASSERT_EQ(receiver.cnt, 1);
+
+    dispatcher.disconnect(receiver);
+    dispatcher.trigger<an_event>();
+
+    ASSERT_EQ(receiver.cnt, 1);
+}