Browse Source

Add Update, PostUpdate, Save, Load function in LuaScriptInstance, Add one more LoadXML and SaveXML in Scene, Add destructor function in Math lib.

Aster Jian 12 years ago
parent
commit
0ddb13f148

+ 46 - 46
Source/Extras/LuaScript/LuaScript.cpp

@@ -104,6 +104,12 @@ LuaScript::LuaScript(Context* context) :
 
 
 LuaScript::~LuaScript()
 LuaScript::~LuaScript()
 {
 {
+    for (HashMap<String, int>::Iterator i = functionNameToFunctionRefMap_.Begin(); i != functionNameToFunctionRefMap_.End(); ++i)
+    {
+        if (i->second_ != LUA_REFNIL)
+            luaL_unref(luaState_, LUA_REGISTRYINDEX, i->second_);
+    }
+
     if (luaState_)
     if (luaState_)
         lua_close(luaState_);
         lua_close(luaState_);
 }
 }
@@ -146,7 +152,7 @@ bool LuaScript::ExecuteFunction(const String& functionName)
 
 
     int top = lua_gettop(luaState_);
     int top = lua_gettop(luaState_);
 
 
-    if (!FindFunction(functionName))
+    if (!PushScriptFunction(functionName))
     {
     {
         lua_settop(luaState_, top);
         lua_settop(luaState_, top);
         return false;
         return false;
@@ -172,10 +178,7 @@ void LuaScript::ScriptSubscribeToEvent(const String& eventName, const String& fu
 {
 {
     StringHash eventType(eventName);
     StringHash eventType(eventName);
 
 
-    int functionRef = LUA_REFNIL;
-    if (FindFunction(functionName))
-        functionRef = luaL_ref(luaState_, LUA_REGISTRYINDEX);
-
+    int functionRef = GetScriptFunctionRef(functionName);
     if (functionRef != LUA_REFNIL)
     if (functionRef != LUA_REFNIL)
     {
     {
         SubscribeToEvent(eventType, HANDLER(LuaScript, HandleEvent));
         SubscribeToEvent(eventType, HANDLER(LuaScript, HandleEvent));
@@ -192,10 +195,6 @@ void LuaScript::ScriptUnsubscribeFromEvent(const String& eventName)
     if (i != eventTypeToFunctionRefMap_.End())
     if (i != eventTypeToFunctionRefMap_.End())
     {
     {
         UnsubscribeFromEvent(eventType);
         UnsubscribeFromEvent(eventType);
-
-        if (i->second_ != LUA_REFNIL)
-            luaL_unref(luaState_, LUA_REGISTRYINDEX, i->second_);
-
         eventTypeToFunctionRefMap_.Erase(i);
         eventTypeToFunctionRefMap_.Erase(i);
     }
     }
 }
 }
@@ -206,63 +205,45 @@ void LuaScript::ScriptUnsubscribeFromAllEvents()
         return;
         return;
 
 
     UnsubscribeFromAllEvents();
     UnsubscribeFromAllEvents();
-
-    for (HashMap<StringHash, int>::Iterator i = eventTypeToFunctionRefMap_.Begin(); i != eventTypeToFunctionRefMap_.End(); ++i)
-        if (i->second_ != LUA_REFNIL)
-            luaL_unref(luaState_, LUA_REGISTRYINDEX, i->second_);
-
     eventTypeToFunctionRefMap_.Clear();
     eventTypeToFunctionRefMap_.Clear();
 }
 }
 
 
-void LuaScript::ScriptSubscribeToEvent(void* object, const String& eventName, const String& functionName)
+void LuaScript::ScriptSubscribeToEvent(void* sender, const String& eventName, const String& functionName)
 {
 {
     StringHash eventType(eventName);
     StringHash eventType(eventName);
-    Object* sender = (Object*)object;
-
-    int functionRef = LUA_REFNIL;
-    if (FindFunction(functionName))
-        functionRef = luaL_ref(luaState_, LUA_REGISTRYINDEX);
+    Object* object = (Object*)sender;
 
 
+    int functionRef = GetScriptFunctionRef(functionName);
     if (functionRef != LUA_REFNIL)
     if (functionRef != LUA_REFNIL)
     {
     {
-        SubscribeToEvent(sender, eventType, HANDLER(LuaScript, HandleObjectEvent));
-        objectToEventTypeToFunctionRefMap_[sender][eventType] = functionRef;
+        SubscribeToEvent(object, eventType, HANDLER(LuaScript, HandleObjectEvent));
+        objectToEventTypeToFunctionRefMap_[object][eventType] = functionRef;
     }
     }
 }
 }
 
 
-void LuaScript::ScriptUnsubscribeFromEvent(void* object, const String& eventName)
+void LuaScript::ScriptUnsubscribeFromEvent(void* sender, const String& eventName)
 {
 {
     StringHash eventType(eventName);
     StringHash eventType(eventName);
-    Object* sender = (Object*)object;
+    Object* object = (Object*)sender;
 
 
-    HashMap<StringHash, int>::Iterator i = objectToEventTypeToFunctionRefMap_[sender].Find(eventType);
-    if (i != objectToEventTypeToFunctionRefMap_[sender].End())
+    HashMap<StringHash, int>::Iterator i = objectToEventTypeToFunctionRefMap_[object].Find(eventType);
+    if (i != objectToEventTypeToFunctionRefMap_[object].End())
     {
     {
-        UnsubscribeFromEvent(sender, eventType);
+        UnsubscribeFromEvent(object, eventType);
 
 
-        if (i->second_ != LUA_REFNIL)
-            luaL_unref(luaState_, LUA_REGISTRYINDEX, i->second_);
-
-        objectToEventTypeToFunctionRefMap_[sender].Erase(i);
+        objectToEventTypeToFunctionRefMap_[object].Erase(i);
     }
     }
 }
 }
 
 
-void LuaScript::ScriptUnsubscribeFromEvents(void* object)
+void LuaScript::ScriptUnsubscribeFromEvents(void* sender)
 {
 {
-    Object* sender = (Object*)object;
+    Object* object = (Object*)sender;
 
 
-    HashMap<Object*, HashMap<StringHash, int> >::Iterator it = objectToEventTypeToFunctionRefMap_.Find(sender);
+    HashMap<Object*, HashMap<StringHash, int> >::Iterator it = objectToEventTypeToFunctionRefMap_.Find(object);
     if (it == objectToEventTypeToFunctionRefMap_.End())
     if (it == objectToEventTypeToFunctionRefMap_.End())
         return;
         return;
 
 
-    UnsubscribeFromEvents(sender);
-
-    HashMap<StringHash, int>& eventTypeToFunctionRefMap = it->second_;
-    for (HashMap<StringHash, int>::Iterator i = eventTypeToFunctionRefMap.Begin(); i != eventTypeToFunctionRefMap.End(); ++i)
-    {
-        if (i->second_ != LUA_REFNIL)
-            luaL_unref(luaState_, LUA_REGISTRYINDEX, i->second_);
-    }
+    UnsubscribeFromEvents(object);
 
 
     objectToEventTypeToFunctionRefMap_.Erase(it);
     objectToEventTypeToFunctionRefMap_.Erase(it);
 }
 }
@@ -337,7 +318,7 @@ int LuaScript::Print(lua_State *L)
     return 0;
     return 0;
 }
 }
 
 
-bool LuaScript::FindFunction(const String& functionName)
+bool LuaScript::PushScriptFunction(const String& functionName)
 {
 {
     Vector<String> splitedNames = functionName.Split('.');
     Vector<String> splitedNames = functionName.Split('.');
 
 
@@ -376,13 +357,32 @@ bool LuaScript::FindFunction(const String& functionName)
     return true;
     return true;
 }
 }
 
 
+int LuaScript::GetScriptFunctionRef(const String& functionName)
+{
+    HashMap<String, int>::Iterator i = functionNameToFunctionRefMap_.Find(functionName);
+    if (i != functionNameToFunctionRefMap_.End())
+        return i->second_;
+
+    int top = lua_gettop(luaState_);
+    
+    int functionRef = LUA_REFNIL;
+    if (PushScriptFunction(functionName))
+        functionRef = luaL_ref(luaState_, LUA_REGISTRYINDEX);
+
+    lua_settop(luaState_, top);
+
+    functionNameToFunctionRefMap_[functionName] = functionRef;
+
+    return functionRef;
+}
+
 void LuaScript::HandleEvent(StringHash eventType, VariantMap& eventData)
 void LuaScript::HandleEvent(StringHash eventType, VariantMap& eventData)
 {
 {
     int functionRef = eventTypeToFunctionRefMap_[eventType];
     int functionRef = eventTypeToFunctionRefMap_[eventType];
     if (functionRef == LUA_REFNIL)
     if (functionRef == LUA_REFNIL)
         return;
         return;
 
 
-    CallEventHandler(functionRef, eventType, eventData);
+    CallScriptFunction(functionRef, eventType, eventData);
 }
 }
 
 
 void LuaScript::HandleObjectEvent(StringHash eventType, VariantMap& eventData)
 void LuaScript::HandleObjectEvent(StringHash eventType, VariantMap& eventData)
@@ -392,7 +392,7 @@ void LuaScript::HandleObjectEvent(StringHash eventType, VariantMap& eventData)
     if (functionRef == LUA_REFNIL)
     if (functionRef == LUA_REFNIL)
         return;
         return;
 
 
-    CallEventHandler(functionRef, eventType, eventData);
+    CallScriptFunction(functionRef, eventType, eventData);
 }
 }
 
 
 void LuaScript::HandleConsoleCommand(StringHash eventType, VariantMap& eventData)
 void LuaScript::HandleConsoleCommand(StringHash eventType, VariantMap& eventData)
@@ -401,7 +401,7 @@ void LuaScript::HandleConsoleCommand(StringHash eventType, VariantMap& eventData
     ExecuteString(eventData[P_COMMAND].GetString());
     ExecuteString(eventData[P_COMMAND].GetString());
 }
 }
 
 
-void LuaScript::CallEventHandler(int functionRef, StringHash eventType, VariantMap& eventData )
+void LuaScript::CallScriptFunction(int functionRef, StringHash eventType, VariantMap& eventData )
 {
 {
     int top = lua_gettop(luaState_);
     int top = lua_gettop(luaState_);
     lua_rawgeti(luaState_, LUA_REGISTRYINDEX, functionRef);
     lua_rawgeti(luaState_, LUA_REGISTRYINDEX, functionRef);

+ 15 - 7
Source/Extras/LuaScript/LuaScript.h

@@ -30,6 +30,8 @@ struct lua_State;
 namespace Urho3D
 namespace Urho3D
 {
 {
 
 
+extern const char* LOGIC_CATEGORY;
+
 class Scene;
 class Scene;
 
 
 /// Lua script subsystem.
 /// Lua script subsystem.
@@ -65,19 +67,22 @@ public:
     void ScriptUnsubscribeFromAllEvents();
     void ScriptUnsubscribeFromAllEvents();
 
 
     /// Script subscribe to a specific sender's event.
     /// Script subscribe to a specific sender's event.
-    void ScriptSubscribeToEvent(void* object, 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* object, const String& eventName);
+    void ScriptUnsubscribeFromEvent(void* sender, const String& eventName);
 
 
     /// Script unsubscribe from a specific sender's all events.
     /// Script unsubscribe from a specific sender's all events.
-    void ScriptUnsubscribeFromEvents(void* object);
+    void ScriptUnsubscribeFromEvents(void* sender);
 
 
     /// Return Lua state.
     /// Return Lua state.
     lua_State* GetLuaState() const { return luaState_; }
     lua_State* GetLuaState() const { return luaState_; }
 
 
-    /// Find Lua function.
-    bool FindFunction(const String& functionName);
+    /// Push script function.
+    bool PushScriptFunction(const String& functionName);
+
+    /// Return script function ref.
+    int GetScriptFunctionRef(const String& functionName);
 
 
 private:
 private:
     /// Register loader.
     /// Register loader.
@@ -102,12 +107,15 @@ private:
     void HandleConsoleCommand(StringHash eventType, VariantMap& eventData);
     void HandleConsoleCommand(StringHash eventType, VariantMap& eventData);
 
 
 private:
 private:
-    /// Call Lua event handler.
-    void CallEventHandler(int functionRef, StringHash eventType, VariantMap& eventData);
+    /// Call script function.
+    void CallScriptFunction(int functionRef, StringHash eventType, VariantMap& eventData);
 
 
     /// Lua state.
     /// Lua state.
     lua_State* luaState_;
     lua_State* luaState_;
 
 
+    /// Function name to function ref map.
+    HashMap<String, int> functionNameToFunctionRefMap_;
+
     /// Event type to function ref map.
     /// Event type to function ref map.
     HashMap<StringHash, int> eventTypeToFunctionRefMap_;
     HashMap<StringHash, int> eventTypeToFunctionRefMap_;
 
 

+ 300 - 92
Source/Extras/LuaScript/LuaScriptInstance.cpp

@@ -21,13 +21,17 @@
 //
 //
 
 
 #include "Precompiled.h"
 #include "Precompiled.h"
+#include "CoreEvents.h"
 #include "Context.h"
 #include "Context.h"
 #include "Log.h"
 #include "Log.h"
 #include "LuaFile.h"
 #include "LuaFile.h"
 #include "LuaScript.h"
 #include "LuaScript.h"
 #include "LuaScriptInstance.h"
 #include "LuaScriptInstance.h"
+#include "MemoryBuffer.h"
+#include "PhysicsEvents.h"
 #include "ResourceCache.h"
 #include "ResourceCache.h"
 #include "ProcessUtils.h"
 #include "ProcessUtils.h"
+#include "VectorBuffer.h"
 
 
 extern "C"
 extern "C"
 {
 {
@@ -40,12 +44,30 @@ extern "C"
 namespace Urho3D
 namespace Urho3D
 {
 {
 
 
+static const char* scriptObjectMethodNames[] = {
+    ".Start",
+    ".Stop",
+    // ".DelayedStart",
+    ".Update",
+    ".PostUpdate",
+    ".FixedUpdate",
+    ".FixedPostUpdate",
+    ".Load",
+    ".Save",
+    ".ReadNetworkUpdate",
+    ".WriteNetworkUpdate",
+    ".ApplyAttributes"
+};
+
 LuaScriptInstance::LuaScriptInstance(Context* context) : 
 LuaScriptInstance::LuaScriptInstance(Context* context) : 
     Component(context),
     Component(context),
     scriptObjectRef_(LUA_REFNIL)
     scriptObjectRef_(LUA_REFNIL)
 {
 {
     luaScript_ = GetSubsystem<LuaScript>();
     luaScript_ = GetSubsystem<LuaScript>();
     luaState_ = luaScript_->GetLuaState();
     luaState_ = luaScript_->GetLuaState();
+
+    for (unsigned i = 0; i < MAX_LUA_SCRIPT_OBJECT_METHODS; ++i)
+        scriptObjectMethodRefs_[i] = LUA_REFNIL;
 }
 }
 
 
 LuaScriptInstance::~LuaScriptInstance()
 LuaScriptInstance::~LuaScriptInstance()
@@ -55,13 +77,61 @@ LuaScriptInstance::~LuaScriptInstance()
 
 
 void LuaScriptInstance::RegisterObject(Context* context)
 void LuaScriptInstance::RegisterObject(Context* context)
 {
 {
-    context->RegisterFactory<LuaScriptInstance>();
+    context->RegisterFactory<LuaScriptInstance>(LOGIC_CATEGORY);
+
+    // ACCESSOR_ATTRIBUTE(LuaScriptInstance, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    REF_ACCESSOR_ATTRIBUTE(LuaScriptInstance, VAR_STRING, "Script File Name", GetScriptFileName, SetScriptFileName, String, String::EMPTY, AM_DEFAULT);
+    REF_ACCESSOR_ATTRIBUTE(LuaScriptInstance, VAR_STRING, "Script Object Type", GetScriptObjectType, SetScriptObjectType, String, String::EMPTY, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(LuaScriptInstance, VAR_BUFFER, "Script Data", GetScriptDataAttr, SetScriptDataAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_FILE | AM_NOEDIT);
+    ACCESSOR_ATTRIBUTE(LuaScriptInstance, VAR_BUFFER, "Script Network Data", GetScriptNetworkDataAttr, SetScriptNetworkDataAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_NET | AM_NOEDIT);
+}
+
+void LuaScriptInstance::ApplyAttributes()
+{
+    CallScriptObjectFunction(scriptObjectMethodRefs_[LSOM_APPLYATTRIBUTES]);
 }
 }
 
 
 bool LuaScriptInstance::CreateObject(const String& scriptObjectType)
 bool LuaScriptInstance::CreateObject(const String& scriptObjectType)
+{
+    SetScriptFileName(String::EMPTY);
+    SetScriptObjectType(scriptObjectType);
+    return scriptObjectRef_ != LUA_REFNIL;
+}
+
+bool LuaScriptInstance::CreateObject(const String& scriptFileName, const String& scriptObjectType)
+{
+    SetScriptFileName(scriptFileName);
+    SetScriptObjectType(scriptObjectType);
+    return scriptObjectRef_ != LUA_REFNIL;
+}
+
+void LuaScriptInstance::SetScriptFileName(const String& scriptFileName)
+{
+    if (scriptFileName_ == scriptFileName)
+        return;
+
+    scriptFileName_ = scriptFileName;
+
+    if (!scriptFileName_.Empty())
+        return;
+
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+    LuaFile* luaFile = cache->GetResource<LuaFile>(scriptFileName_);
+    if (!luaFile)
+    {
+        LOGERROR("Get Lua file failed: " + scriptFileName_);
+    }
+
+    if (!luaFile->LoadAndExecute(luaState_))
+    {
+        LOGERROR("Execute Lua file failed: " + scriptFileName_);
+    }
+}
+
+void LuaScriptInstance::SetScriptObjectType(const String& scriptObjectType)
 {
 {
     if (scriptObjectType_ == scriptObjectType)
     if (scriptObjectType_ == scriptObjectType)
-        return true;
+        return;
 
 
     ReleaseObject();
     ReleaseObject();
 
 
@@ -72,7 +142,7 @@ bool LuaScriptInstance::CreateObject(const String& scriptObjectType)
     {
     {
         LOGERROR("Could not find lua function CreateScriptObjectInstance");
         LOGERROR("Could not find lua function CreateScriptObjectInstance");
         lua_settop(luaState_, top);
         lua_settop(luaState_, top);
-        return false;
+        return;
     }
     }
 
 
     // Get table as first paramter.
     // Get table as first paramter.
@@ -81,52 +151,56 @@ bool LuaScriptInstance::CreateObject(const String& scriptObjectType)
     {
     {
         LOGERROR("Could not find lua table " + scriptObjectType);
         LOGERROR("Could not find lua table " + scriptObjectType);
         lua_settop(luaState_, top);
         lua_settop(luaState_, top);
-        return false;
+        return;
     }
     }
 
 
     // Push this as second parameter.
     // Push this as second parameter.
     tolua_pushusertype(luaState_, (void*)this, "LuaScriptInstance");
     tolua_pushusertype(luaState_, (void*)this, "LuaScriptInstance");
-    
+
     // Call ObjectType:new function.
     // Call ObjectType:new function.
     if (lua_pcall(luaState_, 2, 1, 0) != 0)
     if (lua_pcall(luaState_, 2, 1, 0) != 0)
     {
     {
         const char* message = lua_tostring(luaState_, -1);
         const char* message = lua_tostring(luaState_, -1);
         LOGERROR("Execute Lua function failed: " + String(message));
         LOGERROR("Execute Lua function failed: " + String(message));
         lua_settop(luaState_, top);
         lua_settop(luaState_, top);
-        return false;
+        return;
     }
     }
 
 
     scriptObjectType_ = scriptObjectType;
     scriptObjectType_ = scriptObjectType;
     scriptObjectRef_ = luaL_ref(luaState_, LUA_REGISTRYINDEX);
     scriptObjectRef_ = luaL_ref(luaState_, LUA_REGISTRYINDEX);
 
 
-    return true;
+    // Find script object method refs.
+    FindScriptObjectMethodRefs();
 }
 }
 
 
-bool LuaScriptInstance::CreateObject(const String& fileName, const String& scriptObjectType)
+void LuaScriptInstance::SetScriptDataAttr(PODVector<unsigned char> data)
 {
 {
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-    
-    LuaFile* luaFile = cache->GetResource<LuaFile>(fileName);
-    if (!luaFile)
-        return false;
+    int functionRef = scriptObjectMethodRefs_[LSOM_LOAD];
+    if (scriptObjectRef_ == LUA_REFNIL || functionRef == LUA_REFNIL)
+        return;
 
 
-    if (!luaFile->LoadAndExecute(luaState_))
-        return false;
+    MemoryBuffer buf(data);    
+    CallScriptObjectFunction(functionRef, (Deserializer&)buf);
+}
+
+void LuaScriptInstance::SetScriptNetworkDataAttr(PODVector<unsigned char> data)
+{
+    int functionRef = scriptObjectMethodRefs_[LSOM_READNETWORKUPDATE];
+    if (scriptObjectRef_ == LUA_REFNIL || functionRef == LUA_REFNIL)
+        return;
 
 
-    return CreateObject(scriptObjectType);
+    MemoryBuffer buf(data);
+    CallScriptObjectFunction(functionRef, (Deserializer&)buf);
 }
 }
 
 
 void LuaScriptInstance::ScriptSubscribeToEvent(const String& eventName, const String& functionName)
 void LuaScriptInstance::ScriptSubscribeToEvent(const String& eventName, const String& functionName)
 {
 {
-    StringHash eventType(eventName);
     String realFunctionName = functionName.Replaced(":", ".");
     String realFunctionName = functionName.Replaced(":", ".");
 
 
-    int functionRef = LUA_REFNIL;
-    if (luaScript_->FindFunction(realFunctionName))
-        functionRef = luaL_ref(luaState_, LUA_REGISTRYINDEX);
-
+    int functionRef = luaScript_->GetScriptFunctionRef(realFunctionName);
     if (functionRef != LUA_REFNIL)
     if (functionRef != LUA_REFNIL)
     {
     {
+        StringHash eventType(eventName);
         SubscribeToEvent(eventType, HANDLER(LuaScriptInstance, HandleEvent));
         SubscribeToEvent(eventType, HANDLER(LuaScriptInstance, HandleEvent));
         eventTypeToFunctionRefMap_[eventType] = functionRef;
         eventTypeToFunctionRefMap_[eventType] = functionRef;
     }
     }
@@ -140,10 +214,6 @@ void LuaScriptInstance::ScriptUnsubscribeFromEvent(const String& eventName)
     if (i != eventTypeToFunctionRefMap_.End())
     if (i != eventTypeToFunctionRefMap_.End())
     {
     {
         UnsubscribeFromEvent(eventType);
         UnsubscribeFromEvent(eventType);
-
-        if (i->second_ != LUA_REFNIL)
-            luaL_unref(luaState_, LUA_REGISTRYINDEX, i->second_);
-
         eventTypeToFunctionRefMap_.Erase(i);
         eventTypeToFunctionRefMap_.Erase(i);
     }
     }
 }
 }
@@ -154,66 +224,117 @@ void LuaScriptInstance::ScriptUnsubscribeFromAllEvents()
         return;
         return;
 
 
     UnsubscribeFromAllEvents();
     UnsubscribeFromAllEvents();
-
-    for (HashMap<StringHash, int>::Iterator i = eventTypeToFunctionRefMap_.Begin(); i != eventTypeToFunctionRefMap_.End(); ++i)
-        if (i->second_ != LUA_REFNIL)
-            luaL_unref(luaState_, LUA_REGISTRYINDEX, i->second_);
-
     eventTypeToFunctionRefMap_.Clear();
     eventTypeToFunctionRefMap_.Clear();
 }
 }
 
 
-void LuaScriptInstance::ScriptSubscribeToEvent(void* object, const String& eventName, const String& functionName)
+void LuaScriptInstance::ScriptSubscribeToEvent(void* sender, const String& eventName, const String& functionName)
 {
 {
-    StringHash eventType(eventName);
     String realFunctionName = functionName.Replaced(":", ".");
     String realFunctionName = functionName.Replaced(":", ".");
-    Object* sender = (Object*)object;
-
-    int functionRef = LUA_REFNIL;
-    if (luaScript_->FindFunction(realFunctionName))
-        functionRef = luaL_ref(luaState_, LUA_REGISTRYINDEX);
 
 
+    int functionRef = luaScript_->GetScriptFunctionRef(realFunctionName);
     if (functionRef != LUA_REFNIL)
     if (functionRef != LUA_REFNIL)
     {
     {
-        SubscribeToEvent(sender, eventType, HANDLER(LuaScriptInstance, HandleObjectEvent));
-        objectToEventTypeToFunctionRefMap_[sender][eventType] = functionRef;
+        Object* object = (Object*)sender;
+        StringHash eventType(eventName);
+        SubscribeToEvent(object, eventType, HANDLER(LuaScriptInstance, HandleObjectEvent));
+        objectToEventTypeToFunctionRefMap_[object][eventType] = functionRef;
     }
     }
 }
 }
 
 
-void LuaScriptInstance::ScriptUnsubscribeFromEvent(void* object, const String& eventName)
+void LuaScriptInstance::ScriptUnsubscribeFromEvent(void* sender, const String& eventName)
 {
 {
     StringHash eventType(eventName);
     StringHash eventType(eventName);
-    Object* sender = (Object*)object;
+    Object* object = (Object*)sender ;
 
 
-    HashMap<StringHash, int>::Iterator i = objectToEventTypeToFunctionRefMap_[sender].Find(eventType);
-    if (i != objectToEventTypeToFunctionRefMap_[sender].End())
+    HashMap<StringHash, int>::Iterator i = objectToEventTypeToFunctionRefMap_[object].Find(eventType);
+    if (i != objectToEventTypeToFunctionRefMap_[object].End())
     {
     {
-        UnsubscribeFromEvent(sender, eventType);
-
-        if (i->second_ != LUA_REFNIL)
-            luaL_unref(luaState_, LUA_REGISTRYINDEX, i->second_);
-
-        objectToEventTypeToFunctionRefMap_[sender].Erase(i);
+        UnsubscribeFromEvent(object, eventType);
+        objectToEventTypeToFunctionRefMap_[object].Erase(i);
     }
     }
 }
 }
 
 
-void LuaScriptInstance::ScriptUnsubscribeFromEvents(void* object)
+void LuaScriptInstance::ScriptUnsubscribeFromEvents(void* sender)
 {
 {
-    Object* sender = (Object*)object;
+    Object* object = (Object*)sender;
 
 
-    HashMap<Object*, HashMap<StringHash, int> >::Iterator it = objectToEventTypeToFunctionRefMap_.Find(sender);
+    HashMap<Object*, HashMap<StringHash, int> >::Iterator it = objectToEventTypeToFunctionRefMap_.Find(object);
     if (it == objectToEventTypeToFunctionRefMap_.End())
     if (it == objectToEventTypeToFunctionRefMap_.End())
         return;
         return;
 
 
-    UnsubscribeFromEvents(sender);
+    UnsubscribeFromEvents(object);
+    objectToEventTypeToFunctionRefMap_.Erase(it);
+}
 
 
-    HashMap<StringHash, int>& eventTypeToFunctionRefMap = it->second_;
-    for (HashMap<StringHash, int>::Iterator i = eventTypeToFunctionRefMap.Begin(); i != eventTypeToFunctionRefMap.End(); ++i)
-    {
-        if (i->second_ != LUA_REFNIL)
-            luaL_unref(luaState_, LUA_REGISTRYINDEX, i->second_);
-    }
+PODVector<unsigned char> LuaScriptInstance::GetScriptDataAttr() const
+{
+    int functionRef = scriptObjectMethodRefs_[LSOM_SAVE];
+    if (scriptObjectRef_ == LUA_REFNIL || functionRef == LUA_REFNIL)
+        return PODVector<unsigned char>();
 
 
-    objectToEventTypeToFunctionRefMap_.Erase(it);
+    VectorBuffer buf;
+    CallScriptObjectFunction(functionRef, (Serializer&)buf);
+
+    return buf.GetBuffer();
+}
+
+PODVector<unsigned char> LuaScriptInstance::GetScriptNetworkDataAttr() const
+{
+    int functionRef = scriptObjectMethodRefs_[LSOM_WRITENETWORKUPDATE];
+    if (scriptObjectRef_ == LUA_REFNIL || functionRef == LUA_REFNIL)
+        return PODVector<unsigned char>();
+
+    VectorBuffer buf;
+    CallScriptObjectFunction(functionRef, (Serializer&)buf);
+
+    return buf.GetBuffer();
+}
+
+
+void LuaScriptInstance::FindScriptObjectMethodRefs()
+{
+    for (unsigned i = 0; i < MAX_LUA_SCRIPT_OBJECT_METHODS; ++i)
+        scriptObjectMethodRefs_[i] = luaScript_->GetScriptFunctionRef(scriptObjectType_ + scriptObjectMethodNames[i]);
+
+    if (scriptObjectMethodRefs_[LSOM_UPDATE] != LUA_REFNIL)
+        SubscribeToEvent(E_UPDATE, HANDLER(LuaScriptInstance, HandleUpdate));
+
+    if (scriptObjectMethodRefs_[LSOM_POSTUPDATE] != LUA_REFNIL)
+        SubscribeToEvent(E_POSTUPDATE, HANDLER(LuaScriptInstance, HandlePostUpdate));
+
+    if (scriptObjectMethodRefs_[LSOM_FIXEDUPDATE] != LUA_REFNIL)
+        SubscribeToEvent(E_PHYSICSPRESTEP, HANDLER(LuaScriptInstance, HandleFixedUpdate));
+
+    if (scriptObjectMethodRefs_[LSOM_FIXEDPOSTUPDATE] != LUA_REFNIL)
+        SubscribeToEvent(E_PHYSICSPOSTSTEP, HANDLER(LuaScriptInstance, HandlePostFixedUpdate));
+}
+
+void LuaScriptInstance::HandleUpdate(StringHash eventType, VariantMap& eventData)
+{
+    using namespace Update;
+    float timeStep = eventData[P_TIMESTEP].GetFloat();
+    CallScriptObjectFunction(scriptObjectMethodRefs_[LSOM_UPDATE], timeStep);
+}
+
+void LuaScriptInstance::HandlePostUpdate(StringHash eventType, VariantMap& eventData)
+{
+    using namespace PostUpdate;
+    float timeStep = eventData[P_TIMESTEP].GetFloat();
+    CallScriptObjectFunction(scriptObjectMethodRefs_[LSOM_POSTUPDATE], timeStep);
+}
+
+void LuaScriptInstance::HandleFixedUpdate(StringHash eventType, VariantMap& eventData)
+{
+    using namespace PhysicsPreStep;
+    float timeStep = eventData[P_TIMESTEP].GetFloat();
+    CallScriptObjectFunction(scriptObjectMethodRefs_[LSOM_FIXEDUPDATE], timeStep);
+}
+
+void LuaScriptInstance::HandlePostFixedUpdate(StringHash eventType, VariantMap& eventData)
+{
+    using namespace PhysicsPostStep;
+    float timeStep = eventData[P_TIMESTEP].GetFloat();
+    CallScriptObjectFunction(scriptObjectMethodRefs_[LSOM_FIXEDPOSTUPDATE], timeStep);
 }
 }
 
 
 void LuaScriptInstance::HandleEvent(StringHash eventType, VariantMap& eventData)
 void LuaScriptInstance::HandleEvent(StringHash eventType, VariantMap& eventData)
@@ -225,7 +346,7 @@ void LuaScriptInstance::HandleEvent(StringHash eventType, VariantMap& eventData)
     if (functionRef == LUA_REFNIL)
     if (functionRef == LUA_REFNIL)
         return;
         return;
 
 
-    CallEventHandler(functionRef, eventType, eventData);
+    CallScriptObjectFunction(functionRef, eventType, eventData);
 }
 }
 
 
 void LuaScriptInstance::HandleObjectEvent(StringHash eventType, VariantMap& eventData)
 void LuaScriptInstance::HandleObjectEvent(StringHash eventType, VariantMap& eventData)
@@ -238,11 +359,43 @@ void LuaScriptInstance::HandleObjectEvent(StringHash eventType, VariantMap& even
     if (functionRef == LUA_REFNIL)
     if (functionRef == LUA_REFNIL)
         return;
         return;
 
 
-    CallEventHandler(functionRef, eventType, eventData);
+    CallScriptObjectFunction(functionRef, eventType, eventData);
 }
 }
 
 
-void LuaScriptInstance::CallEventHandler(int functionRef, StringHash eventType, VariantMap& eventData )
+void LuaScriptInstance::ReleaseObject()
 {
 {
+    if (scriptObjectRef_ == LUA_REFNIL)
+        return;
+    
+    // Unref script object.
+    luaL_unref(luaState_, LUA_REGISTRYINDEX, scriptObjectRef_);
+    scriptObjectRef_ = LUA_REFNIL;
+
+    int top = lua_gettop(luaState_);
+    lua_getglobal(luaState_, "DestroyScriptObjectInstance");
+    if (!lua_isfunction(luaState_, -1))
+    {
+        LOGERROR("Could not find lua function DestroyScriptObjectInstance");
+        lua_settop(luaState_, top);
+        return;
+    }
+
+    // Push this as second parameter.
+    tolua_pushusertype(luaState_, (void*)this, "LuaScriptInstance");
+    if (lua_pcall(luaState_, 1, 0, 0) != 0)
+    {
+        const char* message = lua_tostring(luaState_, -1);
+        LOGERROR("Execute Lua function failed: " + String(message));
+        lua_settop(luaState_, top);
+        return;
+    }
+}
+
+void LuaScriptInstance::CallScriptObjectFunction(int functionRef)
+{
+    if (functionRef == LUA_REFNIL)
+        return;
+
     int top = lua_gettop(luaState_);
     int top = lua_gettop(luaState_);
 
 
     // Push function.
     // Push function.
@@ -251,13 +404,34 @@ void LuaScriptInstance::CallEventHandler(int functionRef, StringHash eventType,
     // Push script object.
     // Push script object.
     lua_rawgeti(luaState_, LUA_REGISTRYINDEX, scriptObjectRef_);
     lua_rawgeti(luaState_, LUA_REGISTRYINDEX, scriptObjectRef_);
 
 
-    // Push event type.
-    tolua_pushusertype(luaState_, (void*)&eventType, "StringHash");
+    // Call update function.
+    if (lua_pcall(luaState_, 1, 0, 0) != 0)
+    {
+        const char* message = lua_tostring(luaState_, -1);
+        LOGERROR("Execute Lua function failed: " + String(message));
+        lua_settop(luaState_, top);
+        return;
+    }
+}
 
 
-    // Push event data.
-    tolua_pushusertype(luaState_, (void*)&eventData, "VariantMap");
+void LuaScriptInstance::CallScriptObjectFunction(int functionRef, float timeStep)
+{
+    if (functionRef == LUA_REFNIL)
+        return;
 
 
-    if (lua_pcall(luaState_, 3, 0, 0) != 0)
+    int top = lua_gettop(luaState_);
+
+    // Push function.
+    lua_rawgeti(luaState_, LUA_REGISTRYINDEX, functionRef);
+
+    // Push script object.
+    lua_rawgeti(luaState_, LUA_REGISTRYINDEX, scriptObjectRef_);
+
+    // Push time step.
+    tolua_pushnumber(luaState_, timeStep);
+
+    // Call update function.
+    if (lua_pcall(luaState_, 2, 0, 0) != 0)
     {
     {
         const char* message = lua_tostring(luaState_, -1);
         const char* message = lua_tostring(luaState_, -1);
         LOGERROR("Execute Lua function failed: " + String(message));
         LOGERROR("Execute Lua function failed: " + String(message));
@@ -266,39 +440,74 @@ void LuaScriptInstance::CallEventHandler(int functionRef, StringHash eventType,
     }
     }
 }
 }
 
 
-void LuaScriptInstance::ReleaseObject()
+
+void LuaScriptInstance::CallScriptObjectFunction(int functionRef, Deserializer& deserializer)
 {
 {
-    if (scriptObjectRef_ == LUA_REFNIL)
+    if (functionRef == LUA_REFNIL)
         return;
         return;
-    
-    // Unref script object.
-    luaL_unref(luaState_, LUA_REGISTRYINDEX, scriptObjectRef_);
-    scriptObjectRef_ = LUA_REFNIL;
-    
-    // Unref Lua function.
-    for (HashMap<StringHash, int>::Iterator i = eventTypeToFunctionRefMap_.Begin(); i != eventTypeToFunctionRefMap_.End(); ++i)
-        luaL_unref(luaState_, LUA_REGISTRYINDEX, i->second_);
-    for (HashMap<Object*, HashMap<StringHash, int> >::Iterator i = objectToEventTypeToFunctionRefMap_.Begin(); 
-        i != objectToEventTypeToFunctionRefMap_.End(); ++i)
+
+    int top = lua_gettop(luaState_);
+
+    // Push function.
+    lua_rawgeti(luaState_, LUA_REGISTRYINDEX, functionRef);
+
+    // Push script object.
+    lua_rawgeti(luaState_, LUA_REGISTRYINDEX, scriptObjectRef_);
+
+    // Push Deserializer.
+    tolua_pushusertype(luaState_, (void*)&deserializer, "Deserializer");
+
+    // Call update function.
+    if (lua_pcall(luaState_, 2, 0, 0) != 0)
     {
     {
-        for (HashMap<StringHash, int>::Iterator j = i->second_.Begin(); j != i->second_.End(); ++j)
-            luaL_unref(luaState_, LUA_REGISTRYINDEX, j->second_);
+        const char* message = lua_tostring(luaState_, -1);
+        LOGERROR("Execute Lua function failed: " + String(message));
+        lua_settop(luaState_, top);
     }
     }
-    
+}
+
+void LuaScriptInstance::CallScriptObjectFunction(int functionRef, Serializer& serializer) const
+{
+    if (functionRef == LUA_REFNIL)
+        return;
+
     int top = lua_gettop(luaState_);
     int top = lua_gettop(luaState_);
 
 
-    lua_getglobal(luaState_, "DestroyScriptObjectInstance");
-    if (!lua_isfunction(luaState_, -1))
+    // Push function.
+    lua_rawgeti(luaState_, LUA_REGISTRYINDEX, functionRef);
+
+    // Push script object.
+    lua_rawgeti(luaState_, LUA_REGISTRYINDEX, scriptObjectRef_);
+
+    // Push Deserializer.
+    tolua_pushusertype(luaState_, (void*)&serializer, "Serializer");
+
+    // Call update function.
+    if (lua_pcall(luaState_, 2, 0, 0) != 0)
     {
     {
-        LOGERROR("Could not find lua function DestroyScriptObjectInstance");
+        const char* message = lua_tostring(luaState_, -1);
+        LOGERROR("Execute Lua function failed: " + String(message));
         lua_settop(luaState_, top);
         lua_settop(luaState_, top);
-        return;
     }
     }
+}
 
 
-    // Push this as second parameter.
-    tolua_pushusertype(luaState_, (void*)this, "LuaScriptInstance");
+void LuaScriptInstance::CallScriptObjectFunction(int functionRef, StringHash eventType, VariantMap& eventData )
+{
+    int top = lua_gettop(luaState_);
 
 
-    if (lua_pcall(luaState_, 1, 0, 0) != 0)
+    // Push function.
+    lua_rawgeti(luaState_, LUA_REGISTRYINDEX, functionRef);
+
+    // Push script object.
+    lua_rawgeti(luaState_, LUA_REGISTRYINDEX, scriptObjectRef_);
+
+    // Push event type.
+    tolua_pushusertype(luaState_, (void*)&eventType, "StringHash");
+
+    // Push event data.
+    tolua_pushusertype(luaState_, (void*)&eventData, "VariantMap");
+
+    if (lua_pcall(luaState_, 3, 0, 0) != 0)
     {
     {
         const char* message = lua_tostring(luaState_, -1);
         const char* message = lua_tostring(luaState_, -1);
         LOGERROR("Execute Lua function failed: " + String(message));
         LOGERROR("Execute Lua function failed: " + String(message));
@@ -306,5 +515,4 @@ void LuaScriptInstance::ReleaseObject()
         return;
         return;
     }
     }
 }
 }
-
-}
+}

+ 83 - 8
Source/Extras/LuaScript/LuaScriptInstance.h

@@ -31,7 +31,25 @@ namespace Urho3D
 
 
 class LuaScript;
 class LuaScript;
 
 
-/// Lua instance.
+/// Lua Script object methods.
+enum LuaScriptObjectMethod
+{
+    LSOM_START = 0,
+    LSOM_STOP,
+    // LSOM_DELAYEDSTART,
+    LSOM_UPDATE,
+    LSOM_POSTUPDATE,
+    LSOM_FIXEDUPDATE,
+    LSOM_FIXEDPOSTUPDATE,
+    LSOM_LOAD,
+    LSOM_SAVE,
+    LSOM_READNETWORKUPDATE,
+    LSOM_WRITENETWORKUPDATE,
+    LSOM_APPLYATTRIBUTES,
+    MAX_LUA_SCRIPT_OBJECT_METHODS
+};
+
+/// Lua script instance.
 class URHO3D_API LuaScriptInstance : public Component
 class URHO3D_API LuaScriptInstance : public Component
 {
 {
     OBJECT(LuaScriptInstance);
     OBJECT(LuaScriptInstance);
@@ -44,11 +62,26 @@ public:
     /// Register object factory.
     /// Register object factory.
     static void RegisterObject(Context* context);
     static void RegisterObject(Context* context);
 
 
+    ///// Apply attribute changes that can not be applied immediately. Called after scene load or a network update.
+    virtual void ApplyAttributes();
+
     /// Create script object.
     /// Create script object.
     bool CreateObject(const String& scriptObjectType);
     bool CreateObject(const String& scriptObjectType);
 
 
     /// Create script object.
     /// Create script object.
-    bool CreateObject(const String& fileName, const String& scriptObjectType);
+    bool CreateObject(const String& scriptFileName, const String& scriptObjectType);
+
+    /// Set script file name.
+    void SetScriptFileName(const String& scriptFileName);
+
+    /// Set script object type.
+    void SetScriptObjectType(const String& scriptObjectType);
+
+    /// Set script file serialization attribute by calling a script function.
+    void SetScriptDataAttr(PODVector<unsigned char> data);
+    
+    /// Set script network serialization attribute by calling a script function.
+    void SetScriptNetworkDataAttr(PODVector<unsigned char> data);
 
 
     /// 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);
@@ -60,13 +93,16 @@ public:
     void ScriptUnsubscribeFromAllEvents();
     void ScriptUnsubscribeFromAllEvents();
 
 
     /// Script subscribe to a specific sender's event.
     /// Script subscribe to a specific sender's event.
-    void ScriptSubscribeToEvent(void* object, 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* object, const String& eventName);
+    void ScriptUnsubscribeFromEvent(void* sender, const String& eventName);
 
 
     /// Script unsubscribe from a specific sender's all events.
     /// Script unsubscribe from a specific sender's all events.
-    void ScriptUnsubscribeFromEvents(void* object);
+    void ScriptUnsubscribeFromEvents(void* sender);
+
+    /// Return script file name.
+    const String& GetScriptFileName() const { return scriptFileName_; }
 
 
     /// Return script object type.
     /// Return script object type.
     const String& GetScriptObjectType() const { return scriptObjectType_; }
     const String& GetScriptObjectType() const { return scriptObjectType_; }
@@ -74,31 +110,70 @@ public:
     /// Return script object ref.
     /// Return script object ref.
     int GetScriptObjectRef() const { return scriptObjectRef_; }
     int GetScriptObjectRef() const { return scriptObjectRef_; }
 
 
+    /// Get script file serialization attribute by calling a script function.
+    PODVector<unsigned char> GetScriptDataAttr() const;
+
+    /// Get script network serialization attribute by calling a script function.
+    PODVector<unsigned char> GetScriptNetworkDataAttr() const;
+
 private:
 private:
+    /// Find script object method refs.
+    void FindScriptObjectMethodRefs();
+
+    /// Handle the logic update event.
+    void HandleUpdate(StringHash eventType, VariantMap& eventData);
+
+    /// Handle the logic post update event.
+    void HandlePostUpdate(StringHash eventType, VariantMap& eventData);
+
+    /// Handle the physics update event.
+    void HandleFixedUpdate(StringHash eventType, VariantMap& eventData);
+
+    /// Handle the physics post update event.
+    void HandlePostFixedUpdate(StringHash eventType, VariantMap& eventData);
+
     /// Handle event.
     /// Handle event.
     void HandleEvent(StringHash eventType, VariantMap& eventData);
     void HandleEvent(StringHash eventType, VariantMap& eventData);
 
 
     /// Handle object event.
     /// Handle object event.
     void HandleObjectEvent(StringHash eventType, VariantMap& eventData);
     void HandleObjectEvent(StringHash eventType, VariantMap& eventData);
 
 
-    /// Call event handler.
-    void CallEventHandler(int functionRef, StringHash eventType, VariantMap& eventData);
-
     /// Release the script object.
     /// Release the script object.
     void ReleaseObject();
     void ReleaseObject();
     
     
+    /// Call script object function.
+    void CallScriptObjectFunction(int functionRef);
+
+    /// Call script object function.
+    void CallScriptObjectFunction(int functionRef, float timeStep);
+
+    /// Call script object function.
+    void CallScriptObjectFunction(int functionRef, Deserializer& deserializer);
+
+    /// Call script object function.
+    void CallScriptObjectFunction(int functionRef, Serializer& serializer) const;
+
+    /// Call script object function.
+    void CallScriptObjectFunction(int functionRef, StringHash eventType, VariantMap& eventData);
+
     // Lua Script.
     // Lua Script.
     LuaScript* luaScript_;
     LuaScript* luaScript_;
 
 
     /// Lua state.
     /// Lua state.
     lua_State* luaState_;
     lua_State* luaState_;
 
 
+    /// Script file name.
+    String scriptFileName_;
+
     /// Script object type.
     /// Script object type.
     String scriptObjectType_;
     String scriptObjectType_;
 
 
     /// Script object ref.
     /// Script object ref.
     int scriptObjectRef_;
     int scriptObjectRef_;
 
 
+    /// Script object method refs.
+    int scriptObjectMethodRefs_[MAX_LUA_SCRIPT_OBJECT_METHODS];
+
     /// Event type to function ref map.
     /// Event type to function ref map.
     HashMap<StringHash, int> eventTypeToFunctionRefMap_;
     HashMap<StringHash, int> eventTypeToFunctionRefMap_;
     
     

+ 9 - 9
Source/Extras/LuaScript/pkgs/LuaScript/LuaScript.pkg

@@ -6,9 +6,9 @@ void SendEvent(const String eventName, VariantMap& eventData);
 void SubscribeToEvent(const String eventName, const String functionName);
 void SubscribeToEvent(const String eventName, const String functionName);
 void UnsubscribeFromEvent(const String eventName);
 void UnsubscribeFromEvent(const String eventName);
 void UnsubscribeFromAllEvents();
 void UnsubscribeFromAllEvents();
-void SubscribeToEvent(void* object, const String eventName, const String functionName);
-void UnsubscribeFromEvent(void* object, const String eventName);
-void UnsubscribeFromEvents(void* object);
+void SubscribeToEvent(void* sender, const String eventName, const String functionName);
+void UnsubscribeFromEvent(void* sender, const String eventName);
+void UnsubscribeFromEvents(void* sender);
 
 
 ${
 ${
 static LuaScript* GetLuaScript()
 static LuaScript* GetLuaScript()
@@ -41,18 +41,18 @@ static void UnsubscribeFromAllEvents()
     GetLuaScript()->ScriptUnsubscribeFromAllEvents();
     GetLuaScript()->ScriptUnsubscribeFromAllEvents();
 }
 }
 
 
-static void SubscribeToEvent(void* object, const String& eventName, const String& functionName)
+static void SubscribeToEvent(void* sender, const String& eventName, const String& functionName)
 {
 {
-    GetLuaScript()->ScriptSubscribeToEvent(object, eventName, functionName);
+    GetLuaScript()->ScriptSubscribeToEvent(sender, eventName, functionName);
 }
 }
 
 
-static void UnsubscribeFromEvent(void* object, const String& eventName)
+static void UnsubscribeFromEvent(void* sender, const String& eventName)
 {
 {
-    GetLuaScript()->ScriptUnsubscribeFromEvent(object, eventName);
+    GetLuaScript()->ScriptUnsubscribeFromEvent(sender, eventName);
 }
 }
 
 
-static void UnsubscribeFromEvents(void* object)
+static void UnsubscribeFromEvents(void* sender)
 {
 {
-    GetLuaScript()->ScriptUnsubscribeFromEvents(object);
+    GetLuaScript()->ScriptUnsubscribeFromEvents(sender);
 }
 }
 $}
 $}

+ 11 - 6
Source/Extras/LuaScript/pkgs/LuaScript/LuaScriptInstance.pkg

@@ -3,15 +3,20 @@ $#include "LuaScriptInstance.h"
 class LuaScriptInstance : public Component
 class LuaScriptInstance : public Component
 {
 {
     bool CreateObject(const String scriptObjectType);
     bool CreateObject(const String scriptObjectType);
-    bool CreateObject(const String fileName, const String scriptObjectType);
+    bool CreateObject(const String scriptFileName, const String scriptObjectType);
+    void SetScriptFileName(const String scriptFileName);
+    void SetScriptObjectType(const String scriptObjectType);
     void ScriptSubscribeToEvent @ SubscribeToEvent(const String eventName, const String functionName);
     void ScriptSubscribeToEvent @ SubscribeToEvent(const String eventName, const String functionName);
     void ScriptUnsubscribeFromEvent @ UnsubscribeFromEvent(const String eventName);
     void ScriptUnsubscribeFromEvent @ UnsubscribeFromEvent(const String eventName);
     void ScriptUnsubscribeFromAllEvents @ UnsubscribeFromAllEvents();    
     void ScriptUnsubscribeFromAllEvents @ UnsubscribeFromAllEvents();    
-    void ScriptSubscribeToEvent @ SubscribeToEvent(void* object, const String eventName, const String functionName);
-    void ScriptUnsubscribeFromEvent @ UnsubscribeFromEvent(void* object, const String eventName);
-    void ScriptUnsubscribeFromEvents @ UnsubscribeFromEvents(void* object);
-    const String GetScriptObjectType() const;
-    int GetScriptObjectRef() const;
+    void ScriptSubscribeToEvent @ SubscribeToEvent(void* sender, const String eventName, const String functionName);
+    void ScriptUnsubscribeFromEvent @ UnsubscribeFromEvent(void* sender, const String eventName);
+    void ScriptUnsubscribeFromEvents @ UnsubscribeFromEvents(void* sender);
+    const String& GetScriptFileName() const;
+    const String& GetScriptObjectType() const;
+    
+    tolua_property__get_set const String scriptFileName;
+    tolua_property__get_set const String scriptObjectType;
 };
 };
 
 
 $[
 $[

+ 1 - 0
Source/Extras/LuaScript/pkgs/Math/BoundingBox.pkg

@@ -10,6 +10,7 @@ class BoundingBox
     BoundingBox(const Frustum& frustum);
     BoundingBox(const Frustum& frustum);
     BoundingBox(const Polyhedron& poly);
     BoundingBox(const Polyhedron& poly);
     BoundingBox(const Sphere& sphere);
     BoundingBox(const Sphere& sphere);
+    ~BoundingBox();
     
     
     bool operator == (const BoundingBox& rhs) const;
     bool operator == (const BoundingBox& rhs) const;
     
     

+ 1 - 0
Source/Extras/LuaScript/pkgs/Math/Color.pkg

@@ -7,6 +7,7 @@ class Color
     Color(const Color& color, float a);
     Color(const Color& color, float a);
     Color(float r, float g, float b);
     Color(float r, float g, float b);
     Color(float r, float g, float b, float a);
     Color(float r, float g, float b, float a);
+    ~Color();
     
     
     bool operator == (const Color& rhs) const;
     bool operator == (const Color& rhs) const;
     Color operator * (float rhs) const;
     Color operator * (float rhs) const;

+ 1 - 0
Source/Extras/LuaScript/pkgs/Math/Frustum.pkg

@@ -17,6 +17,7 @@ class Frustum
 {
 {
     Frustum();
     Frustum();
     Frustum(const Frustum& frustum);
     Frustum(const Frustum& frustum);
+    ~Frustum();
 
 
     void Define(float fov, float aspectRatio, float zoom, float nearZ, float farZ, const Matrix3x4& transform = Matrix3x4::IDENTITY);
     void Define(float fov, float aspectRatio, float zoom, float nearZ, float farZ, const Matrix3x4& transform = Matrix3x4::IDENTITY);
     void Define(const Vector3& near, const Vector3& far, const Matrix3x4& transform = Matrix3x4::IDENTITY);
     void Define(const Vector3& near, const Vector3& far, const Matrix3x4& transform = Matrix3x4::IDENTITY);

+ 1 - 0
Source/Extras/LuaScript/pkgs/Math/Matrix3.pkg

@@ -7,6 +7,7 @@ class Matrix3
     Matrix3(float v00, float v01, float v02,
     Matrix3(float v00, float v01, float v02,
             float v10, float v11, float v12,
             float v10, float v11, float v12,
             float v20, float v21, float v22);
             float v20, float v21, float v22);
+    ~Matrix3();
     
     
     bool operator == (const Matrix3& rhs) const;
     bool operator == (const Matrix3& rhs) const;
     
     

+ 1 - 0
Source/Extras/LuaScript/pkgs/Math/Matrix4.pkg

@@ -10,6 +10,7 @@ class Matrix4
             float v10, float v11, float v12, float v13,
             float v10, float v11, float v12, float v13,
             float v20, float v21, float v22, float v23,
             float v20, float v21, float v22, float v23,
             float v30, float v31, float v32, float v33);
             float v30, float v31, float v32, float v33);
+    ~Matrix4();
     
     
     bool operator == (const Matrix4& rhs) const;
     bool operator == (const Matrix4& rhs) const;
     
     

+ 1 - 0
Source/Extras/LuaScript/pkgs/Math/Plane.pkg

@@ -7,6 +7,7 @@ class Plane
     Plane(const Plane& plane);
     Plane(const Plane& plane);
     Plane(const Vector3& v0, const Vector3& v1, const Vector3& v2);
     Plane(const Vector3& v0, const Vector3& v1, const Vector3& v2);
     Plane(const Vector3& normal, const Vector3& point);
     Plane(const Vector3& normal, const Vector3& point);
+    ~Plane();
     
     
     void Define(const Vector3& v0, const Vector3& v1, const Vector3& v2);
     void Define(const Vector3& v0, const Vector3& v1, const Vector3& v2);
     void Define(const Vector3& normal, const Vector3& point);
     void Define(const Vector3& normal, const Vector3& point);

+ 1 - 0
Source/Extras/LuaScript/pkgs/Math/Quaternion.pkg

@@ -10,6 +10,7 @@ class Quaternion
     Quaternion(const Vector3& start, const Vector3& end);
     Quaternion(const Vector3& start, const Vector3& end);
     Quaternion(const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis);
     Quaternion(const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis);
     Quaternion(const Matrix3& matrix);
     Quaternion(const Matrix3& matrix);
+    ~Quaternion();
 
 
     bool operator == (const Quaternion& rhs) const;
     bool operator == (const Quaternion& rhs) const;
     
     

+ 1 - 0
Source/Extras/LuaScript/pkgs/Math/Ray.pkg

@@ -5,6 +5,7 @@ class Ray
     Ray();
     Ray();
     Ray(const Vector3& origin, const Vector3& direction);
     Ray(const Vector3& origin, const Vector3& direction);
     Ray(const Ray& ray);
     Ray(const Ray& ray);
+    ~Ray();
 
 
     bool operator == (const Ray& rhs) const;
     bool operator == (const Ray& rhs) const;
     
     

+ 2 - 0
Source/Extras/LuaScript/pkgs/Math/Rect.pkg

@@ -7,6 +7,7 @@ class Rect
     Rect(const Vector2& min, const Vector2& max);
     Rect(const Vector2& min, const Vector2& max);
     Rect(float left, float top, float right, float bottom);
     Rect(float left, float top, float right, float bottom);
     Rect(const Vector4& vector);
     Rect(const Vector4& vector);
+    ~Rect();
 
 
     bool operator == (const Rect& rhs) const;
     bool operator == (const Rect& rhs) const;
     
     
@@ -40,6 +41,7 @@ class IntRect
 {
 {
     IntRect();
     IntRect();
     IntRect(int left, int top, int right, int bottom);
     IntRect(int left, int top, int right, int bottom);
+    ~IntRect();
 
 
     bool operator == (const IntRect& rhs) const;
     bool operator == (const IntRect& rhs) const;
     
     

+ 1 - 0
Source/Extras/LuaScript/pkgs/Math/Sphere.pkg

@@ -8,6 +8,7 @@ class Sphere
     Sphere(const BoundingBox& box);
     Sphere(const BoundingBox& box);
     Sphere(const Frustum& frustum);
     Sphere(const Frustum& frustum);
     Sphere(const Polyhedron& poly);
     Sphere(const Polyhedron& poly);
+    ~Sphere();
     
     
     bool operator == (const Sphere& rhs) const;
     bool operator == (const Sphere& rhs) const;
     
     

+ 3 - 1
Source/Extras/LuaScript/pkgs/Math/StringHash.pkg

@@ -6,6 +6,7 @@ class StringHash
     StringHash(const StringHash& rhs);
     StringHash(const StringHash& rhs);
     explicit StringHash(unsigned value);
     explicit StringHash(unsigned value);
     StringHash(const String str);
     StringHash(const String str);
+    ~StringHash();
 
 
     StringHash operator + (const StringHash& rhs) const;
     StringHash operator + (const StringHash& rhs) const;
     bool operator == (const StringHash& rhs) const;
     bool operator == (const StringHash& rhs) const;
@@ -28,7 +29,8 @@ class ShortStringHash
     explicit ShortStringHash(const StringHash& rhs);
     explicit ShortStringHash(const StringHash& rhs);
     explicit ShortStringHash(unsigned short value);
     explicit ShortStringHash(unsigned short value);
     ShortStringHash(const String str);
     ShortStringHash(const String str);
-
+    ~ShortStringHash();
+    
     ShortStringHash operator + (const ShortStringHash& rhs) const;
     ShortStringHash operator + (const ShortStringHash& rhs) const;
     bool operator == (const ShortStringHash& rhs) const;
     bool operator == (const ShortStringHash& rhs) const;
     bool operator < (const ShortStringHash& rhs) const;
     bool operator < (const ShortStringHash& rhs) const;

+ 2 - 2
Source/Extras/LuaScript/pkgs/Math/Vector2.pkg

@@ -5,7 +5,7 @@ class Vector2
     Vector2();
     Vector2();
     Vector2(const Vector2& vector);
     Vector2(const Vector2& vector);
     Vector2(float x, float y);
     Vector2(float x, float y);
-    Vector2(const float* data);
+    ~Vector2();
     
     
     bool operator == (const Vector2& rhs) const;
     bool operator == (const Vector2& rhs) const;
     Vector2 operator + (const Vector2& rhs) const;
     Vector2 operator + (const Vector2& rhs) const;
@@ -45,8 +45,8 @@ class IntVector2
 {
 {
     IntVector2();
     IntVector2();
     IntVector2(int x, int y);
     IntVector2(int x, int y);
-    IntVector2(const int* data);
     IntVector2(const IntVector2& rhs);
     IntVector2(const IntVector2& rhs);
+    ~IntVector2();
 
 
     bool operator == (const IntVector2& rhs) const;
     bool operator == (const IntVector2& rhs) const;
     IntVector2 operator + (const IntVector2& rhs) const;
     IntVector2 operator + (const IntVector2& rhs) const;

+ 1 - 0
Source/Extras/LuaScript/pkgs/Math/Vector3.pkg

@@ -6,6 +6,7 @@ class Vector3
     Vector3(const Vector3& vector);
     Vector3(const Vector3& vector);
     Vector3(const Vector2& vector, float z);
     Vector3(const Vector2& vector, float z);
     Vector3(float x, float y, float z);
     Vector3(float x, float y, float z);
+    ~Vector3();
     
     
     bool operator == (const Vector3& rhs) const;
     bool operator == (const Vector3& rhs) const;
     Vector3 operator + (const Vector3& rhs) const;
     Vector3 operator + (const Vector3& rhs) const;

+ 1 - 0
Source/Extras/LuaScript/pkgs/Math/Vector4.pkg

@@ -6,6 +6,7 @@ class Vector4
     Vector4(const Vector4& vector);
     Vector4(const Vector4& vector);
     Vector4(const Vector3& vector, float w);
     Vector4(const Vector3& vector, float w);
     Vector4(float x, float y, float z, float w);
     Vector4(float x, float y, float z, float w);
+    ~Vector4();
 
 
     bool operator == (const Vector4& rhs) const;
     bool operator == (const Vector4& rhs) const;
     Vector4 operator + (const Vector4& rhs) const;
     Vector4 operator + (const Vector4& rhs) const;

+ 2 - 0
Source/Extras/LuaScript/pkgs/Network/Controls.pkg

@@ -2,6 +2,8 @@ $#include "Controls.h"
 
 
 class Controls
 class Controls
 {
 {
+    Controls();
+    
     void Reset();
     void Reset();
     void Set(unsigned buttons, bool down = true);
     void Set(unsigned buttons, bool down = true);
     bool IsDown(unsigned button) const;
     bool IsDown(unsigned button) const;

+ 20 - 0
Source/Extras/LuaScript/pkgs/Scene/Scene.pkg

@@ -12,6 +12,10 @@ class Scene : public Node
     
     
     tolua_outside bool SceneLoadXML @ LoadXML(File* source);
     tolua_outside bool SceneLoadXML @ LoadXML(File* source);
     tolua_outside bool SceneSaveXML @ SaveXML(File* dest) const;
     tolua_outside bool SceneSaveXML @ SaveXML(File* dest) const;
+    
+    tolua_outside bool SceneLoadXML @ LoadXML(const String fileName);
+    tolua_outside bool SceneSaveXML @ SaveXML(const String fileName) const;
+    
     bool LoadAsync(File* file);
     bool LoadAsync(File* file);
     bool LoadAsyncXML(File* file);
     bool LoadAsyncXML(File* file);
     void StopAsyncLoading();
     void StopAsyncLoading();
@@ -78,5 +82,21 @@ static bool SceneSaveXML(const Scene* scene, File* file)
 {
 {
     return file ? scene->SaveXML(*file) : false;
     return file ? scene->SaveXML(*file) : false;
 }
 }
+
+static bool SceneLoadXML(Scene* scene, const String& fileName)
+{
+    File file(scene->GetContext(), fileName, FILE_READ);
+    if (!file.IsOpen())
+        return false;
+    return scene->LoadXML(file);
+}
+
+static bool SceneSaveXML(const Scene* scene, const String& fileName)
+{
+    File file(scene->GetContext(), fileName, FILE_WRITE);
+    if (!file.IsOpen())
+        return false;
+    return scene->SaveXML(file);
+}
 $}
 $}