Browse Source

review: delegate (see #101 and #102)

Michele Caini 7 years ago
parent
commit
957697c383
3 changed files with 27 additions and 11 deletions
  1. 9 3
      README.md
  2. 11 4
      src/entt/signal/delegate.hpp
  3. 7 4
      test/entt/signal/delegate.cpp

+ 9 - 3
README.md

@@ -1890,7 +1890,7 @@ It has member functions to query its internal data structures, like `empty` or
 
 ```cpp
 // checks if there are processes still running
-bool empty = scheduler.empty();
+const auto empty = scheduler.empty();
 
 // gets the number of processes still running
 Scheduler<std::uint32_t>::size_type size = scheduler.size();
@@ -2038,10 +2038,10 @@ _organize_ it:
 
 ```cpp
 // gets the number of resources managed by a cache
-auto size = cache.size();
+const auto size = cache.size();
 
 // checks if a cache contains at least a valid resource
-auto empty = cache.empty();
+const auto empty = cache.empty();
 
 // clears a cache and discards its content
 cache.clear();
@@ -2353,6 +2353,12 @@ delegate.connect<MyStruct, &MyStruct::f>(&instance);
 
 It hasn't a `disconnect` counterpart. Instead, there exists a `reset` member
 function to clear it.<br/>
+The `empty` member function can be used to know if a delegate is empty:
+
+```cpp
+const auto empty = delegate.empty();
+```
+
 Finally, to invoke a delegate, the function call operator is the way to go as
 usual:
 

+ 11 - 4
src/entt/signal/delegate.hpp

@@ -37,8 +37,6 @@ class Delegate<Ret(Args...)> final {
     using proto_type = Ret(*)(void *, Args...);
     using stub_type = std::pair<void *, proto_type>;
 
-    static Ret fallback(void *, Args...) ENTT_NOEXCEPT { return {}; }
-
     template<Ret(*Function)(Args...)>
     static Ret proto(void *, Args... args) {
         return (Function)(args...);
@@ -52,9 +50,18 @@ class Delegate<Ret(Args...)> final {
 public:
     /*! @brief Default constructor. */
     Delegate() ENTT_NOEXCEPT
-        : stub{std::make_pair(nullptr, &fallback)}
+        : stub{std::make_pair(nullptr, proto_type{})}
     {}
 
+    /**
+     * @brief Checks whether a delegate actually stores a listener.
+     * @return True if the delegate is empty, false otherwise.
+     */
+    bool empty() const ENTT_NOEXCEPT {
+        // no need to test also stub.first
+        return !stub.second;
+    }
+
     /**
      * @brief Binds a free function to a delegate.
      * @tparam Function A valid free function pointer.
@@ -86,7 +93,7 @@ public:
      * After a reset, a delegate can be safely invoked with no effect.
      */
     void reset() ENTT_NOEXCEPT {
-        stub = std::make_pair(nullptr, &fallback);
+        stub = std::make_pair(nullptr, proto_type{});
     }
 
     /**

+ 7 - 4
test/entt/signal/delegate.cpp

@@ -16,20 +16,23 @@ TEST(Delegate, Functionalities) {
     entt::Delegate<int(int)> mfdel;
     DelegateFunctor functor;
 
-    ASSERT_EQ(ffdel(42), int{});
-    ASSERT_EQ(mfdel(42), int{});
+    ASSERT_TRUE(ffdel.empty());
+    ASSERT_TRUE(mfdel.empty());
 
     ffdel.connect<&delegateFunction>();
     mfdel.connect<DelegateFunctor, &DelegateFunctor::operator()>(&functor);
 
+    ASSERT_FALSE(ffdel.empty());
+    ASSERT_FALSE(mfdel.empty());
+
     ASSERT_EQ(ffdel(3), 9);
     ASSERT_EQ(mfdel(3), 6);
 
     ffdel.reset();
     mfdel.reset();
 
-    ASSERT_EQ(ffdel(42), int{});
-    ASSERT_EQ(mfdel(42), int{});
+    ASSERT_TRUE(ffdel.empty());
+    ASSERT_TRUE(mfdel.empty());
 }
 
 TEST(Delegate, Comparison) {