From dd3aa1c12ee254888fa4553ba31802d243ecb279 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Wed, 19 Jan 2005 23:33:19 +0000 Subject: [PATCH] I'd hoped to not need explicit initialization of Lua, but it's more trouble than it's worth. Add LuaManager::RunScriptFile, LuaManager::RunScript, LuaManager::Init. --- stepmania/src/LuaHelpers.cpp | 102 ++++++++++++++++++++++++++--------- stepmania/src/LuaHelpers.h | 8 +++ stepmania/src/StepMania.cpp | 3 ++ 3 files changed, 88 insertions(+), 25 deletions(-) diff --git a/stepmania/src/LuaHelpers.cpp b/stepmania/src/LuaHelpers.cpp index 21923c06e4..2fe31c6213 100644 --- a/stepmania/src/LuaHelpers.cpp +++ b/stepmania/src/LuaHelpers.cpp @@ -3,14 +3,14 @@ #include "LuaFunctions.h" #include "RageUtil.h" #include "RageLog.h" +#include "RageFile.h" #include "arch/Dialog/Dialog.h" #include #include -static LuaManager LUAObj; -LuaManager *LUA = &LUAObj; -static LuaFunctionList *g_NewLuaFunctions = NULL; +LuaManager *LUA = NULL; +static LuaFunctionList *g_LuaFunctions = NULL; #if defined(_WINDOWS) #pragma comment(lib, "lua-5.0/lib/LibLua.lib") @@ -123,10 +123,23 @@ static int LuaPanic( lua_State *L ) LuaManager::LuaManager() { - ASSERT( L == NULL ); - if( setjmp(jbuf) ) RageException::Throw("%s", jbuf_error.c_str()); + L = NULL; + + Init(); +} + +LuaManager::~LuaManager() +{ + lua_close( L ); +} + +void LuaManager::Init() +{ + if( L != NULL ) + lua_close( L ); + L = lua_open(); ASSERT( L ); @@ -137,12 +150,8 @@ LuaManager::LuaManager() luaopen_string( L ); lua_settop(L, 0); // luaopen_* pushes stuff onto the stack that we don't need - RegisterFunctions(); -} - -LuaManager::~LuaManager() -{ - lua_close( L ); + for( const LuaFunctionList *p = g_LuaFunctions; p; p=p->next ) + lua_register( L, p->name, p->func ); } void LuaManager::PrepareExpression( CString &sInOut ) @@ -159,10 +168,63 @@ void LuaManager::PrepareExpression( CString &sInOut ) sInOut.erase( 0, 1 ); } +bool LuaManager::RunScriptFile( const CString &sFile ) +{ + RageFile f; + if( !f.Open( sFile ) ) + { + LOG->Warn( "Couldn't open Lua script \"%s\": %s", sFile.c_str(), f.GetError().c_str() ); + return false; + } + + CString sScript; + if( f.Read( sScript ) == -1 ) + { + LOG->Warn( "Error reading Lua script \"%s\": %s", sFile.c_str(), f.GetError().c_str() ); + return false; + } + + return RunScript( sScript ); +} + +bool LuaManager::RunScript( const CString &sScript ) +{ + // load string + { + ChunkReaderData data; + data.buf = &sScript; + int ret = lua_load( L, ChunkReaderString, &data, "in" ); + + if( ret ) + { + CString err; + LuaManager::PopStack( err ); + CString sError = ssprintf( "Lua runtime error parsing \"%s\": %s", sScript.c_str(), err.c_str() ); + Dialog::OK( sError, "LUA_ERROR" ); + return false; + } + + ASSERT_M( lua_gettop(L) == 1, ssprintf("%i", lua_gettop(L)) ); + } + + // evaluate + { + int ret = lua_pcall(L, 0, 0, 0); + if( ret ) + { + CString err; + LuaManager::PopStack( err ); + CString sError = ssprintf( "Lua runtime error evaluating \"%s\": %s", sScript.c_str(), err.c_str() ); + Dialog::OK( sError, "LUA_ERROR" ); + return false; + } + } + + return true; +} + bool LuaManager::RunExpression( const CString &str ) { - RegisterFunctions(); - // load string { ChunkReaderData data; @@ -246,22 +308,12 @@ void LuaManager::Fail( const CString &err ) lua_error( L ); } -/* Add any newly-added functions to the Lua state. This should be called at - * least once after global initialization, to handle global initialization - * order. */ -void LuaManager::RegisterFunctions() -{ - for( const LuaFunctionList *p = g_NewLuaFunctions; p; p=p->next ) - lua_register( L, p->name, p->func ); - g_NewLuaFunctions = NULL; -} - LuaFunctionList::LuaFunctionList( CString name_, lua_CFunction func_ ) { name = name_; func = func_; - next = g_NewLuaFunctions; - g_NewLuaFunctions = this; + next = g_LuaFunctions; + g_LuaFunctions = this; } diff --git a/stepmania/src/LuaHelpers.h b/stepmania/src/LuaHelpers.h index 079350040d..c7ed4f78de 100644 --- a/stepmania/src/LuaHelpers.h +++ b/stepmania/src/LuaHelpers.h @@ -10,6 +10,14 @@ public: void PrepareExpression( CString &sInOut ); // strip "//" comments and "+" + bool RunScriptFile( const CString &sFile ); + + /* Reset the environment, freeing any globals left over by previously executed scripts. */ + void Init(); + + /* Run a complete script in the global environment, which returns no value. */ + bool RunScript( const CString &sScript ); + /* Run an expression in the global environment, returning the given type. */ bool RunExpressionB( const CString &str ); float RunExpressionF( const CString &str ); diff --git a/stepmania/src/StepMania.cpp b/stepmania/src/StepMania.cpp index 18115d34c4..9880a3e592 100644 --- a/stepmania/src/StepMania.cpp +++ b/stepmania/src/StepMania.cpp @@ -44,6 +44,7 @@ #include "ProfileManager.h" #include "MemoryCardManager.h" #include "ScreenManager.h" +#include "LuaHelpers.h" #include "GameManager.h" #include "FontManager.h" #include "InputFilter.h" @@ -203,6 +204,7 @@ void ShutdownGame() SAFE_DELETE( FONT ); SAFE_DELETE( TEXTUREMAN ); SAFE_DELETE( DISPLAY ); + SAFE_DELETE( LUA ); Dialog::Shutdown(); SAFE_DELETE( LOG ); SAFE_DELETE( FILEMAN ); @@ -1082,6 +1084,7 @@ int main(int argc, char* argv[]) CheckSettings(); + LUA = new LuaManager; GAMEMAN = new GameManager; THEME = new ThemeManager; ANNOUNCER = new AnnouncerManager;