Sfoglia il codice sorgente

dispatcher: enable fetching the number of pending events (#848)

Co-authored-by: WoLfulus <WoLfulus@users.noreply.github.com>
Michele Caini 4 anni fa
parent
commit
7a1c2108a1
3 ha cambiato i file con 57 aggiunte e 0 eliminazioni
  1. 1 0
      AUTHORS
  2. 43 0
      src/entt/signal/dispatcher.hpp
  3. 13 0
      test/entt/signal/dispatcher.cpp

+ 1 - 0
AUTHORS

@@ -46,6 +46,7 @@ The5-1
 vblanco20-1
 willtunnels
 WizardIke
+WoLfulus 
 w1th0utnam3
 xissburg
 zaucy

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

@@ -34,6 +34,7 @@ class dispatcher {
         virtual void publish() = 0;
         virtual void disconnect(void *) = 0;
         virtual void clear() ENTT_NOEXCEPT = 0;
+        virtual std::size_t size() const ENTT_NOEXCEPT = 0;
     };
 
     template<typename Event>
@@ -76,6 +77,10 @@ class dispatcher {
             }
         }
 
+        std::size_t size() const ENTT_NOEXCEPT override {
+            return events.size();
+        }
+
     private:
         sigh<void(Event &)> signal{};
         std::vector<Event> events;
@@ -92,7 +97,19 @@ class dispatcher {
         }
     }
 
+    template<typename Event>
+    [[nodiscard]] const pool_handler<Event> *assure(const id_type id) const {
+        if(const auto it = pools.find(id); it != pools.end()) {
+            return static_cast<const pool_handler<Event> *>(it->second.get());
+        }
+
+        return nullptr;
+    }
+
 public:
+    /*! @brief Unsigned integer type. */
+    using size_type = std::size_t;
+
     /*! @brief Default constructor. */
     dispatcher() = default;
 
@@ -102,6 +119,32 @@ public:
     /*! @brief Default move assignment operator. @return This dispatcher. */
     dispatcher &operator=(dispatcher &&) = default;
 
+    /**
+     * @brief Returns the number of pending events for a given type.
+     * @tparam Event Type of event for which to return the count.
+     * @param id Name used to map the event queue within the dispatcher.
+     * @return The number of pending events for the given type.
+     */
+    template<typename Event>
+    size_type size(const id_type id = type_hash<Event>::value()) const ENTT_NOEXCEPT {
+        const auto *cpool = assure<Event>(id);
+        return cpool ? cpool->size() : 0u;
+    }
+
+    /**
+     * @brief Returns the total number of pending events.
+     * @return The total number of pending events.
+     */
+    size_type size() const ENTT_NOEXCEPT {
+        size_type count{};
+
+        for(auto &&cpool: pools) {
+            count += cpool.second->size();
+        }
+
+        return count;
+    }
+
     /**
      * @brief Returns a sink object for the given event and queue.
      *

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

@@ -32,6 +32,9 @@ TEST(Dispatcher, Functionalities) {
     entt::dispatcher dispatcher;
     receiver receiver;
 
+    ASSERT_EQ(dispatcher.size<an_event>(), 0u);
+    ASSERT_EQ(dispatcher.size(), 0u);
+
     dispatcher.trigger(one_more_event{42});
     dispatcher.enqueue<one_more_event>(42);
     dispatcher.update<one_more_event>();
@@ -40,16 +43,24 @@ TEST(Dispatcher, Functionalities) {
     dispatcher.trigger<an_event>();
     dispatcher.enqueue<an_event>();
 
+    ASSERT_EQ(dispatcher.size<one_more_event>(), 0u);
+    ASSERT_EQ(dispatcher.size<an_event>(), 1u);
+    ASSERT_EQ(dispatcher.size(), 1u);
     ASSERT_EQ(receiver.cnt, 1);
 
     dispatcher.enqueue(another_event{});
     dispatcher.update<another_event>();
 
+    ASSERT_EQ(dispatcher.size<another_event>(), 0u);
+    ASSERT_EQ(dispatcher.size<an_event>(), 1u);
+    ASSERT_EQ(dispatcher.size(), 1u);
     ASSERT_EQ(receiver.cnt, 1);
 
     dispatcher.update<an_event>();
     dispatcher.trigger<an_event>();
 
+    ASSERT_EQ(dispatcher.size<an_event>(), 0u);
+    ASSERT_EQ(dispatcher.size(), 0u);
     ASSERT_EQ(receiver.cnt, 3);
 
     dispatcher.enqueue<an_event>();
@@ -60,6 +71,8 @@ TEST(Dispatcher, Functionalities) {
     dispatcher.clear();
     dispatcher.update();
 
+    ASSERT_EQ(dispatcher.size<an_event>(), 0u);
+    ASSERT_EQ(dispatcher.size(), 0u);
     ASSERT_EQ(receiver.cnt, 3);
 
     receiver.reset();