Browse Source

Add LuaScriptEventInvoker in LuaScriptInstance.

aster2013 11 years ago
parent
commit
10f80cd011

+ 28 - 15
Source/Urho3D/LuaScript/LuaScriptEventInvoker.cpp

@@ -130,24 +130,37 @@ void LuaScriptEventInvoker::HandleLuaScriptEvent(StringHash eventType, VariantMa
     if (i == eventTypeToLuaFunctionVectorMap.End())
         return;
 
-    bool ret;
-    LuaFunctionVector& luaFunctionVector = i->second_;
-    for (unsigned i = 0; i < luaFunctionVector.Size(); ++i)
-    {
-        WeakPtr<LuaFunction>& function = luaFunctionVector[i];
-        if (!function)
-            continue;
+    // Create a copy
+    LuaFunctionVector luaFunctionVector = i->second_;
 
-        if (instance_)
-            ret = function->BeginCall(instance_);
-        else
-            ret = function->BeginCall();
+    if (instance_)
+    {
+        instance_->AddRef();
 
-        if (ret)
+        for (unsigned i = 0; i < luaFunctionVector.Size(); ++i)
+        {
+            WeakPtr<LuaFunction>& function = luaFunctionVector[i];
+            if (function && function->BeginCall(instance_))
+            {
+                function->PushUserType(eventType, "StringHash");
+                function->PushUserType(eventData, "VariantMap");
+                function->EndCall();
+            }
+        }
+        
+        instance_->ReleaseRef();
+    }
+    else
+    {
+        for (unsigned i = 0; i < luaFunctionVector.Size(); ++i)
         {
-            function->PushUserType(eventType, "StringHash");
-            function->PushUserType(eventData, "VariantMap");
-            function->EndCall();
+            WeakPtr<LuaFunction>& function = luaFunctionVector[i];
+            if (function && function->BeginCall())
+            {
+                function->PushUserType(eventType, "StringHash");
+                function->PushUserType(eventData, "VariantMap");
+                function->EndCall();
+            }
         }
     }
 }

+ 106 - 119
Source/Urho3D/LuaScript/LuaScriptInstance.cpp

@@ -26,6 +26,7 @@
 #include "../LuaScript/LuaFile.h"
 #include "../LuaScript/LuaFunction.h"
 #include "../LuaScript/LuaScript.h"
+#include "../LuaScript/LuaScriptEventInvoker.h"
 #include "../LuaScript/LuaScriptInstance.h"
 #include "../IO/MemoryBuffer.h"
 #ifdef URHO3D_PHYSICS
@@ -68,6 +69,8 @@ LuaScriptInstance::LuaScriptInstance(Context* context) :
     luaScript_ = GetSubsystem<LuaScript>();
     luaState_ = luaScript_->GetState();
     attributeInfos_ = *context_->GetAttributes(GetTypeStatic());
+
+    eventInvoker_ =  new LuaScriptEventInvoker(this);
 }
 
 LuaScriptInstance::~LuaScriptInstance()
@@ -283,6 +286,109 @@ void LuaScriptInstance::OnSetEnabled()
         UnsubscribeFromScriptMethodEvents();
 }
 
+
+
+void LuaScriptInstance::AddEventHandler(const String& eventName, int functionIndex)
+{
+    WeakPtr<LuaFunction> function = luaScript_->GetFunction(functionIndex);
+    if (function)
+        eventInvoker_->AddEventHandler(0, eventName, function);
+}
+
+void LuaScriptInstance::AddEventHandler(const String& eventName, const String& functionName)
+{
+    String realFunctionName = functionName.Replaced(":", ".");
+    WeakPtr<LuaFunction> function = luaScript_->GetFunction(realFunctionName);
+    if (function)
+        eventInvoker_->AddEventHandler(0, eventName, function);
+}
+
+void LuaScriptInstance::AddEventHandler(Object* sender, const String& eventName, int functionIndex)
+{
+    if (!sender)
+        return;
+
+    WeakPtr<LuaFunction> function = luaScript_->GetFunction(functionIndex);
+    if (function)
+        eventInvoker_->AddEventHandler(sender, eventName, function);
+}
+
+void LuaScriptInstance::AddEventHandler(Object* sender, const String& eventName, const String& functionName)
+{
+    if (!sender)
+        return;
+
+    String realFunctionName = functionName.Replaced(":", ".");
+    WeakPtr<LuaFunction> function = luaScript_->GetFunction(realFunctionName);
+    if (function)
+        eventInvoker_->AddEventHandler(sender, eventName, function);
+}
+
+void LuaScriptInstance::RemoveEventHandler(const String& eventName, int functionIndex)
+{
+    WeakPtr<LuaFunction> function = luaScript_->GetFunction(functionIndex);
+    if (function)
+        eventInvoker_->RemoveEventHandler(0, eventName, function);
+}
+
+void LuaScriptInstance::RemoveEventHandler(const String& eventName, const String& functionName)
+{
+    String realFunctionName = functionName.Replaced(":", ".");
+    WeakPtr<LuaFunction> function = luaScript_->GetFunction(realFunctionName);
+    if (function)
+        eventInvoker_->RemoveEventHandler(0, eventName, function);
+}
+
+void LuaScriptInstance::RemoveEventHandler(const String& eventName)
+{
+    eventInvoker_->RemoveEventHandler(0, eventName, WeakPtr<LuaFunction>());
+}
+
+void LuaScriptInstance::RemoveEventHandler(Object* sender, const String& eventName, int functionIndex)
+{
+    if (!sender)
+        return;
+
+    WeakPtr<LuaFunction> function = luaScript_->GetFunction(functionIndex);
+    if (function)
+        eventInvoker_->RemoveEventHandler(sender, eventName, function);
+}
+
+void LuaScriptInstance::RemoveEventHandler(Object* sender, const String& eventName, const String& functionName)
+{
+    if (!sender)
+        return;
+
+    String realFunctionName = functionName.Replaced(":", ".");
+    WeakPtr<LuaFunction> function = luaScript_->GetFunction(realFunctionName);
+    if (function)
+        eventInvoker_->RemoveEventHandler(sender, eventName, function);
+}
+
+void LuaScriptInstance::RemoveEventHandler(Object* sender, const String& eventName)
+{
+    if (!sender)
+        return;
+
+    eventInvoker_->RemoveEventHandler(sender, eventName, WeakPtr<LuaFunction>());
+}
+void LuaScriptInstance::RemoveEventHandlers(Object* sender)
+{
+    if (!sender)
+        return;
+
+    eventInvoker_->RemoveAllEventHandlers(sender);
+}
+
+void LuaScriptInstance::RemoveAllEventHandlers()
+{
+    eventInvoker_->RemoveAllEventHandlers(0);
+}
+void LuaScriptInstance::RemoveEventHandlersExcept(const Vector<String>& exceptionNames)
+{
+    eventInvoker_->RemoveEventHandlersExcept(exceptionNames);
+}
+
 bool LuaScriptInstance::CreateObject(const String& scriptObjectType)
 {
 	SetScriptFile(0);
@@ -365,102 +471,6 @@ void LuaScriptInstance::SetScriptNetworkDataAttr(const PODVector<unsigned char>&
     }
 }
 
-void LuaScriptInstance::ScriptSubscribeToEvent(const String& eventName, int functionIndex)
-{
-    WeakPtr<LuaFunction> function = luaScript_->GetFunction(functionIndex);
-    if (function)
-    {
-        StringHash eventType(eventName);
-        SubscribeToEvent(eventType, HANDLER(LuaScriptInstance, HandleEvent));
-        eventTypeToFunctionMap_[eventType] = function;
-    }
-}
-
-void LuaScriptInstance::ScriptSubscribeToEvent(const String& eventName, const String& functionName)
-{
-    String realFunctionName = functionName.Replaced(":", ".");
-
-    WeakPtr<LuaFunction> function = luaScript_->GetFunction(realFunctionName);
-    if (function)
-    {
-        StringHash eventType(eventName);
-        SubscribeToEvent(eventType, HANDLER(LuaScriptInstance, HandleEvent));
-        eventTypeToFunctionMap_[eventType] = function;
-    }
-}
-
-void LuaScriptInstance::ScriptUnsubscribeFromEvent(const String& eventName)
-{
-    StringHash eventType(eventName);
-
-    HashMap<StringHash, WeakPtr<LuaFunction> >::Iterator i = eventTypeToFunctionMap_.Find(eventType);
-    if (i != eventTypeToFunctionMap_.End())
-    {
-        UnsubscribeFromEvent(eventType);
-        eventTypeToFunctionMap_.Erase(i);
-    }
-}
-
-void LuaScriptInstance::ScriptUnsubscribeFromAllEvents()
-{
-    if (eventTypeToFunctionMap_.Empty())
-        return;
-
-    UnsubscribeFromAllEvents();
-    eventTypeToFunctionMap_.Clear();
-}
-
-void LuaScriptInstance::ScriptSubscribeToEvent(void* sender, const String& eventName, int functionIndex)
-{
-    WeakPtr<LuaFunction> function = luaScript_->GetFunction(functionIndex);
-    if (function)
-    {
-        Object* object = (Object*)sender;
-        StringHash eventType(eventName);
-        SubscribeToEvent(object, eventType, HANDLER(LuaScriptInstance, HandleObjectEvent));
-        objectToEventTypeToFunctionMap_[object][eventType] = function;
-    }
-}
-
-void LuaScriptInstance::ScriptSubscribeToEvent(void* sender, const String& eventName, const String& functionName)
-{
-    String realFunctionName = functionName.Replaced(":", ".");
-
-    WeakPtr<LuaFunction> function = luaScript_->GetFunction(realFunctionName);
-    if (function)
-    {
-        Object* object = (Object*)sender;
-        StringHash eventType(eventName);
-        SubscribeToEvent(object, eventType, HANDLER(LuaScriptInstance, HandleObjectEvent));
-        objectToEventTypeToFunctionMap_[object][eventType] = function;
-    }
-}
-
-void LuaScriptInstance::ScriptUnsubscribeFromEvent(void* sender, const String& eventName)
-{
-    StringHash eventType(eventName);
-    Object* object = (Object*)sender ;
-
-    HashMap<StringHash, WeakPtr<LuaFunction> >::Iterator i = objectToEventTypeToFunctionMap_[object].Find(eventType);
-    if (i != objectToEventTypeToFunctionMap_[object].End())
-    {
-        UnsubscribeFromEvent(object, eventType);
-        objectToEventTypeToFunctionMap_[object].Erase(i);
-    }
-}
-
-void LuaScriptInstance::ScriptUnsubscribeFromEvents(void* sender)
-{
-    Object* object = (Object*)sender;
-
-    HashMap<Object*, HashMap<StringHash, WeakPtr<LuaFunction> > >::Iterator it = objectToEventTypeToFunctionMap_.Find(object);
-    if (it == objectToEventTypeToFunctionMap_.End())
-        return;
-
-    UnsubscribeFromEvents(object);
-    objectToEventTypeToFunctionMap_.Erase(it);
-}
-
 LuaFile* LuaScriptInstance::GetScriptFile() const
 {
 	return scriptFile_;
@@ -710,29 +720,6 @@ void LuaScriptInstance::HandlePostFixedUpdate(StringHash eventType, VariantMap&
 }
 #endif
 
-void LuaScriptInstance::HandleEvent(StringHash eventType, VariantMap& eventData)
-{
-    WeakPtr<LuaFunction> function = eventTypeToFunctionMap_[eventType];
-    if (function && function->BeginCall(this))
-    {
-        function->PushUserType(eventType, "StringHash");
-        function->PushUserType(eventData, "VariantMap");
-        function->EndCall();
-    }
-}
-
-void LuaScriptInstance::HandleObjectEvent(StringHash eventType, VariantMap& eventData)
-{
-    Object* object = GetEventSender();
-    WeakPtr<LuaFunction> function = objectToEventTypeToFunctionMap_[object][eventType];
-    if (function && function->BeginCall(this))
-    {
-        function->PushUserType(eventType, "StringHash");
-        function->PushUserType(eventData, "VariantMap");
-        function->EndCall();
-    }
-}
-
 void LuaScriptInstance::ReleaseObject()
 {
     if (scriptObjectRef_ == LUA_REFNIL)

+ 32 - 25
Source/Urho3D/LuaScript/LuaScriptInstance.h

@@ -22,6 +22,7 @@
 
 #pragma once
 
+#include "../LuaScript/LuaScriptEventListener.h"
 #include "../Scene/Component.h"
 
 struct lua_State;
@@ -32,6 +33,7 @@ namespace Urho3D
 class LuaFile;
 class LuaFunction;
 class LuaScript;
+class LuaScriptEventInvoker;
 
 /// Lua Script object methods.
 enum LuaScriptObjectMethod
@@ -52,7 +54,7 @@ enum LuaScriptObjectMethod
 };
 
 /// Lua script object component.
-class URHO3D_API LuaScriptInstance : public Component
+class URHO3D_API LuaScriptInstance : public Component, public LuaScriptEventListener
 {
     OBJECT(LuaScriptInstance);
 
@@ -75,6 +77,33 @@ public:
     /// Handle enabled/disabled state change.
     virtual void OnSetEnabled();
 
+    /// Add a scripted event handler by function.
+    virtual void AddEventHandler(const String& eventName, int functionIndex);
+    /// Add a scripted event handler by function name.
+    virtual void AddEventHandler(const String& eventName, const String& functionName);
+    /// Add a scripted event handler by function for a specific sender.
+    virtual void AddEventHandler(Object* sender, const String& eventName, int functionIndex);
+    /// Add a scripted event handler by function name for a specific sender.
+    virtual void AddEventHandler(Object* sender, const String& eventName, const String& functionName);
+    /// Remove a scripted event handler by function.
+    virtual void RemoveEventHandler(const String& eventName, int functionIndex);
+    /// Remove a scripted event handler by function name.
+    virtual void RemoveEventHandler(const String& eventName, const String& functionName);
+    /// Remove a scripted event handler.
+    virtual void RemoveEventHandler(const String& eventName);
+    /// Remove a scripted event handler for a specific sender by function.
+    virtual void RemoveEventHandler(Object* sender, const String& eventName, int functionIndex);
+    /// Remove a scripted event handler for a specific sender by function name.
+    virtual void RemoveEventHandler(Object* sender, const String& eventName, const String& functionName);
+    /// Remove a scripted event handler for a specific sender.
+    virtual void RemoveEventHandler(Object* sender, const String& eventName);
+    /// Remove all scripted event handlers for a specific sender.
+    virtual void RemoveEventHandlers(Object* sender);
+    /// Remove all scripted event handlers.
+    virtual void RemoveAllEventHandlers();
+    /// Remove all scripted event handlers, except those listed.
+    virtual void RemoveEventHandlersExcept(const Vector<String>& exceptionNames);
+
     /// Create script object. Return true if successful.
     bool CreateObject(const String& scriptObjectType);
     /// Create script object. Return true if successful.
@@ -87,22 +116,6 @@ public:
     void SetScriptDataAttr(const PODVector<unsigned char>& data);
     /// Set script network serialization attribute by calling a script function.
     void SetScriptNetworkDataAttr(const PODVector<unsigned char>& data);
-    /// Script subscribe to an event that can by send by any sender.
-    void ScriptSubscribeToEvent(const String& eventName, int functionIndex);
-    /// Script subscribe to an event that can by send by any sender.
-    void ScriptSubscribeToEvent(const String& eventName, const String& functionName);
-    /// Script unsubscribe from an event.
-    void ScriptUnsubscribeFromEvent(const String& eventName);
-    /// Script unsubscribe from all events.
-    void ScriptUnsubscribeFromAllEvents();
-    /// Script subscribe to a specific sender's event.
-    void ScriptSubscribeToEvent(void* sender, const String& eventName, int functionIndex);
-    /// Script subscribe to a specific sender's event.
-    void ScriptSubscribeToEvent(void* sender, const String& eventName, const String& functionName);
-    /// Script unsubscribe from a specific sender's event.
-    void ScriptUnsubscribeFromEvent(void* sender, const String& eventName);
-    /// Script unsubscribe from a specific sender's all events.
-    void ScriptUnsubscribeFromEvents(void* sender);
 
 	/// Return script file.
 	LuaFile* GetScriptFile() const;
@@ -145,10 +158,6 @@ private:
     /// Handle the physics post update event.
     void HandlePostFixedUpdate(StringHash eventType, VariantMap& eventData);
 #endif
-    /// Handle event.
-    void HandleEvent(StringHash eventType, VariantMap& eventData);
-    /// Handle a specific sender's event.
-    void HandleObjectEvent(StringHash eventType, VariantMap& eventData);
     /// Release the script object.
     void ReleaseObject();
 
@@ -156,6 +165,8 @@ private:
     LuaScript* luaScript_;
     /// Lua state.
     lua_State* luaState_;
+    /// Event invoker.
+    SharedPtr<LuaScriptEventInvoker> eventInvoker_;
     /// Script file.
 	SharedPtr<LuaFile> scriptFile_;
 	/// Script object type.
@@ -166,10 +177,6 @@ private:
     int scriptObjectRef_;
     /// Script object method.
     WeakPtr<LuaFunction> scriptObjectMethods_[MAX_LUA_SCRIPT_OBJECT_METHODS];
-    /// Event type to function map.
-    HashMap<StringHash, WeakPtr<LuaFunction> > eventTypeToFunctionMap_;
-    /// Object to event type to function map.
-    HashMap<Object*, HashMap<StringHash, WeakPtr<LuaFunction> > > objectToEventTypeToFunctionMap_;
 };
 
 }

+ 190 - 45
Source/Urho3D/LuaScript/pkgs/LuaScript/LuaScriptInstance.pkg

@@ -6,12 +6,17 @@ class LuaScriptInstance : public Component
     bool CreateObject(LuaFile* scriptFile, const String scriptObjectType);
     void SetScriptFile(LuaFile* scriptFile);
     void SetScriptObjectType(const String scriptObjectType);
-    void ScriptSubscribeToEvent @ SubscribeToEvent(const String eventName, void* functionOrFunctionName);
-    void ScriptUnsubscribeFromEvent @ UnsubscribeFromEvent(const String eventName);
-    void ScriptUnsubscribeFromAllEvents @ UnsubscribeFromAllEvents();    
-    void ScriptSubscribeToEvent @ SubscribeToEvent(void* sender, const String eventName, void* functionOrFunctionName);
-    void ScriptUnsubscribeFromEvent @ UnsubscribeFromEvent(void* sender, const String eventName);
-    void ScriptUnsubscribeFromEvents @ UnsubscribeFromEvents(void* sender);
+
+    void AddEventHandler @ SubscribeToEvent(const String eventName, void* functionOrFunctionName);
+    void AddEventHandler @ SubscribeToEvent(void* sender, const String eventName, void* functionOrFunctionName);
+    void RemoveEventHandler @ UnsubscribeFromEvent(const String eventName, void* functionOrFunctionName);
+    void RemoveEventHandler @ UnsubscribeFromEvent(const String eventName);
+    void RemoveEventHandler @ UnsubscribeFromEvent(Object* sender, const String eventName, void* functionOrFunctionName);
+    void RemoveEventHandler @ UnsubscribeFromEvent(Object* sender, const String eventName);
+    void RemoveEventHandlers @ UnsubscribeFromEvents(Object* sender);
+    void RemoveAllEventHandlers @ UnsubscribeFromAllEvents();
+    void RemoveEventHandlersExcept @ UnsubscribeFromAllEventsExcept(const Vector<String>& exceptionNames);
+
     LuaFile* GetScriptFile() const;
     const String GetScriptObjectType() const;
 
@@ -45,7 +50,7 @@ function LuaScriptObject:SubscribeToEvent(param1, param2, param3)
     end
 end
 
-function LuaScriptObject:UnsubscribeFromEvent(param1, param2)
+function LuaScriptObject:UnsubscribeFromEvent(param1, param2, param3)
     local instance = self.instance
     if instance == nil then
         return
@@ -53,11 +58,21 @@ function LuaScriptObject:UnsubscribeFromEvent(param1, param2)
 
     if param2 == nil then
         instance:UnsubscribeFromEvent(param1)
-    else
+    elseif param3 == nil then
         instance:UnsubscribeFromEvent(param1, param2)
+    else
+        instance:UnsubscribeFromEvent(param1, param2, param3)
     end
 end
 
+function LuaScriptObject:UnsubscribeFromEvents(sender)
+    local instance = self.instance
+    if instance == nil then
+        return
+    end 
+    instance:UnsubscribeFromEvents(sender)
+end
+
 function LuaScriptObject:UnsubscribeFromAllEvents()
     local instance = self.instance
     if instance == nil then
@@ -66,13 +81,12 @@ function LuaScriptObject:UnsubscribeFromAllEvents()
     instance:UnsubscribeFromAllEvents()
 end
 
-function LuaScriptObject:UnsubscribeFromEvents(sender)
+function LuaScriptObject:UnsubscribeFromAllEventsExcept()
     local instance = self.instance
     if instance == nil then
         return
-    end
-
-    instance:UnsubscribeFromEvents(sender)
+    end 
+    instance:UnsubscribeFromAllEventsExcept()
 end
 
 function ScriptObject()
@@ -125,72 +139,203 @@ end
 $]
 
 ${
-#define TOLUA_DISABLE_tolua_LuaScriptLuaAPI_LuaScriptInstance_SubscribeToEvent00
-static int tolua_LuaScriptLuaAPI_LuaScriptInstance_SubscribeToEvent00(lua_State* tolua_S)
+static int tolua_LuaScriptLuaAPI_LuaScriptInstance_SubscribeToEvent(lua_State* tolua_S)
 {
-#ifndef TOLUA_RELEASE
+    int args = lua_gettop(tolua_S);
     tolua_Error tolua_err;
-    if (
-        !tolua_isusertype(tolua_S,1,"LuaScriptInstance",0,&tolua_err) ||
-        !tolua_isurho3dstring(tolua_S,2,0,&tolua_err) ||
-        !tolua_isfunctionorurho3dstring(tolua_S,3,0,&tolua_err) ||
-        !tolua_isnoobj(tolua_S,4,&tolua_err)
-        )
-        goto tolua_lerror;
+
+#ifndef TOLUA_RELEASE
+    if (args == 3)
+    {   
+        // LuaScriptInstance::AddEventHandler(const String eventName, void* functionOrFunctionName);
+        if (!tolua_isusertype(tolua_S,1,"LuaScriptInstance",0,&tolua_err) ||
+            !tolua_isurho3dstring(tolua_S,2,0,&tolua_err) || 
+            !tolua_isfunctionorurho3dstring(tolua_S,3,0,&tolua_err))
+            goto tolua_lerror;
+    }
+    else if (args == 4)
+    {
+        // LuaScriptInstance::AddEventHandler(Object* sender, const String eventName, void* functionOrFunctionName);
+        if (!tolua_isusertype(tolua_S,1,"LuaScriptInstance",0,&tolua_err) || 
+            !tolua_isuserdata(tolua_S,2,0,&tolua_err) ||
+            !tolua_isurho3dstring(tolua_S,3,0,&tolua_err) ||
+            !tolua_isfunctionorurho3dstring(tolua_S,4,0,&tolua_err))
+            goto tolua_lerror;
+    }
     else
+        goto tolua_lerror;
 #endif
+
+    LuaScriptInstance* self = (LuaScriptInstance*)  tolua_tousertype(tolua_S,1,0);
+
+    if (args == 3)
     {
-        LuaScriptInstance* self = (LuaScriptInstance*)  tolua_tousertype(tolua_S,1,0);
+        // LuaScriptInstance::AddEventHandler(const String eventName, void* functionOrFunctionName);
         const String eventName = ((const String)  tolua_tourho3dstring(tolua_S,2,0));
-#ifndef TOLUA_RELEASE
-        if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ScriptSubscribeToEvent'", NULL);
-#endif
         if (lua_isfunction(tolua_S,3))
-            self->ScriptSubscribeToEvent(eventName,3);
+            self->AddEventHandler(eventName,3);
         else
         {
             const String functionName = (const String)tolua_tourho3dstring(tolua_S,3,0);
-            self->ScriptSubscribeToEvent(eventName,functionName);
+            self->AddEventHandler(eventName,functionName);
+        }        
+    }
+    else if (args == 4)
+    {
+        // LuaScriptInstance::AddEventHandler(Object* sender, const String eventName, void* functionOrFunctionName);
+        Object* sender = ((Object*)  tolua_touserdata(tolua_S,2,0));
+        const String eventName = ((const String)  tolua_tourho3dstring(tolua_S,3,0));
+        if (lua_isfunction(tolua_S,4))
+            self->AddEventHandler(sender,eventName,4);
+        else
+        {
+            const String functionName = (const String)tolua_tourho3dstring(tolua_S,4,0);
+            self->AddEventHandler(sender,eventName,functionName);
         }
     }
+
     return 0;
+
 #ifndef TOLUA_RELEASE
 tolua_lerror:
-    tolua_error(tolua_S,"#ferror in function 'SubscribeToEvent'.",&tolua_err);
+    tolua_error(tolua_S,"#ferror in function 'LuaScriptInstance::AddEventHandler'.",&tolua_err);
     return 0;
 #endif
 }
 
+#define TOLUA_DISABLE_tolua_LuaScriptLuaAPI_LuaScriptInstance_SubscribeToEvent00
+static int tolua_LuaScriptLuaAPI_LuaScriptInstance_SubscribeToEvent00(lua_State* tolua_S)
+{
+    return tolua_LuaScriptLuaAPI_LuaScriptInstance_SubscribeToEvent(tolua_S);
+}
+
 #define TOLUA_DISABLE_tolua_LuaScriptLuaAPI_LuaScriptInstance_SubscribeToEvent01
 static int tolua_LuaScriptLuaAPI_LuaScriptInstance_SubscribeToEvent01(lua_State* tolua_S)
 {
+    return tolua_LuaScriptLuaAPI_LuaScriptInstance_SubscribeToEvent(tolua_S);
+}
+
+static int tolua_LuaScriptLuaAPI_LuaScriptInstance_UnsubscribeFromEvent(lua_State* tolua_S)
+{
+    int args = lua_gettop(tolua_S);
     tolua_Error tolua_err;
-    if (
-        !tolua_isusertype(tolua_S,1,"LuaScriptInstance",0,&tolua_err) ||
-        !tolua_isuserdata(tolua_S,2,0,&tolua_err) ||
-        !tolua_isurho3dstring(tolua_S,3,0,&tolua_err) ||
-        !tolua_isfunctionorurho3dstring(tolua_S,4,0,&tolua_err) ||
-        !tolua_isnoobj(tolua_S,5,&tolua_err)
-        )
-        goto tolua_lerror;
+    
+#ifndef TOLUA_RELEASE
+    if (args == 2)
+    {
+        // LuaScriptInstance::RemoveEventHandler(const String eventName);
+        if (!tolua_isusertype(tolua_S,1,"LuaScriptInstance",0,&tolua_err) ||
+            !tolua_isurho3dstring(tolua_S,2,0,&tolua_err))
+            goto tolua_lerror;
+    }
+    else if (args == 3)
+    {
+        // LuaScriptInstance::RemoveEventHandler(const String eventName, void* functionOrFunctionName);
+        if (!tolua_isusertype(tolua_S,1,"LuaScriptInstance",0,&tolua_err))
+            goto tolua_lerror;
+
+        if (tolua_isurho3dstring(tolua_S,2,0,&tolua_err))
+        {
+            if (!tolua_isfunctionorurho3dstring(tolua_S,3,0,&tolua_err))
+                goto tolua_lerror;
+        }
+        // LuaScriptInstance::RemoveEventHandler(Object* sender, const String eventName);
+        else if (tolua_isuserdata(tolua_S,2,0,&tolua_err))
+        {
+            if (!tolua_isurho3dstring(tolua_S,3,0,&tolua_err))
+                goto tolua_lerror;
+        }
+        else
+            goto tolua_lerror;
+    }
+    else if (args == 4)
+    {
+        // LuaScriptInstance::RemoveEventHandler(Object* sender, const String eventName, void* functionOrFunctionName);
+        if (!tolua_isusertype(tolua_S,1,"LuaScriptInstance",0,&tolua_err) ||
+            !tolua_isuserdata(tolua_S,2,0,&tolua_err) ||
+            !tolua_isurho3dstring(tolua_S,3,0,&tolua_err) ||
+            !tolua_isfunctionorurho3dstring(tolua_S,4,0,&tolua_err))
+            goto tolua_lerror;
+    }
     else
+        goto tolua_lerror;
+#endif
+
+    LuaScriptInstance* self = (LuaScriptInstance*)  tolua_tousertype(tolua_S,1,0);
+
+    if (args == 2)
+    {
+        // LuaScriptInstance::RemoveEventHandler(const String eventName);
+        const String eventName = ((const String)  tolua_tourho3dstring(tolua_S,2,0));
+        self->RemoveEventHandler(eventName);
+    }
+    else if (args == 2)
+    {
+        // LuaScriptInstance::RemoveEventHandler(const String eventName, void* functionOrFunctionName);
+        if (tolua_isurho3dstring(tolua_S,2,0,&tolua_err))
+        {
+            const String eventName = ((const String)  tolua_tourho3dstring(tolua_S,2,0));
+            if (lua_isfunction(tolua_S, 3))
+                self->RemoveEventHandler(eventName, 3);
+            else
+            {
+                const String functionName = (const String)tolua_tourho3dstring(tolua_S,3,0);
+                self->RemoveEventHandler(eventName, functionName);
+            }
+        }
+        // LuaScriptInstance::RemoveEventHandler(Object* sender, const String eventName);
+        else if (tolua_isuserdata(tolua_S,2,0,&tolua_err))
+        {
+            Object* sender = ((Object*)  tolua_touserdata(tolua_S,2,0));
+            const String eventName = ((const String)  tolua_tourho3dstring(tolua_S,3,0));
+            self->RemoveEventHandler(sender, eventName);
+        }
+    }
+    else if (args == 4)
     {
-        LuaScriptInstance* self = (LuaScriptInstance*)  tolua_tousertype(tolua_S,1,0);
-        void* sender = ((void*)  tolua_touserdata(tolua_S,2,0));
+        // LuaScriptInstance::RemoveEventHandler(Object* sender, const String eventName, void* functionOrFunctionName);
+        Object* sender = ((Object*)  tolua_touserdata(tolua_S,2,0));
         const String eventName = ((const String)  tolua_tourho3dstring(tolua_S,3,0));
-#ifndef TOLUA_RELEASE
-        if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ScriptSubscribeToEvent'", NULL);
-#endif
         if (lua_isfunction(tolua_S,4))
-            self->ScriptSubscribeToEvent(sender,eventName,4);
+            self->RemoveEventHandler(sender,eventName,4);
         else
         {
             const String functionName = (const String)tolua_tourho3dstring(tolua_S,4,0);
-            self->ScriptSubscribeToEvent(sender,eventName,functionName);
+            self->RemoveEventHandler(sender,eventName,functionName);
         }
     }
+
     return 0;
+
+#ifndef TOLUA_RELEASE
 tolua_lerror:
-    return tolua_LuaScriptLuaAPI_LuaScriptInstance_SubscribeToEvent00(tolua_S);
+    tolua_error(tolua_S,"#ferror in function 'UnsubscribeFromEvent'.",&tolua_err);
+    return 0;
+#endif
+}
+
+#define TOLUA_DISABLE_tolua_LuaScriptLuaAPI_LuaScriptInstance_UnsubscribeFromEvent00
+static int tolua_LuaScriptLuaAPI_LuaScriptInstance_UnsubscribeFromEvent00(lua_State* tolua_S)
+{
+    return tolua_LuaScriptLuaAPI_LuaScriptInstance_UnsubscribeFromEvent(tolua_S);
+}
+
+#define TOLUA_DISABLE_tolua_LuaScriptLuaAPI_LuaScriptInstance_UnsubscribeFromEvent01
+static int tolua_LuaScriptLuaAPI_LuaScriptInstance_UnsubscribeFromEvent01(lua_State* tolua_S)
+{
+    return tolua_LuaScriptLuaAPI_LuaScriptInstance_UnsubscribeFromEvent(tolua_S);
+}
+
+#define TOLUA_DISABLE_tolua_LuaScriptLuaAPI_LuaScriptInstance_UnsubscribeFromEvent02
+static int tolua_LuaScriptLuaAPI_LuaScriptInstance_UnsubscribeFromEvent02(lua_State* tolua_S)
+{
+    return tolua_LuaScriptLuaAPI_LuaScriptInstance_UnsubscribeFromEvent(tolua_S);
+}
+
+#define TOLUA_DISABLE_tolua_LuaScriptLuaAPI_LuaScriptInstance_UnsubscribeFromEvent03
+static int tolua_LuaScriptLuaAPI_LuaScriptInstance_UnsubscribeFromEvent03(lua_State* tolua_S)
+{
+    return tolua_LuaScriptLuaAPI_LuaScriptInstance_UnsubscribeFromEvent(tolua_S);
 }
+
 $}