Browse Source

C++11 event binding (lambdas/std::bind).
Removed redundant EventHandler() constructor.

rokups 9 years ago
parent
commit
740ff3491a
2 changed files with 55 additions and 19 deletions
  1. 12 0
      Source/Urho3D/Core/Object.cpp
  2. 43 19
      Source/Urho3D/Core/Object.h

+ 12 - 0
Source/Urho3D/Core/Object.cpp

@@ -181,6 +181,18 @@ void Object::SubscribeToEvent(Object* sender, StringHash eventType, EventHandler
     context_->AddEventReceiver(this, sender, eventType);
 }
 
+#if URHO3D_CXX11
+void Object::SubscribeToEvent(StringHash eventType, const std::function<void(StringHash, VariantMap&)>& function, void* userData/*=0*/)
+{
+    SubscribeToEvent(eventType, new EventHandler11Impl(function, userData));
+}
+
+void Object::SubscribeToEvent(Object* sender, StringHash eventType, const std::function<void(StringHash, VariantMap&)>& function, void* userData/*=0*/)
+{
+    SubscribeToEvent(sender, eventType, new EventHandler11Impl(function, userData));
+}
+#endif
+
 void Object::UnsubscribeFromEvent(StringHash eventType)
 {
     for (;;)

+ 43 - 19
Source/Urho3D/Core/Object.h

@@ -24,6 +24,9 @@
 
 #include "../Container/LinkedList.h"
 #include "../Core/Variant.h"
+#if URHO3D_CXX11
+#include <functional>
+#endif
 
 namespace Urho3D
 {
@@ -113,6 +116,12 @@ public:
     void SubscribeToEvent(StringHash eventType, EventHandler* handler);
     /// Subscribe to a specific sender's event.
     void SubscribeToEvent(Object* sender, StringHash eventType, EventHandler* handler);
+#ifdef URHO3D_CXX11
+    /// Subscribe to an event that can be sent by any sender.
+    void SubscribeToEvent(StringHash eventType, const std::function<void(StringHash, VariantMap&)>& function, void* userData=0);
+    /// Subscribe to a specific sender's event.
+    void SubscribeToEvent(Object* sender, StringHash eventType, const std::function<void(StringHash, VariantMap&)>& function, void* userData=0);
+#endif
     /// Unsubscribe from an event.
     void UnsubscribeFromEvent(StringHash eventType);
     /// Unsubscribe from a specific sender's event.
@@ -229,17 +238,8 @@ public:
 class URHO3D_API EventHandler : public LinkedListNode
 {
 public:
-    /// Construct with specified receiver.
-    EventHandler(Object* receiver) :
-        receiver_(receiver),
-        sender_(0),
-        userData_(0)
-    {
-        assert(receiver_);
-    }
-
     /// Construct with specified receiver and userdata.
-    EventHandler(Object* receiver, void* userData) :
+    EventHandler(Object* receiver, void* userData = 0) :
         receiver_(receiver),
         sender_(0),
         userData_(userData)
@@ -291,16 +291,8 @@ template <class T> class EventHandlerImpl : public EventHandler
 public:
     typedef void (T::*HandlerFunctionPtr)(StringHash, VariantMap&);
 
-    /// Construct with receiver and function pointers.
-    EventHandlerImpl(T* receiver, HandlerFunctionPtr function) :
-        EventHandler(receiver),
-        function_(function)
-    {
-        assert(function_);
-    }
-
     /// Construct with receiver and function pointers and userdata.
-    EventHandlerImpl(T* receiver, HandlerFunctionPtr function, void* userData) :
+    EventHandlerImpl(T* receiver, HandlerFunctionPtr function, void* userData = 0) :
         EventHandler(receiver, userData),
         function_(function)
     {
@@ -325,6 +317,38 @@ private:
     HandlerFunctionPtr function_;
 };
 
+#if URHO3D_CXX11
+/// Template implementation of the event handler invoke helper (std::function instance).
+class EventHandler11Impl : public EventHandler
+{
+public:
+    /// Construct with receiver and function pointers and userdata.
+    EventHandler11Impl(std::function<void(StringHash, VariantMap&)> function, void* userData = 0) :
+        EventHandler((Object*)0xDEADBEEF /* EventHandler insists for receiver_ not being null but it is captured in
+                                          * `function_` already and is not used by `EventHandler11Impl` */, userData),
+        function_(function)
+    {
+        assert(function_);
+    }
+
+    /// Invoke event handler function.
+    virtual void Invoke(VariantMap& eventData)
+    {
+        function_(eventType_, eventData);
+    }
+
+    /// Return a unique copy of the event handler.
+    virtual EventHandler* Clone() const
+    {
+        return new EventHandler11Impl(function_, userData_);
+    }
+
+private:
+    /// Class-specific pointer to handler function.
+    std::function<void(StringHash, VariantMap&)> function_;
+};
+#endif
+
 /// Describe an event's hash ID and begin a namespace in which to define its parameters.
 #define URHO3D_EVENT(eventID, eventName) static const Urho3D::StringHash eventID(#eventName); namespace eventName
 /// Describe an event's parameter hash ID. Should be used inside an event namespace.