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:
@@ -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 )
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user