From 132beb0dd6e2c8499fb1856c11be1c348e4ea98b Mon Sep 17 00:00:00 2001 From: SantaSpeen Date: Sat, 22 Jul 2023 07:48:35 +0300 Subject: [PATCH] Add MP.CreateTimer(), MP.CreateEventTimer(), MP.CancelEventTimer() --- src/modules/PluginsLoader/add_in.lua | 89 +++++++++++++++++-- .../PluginsLoader/lua_plugins_loader.py | 63 ++++++++++--- 2 files changed, 133 insertions(+), 19 deletions(-) diff --git a/src/modules/PluginsLoader/add_in.lua b/src/modules/PluginsLoader/add_in.lua index ade1795..ec9f158 100644 --- a/src/modules/PluginsLoader/add_in.lua +++ b/src/modules/PluginsLoader/add_in.lua @@ -1,10 +1,5 @@ package.path = package.path..";modules/PluginsLoader/lua_libs/?.lua" -function MP.Sleep(time_ms) - local start = getTickCount() - while getTickCount() - start < time_ms do end -end - MP.CallStrategy = { BestEffort = 0, Precise = 1 @@ -19,3 +14,87 @@ MP.Settings = { Name = 5, Description = 6 } + +function MP.CreateTimer() + MP.log.debug("request MP.CreateTimer()") + local timer = {} + timer.start_time = os.clock() + + function timer:GetCurrent() + return os.clock() - self.start_time + end + + function timer:Start() + self.start_time = os.clock() + end + + return timer +end + +----Timer object for event timers +--local TimedEvent = {} +--TimedEvent.__index = TimedEvent +-- +--function TimedEvent:new(interval_ms, event_name, strategy) +-- local o = {} +-- setmetatable(o, self) +-- o.interval = interval_ms +-- o.event_name = event_name +-- o.strategy = strategy or MP.CallStrategy.BestEffort +-- o.last_trigger_time = 0 +-- o.timer = MP.CreateTimer() +-- return o +--end +-- +--function TimedEvent:trigger() +-- MP.TriggerLocalEvent(self.event_name) +-- self.last_trigger_time = self.timer:GetCurrent() +--end +-- +--function TimedEvent:is_ready() +-- local elapsed_time = self.timer:GetCurrent() - self.last_trigger_time +-- return elapsed_time * 1000 >= self.interval +--end +-- +---- Event timer management functions +--MP.event_timers = {} +--MP.event_timers_mutex = {} +-- +--function MP.CreateEventTimer(event_name, interval_ms, strategy) +-- MP.log.debug("request MP.CreateEventTimer()") +-- strategy = strategy or MP.CallStrategy.BestEffort +-- local timer = TimedEvent:new(interval_ms, event_name, strategy) +-- table.insert(MP.event_timers, timer) +-- MP.log.debug("created event timer for \"" .. event_name .. "\" with " .. interval_ms .. "ms interval") +--end +-- +--function MP.CancelEventTimer(event_name) +-- MP.log.debug("request MP.CancelEventTimer()") +-- for i, timer in ipairs(MP.event_timers) do +-- if timer.event_name == event_name then +-- table.remove(MP.event_timers, i) +-- end +-- end +-- MP.log.debug("cancelled event timer for \"" .. event_name .. "\"") +--end +-- +--function MP.run_event_timers() +-- MP.log.debug("request MP.run_event_timers()") +-- while true do +-- -- Wait for some time before checking timers +-- MP.Sleep(100) +-- +-- -- Check each timer and trigger events as necessary +-- for _, timer in ipairs(MP.event_timers) do +-- if timer:is_ready() then +-- if timer.strategy == MP.CallStrategy.Precise then +-- while timer:is_ready() do +-- timer:trigger() +-- end +-- else +-- timer:trigger() +-- end +-- end +-- end +-- end +--end diff --git a/src/modules/PluginsLoader/lua_plugins_loader.py b/src/modules/PluginsLoader/lua_plugins_loader.py index b0bf160..772e5ef 100644 --- a/src/modules/PluginsLoader/lua_plugins_loader.py +++ b/src/modules/PluginsLoader/lua_plugins_loader.py @@ -4,6 +4,9 @@ import os import platform import random import shutil +import threading +import time +from threading import Thread import toml from lupa.lua53 import LuaRuntime @@ -11,11 +14,37 @@ from lupa.lua53 import LuaRuntime from core import get_logger +class EventTimer: + def __init__(self, event_name, interval_ms, strategy=None): + self.event_name = event_name + self.interval_ms = interval_ms + self.strategy = strategy + self.timer = None + self.stopped = False + + def start(self): + def callback(): + if not self.stopped: + self.start() + self.trigger_event() + + self.timer = threading.Timer(self.interval_ms / 1000.0, callback) + self.timer.start() + + def stop(self): + self.stopped = True + if self.timer is not None: + self.timer.cancel() + + def trigger_event(self): + # trigger the event with the given name + print(f"Event '{self.event_name}' triggered") + + # noinspection PyPep8Naming class MP: # In ./in_lua.lua - # MP.Sleep def __init__(self, name: str, lua: LuaRuntime): self.loaded = False @@ -30,6 +59,7 @@ class MP: "onPlayerJoin": [], "onPlayerDisconnect": [], "onChatMessage": [], "onVehicleSpawn": [], "onVehicleEdited": [], "onVehicleDeleted": [], "onVehicleReset": [], "onFileChanged": [] } + self._event_timers = {} def _print(self, *args): args = list(args) @@ -39,11 +69,6 @@ class MP: s = " ".join(map(str, args)) self.log.info(s) - def CreateTimer(self): - self.log.debug("request CreateTimer()") - # TODO: CreateTimer - self.log.warning("KuiToi does not currently support: MP.CreateTimer()") - def GetOSName(self) -> str: self.log.debug("request MP.GetOSName()") pl = platform.system() @@ -78,13 +103,16 @@ class MP: def CreateEventTimer(self, event_name: str, interval_ms: int, strategy: int = None): self.log.debug("request CreateEventTimer()") - # TODO: CreateEventTimer - self.log.warning("KuiToi does not currently support: MP.CreateEventTimer()") + event_timer = EventTimer(event_name, interval_ms, strategy) + self._event_timers[event_name] = event_timer + event_timer.start() def CancelEventTimer(self, event_name: str): self.log.debug("request CancelEventTimer()") - # TODO: CancelEventTimer - self.log.warning("KuiToi does not currently support: MP.CancelEventTimer()") + if event_name in self._event_timers: + event_timer = self._event_timers[event_name] + event_timer.stop() + del self._event_timers[event_name] def TriggerLocalEvent(self, event_name, *args): self.log.debug("request TriggerLocalEvent()") @@ -110,6 +138,10 @@ class MP: GetResults=lambda: self._lua.table_from(ev.call_lua_event(event_name, *args)) ) + def Sleep(self, time_ms): + self.log.debug(f"request Sleep(); Thread: {threading.current_thread().name}") + time.sleep(time_ms * 0.001) + def SendChatMessage(self, player_id, message): self.log.debug("request SendChatMessage()") client = ev.call_event("_get_player", cid=player_id)[0] @@ -585,8 +617,6 @@ class LuaPluginsLoader: } with open("ServerConfig.toml", "w") as f: toml.dump(data, f) - self.log.warning("KuiToi does not currently support: MP.CreateTimer(), MP.CreateEventTimer(), " - "MP.CancelEventTimer()") self.log.warning("KuiToi will not support at all: MP.Set()") py_folders = ev.call_event("_plugins_get")[0] for name in os.listdir(self.plugins_dir): @@ -617,7 +647,7 @@ class LuaPluginsLoader: lua_globals.package.path += f';{p0};{p1}' with open("modules/PluginsLoader/add_in.lua", "r") as f: lua.execute(f.read()) - self.lua_plugins.update({name: {"lua": lua, "ok": False}}) + self.lua_plugins.update({name: {"lua": lua, "ok": False, "th": None, "stop_th": None}}) plugin_path = os.path.join(self.plugins_dir, name) for file in os.listdir(plugin_path): path = f"plugins/{name}/{file}" @@ -640,4 +670,9 @@ class LuaPluginsLoader: self.log.exception(e) def unload(self, _): - ... + self.log.debug("Unloading lua plugins") + for k, data in self.lua_plugins.items(): + if data['ok']: + self.log.debug(f"Unloading lua plugin: {k}") + # data['stop_th']() + # data['th'].join()