diff --git a/src/Actor.cpp b/src/Actor.cpp index 63824780f8..a2623b02f6 100644 --- a/src/Actor.cpp +++ b/src/Actor.cpp @@ -1297,7 +1297,8 @@ void Actor::RunCommands( const LuaReference& cmds, const LuaReference *pParamTab pParamTable->PushSelf( L ); // call function with 2 arguments and 0 results - LuaHelpers::RunScriptOnStack(L, 2, 0); + RString Error= "Error playing command:"; + LuaHelpers::RunScriptOnStack(L, Error, 2, 0, true); LUA->Release(L); } diff --git a/src/ActorFrame.cpp b/src/ActorFrame.cpp index b7d48c2dac..dd165eac62 100644 --- a/src/ActorFrame.cpp +++ b/src/ActorFrame.cpp @@ -243,7 +243,8 @@ void ActorFrame::DrawPrimitives() return; } this->PushSelf( L ); - LuaHelpers::RunScriptOnStack(L, 1, 0); // 1 arg, 0 results + RString Error= "Error running DrawFunction: "; + LuaHelpers::RunScriptOnStack(L, Error, 1, 0, true); // 1 arg, 0 results LUA->Release(L); return; } @@ -493,7 +494,8 @@ void ActorFrame::UpdateInternal( float fDeltaTime ) } this->PushSelf( L ); lua_pushnumber( L, fDeltaTime ); - LuaHelpers::RunScriptOnStack(L, 2, 0); // 1 args, 0 results + RString Error= "Error running UpdateFunction: "; + LuaHelpers::RunScriptOnStack(L, Error, 2, 0, true); // 1 args, 0 results LUA->Release(L); } } diff --git a/src/ActorUtil.cpp b/src/ActorUtil.cpp index 745791757d..70c2aa891f 100644 --- a/src/ActorUtil.cpp +++ b/src/ActorUtil.cpp @@ -272,7 +272,8 @@ bool ActorUtil::LoadTableFromStackShowErrors( Lua *L ) lua_pushvalue( L, -1 ); func.SetFromStack( L ); - if( !LuaHelpers::RunScriptOnStack(L, 0, 1) ) + RString Error= "Lua runtime error: "; + if( !LuaHelpers::RunScriptOnStack(L, Error, 0, 1, true) ) { lua_pop( L, 1 ); return false; @@ -286,7 +287,7 @@ bool ActorUtil::LoadTableFromStackShowErrors( Lua *L ) lua_Debug debug; lua_getinfo( L, ">nS", &debug ); - RString Error = ssprintf( "%s: must return a table", debug.short_src ); + Error = ssprintf( "%s: must return a table", debug.short_src ); LuaHelpers::ReportScriptError(Error, "LUA_ERROR"); return false; diff --git a/src/DynamicActorScroller.cpp b/src/DynamicActorScroller.cpp index cf7a2c69b2..b8f4cc7d86 100644 --- a/src/DynamicActorScroller.cpp +++ b/src/DynamicActorScroller.cpp @@ -52,7 +52,8 @@ void DynamicActorScroller::LoadFromNode( const XNode *pNode ) lua_pushnil( L ); lua_pushnil( L ); - LuaHelpers::RunScriptOnStack(L, 2, 1); // 2 args, 1 result + RString Error= "Error running LoadFunction: "; + LuaHelpers::RunScriptOnStack(L, Error, 2, 1, true); // 2 args, 1 result m_iNumItems = (int) luaL_checknumber( L, -1 ); lua_pop( L, 1 ); @@ -125,7 +126,8 @@ void DynamicActorScroller::ConfigureActor( Actor *pActor, int iItem ) pActor->PushSelf( L ); LuaHelpers::Push( L, iItem ); - LuaHelpers::RunScriptOnStack(L, 2, 0); // 2 args, 0 results + RString Error= "Error running LoadFunction: "; + LuaHelpers::RunScriptOnStack(L, Error, 2, 0, true); // 2 args, 0 results LUA->Release(L); } diff --git a/src/GameCommand.cpp b/src/GameCommand.cpp index c15e1af4e7..4d7d67a58c 100644 --- a/src/GameCommand.cpp +++ b/src/GameCommand.cpp @@ -762,7 +762,8 @@ void GameCommand::ApplySelf( const vector &vpns ) const ASSERT( !lua_isnil(L, -1) ); lua_pushnumber( L, *pn ); // 1st parameter - LuaHelpers::RunScriptOnStack(L, 1, 0); + RString error= "Lua GameCommand error: "; + LuaHelpers::RunScriptOnStack(L, error, 1, 0, true); } LUA->Release(L); } diff --git a/src/LifeMeterBattery.cpp b/src/LifeMeterBattery.cpp index f5501428f9..f02216adff 100644 --- a/src/LifeMeterBattery.cpp +++ b/src/LifeMeterBattery.cpp @@ -98,7 +98,8 @@ void LifeMeterBattery::OnSongEnded() COURSE_SONG_REWARD_LIVES.PushSelf(L); PushSelf(L); LuaHelpers::Push(L, pn); - LuaHelpers::RunScriptOnStack(L, 2, 1); + RString error= "Error running CourseSongRewardLives callback: "; + LuaHelpers::RunScriptOnStack(L, error, 2, 1, true); m_iLivesLeft += luaL_optnumber(L, -1, 0); lua_settop(L, 0); LUA->Release(L); diff --git a/src/LuaExpressionTransform.cpp b/src/LuaExpressionTransform.cpp index 8cf9275e34..7ddeb91d56 100644 --- a/src/LuaExpressionTransform.cpp +++ b/src/LuaExpressionTransform.cpp @@ -26,7 +26,8 @@ void LuaExpressionTransform::TransformItemDirect( Actor &a, float fPositionOffse LuaHelpers::Push( L, fPositionOffsetFromCenter ); LuaHelpers::Push( L, iItemIndex ); LuaHelpers::Push( L, iNumItems ); - LuaHelpers::RunScriptOnStack(L, 4, 0); + RString error= "Lua error in Transform function: "; + LuaHelpers::RunScriptOnStack(L, error, 4, 0, true); LUA->Release(L); } diff --git a/src/LuaManager.cpp b/src/LuaManager.cpp index 1526a01fdf..0051305b47 100644 --- a/src/LuaManager.cpp +++ b/src/LuaManager.cpp @@ -829,19 +829,36 @@ void LuaHelpers::ReportScriptErrorFmt(const char *fmt, ...) ReportScriptError(Buff); } -bool LuaHelpers::RunScriptOnStack(Lua *L, int Args, int ReturnValues) +bool LuaHelpers::RunScriptOnStack( Lua *L, RString &Error, int Args, int ReturnValues, bool ReportError ) { + lua_pushcfunction( L, GetLuaStack ); + + // move the error function above the function and params + int ErrFunc = lua_gettop(L) - Args - 1; + lua_insert( L, ErrFunc ); + // evaluate - int ret = lua_pcall(L, Args, ReturnValues, 0); + int ret = lua_pcall( L, Args, ReturnValues, ErrFunc ); if( ret ) { - lua_pop(L, 1); - for( int i = 0; i < ReturnValues; ++i ) + if(ReportError) { - lua_pushnil( L ); + RString lerror; + LuaHelpers::Pop( L, lerror ); + Error+= lerror; + ReportScriptError(Error); } + else + { + LuaHelpers::Pop( L, Error ); + } + lua_remove( L, ErrFunc ); + for( int i = 0; i < ReturnValues; ++i ) + lua_pushnil( L ); return false; } + + lua_remove( L, ErrFunc ); return true; } @@ -864,7 +881,7 @@ bool LuaHelpers::RunScript( Lua *L, const RString &Script, const RString &Name, // move the function above the params lua_insert( L, lua_gettop(L) - Args ); - return LuaHelpers::RunScriptOnStack(L, Args, ReturnValues); + return LuaHelpers::RunScriptOnStack( L, Error, Args, ReturnValues, ReportError ); } bool LuaHelpers::RunExpression( Lua *L, const RString &sExpression, const RString &sName ) diff --git a/src/LuaManager.h b/src/LuaManager.h index cf02321bcf..79b5f217ee 100644 --- a/src/LuaManager.h +++ b/src/LuaManager.h @@ -80,7 +80,7 @@ namespace LuaHelpers * when reporting. The error is reported through LOG->Warn and * SCREENMAN->SystemMessage. */ - bool RunScriptOnStack(Lua *L, int Args = 0, int ReturnValues = 0); + bool RunScriptOnStack( Lua *L, RString &Error, int Args = 0, int ReturnValues = 0, bool ReportError = false ); /* LoadScript the given script, and RunScriptOnStack it. * iArgs arguments are at the top of the stack. */ diff --git a/src/MenuTimer.cpp b/src/MenuTimer.cpp index 6d2e466ea3..c90e835612 100644 --- a/src/MenuTimer.cpp +++ b/src/MenuTimer.cpp @@ -183,7 +183,9 @@ void MenuTimer::SetText( float fSeconds ) LuaHelpers::Push( L, fSeconds ); // call function with 1 argument and 1 result - LuaHelpers::RunScriptOnStack(L, 1, 1); + RString Error= "Error running Text" + (i+1); + Error+= "FormatFunction: "; + LuaHelpers::RunScriptOnStack(L, Error, 1, 1, true); RString sText; LuaHelpers::Pop( L, sText ); diff --git a/src/NoteField.cpp b/src/NoteField.cpp index d34b2962cc..8dc0c567cb 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -1076,7 +1076,8 @@ void NoteField::FadeToFail() member_name.PushSelf(L); #define OPEN_RUN_BLOCK(arg_count) \ - if(LuaHelpers::RunScriptOnStack(L, arg_count, arg_count)) \ + RString error= "Error running callback: "; \ + if(LuaHelpers::RunScriptOnStack(L, error, arg_count, arg_count, true)) \ { #define CLOSE_RUN_AND_CALLBACK_BLOCKS } lua_settop(L, 0); LUA->Release(L); } diff --git a/src/OptionRowHandler.cpp b/src/OptionRowHandler.cpp index 39c7a18036..4820b150b8 100644 --- a/src/OptionRowHandler.cpp +++ b/src/OptionRowHandler.cpp @@ -904,7 +904,8 @@ public: return false; } m_pLuaTable->PushSelf( L ); - LuaHelpers::RunScriptOnStack(L, 1, 1); + RString error= RowName + " \"EnabledForPlayers\": "; + LuaHelpers::RunScriptOnStack(L, error, 1, 1, true); if(!lua_istable(L, -1)) { LuaHelpers::ReportScriptErrorFmt("LUA_ERROR: \"%s\" \"EnabledForPlayers\" did not return a table.", RowName.c_str()); @@ -987,7 +988,8 @@ public: // Argument 1 (self): m_pLuaTable->PushSelf( L ); - LuaHelpers::RunScriptOnStack( L, 1, 1 ); + RString error= "EnabledForPlayers: "; + LuaHelpers::RunScriptOnStack( L, error, 1, 1, true ); m_Def.m_vEnabledForPlayers.clear(); // and fill in with supplied PlayerNumbers below lua_pushnil( L ); @@ -1147,7 +1149,8 @@ public: ASSERT( lua_gettop(L) == 6 ); // vbSelectedOut, m_iLuaTable, function, self, arg, arg - LuaHelpers::RunScriptOnStack( L, 3, 0 ); + RString error= "LoadSelections: "; + LuaHelpers::RunScriptOnStack( L, error, 3, 0, true ); ASSERT( lua_gettop(L) == 2 ); lua_pop( L, 1 ); // pop option table @@ -1202,7 +1205,8 @@ public: ASSERT( lua_gettop(L) == 6 ); // vbSelectedOut, m_iLuaTable, function, self, arg, arg - LuaHelpers::RunScriptOnStack( L, 3, 0 ); + RString error= "SaveSelections: "; + LuaHelpers::RunScriptOnStack( L, error, 3, 0, true ); ASSERT( lua_gettop(L) == 2 ); lua_pop( L, 1 ); // pop option table @@ -1233,7 +1237,8 @@ public: LuaHelpers::Push(L, pn); // Convert choice to a lua index so it matches up with the Choices table. lua_pushinteger(L, choice+1); - LuaHelpers::RunScriptOnStack(L, 3, 1); + RString error= "NotifyOfSelection: "; + LuaHelpers::RunScriptOnStack(L, error, 3, 1, true); if(lua_toboolean(L, -1)) { lua_pop(L, 1); diff --git a/src/PercentageDisplay.cpp b/src/PercentageDisplay.cpp index 68d831171a..dfcbfe7f81 100644 --- a/src/PercentageDisplay.cpp +++ b/src/PercentageDisplay.cpp @@ -177,7 +177,8 @@ void PercentageDisplay::Refresh() Lua *L = LUA->Get(); m_FormatPercentScore.PushSelf( L ); LuaHelpers::Push( L, fPercentDancePoints ); - LuaHelpers::RunScriptOnStack(L, 1, 1); // 1 arg, 1 result + RString Error= "Error running FormatPercentScore: "; + LuaHelpers::RunScriptOnStack(L, Error, 1, 1, true); // 1 arg, 1 result LuaHelpers::Pop( L, sNumToDisplay ); LUA->Release(L); } diff --git a/src/Profile.cpp b/src/Profile.cpp index 7aed84dbc8..df9f8243df 100644 --- a/src/Profile.cpp +++ b/src/Profile.cpp @@ -1060,7 +1060,8 @@ void Profile::LoadCustomFunction( RString sDir ) LuaHelpers::Push(L, sDir); // Run it - LuaHelpers::RunScriptOnStack(L, 2, 0); + RString Error= "Error running CustomLoadFunction: "; + LuaHelpers::RunScriptOnStack(L, Error, 2, 0, true); LUA->Release(L); } @@ -1343,7 +1344,8 @@ bool Profile::SaveAllToDir( RString sDir, bool bSignData ) const LuaHelpers::Push(L, sDir); // Run it - LuaHelpers::RunScriptOnStack(L, 2, 0); + RString Error= "Error running CustomSaveFunction: "; + LuaHelpers::RunScriptOnStack(L, Error, 2, 0, true); LUA->Release(L); diff --git a/src/ScoreKeeperNormal.cpp b/src/ScoreKeeperNormal.cpp index 8775e9be96..835c826100 100644 --- a/src/ScoreKeeperNormal.cpp +++ b/src/ScoreKeeperNormal.cpp @@ -344,9 +344,10 @@ int ScoreKeeperNormal::CalcNextToastyAt(int level) break; case LUA_TFUNCTION: { + RString err= "Error running ToastyTriggersAt: "; LuaHelpers::Push(L, m_pPlayerState->m_PlayerNumber); lua_pushnumber(L, level); - if(LuaHelpers::RunScriptOnStack(L, 2, 1)) + if(LuaHelpers::RunScriptOnStack(L, err, 2, 1, true)) { if(lua_isnumber(L, -1)) { diff --git a/src/Screen.cpp b/src/Screen.cpp index ccf1178dae..f52ec27d74 100644 --- a/src/Screen.cpp +++ b/src/Screen.cpp @@ -360,7 +360,8 @@ bool Screen::PassInputToLua(const InputEventPlus& input) { callback->second.PushSelf(L); lua_pushvalue(L, -2); - LuaHelpers::RunScriptOnStack(L, 1, 1); + RString error= "Error running input callback: "; + LuaHelpers::RunScriptOnStack(L, error, 1, 1, true); handled= lua_toboolean(L, -1); lua_pop(L, 1); } diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp index d168a1101d..1801468b5f 100644 --- a/src/ScreenGameplay.cpp +++ b/src/ScreenGameplay.cpp @@ -547,7 +547,8 @@ void ScreenGameplay::Init() ++next_player_slot; } Enum::Push(L, GAMESTATE->GetCurrentStyle(PLAYER_INVALID)->m_StyleType); - if(LuaHelpers::RunScriptOnStack(L, 2, 3)) + RString err= "Error running MarginFunction: "; + if(LuaHelpers::RunScriptOnStack(L, err, 2, 3, true)) { RString marge= "Margin value must be a number."; margins[PLAYER_1][0]= SafeFArg(L, -3, marge, 40); diff --git a/src/ScreenSelectMaster.cpp b/src/ScreenSelectMaster.cpp index 51edf82a1c..712c585ee6 100644 --- a/src/ScreenSelectMaster.cpp +++ b/src/ScreenSelectMaster.cpp @@ -120,7 +120,8 @@ void ScreenSelectMaster::Init() Lua* L= LUA->Get(); command.PushSelf(L); lua_pushnumber(L, m_aGameCommands.size()); - if(!LuaHelpers::RunScriptOnStack(L, 1, 1)) + RString err= m_sName + "::IconChoicePosFunction: "; + if(!LuaHelpers::RunScriptOnStack(L, err, 1, 1, true)) { positions_set_by_lua= false; } diff --git a/src/ScreenTextEntry.cpp b/src/ScreenTextEntry.cpp index 422178c7c9..fa269e93e3 100644 --- a/src/ScreenTextEntry.cpp +++ b/src/ScreenTextEntry.cpp @@ -458,7 +458,8 @@ static bool ValidateFromLua( const RString &sAnswer, RString &sErrorOut ) bool valid= false; - if(LuaHelpers::RunScriptOnStack(L, 2, 2)) + RString error= "Lua error in ScreenTextEntry Validate: "; + if(LuaHelpers::RunScriptOnStack(L, error, 2, 2, true)) { if(!lua_isstring(L, -1) || !lua_isboolean(L, -2)) { @@ -491,7 +492,8 @@ static void OnOKFromLua( const RString &sAnswer ) g_OnOKFunc.PushSelf( L ); // Argument 1 (answer): lua_pushstring( L, sAnswer ); - LuaHelpers::RunScriptOnStack(L, 1, 0); + RString error= "Lua error in ScreenTextEntry OnOK: "; + LuaHelpers::RunScriptOnStack(L, error, 1, 0, true); LUA->Release(L); } @@ -505,7 +507,8 @@ static void OnCancelFromLua() Lua *L = LUA->Get(); g_OnCancelFunc.PushSelf( L ); - LuaHelpers::RunScriptOnStack(L, 0, 0); + RString error= "Lua error in ScreenTextEntry OnCancel: "; + LuaHelpers::RunScriptOnStack(L, error, 0, 0, true); LUA->Release(L); } @@ -528,7 +531,8 @@ static bool ValidateAppendFromLua( const RString &sAnswerBeforeChar, RString &sA bool append= false; - if(LuaHelpers::RunScriptOnStack(L, 2, 1)) + RString error= "Lua error in ScreenTextEntry ValidateAppend: "; + if(LuaHelpers::RunScriptOnStack(L, error, 2, 1, true)) { if( !lua_isboolean(L, -1) ) { @@ -557,7 +561,8 @@ static RString FormatAnswerForDisplayFromLua( const RString &sAnswer ) lua_pushstring( L, sAnswer ); RString answer; - if(LuaHelpers::RunScriptOnStack(L, 1, 1)) + RString error= "Lua error in ScreenTextEntry FormatAnswerForDisplay: "; + if(LuaHelpers::RunScriptOnStack(L, error, 1, 1, true)) { if( !lua_isstring(L, -1) ) { diff --git a/src/ThemeMetric.h b/src/ThemeMetric.h index 8f728106dd..f74d1c4e0b 100644 --- a/src/ThemeMetric.h +++ b/src/ThemeMetric.h @@ -146,7 +146,8 @@ public: // call function with 0 arguments and 1 result m_Value.PushSelf( L ); - LuaHelpers::RunScriptOnStack(L, 0, 1); + RString error= m_sGroup + ": " + m_sName + ": "; + LuaHelpers::RunScriptOnStack(L, error, 0, 1, true); if(!lua_isnil(L, -1)) { LuaHelpers::Pop( L, m_currentValue ); diff --git a/src/UnlockManager.cpp b/src/UnlockManager.cpp index e9f5fb82df..fca32edc61 100644 --- a/src/UnlockManager.cpp +++ b/src/UnlockManager.cpp @@ -502,7 +502,8 @@ void UnlockManager::Load() current.PushSelf( L ); // call function with 1 argument and 0 results - LuaHelpers::RunScriptOnStack(L, 1, 0); + RString error= "Lua error in command: "; + LuaHelpers::RunScriptOnStack(L, error, 1, 0, true); if( current.m_bRoulette ) m_RouletteCodes.insert( current.m_sEntryID );