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()
{
if( L != NULL )
{
LuaReference::BeforeResetAll();
lua_close( L );
}
L = lua_open();
ASSERT( L );
@@ -212,6 +216,7 @@ void LuaManager::ResetState()
luaopen_base( L );
luaopen_math( L );
luaopen_string( L );
luaopen_table( L );
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 )
@@ -226,7 +231,7 @@ void LuaManager::ResetState()
}
}
LuaReference::ReRegisterAll();
LuaReference::AfterResetAll();
}
void LuaManager::PrepareExpression( CString &sInOut )
+48 -5
View File
@@ -3,6 +3,7 @@
#include "LuaManager.h"
#include "LuaBinding.h"
#include "Foreach.h"
#include "RageLog.h"
#include "SubscriptionManager.h"
template<>
@@ -74,10 +75,6 @@ int LuaReference::GetLuaType() const
return iRet;
}
void LuaReference::Register()
{
}
void LuaReference::Unregister()
{
if( LUA == NULL )
@@ -87,7 +84,15 @@ void LuaReference::Unregister()
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 )
return;
@@ -120,6 +125,44 @@ void LuaExpression::Register()
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
* All rights reserved.
+17 -2
View File
@@ -29,13 +29,17 @@ public:
/* Return the referenced type, or LUA_TNONE if not set. */
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:
/* 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
* will work; the reference will still exist after a theme change. If not
* implemented, the reference will be unset after ReRegister. */
virtual void Register();
virtual void Register() { }
private:
void Unregister();
@@ -57,6 +61,17 @@ private:
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
/*