Lua: Add Lua panic handler

This commit is contained in:
Lion Kortlepel 2021-09-19 23:34:27 +02:00
parent 785b858651
commit 366a7dc9a6
No known key found for this signature in database
GPG Key ID: 4322FF2B4C71259B
4 changed files with 28 additions and 1 deletions

View File

@ -4,6 +4,8 @@
#include <tuple> #include <tuple>
namespace LuaAPI { namespace LuaAPI {
int PanicHandler(lua_State* State);
void Print(sol::variadic_args); void Print(sol::variadic_args);
namespace MP { namespace MP {
extern TLuaEngine* Engine; extern TLuaEngine* Engine;

View File

@ -98,6 +98,7 @@ private:
void CollectAndInitPlugins(); void CollectAndInitPlugins();
void InitializePlugin(const fs::path& Folder, const TLuaPluginConfig& Config); void InitializePlugin(const fs::path& Folder, const TLuaPluginConfig& Config);
void FindAndParseConfig(const fs::path& Folder, TLuaPluginConfig& Config); void FindAndParseConfig(const fs::path& Folder, TLuaPluginConfig& Config);
size_t CalculateMemoryUsage();
class StateThreadData : IThreaded { class StateThreadData : IThreaded {
public: public:
@ -109,6 +110,7 @@ private:
void RegisterEvent(const std::string& EventName, const std::string& FunctionName); void RegisterEvent(const std::string& EventName, const std::string& FunctionName);
void AddPath(const fs::path& Path); // to be added to path and cpath void AddPath(const fs::path& Path); // to be added to path and cpath
void operator()() override; void operator()() override;
sol::state_view State() { return sol::state_view(mState); }
private: private:
sol::table Lua_TriggerGlobalEvent(const std::string& EventName, sol::variadic_args EventArgs); sol::table Lua_TriggerGlobalEvent(const std::string& EventName, sol::variadic_args EventArgs);

View File

@ -246,3 +246,8 @@ void LuaAPI::MP::PrintRaw(sol::variadic_args Args) {
} }
Application::Console().WriteRaw(ToPrint); Application::Console().WriteRaw(ToPrint);
} }
int LuaAPI::PanicHandler(lua_State* State) {
beammp_lua_error("PANIC: " + sol::stack::get<std::string>(State, 1));
return 0;
}

View File

@ -44,10 +44,20 @@ void TLuaEngine::operator()() {
} }
// this thread handles timers // this thread handles timers
while (!mShutdown) { while (!mShutdown) {
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::seconds(1));
beammp_debug("Lua uses " + std::to_string(CalculateMemoryUsage()) + " B of memory");
} }
} }
size_t TLuaEngine::CalculateMemoryUsage() {
size_t Usage = 0;
std::unique_lock Lock(mLuaStatesMutex);
for (auto& State : mLuaStates) {
Usage += State.second->State().memory_used();
}
return Usage;
}
void TLuaEngine::WaitForAll(std::vector<std::shared_ptr<TLuaResult>>& Results) { void TLuaEngine::WaitForAll(std::vector<std::shared_ptr<TLuaResult>>& Results) {
for (const auto& Result : Results) { for (const auto& Result : Results) {
while (!Result->Ready) { while (!Result->Ready) {
@ -269,8 +279,13 @@ TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomi
, mStateId(StateId) , mStateId(StateId)
, mState(luaL_newstate()) , mState(luaL_newstate())
, mEngine(&Engine) { , mEngine(&Engine) {
if (!mState) {
beammp_error("failed to create lua state for \"" + StateId + "\"");
return;
}
luaL_openlibs(mState); luaL_openlibs(mState);
sol::state_view StateView(mState); sol::state_view StateView(mState);
lua_atpanic(mState, LuaAPI::PanicHandler);
// StateView.globals()["package"].get() // StateView.globals()["package"].get()
StateView.set_function("print", &LuaAPI::Print); StateView.set_function("print", &LuaAPI::Print);
StateView.set_function("exit", &Application::GracefullyShutdown); StateView.set_function("exit", &Application::GracefullyShutdown);
@ -317,6 +332,9 @@ TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomi
}); });
MPTable.set_function("IsPlayerGuest", &LuaAPI::MP::IsPlayerGuest); MPTable.set_function("IsPlayerGuest", &LuaAPI::MP::IsPlayerGuest);
MPTable.set_function("DropPlayer", &LuaAPI::MP::DropPlayer); MPTable.set_function("DropPlayer", &LuaAPI::MP::DropPlayer);
MPTable.set_function("GetStateMemoryUsage", [&]() -> size_t {
return mStateView.memory_used();
});
MPTable.set_function("GetPlayerIdentifiers", [&](int ID) -> sol::table { MPTable.set_function("GetPlayerIdentifiers", [&](int ID) -> sol::table {
return Lua_GetPlayerIdentifiers(ID); return Lua_GetPlayerIdentifiers(ID);
}); });