Ver Fonte

sink: before/disconnect and const void *

Michele Caini há 6 anos atrás
pai
commit
faf5a38f1c
2 ficheiros alterados com 33 adições e 31 exclusões
  1. 1 1
      TODO
  2. 32 30
      src/entt/signal/sigh.hpp

+ 1 - 1
TODO

@@ -18,7 +18,6 @@
 * allow for custom stomp functions
 * deprecate/replace snapshot
 * experiment with hi-bitset for views
-* pointer payload optimization for delegates
 * custom (decoupled) pools ==> double buffering, shared components, multi-model
 * make meta work across boundaries
   - inline variables are fine here, only the head represents a problem
@@ -34,3 +33,4 @@
   - auto foo(It first, It last = entity_type{null})
 * range based registry::remove and some others?
 * nested groups: AB/ABC/ABCD/... (hints: sort, check functions)
+* pointer payload optimization for delegates

+ 32 - 30
src/entt/signal/sigh.hpp

@@ -379,27 +379,28 @@ public:
      * @return A properly initialized sink object.
      */
     template<typename Type>
-    sink before(Type &&value_or_instance) {
-        auto func = [this](const void *instance) {
-            sink other{*this};
-
-            if(instance) {
-                const auto &calls = signal->calls;
-                const auto it = std::find_if(calls.cbegin(), calls.cend(), [instance](const auto &delegate) {
-                    return delegate.instance() == instance;
-                });
+    sink before(Type &value_or_instance) {
+        return before(&value_or_instance);
+    }
 
-                other.offset = std::distance(it, calls.cend());
-            }
+    /**
+     * @brief Returns a sink that connects before an opaque instance or payload.
+     * @param value_or_instance An opaque pointer that fits the purpose.
+     * @return A properly initialized sink object.
+     */
+    sink before(const void *value_or_instance) {
+        sink other{*this};
 
-            return other;
-        };
+        if(value_or_instance) {
+            const auto &calls = signal->calls;
+            const auto it = std::find_if(calls.cbegin(), calls.cend(), [value_or_instance](const auto &delegate) {
+                return delegate.instance() == value_or_instance;
+            });
 
-        if constexpr(std::is_pointer_v<std::decay_t<Type>>) {
-            return func(value_or_instance);
-        } else {
-            return func(&value_or_instance);
+            other.offset = std::distance(it, calls.cend());
         }
+
+        return other;
     }
 
     /**
@@ -498,20 +499,21 @@ public:
      * @param value_or_instance A valid object that fits the purpose.
      */
     template<typename Type>
-    void disconnect(Type &&value_or_instance) {
-        auto func = [this](const void *instance) {
-            if(instance) {
-                auto &calls = signal->calls;
-                calls.erase(std::remove_if(calls.begin(), calls.end(), [instance](const auto &delegate) {
-                    return delegate.instance() == instance;
-                }), calls.end());
-            }
-        };
+    void disconnect(Type &value_or_instance) {
+        disconnect(&value_or_instance);
+    }
 
-        if constexpr(std::is_pointer_v<std::decay_t<Type>>) {
-            func(value_or_instance);
-        } else {
-            func(&value_or_instance);
+    /**
+     * @brief Disconnects member functions or free functions based on an opaque
+     * instance or payload.
+     * @param value_or_instance An opaque pointer that fits the purpose.
+     */
+    void disconnect(const void *value_or_instance) {
+        if(value_or_instance) {
+            auto &calls = signal->calls;
+            calls.erase(std::remove_if(calls.begin(), calls.end(), [value_or_instance](const auto &delegate) {
+                return delegate.instance() == value_or_instance;
+            }), calls.end());
         }
     }