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