فهرست منبع

more on sigh/sink

Michele Caini 6 سال پیش
والد
کامیت
ddba29cc09
4فایلهای تغییر یافته به همراه37 افزوده شده و 17 حذف شده
  1. 1 0
      TODO
  2. 5 2
      docs/md/signal.md
  3. 11 0
      src/entt/signal/sigh.hpp
  4. 20 15
      test/entt/signal/sigh.cpp

+ 1 - 0
TODO

@@ -5,6 +5,7 @@
 * debugging tools (#60): the issue online already contains interesting tips on this, look at it
 * runner proposal: https://en.wikipedia.org/wiki/Fork%E2%80%93join_model https://slide-rs.github.io/specs/03_dispatcher.html
 * work stealing job system (see #100)
+  - mt scheduler based on const awareness for types
 * meta: sort of meta view based on meta stuff to iterate entities, void * and meta info objects
 * allow for built-in parallel each if possible
 * allow to replace std:: with custom implementations

+ 5 - 2
docs/md/signal.md

@@ -201,6 +201,9 @@ signal.sink().disconnect<&foo>();
 // disconnect a member function of an instance
 signal.sink().disconnect<&listener::bar>(&instance);
 
+// disconnect all the member functions of an instance, if any
+signal.sink().disconnect(&instance);
+
 // discards all the listeners at once
 signal.sink().disconnect();
 ```
@@ -289,11 +292,11 @@ dispatcher.sink<another_event>().connect<&listener::method>(&listener);
 ```
 
 The `disconnect` member function follows the same pattern and can be used to
-selectively remove listeners:
+remove one listener at a time or all of them at once:
 
 ```cpp
 dispatcher.sink<an_event>().disconnect<&listener::receive>(&listener);
-dispatcher.sink<another_event>().disconnect<&listener::method>(&listener);
+dispatcher.sink<another_event>().disconnect(&listener);
 ```
 
 The `trigger` member function serves the purpose of sending an immediate event

+ 11 - 0
src/entt/signal/sigh.hpp

@@ -213,6 +213,17 @@ public:
         }), calls->end());
     }
 
+    /**
+     * @brief Disconnects member functions or free functions based on an
+     * instance or specific payload.
+     * @param value_or_instance A valid pointer that fits the purpose.
+     */
+    void disconnect(const void *value_or_instance) {
+        calls->erase(std::remove_if(calls->begin(), calls->end(), [value_or_instance](const auto &delegate) {
+            return value_or_instance == delegate.instance();
+        }), calls->end());
+    }
+
     /**
      * @brief Disconnects all the listeners from a signal.
      */

+ 20 - 15
test/entt/signal/sigh.cpp

@@ -111,7 +111,7 @@ TEST(SigH, Functions) {
     sigh.publish(v);
 
     ASSERT_FALSE(sigh.empty());
-    ASSERT_EQ(static_cast<entt::sigh<bool(int)>::size_type>(1), sigh.size());
+    ASSERT_EQ(static_cast<entt::sigh<void(int &)>::size_type>(1), sigh.size());
     ASSERT_EQ(42, v);
 
     v = 0;
@@ -119,42 +119,47 @@ TEST(SigH, Functions) {
     sigh.publish(v);
 
     ASSERT_TRUE(sigh.empty());
-    ASSERT_EQ(static_cast<entt::sigh<bool(int)>::size_type>(0), sigh.size());
+    ASSERT_EQ(static_cast<entt::sigh<void(int &)>::size_type>(0), sigh.size());
     ASSERT_EQ(v, 0);
 
     sigh.sink().connect<&sigh_listener::f>();
-}
+
+    ASSERT_FALSE(sigh.empty());
+    ASSERT_EQ(static_cast<entt::sigh<void(int &)>::size_type>(1), sigh.size());
+
+    sigh.sink().disconnect(nullptr);
+
+    ASSERT_TRUE(sigh.empty());
+    ASSERT_EQ(static_cast<entt::sigh<void(int &)>::size_type>(0), sigh.size());}
 
 TEST(SigH, Members) {
-    sigh_listener s;
-    sigh_listener *ptr = &s;
+    sigh_listener l1, l2;
     entt::sigh<bool(int)> sigh;
 
-    sigh.sink().connect<&sigh_listener::g>(ptr);
+    sigh.sink().connect<&sigh_listener::g>(&l1);
     sigh.publish(42);
 
-    ASSERT_TRUE(s.k);
+    ASSERT_TRUE(l1.k);
     ASSERT_FALSE(sigh.empty());
     ASSERT_EQ(static_cast<entt::sigh<bool(int)>::size_type>(1), sigh.size());
 
-    sigh.sink().disconnect<&sigh_listener::g>(ptr);
+    sigh.sink().disconnect<&sigh_listener::g>(&l1);
     sigh.publish(42);
 
-    ASSERT_TRUE(s.k);
+    ASSERT_TRUE(l1.k);
     ASSERT_TRUE(sigh.empty());
     ASSERT_EQ(static_cast<entt::sigh<bool(int)>::size_type>(0), sigh.size());
 
-    sigh.sink().connect<&sigh_listener::g>(ptr);
-    sigh.sink().connect<&sigh_listener::h>(ptr);
+    sigh.sink().connect<&sigh_listener::g>(&l1);
+    sigh.sink().connect<&sigh_listener::h>(&l2);
 
     ASSERT_FALSE(sigh.empty());
     ASSERT_EQ(static_cast<entt::sigh<bool(int)>::size_type>(2), sigh.size());
 
-    sigh.sink().disconnect<&sigh_listener::g>(ptr);
-    sigh.sink().disconnect<&sigh_listener::h>(ptr);
+    sigh.sink().disconnect(&l1);
 
-    ASSERT_TRUE(sigh.empty());
-    ASSERT_EQ(static_cast<entt::sigh<bool(int)>::size_type>(0), sigh.size());
+    ASSERT_FALSE(sigh.empty());
+    ASSERT_EQ(static_cast<entt::sigh<bool(int)>::size_type>(1), sigh.size());
 }
 
 TEST(SigH, Collector) {