mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2025-07-04 00:36:14 +00:00
Lua: Add MP.CreateTimedEvent as CreateThread replacement
This commit is contained in:
parent
a97791d4ee
commit
4bf89706b4
@ -21,6 +21,7 @@
|
|||||||
- ADDED `MP.HttpsPOST(host,port,target,body,content_type) -> status,body`: Does a synchronous HTTPS POST request
|
- ADDED `MP.HttpsPOST(host,port,target,body,content_type) -> status,body`: Does a synchronous HTTPS POST request
|
||||||
- ADDED `MP.GetStateMemoryUsage() -> number`: Current memory usage of the current state in bytes
|
- ADDED `MP.GetStateMemoryUsage() -> number`: Current memory usage of the current state in bytes
|
||||||
- ADDED `MP.GetLuaMemoryUsage() -> number`: Current memory usage of all states combined, in bytes
|
- ADDED `MP.GetLuaMemoryUsage() -> number`: Current memory usage of all states combined, in bytes
|
||||||
|
- ADDED `MP.CreateTimedEvent(event,interval_ms)`: Replacement for `CreateThread` - calls the event in the given interval
|
||||||
|
|
||||||
# v2.3.3
|
# v2.3.3
|
||||||
|
|
||||||
|
@ -75,12 +75,12 @@ public:
|
|||||||
void RegisterEvent(const std::string& EventName, TLuaStateId StateId, const std::string& FunctionName);
|
void RegisterEvent(const std::string& EventName, TLuaStateId StateId, const std::string& FunctionName);
|
||||||
template <typename... ArgsT>
|
template <typename... ArgsT>
|
||||||
[[nodiscard]] std::vector<std::shared_ptr<TLuaResult>> TriggerEvent(const std::string& EventName, TLuaStateId IgnoreId, ArgsT&&... Args) {
|
[[nodiscard]] std::vector<std::shared_ptr<TLuaResult>> TriggerEvent(const std::string& EventName, TLuaStateId IgnoreId, ArgsT&&... Args) {
|
||||||
std::unique_lock Lock(mEventsMutex);
|
std::unique_lock Lock(mLuaEventsMutex);
|
||||||
if (mEvents.find(EventName) == mEvents.end()) {
|
if (mLuaEvents.find(EventName) == mLuaEvents.end()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
std::vector<std::shared_ptr<TLuaResult>> Results;
|
std::vector<std::shared_ptr<TLuaResult>> Results;
|
||||||
for (const auto& Event : mEvents.at(EventName)) {
|
for (const auto& Event : mLuaEvents.at(EventName)) {
|
||||||
for (const auto& Function : Event.second) {
|
for (const auto& Function : Event.second) {
|
||||||
if (Event.first != IgnoreId) {
|
if (Event.first != IgnoreId) {
|
||||||
Results.push_back(EnqueueFunctionCall(Event.first, Function, { TLuaArgTypes { std::forward<ArgsT>(Args) }... }));
|
Results.push_back(EnqueueFunctionCall(Event.first, Function, { TLuaArgTypes { std::forward<ArgsT>(Args) }... }));
|
||||||
@ -90,6 +90,7 @@ public:
|
|||||||
return Results;
|
return Results;
|
||||||
}
|
}
|
||||||
std::set<std::string> GetEventHandlersForState(const std::string& EventName, TLuaStateId StateId);
|
std::set<std::string> GetEventHandlersForState(const std::string& EventName, TLuaStateId StateId);
|
||||||
|
void CreateTimedEvent(const std::string& EventName, TLuaStateId StateId, size_t IntervalMS);
|
||||||
|
|
||||||
static constexpr const char* BeamMPFnNotFoundError = "BEAMMP_FN_NOT_FOUND";
|
static constexpr const char* BeamMPFnNotFoundError = "BEAMMP_FN_NOT_FOUND";
|
||||||
|
|
||||||
@ -134,6 +135,15 @@ private:
|
|||||||
std::recursive_mutex mPathsMutex;
|
std::recursive_mutex mPathsMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TimedEvent {
|
||||||
|
const std::chrono::high_resolution_clock::duration Duration {};
|
||||||
|
std::chrono::high_resolution_clock::time_point LastCompletion { };
|
||||||
|
std::string EventName;
|
||||||
|
TLuaStateId StateId;
|
||||||
|
bool Expired();
|
||||||
|
void Reset();
|
||||||
|
};
|
||||||
|
|
||||||
TNetwork* mNetwork;
|
TNetwork* mNetwork;
|
||||||
TServer* mServer;
|
TServer* mServer;
|
||||||
std::atomic_bool mShutdown { false };
|
std::atomic_bool mShutdown { false };
|
||||||
@ -141,8 +151,10 @@ private:
|
|||||||
std::vector<TLuaPlugin*> mLuaPlugins;
|
std::vector<TLuaPlugin*> mLuaPlugins;
|
||||||
std::unordered_map<TLuaStateId, std::unique_ptr<StateThreadData>> mLuaStates;
|
std::unordered_map<TLuaStateId, std::unique_ptr<StateThreadData>> mLuaStates;
|
||||||
std::recursive_mutex mLuaStatesMutex;
|
std::recursive_mutex mLuaStatesMutex;
|
||||||
std::unordered_map<std::string /* event name */, std::unordered_map<TLuaStateId, std::set<std::string>>> mEvents;
|
std::unordered_map<std::string /* event name */, std::unordered_map<TLuaStateId, std::set<std::string>>> mLuaEvents;
|
||||||
std::recursive_mutex mEventsMutex;
|
std::recursive_mutex mLuaEventsMutex;
|
||||||
|
std::vector<TimedEvent> mTimedEvents;
|
||||||
|
std::recursive_mutex mTimedEventsMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
//std::any TriggerLuaEvent(const std::string& Event, bool local, TLuaPlugin* Caller, std::shared_ptr<TLuaArg> arg, bool Wait);
|
//std::any TriggerLuaEvent(const std::string& Event, bool local, TLuaPlugin* Caller, std::shared_ptr<TLuaArg> arg, bool Wait);
|
||||||
|
@ -42,9 +42,23 @@ void TLuaEngine::operator()() {
|
|||||||
beammp_lua_error("Calling \"onInit\" on \"" + Future->StateId + "\" failed: " + Future->ErrorMessage);
|
beammp_lua_error("Calling \"onInit\" on \"" + Future->StateId + "\" failed: " + Future->ErrorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// this thread handles timers
|
// event loop
|
||||||
while (!mShutdown) {
|
while (!mShutdown) {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
auto Before = std::chrono::high_resolution_clock::now();
|
||||||
|
std::unique_lock Lock(mTimedEventsMutex);
|
||||||
|
for (auto& Timer : mTimedEvents) {
|
||||||
|
if (Timer.Expired()) {
|
||||||
|
Timer.Reset();
|
||||||
|
std::unique_lock Lock2(mLuaStatesMutex);
|
||||||
|
beammp_ignore(mLuaStates[Timer.StateId]->EnqueueFunctionCall("TriggerLocalEvent", { Timer.EventName }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// sleep for the remaining time to get to 1ms (our atom duration)
|
||||||
|
if (std::chrono::high_resolution_clock::duration Diff;
|
||||||
|
(Diff = Before - std::chrono::high_resolution_clock::now())
|
||||||
|
< std::chrono::milliseconds(1)) {
|
||||||
|
std::this_thread::sleep_for(Diff);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,12 +152,12 @@ void TLuaEngine::EnsureStateExists(TLuaStateId StateId, const std::string& Name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TLuaEngine::RegisterEvent(const std::string& EventName, TLuaStateId StateId, const std::string& FunctionName) {
|
void TLuaEngine::RegisterEvent(const std::string& EventName, TLuaStateId StateId, const std::string& FunctionName) {
|
||||||
std::unique_lock Lock(mEventsMutex);
|
std::unique_lock Lock(mLuaEventsMutex);
|
||||||
mEvents[EventName][StateId].insert(FunctionName);
|
mLuaEvents[EventName][StateId].insert(FunctionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<std::string> TLuaEngine::GetEventHandlersForState(const std::string& EventName, TLuaStateId StateId) {
|
std::set<std::string> TLuaEngine::GetEventHandlersForState(const std::string& EventName, TLuaStateId StateId) {
|
||||||
return mEvents[EventName][StateId];
|
return mLuaEvents[EventName][StateId];
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table TLuaEngine::StateThreadData::Lua_TriggerGlobalEvent(const std::string& EventName, sol::variadic_args EventArgs) {
|
sol::table TLuaEngine::StateThreadData::Lua_TriggerGlobalEvent(const std::string& EventName, sol::variadic_args EventArgs) {
|
||||||
@ -343,6 +357,9 @@ TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomi
|
|||||||
});
|
});
|
||||||
MPTable.set_function("Sleep", &LuaAPI::MP::Sleep);
|
MPTable.set_function("Sleep", &LuaAPI::MP::Sleep);
|
||||||
MPTable.set_function("PrintRaw", &LuaAPI::MP::PrintRaw);
|
MPTable.set_function("PrintRaw", &LuaAPI::MP::PrintRaw);
|
||||||
|
MPTable.set_function("CreateTimedEvent", [&](const std::string& EventName, size_t IntervalMS) {
|
||||||
|
mEngine->CreateTimedEvent(EventName, mStateId, IntervalMS);
|
||||||
|
});
|
||||||
MPTable.set_function("Set", &LuaAPI::MP::Set);
|
MPTable.set_function("Set", &LuaAPI::MP::Set);
|
||||||
MPTable.set_function("HttpsGET", [&](const std::string& Host, int Port, const std::string& Target) -> std::tuple<int, std::string> {
|
MPTable.set_function("HttpsGET", [&](const std::string& Host, int Port, const std::string& Target) -> std::tuple<int, std::string> {
|
||||||
unsigned Status;
|
unsigned Status;
|
||||||
@ -497,6 +514,17 @@ void TLuaEngine::StateThreadData::operator()() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TLuaEngine::CreateTimedEvent(const std::string& EventName, TLuaStateId StateId, size_t IntervalMS) {
|
||||||
|
std::unique_lock Lock(mTimedEventsMutex);
|
||||||
|
TimedEvent Event {
|
||||||
|
std::chrono::high_resolution_clock::duration { std::chrono::milliseconds(IntervalMS) },
|
||||||
|
std::chrono::high_resolution_clock::now(),
|
||||||
|
EventName,
|
||||||
|
StateId
|
||||||
|
};
|
||||||
|
mTimedEvents.push_back(std::move(Event));
|
||||||
|
}
|
||||||
|
|
||||||
void TLuaEngine::StateThreadData::AddPath(const fs::path& Path) {
|
void TLuaEngine::StateThreadData::AddPath(const fs::path& Path) {
|
||||||
std::unique_lock Lock(mPathsMutex);
|
std::unique_lock Lock(mPathsMutex);
|
||||||
mPaths.push(Path);
|
mPaths.push(Path);
|
||||||
@ -513,3 +541,12 @@ TLuaChunk::TLuaChunk(std::shared_ptr<std::string> Content, std::string FileName,
|
|||||||
, FileName(FileName)
|
, FileName(FileName)
|
||||||
, PluginPath(PluginPath) {
|
, PluginPath(PluginPath) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TLuaEngine::TimedEvent::Expired() {
|
||||||
|
auto Waited = (std::chrono::high_resolution_clock::now() - LastCompletion);
|
||||||
|
return Waited < Duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TLuaEngine::TimedEvent::Reset() {
|
||||||
|
LastCompletion = std::chrono::high_resolution_clock::now();
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user