correct locking semantics for LuaReference (SGameplay commit in a moment)
This commit is contained in:
@@ -88,6 +88,8 @@ ActorCommands::ActorCommands( const CString &sCommands )
|
|||||||
|
|
||||||
void ActorCommands::Register()
|
void ActorCommands::Register()
|
||||||
{
|
{
|
||||||
|
Lua *L = LUA->Get();
|
||||||
|
|
||||||
CString sError;
|
CString sError;
|
||||||
if( !LUA->RunScript( m_sLuaFunction, "in", sError, 1 ) )
|
if( !LUA->RunScript( m_sLuaFunction, "in", sError, 1 ) )
|
||||||
{
|
{
|
||||||
@@ -95,7 +97,8 @@ void ActorCommands::Register()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* The function is now on the stack. */
|
/* The function is now on the stack. */
|
||||||
this->SetFromStack();
|
this->SetFromStack( L );
|
||||||
|
LUA->Release( L );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,10 @@ LuaReference::LuaReference( const LuaReference &cpy )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Make a new reference. */
|
/* Make a new reference. */
|
||||||
lua_rawgeti( LUA->L, LUA_REGISTRYINDEX, cpy.m_iReference );
|
Lua *L = LUA->Get();
|
||||||
m_iReference = luaL_ref( LUA->L, LUA_REGISTRYINDEX );
|
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
|
else
|
||||||
{
|
{
|
||||||
/* Make a new reference. */
|
/* Make a new reference. */
|
||||||
lua_rawgeti( LUA->L, LUA_REGISTRYINDEX, cpy.m_iReference );
|
Lua *L = LUA->Get();
|
||||||
m_iReference = luaL_ref( LUA->L, LUA_REGISTRYINDEX );
|
lua_rawgeti( L, LUA_REGISTRYINDEX, cpy.m_iReference );
|
||||||
|
m_iReference = luaL_ref( L, LUA_REGISTRYINDEX );
|
||||||
|
LUA->Release( L );
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaReference::SetFromStack()
|
void LuaReference::SetFromStack( Lua *L )
|
||||||
{
|
{
|
||||||
Unregister();
|
Unregister();
|
||||||
|
|
||||||
m_iReference = luaL_ref( LUA->L, LUA_REGISTRYINDEX );
|
m_iReference = luaL_ref( L, LUA_REGISTRYINDEX );
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaReference::SetFromNil()
|
void LuaReference::SetFromNil()
|
||||||
@@ -69,7 +73,7 @@ void LuaReference::SetFromNil()
|
|||||||
|
|
||||||
void LuaReference::PushSelf( lua_State *L ) const
|
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
|
bool LuaReference::IsSet() const
|
||||||
@@ -84,9 +88,12 @@ bool LuaReference::IsNil() const
|
|||||||
|
|
||||||
int LuaReference::GetLuaType() const
|
int LuaReference::GetLuaType() const
|
||||||
{
|
{
|
||||||
this->PushSelf( LUA->L );
|
Lua *L = LUA->Get();
|
||||||
int iRet = lua_type( LUA->L, -1 );
|
this->PushSelf( L );
|
||||||
lua_pop( LUA->L, 1 );
|
int iRet = lua_type( L, -1 );
|
||||||
|
lua_pop( L, 1 );
|
||||||
|
LUA->Release( L );
|
||||||
|
|
||||||
return iRet;
|
return iRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +102,9 @@ void LuaReference::Unregister()
|
|||||||
if( LUA == NULL )
|
if( LUA == NULL )
|
||||||
return; // nothing to do
|
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;
|
m_iReference = LUA_NOREF;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,42 +143,51 @@ void LuaExpression::SetFromExpression( const CString &sExpression )
|
|||||||
|
|
||||||
void LuaExpression::Register()
|
void LuaExpression::Register()
|
||||||
{
|
{
|
||||||
|
Lua *L = LUA->Get();
|
||||||
|
|
||||||
if( !LUA->RunScript( m_sExpression, "expression", 1 ) )
|
if( !LUA->RunScript( m_sExpression, "expression", 1 ) )
|
||||||
{
|
{
|
||||||
this->SetFromNil();
|
this->SetFromNil();
|
||||||
|
LUA->Release( L );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store the result. */
|
/* Store the result. */
|
||||||
this->SetFromStack();
|
this->SetFromStack( L );
|
||||||
|
LUA->Release( L );
|
||||||
}
|
}
|
||||||
|
|
||||||
CString LuaData::Serialize() const
|
CString LuaData::Serialize() const
|
||||||
{
|
{
|
||||||
/* Call Serialize(t), where t is our referenced object. */
|
/* Call Serialize(t), where t is our referenced object. */
|
||||||
lua_pushstring( LUA->L, "Serialize" );
|
Lua *L = LUA->Get();
|
||||||
lua_gettable( LUA->L, LUA_GLOBALSINDEX );
|
lua_pushstring( L, "Serialize" );
|
||||||
|
lua_gettable( L, LUA_GLOBALSINDEX );
|
||||||
|
|
||||||
ASSERT_M( !lua_isnil(LUA->L, -1), "Serialize() missing" );
|
ASSERT_M( !lua_isnil(L, -1), "Serialize() missing" );
|
||||||
ASSERT_M( lua_isfunction(LUA->L, -1), "Serialize() not a function" );
|
ASSERT_M( lua_isfunction(L, -1), "Serialize() not a function" );
|
||||||
|
|
||||||
/* Arg 1 (t): */
|
/* 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. */
|
/* 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" );
|
ASSERT_M( pString != NULL, "Serialize() didn't return a string" );
|
||||||
|
|
||||||
CString sRet = pString;
|
CString sRet = pString;
|
||||||
lua_pop( LUA->L, 1 );
|
lua_pop( L, 1 );
|
||||||
|
|
||||||
|
LUA->Release( L );
|
||||||
|
|
||||||
return sRet;
|
return sRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaData::LoadFromString( const CString &s )
|
void LuaData::LoadFromString( const CString &s )
|
||||||
{
|
{
|
||||||
|
Lua *L = LUA->Get();
|
||||||
|
|
||||||
/* Restore the serialized data by evaluating it. */
|
/* Restore the serialized data by evaluating it. */
|
||||||
CString sError;
|
CString sError;
|
||||||
if( !LUA->RunScript( s, "serialization", sError, 1 ) )
|
if( !LUA->RunScript( s, "serialization", sError, 1 ) )
|
||||||
@@ -180,7 +198,8 @@ void LuaData::LoadFromString( const CString &s )
|
|||||||
FAIL_M( "Unserialization failed" );
|
FAIL_M( "Unserialization failed" );
|
||||||
}
|
}
|
||||||
|
|
||||||
this->SetFromStack();
|
this->SetFromStack( L );
|
||||||
|
LUA->Release( L );
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaData::BeforeReset()
|
void LuaData::BeforeReset()
|
||||||
@@ -203,34 +222,37 @@ void LuaData::Register()
|
|||||||
|
|
||||||
LuaTable::LuaTable()
|
LuaTable::LuaTable()
|
||||||
{
|
{
|
||||||
lua_newtable( LUA->L );
|
Lua *L = LUA->Get();
|
||||||
this->SetFromStack();
|
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 );
|
int iTop = lua_gettop( L );
|
||||||
this->PushSelf( LUA->L );
|
this->PushSelf( L );
|
||||||
lua_pushstring( LUA->L, sKey ); // push the key
|
lua_pushstring( L, sKey ); // push the key
|
||||||
lua_pushvalue( LUA->L, iTop ); // push the value
|
lua_pushvalue( L, iTop ); // push the value
|
||||||
lua_settable( LUA->L, iTop+1 );
|
lua_settable( L, iTop+1 );
|
||||||
lua_settop( LUA->L, iTop-1 ); // remove all of the above
|
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 );
|
lua_pushnil( L );
|
||||||
Set( sKey );
|
Set( L, sKey );
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaTable::SetKeyAndValue()
|
void LuaTable::SetKeyAndValue( Lua *L )
|
||||||
{
|
{
|
||||||
int iTop = lua_gettop( LUA->L );
|
int iTop = lua_gettop( L );
|
||||||
this->PushSelf( LUA->L );
|
this->PushSelf( L );
|
||||||
lua_pushvalue( LUA->L, iTop-1 ); // push the value after the table
|
lua_pushvalue( L, iTop-1 ); // push the value after the table
|
||||||
lua_pushvalue( LUA->L, iTop ); // push the key after the value
|
lua_pushvalue( L, iTop ); // push the key after the value
|
||||||
lua_settable( LUA->L, iTop+1 );
|
lua_settable( L, iTop+1 );
|
||||||
lua_settop( LUA->L, iTop-1 ); // remove all of the above
|
lua_settop( L, iTop-1 ); // remove all of the above
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#define LUA_REFERENCE_H
|
#define LUA_REFERENCE_H
|
||||||
|
|
||||||
struct lua_State;
|
struct lua_State;
|
||||||
|
typedef lua_State Lua;
|
||||||
|
|
||||||
class LuaReference
|
class LuaReference
|
||||||
{
|
{
|
||||||
@@ -17,11 +18,11 @@ public:
|
|||||||
|
|
||||||
/* Create a reference pointing to the item at the top of the stack, and pop
|
/* Create a reference pointing to the item at the top of the stack, and pop
|
||||||
* the stack. */
|
* the stack. */
|
||||||
void SetFromStack();
|
void SetFromStack( Lua *L );
|
||||||
void SetFromNil();
|
void SetFromNil();
|
||||||
|
|
||||||
/* Push the referenced object onto the stack. If not set (or set to nil), push nil. */
|
/* 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.) */
|
/* Return true if set. (SetFromNil() counts as being set.) */
|
||||||
bool IsSet() const;
|
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
|
/* Set a key by the given name to a value on the stack, and pop the value
|
||||||
* off the stack. */
|
* off the stack. */
|
||||||
void Set( const CString &sKey );
|
void Set( Lua *L, const CString &sKey );
|
||||||
|
|
||||||
/* Unset the given key (set it to nil). */
|
/* 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
|
/* 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. */
|
* both the key and the value off the stack. */
|
||||||
void SetKeyAndValue();
|
void SetKeyAndValue( Lua *L );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -115,8 +115,10 @@ void Profile::InitGeneralData()
|
|||||||
ZERO( m_iNumStagesPassedByPlayMode );
|
ZERO( m_iNumStagesPassedByPlayMode );
|
||||||
ZERO( m_iNumStagesPassedByGrade );
|
ZERO( m_iNumStagesPassedByGrade );
|
||||||
|
|
||||||
lua_newtable( LUA->L );
|
Lua *L = LUA->Get();
|
||||||
m_SavedLuaData.SetFromStack();
|
lua_newtable( L );
|
||||||
|
m_SavedLuaData.SetFromStack( L );
|
||||||
|
LUA->Release( L );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Profile::InitSongScores()
|
void Profile::InitSongScores()
|
||||||
@@ -1099,8 +1101,10 @@ void Profile::LoadGeneralDataFromNode( const XNode* pNode )
|
|||||||
if( m_SavedLuaData.GetLuaType() != LUA_TTABLE )
|
if( m_SavedLuaData.GetLuaType() != LUA_TTABLE )
|
||||||
{
|
{
|
||||||
LOG->Warn( "Profile data did not evaluate to a table" );
|
LOG->Warn( "Profile data did not evaluate to a table" );
|
||||||
lua_newtable( LUA->L );
|
Lua *L = LUA->Get();
|
||||||
m_SavedLuaData.SetFromStack();
|
lua_newtable( L );
|
||||||
|
m_SavedLuaData.SetFromStack( L );
|
||||||
|
LUA->Release( L );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user