From 883463ef41f5c8741513d2aef5658bfb953e04f3 Mon Sep 17 00:00:00 2001 From: Kipstz <140314732+Kipstz@users.noreply.github.com> Date: Wed, 24 Dec 2025 03:16:17 +0100 Subject: [PATCH] feat: add onInitFinal event for post-initialization synchronization Adds a new 'onInitFinal' event that triggers after ALL Lua states have completed their 'onInit' handlers. This provides a reliable synchronization point for inter-state communication. Use case: When multiple Lua states need to communicate (e.g., a centralized settings manager), they can now safely interact in onInitFinal knowing all states are fully initialized. Closes #434 --- src/TLuaEngine.cpp | 10 ++++++++++ src/TServer.cpp | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/TLuaEngine.cpp b/src/TLuaEngine.cpp index 83fa34f4..411b91aa 100644 --- a/src/TLuaEngine.cpp +++ b/src/TLuaEngine.cpp @@ -82,6 +82,15 @@ void TLuaEngine::operator()() { } } + // now call onInitFinal after all states have completed their onInit + auto FinalFutures = TriggerEvent("onInitFinal", ""); + WaitForAll(FinalFutures, std::chrono::seconds(5)); + for (const auto& Future : FinalFutures) { + if (Future->Error && Future->ErrorMessage != BeamMPFnNotFoundError) { + beammp_lua_error("Calling \"onInitFinal\" on \"" + Future->StateId + "\" failed: " + Future->ErrorMessage); + } + } + auto ResultCheckThread = std::thread([&] { RegisterThread("ResultCheckThread"); while (!Application::IsShuttingDown()) { @@ -433,6 +442,7 @@ void TLuaEngine::EnsureStateExists(TLuaStateId StateId, const std::string& Name, auto DataPtr = std::make_unique(Name, StateId, *this); mLuaStates[StateId] = std::move(DataPtr); RegisterEvent("onInit", StateId, "onInit"); + RegisterEvent("onInitFinal", StateId, "onInitFinal"); if (!DontCallOnInit) { auto Res = EnqueueFunctionCall(StateId, "onInit", {}, "onInit"); Res->WaitUntilReady(); diff --git a/src/TServer.cpp b/src/TServer.cpp index ae16c1cd..e876a2c9 100644 --- a/src/TServer.cpp +++ b/src/TServer.cpp @@ -321,7 +321,7 @@ void TServer::HandleEvent(TClient& c, const std::string& RawData) { std::string Name = RawData.substr(2, NameDataSep - 2); std::string Data = RawData.substr(NameDataSep + 1); - std::vector exclude = {"onInit", "onFileChanged","onVehicleDeleted","onConsoleInput","onPlayerAuth","postPlayerAuth", "onPlayerDisconnect", + std::vector exclude = {"onInit", "onInitFinal", "onFileChanged","onVehicleDeleted","onConsoleInput","onPlayerAuth","postPlayerAuth", "onPlayerDisconnect", "onPlayerConnecting","onPlayerJoining","onPlayerJoin","onChatMessage","postChatMessage","onVehicleSpawn","postVehicleSpawn","onVehicleEdited", "postVehicleEdited", "onVehicleReset","onVehiclePaintChanged","onShutdown"};