Add LuaData, a reference type that restores itself over Lua resets. This

works only with static data types that can be restored: tables, strings,
numbers, and not functions, userdata, etc.
This commit is contained in:
Glenn Maynard
2005-02-16 00:38:40 +00:00
parent f0a2c6faff
commit 6175a16f24
3 changed files with 71 additions and 8 deletions
+6 -1
View File
@@ -202,7 +202,11 @@ LuaManager::~LuaManager()
void LuaManager::ResetState() void LuaManager::ResetState()
{ {
if( L != NULL ) if( L != NULL )
{
LuaReference::BeforeResetAll();
lua_close( L ); lua_close( L );
}
L = lua_open(); L = lua_open();
ASSERT( L ); ASSERT( L );
@@ -212,6 +216,7 @@ void LuaManager::ResetState()
luaopen_base( L ); luaopen_base( L );
luaopen_math( L ); luaopen_math( L );
luaopen_string( L ); luaopen_string( L );
luaopen_table( L );
lua_settop(L, 0); // luaopen_* pushes stuff onto the stack that we don't need lua_settop(L, 0); // luaopen_* pushes stuff onto the stack that we don't need
for( const LuaFunctionList *p = g_LuaFunctions; p; p=p->next ) for( const LuaFunctionList *p = g_LuaFunctions; p; p=p->next )
@@ -226,7 +231,7 @@ void LuaManager::ResetState()
} }
} }
LuaReference::ReRegisterAll(); LuaReference::AfterResetAll();
} }
void LuaManager::PrepareExpression( CString &sInOut ) void LuaManager::PrepareExpression( CString &sInOut )
+48 -5
View File
@@ -3,6 +3,7 @@
#include "LuaManager.h" #include "LuaManager.h"
#include "LuaBinding.h" #include "LuaBinding.h"
#include "Foreach.h" #include "Foreach.h"
#include "RageLog.h"
#include "SubscriptionManager.h" #include "SubscriptionManager.h"
template<> template<>
@@ -74,10 +75,6 @@ int LuaReference::GetLuaType() const
return iRet; return iRet;
} }
void LuaReference::Register()
{
}
void LuaReference::Unregister() void LuaReference::Unregister()
{ {
if( LUA == NULL ) if( LUA == NULL )
@@ -87,7 +84,15 @@ void LuaReference::Unregister()
m_iReference = LUA_NOREF; m_iReference = LUA_NOREF;
} }
void LuaReference::ReRegisterAll() void LuaReference::BeforeResetAll()
{
if( SubscriptionManager<LuaReference>::s_pSubscribers == NULL )
return;
FOREACHS( LuaReference*, *SubscriptionManager<LuaReference>::s_pSubscribers, p )
(*p)->BeforeReset();
}
void LuaReference::AfterResetAll()
{ {
if( SubscriptionManager<LuaReference>::s_pSubscribers == NULL ) if( SubscriptionManager<LuaReference>::s_pSubscribers == NULL )
return; return;
@@ -120,6 +125,44 @@ void LuaExpression::Register()
this->SetFromStack(); this->SetFromStack();
} }
void LuaData::BeforeReset()
{
/* Call Serialize(t), where t is our referenced object. */
this->PushSelf( LUA->L );
lua_pushstring( LUA->L, "Serialize" );
lua_gettable( LUA->L, LUA_GLOBALSINDEX );
if( lua_isnil(LUA->L, -1) )
FAIL_M( "Serialize() missing" );
lua_call( LUA->L, 0, 1 );
/* The return value is a string, which we store in m_sSerializedData. */
const char *pString = lua_tostring( LUA->L, -1 );
if( pString == NULL )
FAIL_M( "Serialize() didn't return a string" );
m_sSerializedData = pString;
}
void LuaData::Register()
{
/* Restore the serialized data by evaluating the serialized data. */
CString sError;
if( !LUA->RunScript( m_sSerializedData, "serialization", sError, 1 ) )
{
/* Serialize() should never return an invalid script. Drop the failed
* script into the log (it may be too big to pass to FAIL_M) and fail. */
LOG->Warn( "Unserialization of \"%s\" failed: %s", m_sSerializedData.c_str(), sError.c_str() );
FAIL_M( "Unserialization failed" );
}
this->SetFromStack();
m_sSerializedData.clear();
}
/* /*
* (c) 2005 Glenn Maynard, Chris Danford * (c) 2005 Glenn Maynard, Chris Danford
* All rights reserved. * All rights reserved.
+17 -2
View File
@@ -29,13 +29,17 @@ public:
/* Return the referenced type, or LUA_TNONE if not set. */ /* Return the referenced type, or LUA_TNONE if not set. */
int GetLuaType() const; int GetLuaType() const;
static void ReRegisterAll(); // call this after resetting Lua static void BeforeResetAll(); // call this before resetting Lua
static void AfterResetAll(); // call this after resetting Lua
protected: protected:
/* If this object needs to store state to recreate itself, overload this. */
virtual void BeforeReset() { }
/* If this object is able to recreate itself, overload this, and ReRegisterAll /* If this object is able to recreate itself, overload this, and ReRegisterAll
* will work; the reference will still exist after a theme change. If not * will work; the reference will still exist after a theme change. If not
* implemented, the reference will be unset after ReRegister. */ * implemented, the reference will be unset after ReRegister. */
virtual void Register(); virtual void Register() { }
private: private:
void Unregister(); void Unregister();
@@ -57,6 +61,17 @@ private:
CString m_sExpression; CString m_sExpression;
}; };
/* Reference a trivially restorable Lua object (any object that Serialize can handle).
* The object will be saved and restored across Lua resets. */
class LuaData: public LuaReference
{
protected:
virtual void BeforeReset();
virtual void Register();
CString m_sSerializedData;
};
#endif #endif
/* /*