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()
 {
+    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_)
         lua_close(luaState_);
 }
@@ -146,7 +152,7 @@ bool LuaScript::ExecuteFunction(const String& functionName)
 
     int top = lua_gettop(luaState_);
 
-    if (!FindFunction(functionName))
+    if (!PushScriptFunction(functionName))
     {
         lua_settop(luaState_, top);
         return false;
@@ -172,10 +178,7 @@ void LuaScript::ScriptSubscribeToEvent(const String& eventName, const String& fu
 {
     StringHash eventType(eventName);
 
-    int functionRef = LUA_REFNIL;
-    if (FindFunction(functionName))
-        functionRef = luaL_ref(luaState_, LUA_REGISTRYINDEX);
-
+    int functionRef = GetScriptFunctionRef(functionName);
     if (functionRef != LUA_REFNIL)
     {
         SubscribeToEvent(eventType, HANDLER(LuaScript, HandleEvent));
@@ -192,10 +195,6 @@ void LuaScript::ScriptUnsubscribeFromEvent(const String& eventName)
     if (i != eventTypeToFunctionRefMap_.End())
     {
         UnsubscribeFromEvent(eventType);
-
-        if (i->second_ != LUA_REFNIL)
-            luaL_unref(luaState_, LUA_REGISTRYINDEX, i->second_);
-
         eventTypeToFunctionRefMap_.Erase(i);
     }
 }
@@ -206,63 +205,45 @@ void LuaScript::ScriptUnsubscribeFromAllEvents()
         return;
 
     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();
 }
 
-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);
-    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)
     {
-        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);
-    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())
         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);
 }
@@ -337,7 +318,7 @@ int LuaScript::Print(lua_State *L)
     return 0;
 }
 
-bool LuaScript::FindFunction(const String& functionName)
+bool LuaScript::PushScriptFunction(const String& functionName)
 {
     Vector<String> splitedNames = functionName.Split('.');
 
@@ -376,13 +357,32 @@ bool LuaScript::FindFunction(const String& functionName)
     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)
 {
     int functionRef = eventTypeToFunctionRefMap_[eventType];
     if (functionRef == LUA_REFNIL)
         return;
 
-    CallEventHandler(functionRef, eventType, eventData);
+    CallScriptFunction(functionRef, eventType, eventData);
 }
 
 void LuaScript::HandleObjectEvent(StringHash eventType, VariantMap& eventData)
@@ -392,7 +392,7 @@ void LuaScript::HandleObjectEvent(StringHash eventType, VariantMap& eventData)
     if (functionRef == LUA_REFNIL)
         return;
 
-    CallEventHandler(functionRef, eventType, eventData);
+    CallScriptFunction(functionRef, eventType, eventData);
 }
 
 void LuaScript::HandleConsoleCommand(StringHash eventType, VariantMap& eventData)
@@ -401,7 +401,7 @@ void LuaScript::HandleConsoleCommand(StringHash eventType, VariantMap& eventData
     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_);
     lua_rawgeti(luaState_, LUA_REGISTRYINDEX, functionRef);

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

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

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

@@ -21,13 +21,17 @@
 //
 
 #include "Precompiled.h"
+#include "CoreEvents.h"
 #include "Context.h"
 #include "Log.h"
 #include "LuaFile.h"
 #include "LuaScript.h"
 #include "LuaScriptInstance.h"
+#include "MemoryBuffer.h"
+#include "PhysicsEvents.h"
 #include "ResourceCache.h"
 #include "ProcessUtils.h"
+#include "VectorBuffer.h"
 
 extern "C"
 {
@@ -40,12 +44,30 @@ extern "C"
 namespace Urho3D
 {
 
+static const char* scriptObjectMethodNames[] = {
+    ".Start",
+    ".Stop",
+    // ".DelayedStart",
+    ".Update",
+    ".PostUpdate",
+    ".FixedUpdate",
+    ".FixedPostUpdate",
+    ".Load",
+    ".Save",
+    ".ReadNetworkUpdate",
+    ".WriteNetworkUpdate",
+    ".ApplyAttributes"
+};
+
 LuaScriptInstance::LuaScriptInstance(Context* context) : 
     Component(context),
     scriptObjectRef_(LUA_REFNIL)
 {
     luaScript_ = GetSubsystem<LuaScript>();
     luaState_ = luaScript_->GetLuaState();
+
+    for (unsigned i = 0; i < MAX_LUA_SCRIPT_OBJECT_METHODS; ++i)
+        scriptObjectMethodRefs_[i] = LUA_REFNIL;
 }
 
 LuaScriptInstance::~LuaScriptInstance()
@@ -55,13 +77,61 @@ LuaScriptInstance::~LuaScriptInstance()
 
 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)
+{
+    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)
-        return true;
+        return;
 
     ReleaseObject();
 
@@ -72,7 +142,7 @@ bool LuaScriptInstance::CreateObject(const String& scriptObjectType)
     {
         LOGERROR("Could not find lua function CreateScriptObjectInstance");
         lua_settop(luaState_, top);
-        return false;
+        return;
     }
 
     // Get table as first paramter.
@@ -81,52 +151,56 @@ bool LuaScriptInstance::CreateObject(const String& scriptObjectType)
     {
         LOGERROR("Could not find lua table " + scriptObjectType);
         lua_settop(luaState_, top);
-        return false;
+        return;
     }
 
     // Push this as second parameter.
     tolua_pushusertype(luaState_, (void*)this, "LuaScriptInstance");
-    
+
     // Call ObjectType:new function.
     if (lua_pcall(luaState_, 2, 1, 0) != 0)
     {
         const char* message = lua_tostring(luaState_, -1);
         LOGERROR("Execute Lua function failed: " + String(message));
         lua_settop(luaState_, top);
-        return false;
+        return;
     }
 
     scriptObjectType_ = scriptObjectType;
     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)
 {
-    StringHash eventType(eventName);
     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)
     {
+        StringHash eventType(eventName);
         SubscribeToEvent(eventType, HANDLER(LuaScriptInstance, HandleEvent));
         eventTypeToFunctionRefMap_[eventType] = functionRef;
     }
@@ -140,10 +214,6 @@ void LuaScriptInstance::ScriptUnsubscribeFromEvent(const String& eventName)
     if (i != eventTypeToFunctionRefMap_.End())
     {
         UnsubscribeFromEvent(eventType);
-
-        if (i->second_ != LUA_REFNIL)
-            luaL_unref(luaState_, LUA_REGISTRYINDEX, i->second_);
-
         eventTypeToFunctionRefMap_.Erase(i);
     }
 }
@@ -154,66 +224,117 @@ void LuaScriptInstance::ScriptUnsubscribeFromAllEvents()
         return;
 
     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();
 }
 
-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(":", ".");
-    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)
     {
-        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);
-    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())
         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)
@@ -225,7 +346,7 @@ void LuaScriptInstance::HandleEvent(StringHash eventType, VariantMap& eventData)
     if (functionRef == LUA_REFNIL)
         return;
 
-    CallEventHandler(functionRef, eventType, eventData);
+    CallScriptObjectFunction(functionRef, eventType, eventData);
 }
 
 void LuaScriptInstance::HandleObjectEvent(StringHash eventType, VariantMap& eventData)
@@ -238,11 +359,43 @@ void LuaScriptInstance::HandleObjectEvent(StringHash eventType, VariantMap& even
     if (functionRef == LUA_REFNIL)
         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_);
 
     // Push function.
@@ -251,13 +404,34 @@ void LuaScriptInstance::CallEventHandler(int functionRef, StringHash eventType,
     // Push script object.
     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);
         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;
-    
-    // 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_);
 
-    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);
-        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);
         LOGERROR("Execute Lua function failed: " + String(message));
@@ -306,5 +515,4 @@ void LuaScriptInstance::ReleaseObject()
         return;
     }
 }
-
-}
+}

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

@@ -31,7 +31,25 @@ namespace Urho3D
 
 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
 {
     OBJECT(LuaScriptInstance);
@@ -44,11 +62,26 @@ public:
     /// Register object factory.
     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.
     bool CreateObject(const String& scriptObjectType);
 
     /// 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.
     void ScriptSubscribeToEvent(const String& eventName, const String& functionName);
@@ -60,13 +93,16 @@ public:
     void ScriptUnsubscribeFromAllEvents();
 
     /// 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.
-    void ScriptUnsubscribeFromEvent(void* object, const String& eventName);
+    void ScriptUnsubscribeFromEvent(void* sender, const String& eventName);
 
     /// 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.
     const String& GetScriptObjectType() const { return scriptObjectType_; }
@@ -74,31 +110,70 @@ public:
     /// Return script object ref.
     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:
+    /// 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.
     void HandleEvent(StringHash eventType, VariantMap& eventData);
 
     /// Handle object event.
     void HandleObjectEvent(StringHash eventType, VariantMap& eventData);
 
-    /// Call event handler.
-    void CallEventHandler(int functionRef, StringHash eventType, VariantMap& eventData);
-
     /// Release the script object.
     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.
     LuaScript* luaScript_;
 
     /// Lua state.
     lua_State* luaState_;
 
+    /// Script file name.
+    String scriptFileName_;
+
     /// Script object type.
     String scriptObjectType_;
 
     /// Script object ref.
     int scriptObjectRef_;
 
+    /// Script object method refs.
+    int scriptObjectMethodRefs_[MAX_LUA_SCRIPT_OBJECT_METHODS];
+
     /// Event type to function ref map.
     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 UnsubscribeFromEvent(const String eventName);
 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()
@@ -41,18 +41,18 @@ static void UnsubscribeFromAllEvents()
     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
 {
     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 ScriptUnsubscribeFromEvent @ UnsubscribeFromEvent(const String eventName);
     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 Polyhedron& poly);
     BoundingBox(const Sphere& sphere);
+    ~BoundingBox();
     
     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(float r, float g, float b);
     Color(float r, float g, float b, float a);
+    ~Color();
     
     bool operator == (const Color& rhs) const;
     Color operator * (float rhs) const;

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

@@ -17,6 +17,7 @@ class 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(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,
             float v10, float v11, float v12,
             float v20, float v21, float v22);
+    ~Matrix3();
     
     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 v20, float v21, float v22, float v23,
             float v30, float v31, float v32, float v33);
+    ~Matrix4();
     
     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 Vector3& v0, const Vector3& v1, const Vector3& v2);
     Plane(const Vector3& normal, const Vector3& point);
+    ~Plane();
     
     void Define(const Vector3& v0, const Vector3& v1, const Vector3& v2);
     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& xAxis, const Vector3& yAxis, const Vector3& zAxis);
     Quaternion(const Matrix3& matrix);
+    ~Quaternion();
 
     bool operator == (const Quaternion& rhs) const;
     

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

@@ -5,6 +5,7 @@ class Ray
     Ray();
     Ray(const Vector3& origin, const Vector3& direction);
     Ray(const Ray& ray);
+    ~Ray();
 
     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(float left, float top, float right, float bottom);
     Rect(const Vector4& vector);
+    ~Rect();
 
     bool operator == (const Rect& rhs) const;
     
@@ -40,6 +41,7 @@ class IntRect
 {
     IntRect();
     IntRect(int left, int top, int right, int bottom);
+    ~IntRect();
 
     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 Frustum& frustum);
     Sphere(const Polyhedron& poly);
+    ~Sphere();
     
     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);
     explicit StringHash(unsigned value);
     StringHash(const String str);
+    ~StringHash();
 
     StringHash operator + (const StringHash& rhs) const;
     bool operator == (const StringHash& rhs) const;
@@ -28,7 +29,8 @@ class ShortStringHash
     explicit ShortStringHash(const StringHash& rhs);
     explicit ShortStringHash(unsigned short value);
     ShortStringHash(const String str);
-
+    ~ShortStringHash();
+    
     ShortStringHash 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(const Vector2& vector);
     Vector2(float x, float y);
-    Vector2(const float* data);
+    ~Vector2();
     
     bool operator == (const Vector2& rhs) const;
     Vector2 operator + (const Vector2& rhs) const;
@@ -45,8 +45,8 @@ class IntVector2
 {
     IntVector2();
     IntVector2(int x, int y);
-    IntVector2(const int* data);
     IntVector2(const IntVector2& rhs);
+    ~IntVector2();
 
     bool 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 Vector2& vector, float z);
     Vector3(float x, float y, float z);
+    ~Vector3();
     
     bool 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 Vector3& vector, float w);
     Vector4(float x, float y, float z, float w);
+    ~Vector4();
 
     bool 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
 {
+    Controls();
+    
     void Reset();
     void Set(unsigned buttons, bool down = true);
     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 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 LoadAsyncXML(File* file);
     void StopAsyncLoading();
@@ -78,5 +82,21 @@ static bool SceneSaveXML(const Scene* scene, File* file)
 {
     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);
+}
 $}