correct locking semantics for LuaReference (SGameplay commit in a moment)

This commit is contained in:
Glenn Maynard
2005-06-16 03:13:06 +00:00
parent 63eebeb75e
commit 1e02955e63
4 changed files with 80 additions and 50 deletions
+4 -1
View File
@@ -88,6 +88,8 @@ ActorCommands::ActorCommands( const CString &sCommands )
void ActorCommands::Register()
{
Lua *L = LUA->Get();
CString sError;
if( !LUA->RunScript( m_sLuaFunction, "in", sError, 1 ) )
{
@@ -95,7 +97,8 @@ void ActorCommands::Register()
}
/* The function is now on the stack. */
this->SetFromStack();
this->SetFromStack( L );
LUA->Release( L );
}
+62 -40
View File
@@ -30,8 +30,10 @@ LuaReference::LuaReference( const LuaReference &cpy )
else
{
/* Make a new reference. */
lua_rawgeti( LUA->L, LUA_REGISTRYINDEX, cpy.m_iReference );
m_iReference = luaL_ref( LUA->L, LUA_REGISTRYINDEX );
Lua *L = LUA->Get();
lua_rawgeti( L, LUA_REGISTRYINDEX, cpy.m_iReference );
m_iReference = luaL_ref( L, LUA_REGISTRYINDEX );
LUA->Release( L );
}
}
@@ -47,18 +49,20 @@ LuaReference &LuaReference::operator=( const LuaReference &cpy )
else
{
/* Make a new reference. */
lua_rawgeti( LUA->L, LUA_REGISTRYINDEX, cpy.m_iReference );
m_iReference = luaL_ref( LUA->L, LUA_REGISTRYINDEX );
Lua *L = LUA->Get();
lua_rawgeti( L, LUA_REGISTRYINDEX, cpy.m_iReference );
m_iReference = luaL_ref( L, LUA_REGISTRYINDEX );
LUA->Release( L );
}
return *this;
}
void LuaReference::SetFromStack()
void LuaReference::SetFromStack( Lua *L )
{
Unregister();
m_iReference = luaL_ref( LUA->L, LUA_REGISTRYINDEX );
m_iReference = luaL_ref( L, LUA_REGISTRYINDEX );
}
void LuaReference::SetFromNil()
@@ -69,7 +73,7 @@ void LuaReference::SetFromNil()
void LuaReference::PushSelf( lua_State *L ) const
{
lua_rawgeti( LUA->L, LUA_REGISTRYINDEX, m_iReference );
lua_rawgeti( L, LUA_REGISTRYINDEX, m_iReference );
}
bool LuaReference::IsSet() const
@@ -84,9 +88,12 @@ bool LuaReference::IsNil() const
int LuaReference::GetLuaType() const
{
this->PushSelf( LUA->L );
int iRet = lua_type( LUA->L, -1 );
lua_pop( LUA->L, 1 );
Lua *L = LUA->Get();
this->PushSelf( L );
int iRet = lua_type( L, -1 );
lua_pop( L, 1 );
LUA->Release( L );
return iRet;
}
@@ -95,7 +102,9 @@ void LuaReference::Unregister()
if( LUA == NULL )
return; // nothing to do
luaL_unref( LUA->L, LUA_REGISTRYINDEX, m_iReference );
Lua *L = LUA->Get();
luaL_unref( L, LUA_REGISTRYINDEX, m_iReference );
LUA->Release( L );
m_iReference = LUA_NOREF;
}
@@ -134,42 +143,51 @@ void LuaExpression::SetFromExpression( const CString &sExpression )
void LuaExpression::Register()
{
Lua *L = LUA->Get();
if( !LUA->RunScript( m_sExpression, "expression", 1 ) )
{
this->SetFromNil();
LUA->Release( L );
return;
}
/* Store the result. */
this->SetFromStack();
this->SetFromStack( L );
LUA->Release( L );
}
CString LuaData::Serialize() const
{
/* Call Serialize(t), where t is our referenced object. */
lua_pushstring( LUA->L, "Serialize" );
lua_gettable( LUA->L, LUA_GLOBALSINDEX );
Lua *L = LUA->Get();
lua_pushstring( L, "Serialize" );
lua_gettable( L, LUA_GLOBALSINDEX );
ASSERT_M( !lua_isnil(LUA->L, -1), "Serialize() missing" );
ASSERT_M( lua_isfunction(LUA->L, -1), "Serialize() not a function" );
ASSERT_M( !lua_isnil(L, -1), "Serialize() missing" );
ASSERT_M( lua_isfunction(L, -1), "Serialize() not a function" );
/* Arg 1 (t): */
this->PushSelf( LUA->L );
this->PushSelf( L );
lua_call( LUA->L, 1, 1 );
lua_call( L, 1, 1 );
/* The return value is a string, which we store in m_sSerializedData. */
const char *pString = lua_tostring( LUA->L, -1 );
const char *pString = lua_tostring( L, -1 );
ASSERT_M( pString != NULL, "Serialize() didn't return a string" );
CString sRet = pString;
lua_pop( LUA->L, 1 );
lua_pop( L, 1 );
LUA->Release( L );
return sRet;
}
void LuaData::LoadFromString( const CString &s )
{
Lua *L = LUA->Get();
/* Restore the serialized data by evaluating it. */
CString sError;
if( !LUA->RunScript( s, "serialization", sError, 1 ) )
@@ -180,7 +198,8 @@ void LuaData::LoadFromString( const CString &s )
FAIL_M( "Unserialization failed" );
}
this->SetFromStack();
this->SetFromStack( L );
LUA->Release( L );
}
void LuaData::BeforeReset()
@@ -203,34 +222,37 @@ void LuaData::Register()
LuaTable::LuaTable()
{
lua_newtable( LUA->L );
this->SetFromStack();
Lua *L = LUA->Get();
lua_newtable( L );
this->SetFromStack(L);
LUA->Release( L );
}
void LuaTable::Set( const CString &sKey )
void LuaTable::Set( Lua *L, const CString &sKey )
{
int iTop = lua_gettop( LUA->L );
this->PushSelf( LUA->L );
lua_pushstring( LUA->L, sKey ); // push the key
lua_pushvalue( LUA->L, iTop ); // push the value
lua_settable( LUA->L, iTop+1 );
lua_settop( LUA->L, iTop-1 ); // remove all of the above
int iTop = lua_gettop( L );
this->PushSelf( L );
lua_pushstring( L, sKey ); // push the key
lua_pushvalue( L, iTop ); // push the value
lua_settable( L, iTop+1 );
lua_settop( L, iTop-1 ); // remove all of the above
LUA->Release( L );
}
void LuaTable::Unset( const CString &sKey )
void LuaTable::Unset( Lua *L, const CString &sKey )
{
lua_pushnil( LUA->L );
Set( sKey );
lua_pushnil( L );
Set( L, sKey );
}
void LuaTable::SetKeyAndValue()
void LuaTable::SetKeyAndValue( Lua *L )
{
int iTop = lua_gettop( LUA->L );
this->PushSelf( LUA->L );
lua_pushvalue( LUA->L, iTop-1 ); // push the value after the table
lua_pushvalue( LUA->L, iTop ); // push the key after the value
lua_settable( LUA->L, iTop+1 );
lua_settop( LUA->L, iTop-1 ); // remove all of the above
int iTop = lua_gettop( L );
this->PushSelf( L );
lua_pushvalue( L, iTop-1 ); // push the value after the table
lua_pushvalue( L, iTop ); // push the key after the value
lua_settable( L, iTop+1 );
lua_settop( L, iTop-1 ); // remove all of the above
}
/*
+6 -5
View File
@@ -4,6 +4,7 @@
#define LUA_REFERENCE_H
struct lua_State;
typedef lua_State Lua;
class LuaReference
{
@@ -17,11 +18,11 @@ public:
/* Create a reference pointing to the item at the top of the stack, and pop
* the stack. */
void SetFromStack();
void SetFromStack( Lua *L );
void SetFromNil();
/* Push the referenced object onto the stack. If not set (or set to nil), push nil. */
virtual void PushSelf( lua_State *L ) const;
virtual void PushSelf( Lua *L ) const;
/* Return true if set. (SetFromNil() counts as being set.) */
bool IsSet() const;
@@ -87,14 +88,14 @@ public:
/* Set a key by the given name to a value on the stack, and pop the value
* off the stack. */
void Set( const CString &sKey );
void Set( Lua *L, const CString &sKey );
/* Unset the given key (set it to nil). */
void Unset( const CString &sKey );
void Unset( Lua *L, const CString &sKey );
/* Set a key on the stack to a value on the stack; push the key first. Pop
* both the key and the value off the stack. */
void SetKeyAndValue();
void SetKeyAndValue( Lua *L );
};
#endif
+8 -4
View File
@@ -115,8 +115,10 @@ void Profile::InitGeneralData()
ZERO( m_iNumStagesPassedByPlayMode );
ZERO( m_iNumStagesPassedByGrade );
lua_newtable( LUA->L );
m_SavedLuaData.SetFromStack();
Lua *L = LUA->Get();
lua_newtable( L );
m_SavedLuaData.SetFromStack( L );
LUA->Release( L );
}
void Profile::InitSongScores()
@@ -1099,8 +1101,10 @@ void Profile::LoadGeneralDataFromNode( const XNode* pNode )
if( m_SavedLuaData.GetLuaType() != LUA_TTABLE )
{
LOG->Warn( "Profile data did not evaluate to a table" );
lua_newtable( LUA->L );
m_SavedLuaData.SetFromStack();
Lua *L = LUA->Get();
lua_newtable( L );
m_SavedLuaData.SetFromStack( L );
LUA->Release( L );
}
}
}