Browse Source

Allow subscribe to same event with multi functions in Lua.

aster2013 11 years ago
parent
commit
98b924d9c5

+ 60 - 30
Source/Engine/LuaScript/LuaScript.cpp

@@ -169,33 +169,44 @@ void LuaScript::ScriptSubscribeToEvent(const String& eventName, const String& fu
     WeakPtr<LuaFunction> function = GetFunction(functionName);
     WeakPtr<LuaFunction> function = GetFunction(functionName);
     if (function)
     if (function)
     {
     {
-        SubscribeToEvent(eventType, HANDLER(LuaScript, HandleEvent));
+        LuaFunctionVector& functions = eventHandleFunctions_[eventType];
+        if (functions.Empty())
+            SubscribeToEvent(eventType, HANDLER(LuaScript, HandleEvent));
 
 
-        eventTypeToFunctionMap_[eventType] = function;
+        functions.Push(function);
     }
     }
 }
 }
 
 
-void LuaScript::ScriptUnsubscribeFromEvent(const String& eventName)
+void LuaScript::ScriptUnsubscribeFromEvent(const String& eventName, const String& functionName)
 {
 {
     StringHash eventType(eventName);
     StringHash eventType(eventName);
-
-    HashMap<StringHash, WeakPtr<LuaFunction> >::Iterator i = eventTypeToFunctionMap_.Find(eventType);
-    if (i != eventTypeToFunctionMap_.End())
+    
+    HashMap<StringHash, LuaFunctionVector>::Iterator i = eventHandleFunctions_.Find(eventType);
+    if (i != eventHandleFunctions_.End())
     {
     {
-        UnsubscribeFromEvent(eventType);
+        LuaFunctionVector& functions = i->second_;
+        if (!functionName.Empty())
+        {   
+            WeakPtr<LuaFunction> function = GetFunction(functionName);
+            functions.Remove(function);
+        }
 
 
-        eventTypeToFunctionMap_.Erase(i);
+        if (functionName.Empty() || functions.Empty())
+        {
+            UnsubscribeFromEvent(eventType);
+            eventHandleFunctions_.Erase(i);
+        }   
     }
     }
 }
 }
 
 
 void LuaScript::ScriptUnsubscribeFromAllEvents()
 void LuaScript::ScriptUnsubscribeFromAllEvents()
 {
 {
-    if (eventTypeToFunctionMap_.Empty())
+    if (eventHandleFunctions_.Empty())
         return;
         return;
 
 
     UnsubscribeFromAllEvents();
     UnsubscribeFromAllEvents();
 
 
-    eventTypeToFunctionMap_.Clear();
+    eventHandleFunctions_.Clear();
 }
 }
 
 
 void LuaScript::ScriptSubscribeToEvent(void* sender, const String& eventName, const String& functionName)
 void LuaScript::ScriptSubscribeToEvent(void* sender, const String& eventName, const String& functionName)
@@ -206,23 +217,34 @@ void LuaScript::ScriptSubscribeToEvent(void* sender, const String& eventName, co
     WeakPtr<LuaFunction> function = GetFunction(functionName);
     WeakPtr<LuaFunction> function = GetFunction(functionName);
     if (function)
     if (function)
     {
     {
-        SubscribeToEvent(object, eventType, HANDLER(LuaScript, HandleObjectEvent));
+        LuaFunctionVector& functions = objectHandleFunctions_[object][eventType];
+        if (functions.Empty())
+            SubscribeToEvent(object, eventType, HANDLER(LuaScript, HandleObjectEvent));
 
 
-        objectToEventTypeToFunctionMap_[object][eventType] = function;
+        functions.Push(function);
     }
     }
 }
 }
 
 
-void LuaScript::ScriptUnsubscribeFromEvent(void* sender, const String& eventName)
+void LuaScript::ScriptUnsubscribeFromEvent(void* sender, const String& eventName, const String& functionName)
 {
 {
     StringHash eventType(eventName);
     StringHash eventType(eventName);
     Object* object = (Object*)sender;
     Object* object = (Object*)sender;
 
 
-    HashMap<StringHash, WeakPtr<LuaFunction> >::Iterator i = objectToEventTypeToFunctionMap_[object].Find(eventType);
-    if (i != objectToEventTypeToFunctionMap_[object].End())
+    HashMap<StringHash, LuaFunctionVector>::Iterator i = objectHandleFunctions_[object].Find(eventType);
+    if (i != objectHandleFunctions_[object].End())
     {
     {
-        UnsubscribeFromEvent(object, eventType);
+        LuaFunctionVector& functions = i->second_;
+        if (!functionName.Empty())
+        {
+            WeakPtr<LuaFunction> function = GetFunction(functionName);
+            functions.Remove(function);
+        }
 
 
-        objectToEventTypeToFunctionMap_[object].Erase(i);
+        if (functionName.Empty() || functions.Empty())
+        {
+            UnsubscribeFromEvent(object, eventType);
+            objectHandleFunctions_[object].Erase(i);
+        }
     }
     }
 }
 }
 
 
@@ -230,12 +252,12 @@ void LuaScript::ScriptUnsubscribeFromEvents(void* sender)
 {
 {
     Object* object = (Object*)sender;
     Object* object = (Object*)sender;
 
 
-    HashMap<Object*, HashMap<StringHash, WeakPtr<LuaFunction> > >::Iterator it = objectToEventTypeToFunctionMap_.Find(object);
-    if (it == objectToEventTypeToFunctionMap_.End())
+    HashMap<Object*, HashMap<StringHash, LuaFunctionVector> >::Iterator it = objectHandleFunctions_.Find(object);
+    if (it == objectHandleFunctions_.End())
         return;
         return;
 
 
     UnsubscribeFromEvents(object);
     UnsubscribeFromEvents(object);
-    objectToEventTypeToFunctionMap_.Erase(it);
+    objectHandleFunctions_.Erase(it);
 }
 }
 
 
 void LuaScript::RegisterLoader()
 void LuaScript::RegisterLoader()
@@ -352,24 +374,32 @@ WeakPtr<LuaFunction> LuaScript::GetFunction(const String& functionName, bool sil
 
 
 void LuaScript::HandleEvent(StringHash eventType, VariantMap& eventData)
 void LuaScript::HandleEvent(StringHash eventType, VariantMap& eventData)
 {
 {
-    WeakPtr<LuaFunction> function = eventTypeToFunctionMap_[eventType];
-    if (function && function->BeginCall())
+    LuaFunctionVector& functions = eventHandleFunctions_[eventType];
+    for (unsigned i = 0; i < functions.Size(); ++i)
     {
     {
-        function->PushUserType(eventType, "StringHash");
-        function->PushUserType(eventData, "VariantMap");
-        function->EndCall();
+        WeakPtr<LuaFunction> function = functions[i];
+        if (function && function->BeginCall())
+        {
+            function->PushUserType(eventType, "StringHash");
+            function->PushUserType(eventData, "VariantMap");
+            function->EndCall();
+        }
     }
     }
 }
 }
 
 
 void LuaScript::HandleObjectEvent(StringHash eventType, VariantMap& eventData)
 void LuaScript::HandleObjectEvent(StringHash eventType, VariantMap& eventData)
 {
 {
     Object* object = GetEventSender();
     Object* object = GetEventSender();
-    WeakPtr<LuaFunction> function = objectToEventTypeToFunctionMap_[object][eventType];
-    if (function && function->BeginCall())
+    LuaFunctionVector& functions = objectHandleFunctions_[object][eventType];
+    for (unsigned i = 0; i < functions.Size(); ++i)
     {
     {
-        function->PushUserType(eventType, "StringHash");
-        function->PushUserType(eventData, "VariantMap");
-        function->EndCall();
+        WeakPtr<LuaFunction> function = functions[i];
+        if (function && function->BeginCall())
+        {
+            function->PushUserType(eventType, "StringHash");
+            function->PushUserType(eventData, "VariantMap");
+            function->EndCall();
+        }
     }
     }
 }
 }
 
 

+ 8 - 6
Source/Engine/LuaScript/LuaScript.h

@@ -57,13 +57,13 @@ public:
     /// Script subscribe to an event that can by send by any sender.
     /// Script subscribe to an event that can by send by any sender.
     void ScriptSubscribeToEvent(const String& eventName, const String& functionName);
     void ScriptSubscribeToEvent(const String& eventName, const String& functionName);
     /// Script unsubscribe from an event.
     /// Script unsubscribe from an event.
-    void ScriptUnsubscribeFromEvent(const String& eventName);
+    void ScriptUnsubscribeFromEvent(const String& eventName, const String& functionName = String::EMPTY);
     /// Script unsubscribe from all events.
     /// Script unsubscribe from all events.
     void ScriptUnsubscribeFromAllEvents();
     void ScriptUnsubscribeFromAllEvents();
     /// Script subscribe to a specific sender's event.
     /// Script subscribe to a specific sender's event.
     void ScriptSubscribeToEvent(void* sender, const String& eventName, const String& functionName);
     void ScriptSubscribeToEvent(void* sender, const String& eventName, const String& functionName);
     /// Script unsubscribe from a specific sender's event.
     /// Script unsubscribe from a specific sender's event.
-    void ScriptUnsubscribeFromEvent(void* sender, const String& eventName);
+    void ScriptUnsubscribeFromEvent(void* sender, const String& eventName, const String& functionName = String::EMPTY);
     /// Script unsubscribe from a specific sender's all events.
     /// Script unsubscribe from a specific sender's all events.
     void ScriptUnsubscribeFromEvents(void* sender);
     void ScriptUnsubscribeFromEvents(void* sender);
 
 
@@ -101,10 +101,12 @@ private:
     WeakPtr<LuaFunction> coroutineUpdate_;
     WeakPtr<LuaFunction> coroutineUpdate_;
     /// Function name to function map.
     /// Function name to function map.
     HashMap<String, SharedPtr<LuaFunction> > functionNameToFunctionMap_;
     HashMap<String, SharedPtr<LuaFunction> > functionNameToFunctionMap_;
-    /// Event type to function map.
-    HashMap<StringHash, WeakPtr<LuaFunction> > eventTypeToFunctionMap_;
-    /// Object to event type to function map.
-    HashMap<Object*, HashMap<StringHash, WeakPtr<LuaFunction> > > objectToEventTypeToFunctionMap_;
+    /// Typedef Lua function vector.
+    typedef Vector<WeakPtr<LuaFunction> > LuaFunctionVector;
+    /// Event handle functions.
+    HashMap<StringHash, LuaFunctionVector> eventHandleFunctions_;
+    /// Object event handle funcitons.
+    HashMap<Object*, HashMap<StringHash, LuaFunctionVector> > objectHandleFunctions_;
 };
 };
 
 
 /// Register Lua script library objects.
 /// Register Lua script library objects.

+ 14 - 183
Source/Engine/LuaScript/pkgs/LuaScript/LuaScript.pkg

@@ -1,191 +1,22 @@
 $#include "LuaScript.h"
 $#include "LuaScript.h"
 
 
-void SendEvent(const String eventName, VariantMap& eventData);
-void SubscribeToEvent(const String eventName, const String functionName);
-void UnsubscribeFromEvent(const String eventName);
-void UnsubscribeFromAllEvents();
-void SubscribeToEvent(void* sender, const String eventName, const String functionName);
-void UnsubscribeFromEvent(void* sender, const String eventName);
-void UnsubscribeFromEvents(void* sender);
+void LuaScriptSendEvent @ SendEvent(const String eventName, VariantMap& eventData);
+void LuaScriptSubscribeToEvent @ SubscribeToEvent(const String eventName, const String functionName);
+void LuaScriptUnsubscribeFromEvent @ UnsubscribeFromEvent(const String eventName, const String functionName = String::EMPTY);
+void LuaScriptUnsubscribeFromAllEvents @ UnsubscribeFromAllEvents();
+void LuaScriptSubscribeToEvent @ SubscribeToEvent(void* sender, const String eventName, const String functionName);
+void LuaScriptUnsubscribeFromEvent @ UnsubscribeFromEvent(void* sender, const String eventName, const String functionName = String::EMPTY);
+void LuaScriptUnsubscribeFromEvents @ UnsubscribeFromEvents(void* sender);
 
 
 ${
 ${
-#define TOLUA_DISABLE_tolua_LuaScriptLuaAPI_SendEvent00
-static int tolua_LuaScriptLuaAPI_SendEvent00(lua_State* tolua_S)
+static LuaScript* GetLuaScript(lua_State* L)
 {
 {
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isurho3dstring(tolua_S,1,0,&tolua_err) ||
- (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"VariantMap",0,&tolua_err)) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
-  const String eventName = ((const String)  tolua_tourho3dstring(tolua_S,1,0));
-  VariantMap* eventData = ((VariantMap*)  tolua_tousertype(tolua_S,2,0));
- {
-  GetContext(tolua_S)->GetSubsystem<LuaScript>()->ScriptSendEvent(eventName,*eventData);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SendEvent'.",&tolua_err);
- return 0;
-#endif
+    return GetContext(L)->GetSubsystem<LuaScript>();
 }
 }
 
 
-#define TOLUA_DISABLE_tolua_LuaScriptLuaAPI_SubscribeToEvent00
-static int tolua_LuaScriptLuaAPI_SubscribeToEvent00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isurho3dstring(tolua_S,1,0,&tolua_err) ||
- !tolua_isurho3dstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
-  const String eventName = ((const String)  tolua_tourho3dstring(tolua_S,1,0));
-  const String functionName = ((const String)  tolua_tourho3dstring(tolua_S,2,0));
- {
-  GetContext(tolua_S)->GetSubsystem<LuaScript>()->ScriptSubscribeToEvent(eventName,functionName);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'SubscribeToEvent'.",&tolua_err);
- return 0;
-#endif
-}
-
-#define TOLUA_DISABLE_tolua_LuaScriptLuaAPI_UnsubscribeFromEvent00
-static int tolua_LuaScriptLuaAPI_UnsubscribeFromEvent00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isurho3dstring(tolua_S,1,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
-  const String eventName = ((const String)  tolua_tourho3dstring(tolua_S,1,0));
- {
-  GetContext(tolua_S)->GetSubsystem<LuaScript>()->ScriptUnsubscribeFromEvent(eventName);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'UnsubscribeFromEvent'.",&tolua_err);
- return 0;
-#endif
-}
-
-#define TOLUA_DISABLE_tolua_LuaScriptLuaAPI_UnsubscribeFromAllEvents00
-static int tolua_LuaScriptLuaAPI_UnsubscribeFromAllEvents00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isnoobj(tolua_S,1,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
- {
-  GetContext(tolua_S)->GetSubsystem<LuaScript>()->ScriptUnsubscribeFromAllEvents();
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'UnsubscribeFromAllEvents'.",&tolua_err);
- return 0;
-#endif
-}
-
-#define TOLUA_DISABLE_tolua_LuaScriptLuaAPI_SubscribeToEvent01
-static int tolua_LuaScriptLuaAPI_SubscribeToEvent01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isuserdata(tolua_S,1,0,&tolua_err) ||
- !tolua_isurho3dstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isurho3dstring(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
-  void* sender = ((void*)  tolua_touserdata(tolua_S,1,0));
-  const String eventName = ((const String)  tolua_tourho3dstring(tolua_S,2,0));
-  const String functionName = ((const String)  tolua_tourho3dstring(tolua_S,3,0));
- {
-  GetContext(tolua_S)->GetSubsystem<LuaScript>()->ScriptSubscribeToEvent(sender,eventName,functionName);
- }
- }
- return 0;
-tolua_lerror:
- return tolua_LuaScriptLuaAPI_SubscribeToEvent00(tolua_S);
-}
-
-#define TOLUA_DISABLE_tolua_LuaScriptLuaAPI_UnsubscribeFromEvent01
-static int tolua_LuaScriptLuaAPI_UnsubscribeFromEvent01(lua_State* tolua_S)
-{
- tolua_Error tolua_err;
- if (
- !tolua_isuserdata(tolua_S,1,0,&tolua_err) ||
- !tolua_isurho3dstring(tolua_S,2,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,3,&tolua_err)
- )
- goto tolua_lerror;
- else
- {
-  void* sender = ((void*)  tolua_touserdata(tolua_S,1,0));
-  const String eventName = ((const String)  tolua_tourho3dstring(tolua_S,2,0));
- {
-  GetContext(tolua_S)->GetSubsystem<LuaScript>()->ScriptUnsubscribeFromEvent(sender,eventName);
- }
- }
- return 0;
-tolua_lerror:
- return tolua_LuaScriptLuaAPI_UnsubscribeFromEvent00(tolua_S);
-}
-
-#define TOLUA_DISABLE_tolua_LuaScriptLuaAPI_UnsubscribeFromEvents00
-static int tolua_LuaScriptLuaAPI_UnsubscribeFromEvents00(lua_State* tolua_S)
-{
-#ifndef TOLUA_RELEASE
- tolua_Error tolua_err;
- if (
- !tolua_isuserdata(tolua_S,1,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,2,&tolua_err)
- )
- goto tolua_lerror;
- else
-#endif
- {
-  void* sender = ((void*)  tolua_touserdata(tolua_S,1,0));
- {
-  GetContext(tolua_S)->GetSubsystem<LuaScript>()->ScriptUnsubscribeFromEvents(sender);
- }
- }
- return 0;
-#ifndef TOLUA_RELEASE
- tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'UnsubscribeFromEvents'.",&tolua_err);
- return 0;
-#endif
-}
+#define LuaScriptSendEvent GetLuaScript(tolua_S)->ScriptSendEvent
+#define LuaScriptSubscribeToEvent GetLuaScript(tolua_S)->ScriptSubscribeToEvent
+#define LuaScriptUnsubscribeFromEvent GetLuaScript(tolua_S)->ScriptUnsubscribeFromEvent
+#define LuaScriptUnsubscribeFromAllEvents GetLuaScript(tolua_S)->ScriptUnsubscribeFromAllEvents
+#define LuaScriptUnsubscribeFromEvents GetLuaScript(tolua_S)->ScriptUnsubscribeFromEvents
 $}
 $}