mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2026-04-19 06:40:01 +00:00
Lua: Fix multiple issues with events
This commit is contained in:
@@ -26,6 +26,8 @@ struct TLuaResult {
|
|||||||
std::atomic_bool Error;
|
std::atomic_bool Error;
|
||||||
std::string ErrorMessage;
|
std::string ErrorMessage;
|
||||||
sol::protected_function_result Result;
|
sol::protected_function_result Result;
|
||||||
|
TLuaStateId StateId;
|
||||||
|
std::string Function;
|
||||||
// TODO: Add condition_variable
|
// TODO: Add condition_variable
|
||||||
void WaitUntilReady();
|
void WaitUntilReady();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -58,16 +58,17 @@ TConsole::TConsole() {
|
|||||||
} else if (cmd == "clear" || cmd == "cls") {
|
} else if (cmd == "clear" || cmd == "cls") {
|
||||||
// TODO: clear screen
|
// TODO: clear screen
|
||||||
} else {
|
} else {
|
||||||
while (!mLuaEngine) {
|
if (!mLuaEngine) {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
beammp_info("Lua not started yet, please try again in a second");
|
||||||
}
|
} else {
|
||||||
auto Future = mLuaEngine->EnqueueScript(mStateId, std::make_shared<std::string>(cmd));
|
auto Future = mLuaEngine->EnqueueScript(mStateId, std::make_shared<std::string>(cmd));
|
||||||
// wait for it to finish
|
// wait for it to finish
|
||||||
while (!Future->Ready) {
|
/*while (!Future->Ready) {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
}
|
}
|
||||||
if (Future->Error) {
|
if (Future->Error) {
|
||||||
beammp_error(Future->ErrorMessage);
|
beammp_error(Future->ErrorMessage);
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ void TLuaEngine::FindAndParseConfig(const fs::path& Folder, TLuaPluginConfig& Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TLuaEngine::EnsureStateExists(TLuaStateId StateId, const std::string& Name, bool DontCallOnInit) {
|
void TLuaEngine::EnsureStateExists(TLuaStateId StateId, const std::string& Name, bool DontCallOnInit) {
|
||||||
|
beammp_assert(!StateId.empty());
|
||||||
std::unique_lock Lock(mLuaStatesMutex);
|
std::unique_lock Lock(mLuaStatesMutex);
|
||||||
if (mLuaStates.find(StateId) == mLuaStates.end()) {
|
if (mLuaStates.find(StateId) == mLuaStates.end()) {
|
||||||
beammp_debug("Creating lua state for state id \"" + StateId + "\"");
|
beammp_debug("Creating lua state for state id \"" + StateId + "\"");
|
||||||
@@ -134,10 +135,14 @@ void TLuaEngine::RegisterEvent(const std::string& EventName, TLuaStateId StateId
|
|||||||
|
|
||||||
std::vector<std::shared_ptr<TLuaResult>> TLuaEngine::TriggerEvent(const std::string& EventName) {
|
std::vector<std::shared_ptr<TLuaResult>> TLuaEngine::TriggerEvent(const std::string& EventName) {
|
||||||
std::unique_lock Lock(mEventsMutex);
|
std::unique_lock Lock(mEventsMutex);
|
||||||
|
if (mEvents.find(EventName) == mEvents.end()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
std::vector<std::shared_ptr<TLuaResult>> Results;
|
std::vector<std::shared_ptr<TLuaResult>> Results;
|
||||||
for (const auto& Entry : mEvents[EventName]) {
|
for (const auto& Event : mEvents.at(EventName)) {
|
||||||
for (const auto& Function : Entry.second) {
|
for (const auto& Function : Event.second) {
|
||||||
Results.emplace_back(EnqueueFunctionCall(Entry.first, Function));
|
beammp_debug("TriggerEvent: triggering \"" + Function + "\" on \"" + Event.first + "\"");
|
||||||
|
Results.push_back(EnqueueFunctionCall(Event.first, Function));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Results;
|
return Results;
|
||||||
@@ -151,6 +156,7 @@ TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomi
|
|||||||
mState = luaL_newstate();
|
mState = luaL_newstate();
|
||||||
luaL_openlibs(mState);
|
luaL_openlibs(mState);
|
||||||
sol::state_view StateView(mState);
|
sol::state_view StateView(mState);
|
||||||
|
// StateView.globals()["package"].get()
|
||||||
StateView.set_function("print", &LuaAPI::Print);
|
StateView.set_function("print", &LuaAPI::Print);
|
||||||
auto Table = StateView.create_named_table("MP");
|
auto Table = StateView.create_named_table("MP");
|
||||||
Table.set_function("GetOSName", &LuaAPI::MP::GetOSName);
|
Table.set_function("GetOSName", &LuaAPI::MP::GetOSName);
|
||||||
@@ -160,8 +166,32 @@ TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomi
|
|||||||
RegisterEvent(EventName, FunctionName);
|
RegisterEvent(EventName, FunctionName);
|
||||||
});
|
});
|
||||||
Table.set_function("TriggerGlobalEvent",
|
Table.set_function("TriggerGlobalEvent",
|
||||||
[&](const std::string& EventName) {
|
[&](const std::string& EventName) -> sol::table {
|
||||||
return mEngine->TriggerEvent(EventName);
|
auto Return = mEngine->TriggerEvent(EventName);
|
||||||
|
beammp_debug("Triggering event \"" + EventName + "\" in \"" + mStateId + "\"");
|
||||||
|
sol::state_view StateView(mState);
|
||||||
|
sol::table AsyncEventReturn = StateView.create_table();
|
||||||
|
AsyncEventReturn["ReturnValueImpl"] = Return;
|
||||||
|
AsyncEventReturn.set_function("Wait",
|
||||||
|
[&](const sol::table& Self) -> sol::table {
|
||||||
|
sol::state_view StateView(mState);
|
||||||
|
sol::table Result = StateView.create_table();
|
||||||
|
beammp_debug("beginning to loop");
|
||||||
|
auto Vector = Self.get<std::vector<std::shared_ptr<TLuaResult>>>("ReturnValueImpl");
|
||||||
|
for (const auto& Value : Vector) {
|
||||||
|
beammp_debug("waiting on a value");
|
||||||
|
Value->WaitUntilReady();
|
||||||
|
if (Value->Error) {
|
||||||
|
if (Value->ErrorMessage != BeamMPFnNotFoundError) {
|
||||||
|
beammp_lua_error("\"" + StateId + "\"" + Value->ErrorMessage);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Result.add(Value->Result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
});
|
||||||
|
return AsyncEventReturn;
|
||||||
});
|
});
|
||||||
Table.create_named("Settings",
|
Table.create_named("Settings",
|
||||||
"Debug", 0,
|
"Debug", 0,
|
||||||
@@ -186,6 +216,7 @@ std::shared_ptr<TLuaResult> TLuaEngine::StateThreadData::EnqueueFunctionCall(con
|
|||||||
beammp_debug("calling \"" + FunctionName + "\" in \"" + mName + "\"");
|
beammp_debug("calling \"" + FunctionName + "\" in \"" + mName + "\"");
|
||||||
std::unique_lock Lock(mStateFunctionQueueMutex);
|
std::unique_lock Lock(mStateFunctionQueueMutex);
|
||||||
auto Result = std::make_shared<TLuaResult>();
|
auto Result = std::make_shared<TLuaResult>();
|
||||||
|
Result->StateId = mStateId;
|
||||||
mStateFunctionQueue.push({ FunctionName, Result });
|
mStateFunctionQueue.push({ FunctionName, Result });
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@@ -199,10 +230,7 @@ void TLuaEngine::StateThreadData::operator()() {
|
|||||||
while (!mShutdown) {
|
while (!mShutdown) {
|
||||||
{ // StateExecuteQueue Scope
|
{ // StateExecuteQueue Scope
|
||||||
std::unique_lock Lock(mStateExecuteQueueMutex);
|
std::unique_lock Lock(mStateExecuteQueueMutex);
|
||||||
if (mStateExecuteQueue.empty()) {
|
if (!mStateExecuteQueue.empty()) {
|
||||||
Lock.unlock();
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
|
||||||
} else {
|
|
||||||
auto S = mStateExecuteQueue.front();
|
auto S = mStateExecuteQueue.front();
|
||||||
mStateExecuteQueue.pop();
|
mStateExecuteQueue.pop();
|
||||||
Lock.unlock();
|
Lock.unlock();
|
||||||
@@ -222,19 +250,17 @@ void TLuaEngine::StateThreadData::operator()() {
|
|||||||
}
|
}
|
||||||
{ // StateFunctionQueue Scope
|
{ // StateFunctionQueue Scope
|
||||||
std::unique_lock Lock(mStateFunctionQueueMutex);
|
std::unique_lock Lock(mStateFunctionQueueMutex);
|
||||||
if (mStateFunctionQueue.empty()) {
|
if (!mStateFunctionQueue.empty()) {
|
||||||
Lock.unlock();
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
|
||||||
} else {
|
|
||||||
auto FnNameResultPair = mStateFunctionQueue.front();
|
auto FnNameResultPair = mStateFunctionQueue.front();
|
||||||
mStateFunctionQueue.pop();
|
mStateFunctionQueue.pop();
|
||||||
Lock.unlock();
|
Lock.unlock();
|
||||||
beammp_debug("Running function");
|
FnNameResultPair.second->StateId = mStateId;
|
||||||
|
beammp_debug("Running function \"" + FnNameResultPair.first + "\"");
|
||||||
sol::state_view StateView(mState);
|
sol::state_view StateView(mState);
|
||||||
auto Fn = StateView[FnNameResultPair.first];
|
auto Fn = StateView[FnNameResultPair.first];
|
||||||
|
beammp_debug("Done running function \"" + FnNameResultPair.first + "\"");
|
||||||
if (Fn.valid() && Fn.get_type() == sol::type::function) {
|
if (Fn.valid() && Fn.get_type() == sol::type::function) {
|
||||||
auto Res = Fn();
|
auto Res = Fn();
|
||||||
FnNameResultPair.second->Ready = true;
|
|
||||||
if (Res.valid()) {
|
if (Res.valid()) {
|
||||||
FnNameResultPair.second->Error = false;
|
FnNameResultPair.second->Error = false;
|
||||||
FnNameResultPair.second->Result = std::move(Res);
|
FnNameResultPair.second->Result = std::move(Res);
|
||||||
@@ -243,10 +269,11 @@ void TLuaEngine::StateThreadData::operator()() {
|
|||||||
sol::error Err = Res;
|
sol::error Err = Res;
|
||||||
FnNameResultPair.second->ErrorMessage = Err.what();
|
FnNameResultPair.second->ErrorMessage = Err.what();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
FnNameResultPair.second->Ready = true;
|
FnNameResultPair.second->Ready = true;
|
||||||
|
} else {
|
||||||
FnNameResultPair.second->Error = true;
|
FnNameResultPair.second->Error = true;
|
||||||
FnNameResultPair.second->ErrorMessage = BeamMPFnNotFoundError; // special error kind that we can ignore later
|
FnNameResultPair.second->ErrorMessage = BeamMPFnNotFoundError; // special error kind that we can ignore later
|
||||||
|
FnNameResultPair.second->Ready = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user