Преглед изворни кода

allow attaching listeners at any time, allow removing current listener

Michele Caini пре 8 година
родитељ
комит
cb49910ed2
3 измењених фајлова са 17 додато и 6 уклоњено
  1. 3 1
      src/entt/signal/dispatcher.hpp
  2. 5 2
      src/entt/signal/sigh.hpp
  3. 9 3
      src/entt/signal/signal.hpp

+ 3 - 1
src/entt/signal/dispatcher.hpp

@@ -181,7 +181,9 @@ public:
         const auto buf = buffer(mode);
         const auto buf = buffer(mode);
         mode = !mode;
         mode = !mode;
 
 
-        for(auto &&wrapper: wrappers) {
+        for(auto pos = wrappers.size(); pos > decltype(pos){0}; --pos) {
+            auto &wrapper = wrappers[pos-1];
+
             if(wrapper) {
             if(wrapper) {
                 wrapper->publish(buf);
                 wrapper->publish(buf);
             }
             }

+ 5 - 2
src/entt/signal/sigh.hpp

@@ -229,7 +229,8 @@ public:
      * @param args Arguments to use to invoke listeners.
      * @param args Arguments to use to invoke listeners.
      */
      */
     void publish(Args... args) {
     void publish(Args... args) {
-        for(auto &&call: calls) {
+        for(auto pos = calls.size(); pos > size_type{0}; --pos) {
+            auto &call = calls[pos-1];
             call.second(call.first, args...);
             call.second(call.first, args...);
         }
         }
     }
     }
@@ -242,7 +243,9 @@ public:
     collector_type collect(Args... args) {
     collector_type collect(Args... args) {
         collector_type collector;
         collector_type collector;
 
 
-        for(auto &&call: calls) {
+        for(auto pos = calls.size(); pos > size_type{0}; --pos) {
+            auto &call = calls[pos-1];
+
             if(!this->invoke(collector, call.second, call.first, args...)) {
             if(!this->invoke(collector, call.second, call.first, args...)) {
                 break;
                 break;
             }
             }

+ 9 - 3
src/entt/signal/signal.hpp

@@ -167,11 +167,17 @@ public:
      * @param args Arguments to use to invoke listeners.
      * @param args Arguments to use to invoke listeners.
      */
      */
     void publish(Args... args) {
     void publish(Args... args) {
-        for(auto it = calls.rbegin(), end = calls.rend(); it != end; it++) {
-            if(!(it->second)(it->first, args...)) {
-                calls.erase(std::next(it).base());
+        std::vector<call_type> next;
+
+        for(auto pos = calls.size(); pos > size_type{0}; --pos) {
+            auto &call = calls[pos-1];
+
+            if((call.second)(call.first, args...)) {
+                next.push_back(call);
             }
             }
         }
         }
+
+        calls.swap(next);
     }
     }
 
 
     /**
     /**