Merge pull request #581 from MihailRis/schedule
Schedule class, built-in schedules, await function
This commit is contained in:
commit
df8dbc14f7
@ -259,6 +259,13 @@ function sleep(timesec: number)
|
|||||||
|
|
||||||
Вызывает остановку корутины до тех пор, пока не пройдёт количество секунд, указанное в **timesec**. Функция может быть использована только внутри корутины.
|
Вызывает остановку корутины до тех пор, пока не пройдёт количество секунд, указанное в **timesec**. Функция может быть использована только внутри корутины.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
function await(co: coroutine) -> result, error
|
||||||
|
```
|
||||||
|
|
||||||
|
Ожидает завершение переданной корутины, возвращая поток управления. Функция может быть использована только внутри корутины.
|
||||||
|
Возвращает значения аналогичные возвращаемым значениям *pcall*.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
os.pid -> number
|
os.pid -> number
|
||||||
```
|
```
|
||||||
|
|||||||
46
res/modules/schedule.lua
Normal file
46
res/modules/schedule.lua
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
local Schedule = {
|
||||||
|
__index = {
|
||||||
|
set_interval = function(self, ms, callback, repetions)
|
||||||
|
local id = self._next_interval
|
||||||
|
self._intervals[id] = {
|
||||||
|
last_called = 0.0,
|
||||||
|
delay = ms / 1000.0,
|
||||||
|
callback = callback,
|
||||||
|
repetions = repetions,
|
||||||
|
}
|
||||||
|
self._next_interval = id + 1
|
||||||
|
return id
|
||||||
|
end,
|
||||||
|
tick = function(self, dt)
|
||||||
|
local timer = self._timer + dt
|
||||||
|
for id, interval in pairs(self._intervals) do
|
||||||
|
if timer - interval.last_called >= interval.delay then
|
||||||
|
xpcall(interval.callback, function(s)
|
||||||
|
debug.error(s..'\n'..debug.traceback())
|
||||||
|
end)
|
||||||
|
interval.last_called = timer
|
||||||
|
local repetions = interval.repetions
|
||||||
|
if repetions then
|
||||||
|
if repetions <= 1 then
|
||||||
|
self:remove_interval(id)
|
||||||
|
else
|
||||||
|
interval.repetions = repetions - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self._timer = timer
|
||||||
|
end,
|
||||||
|
remove_interval = function (self, id)
|
||||||
|
self._intervals[id] = nil
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return function ()
|
||||||
|
return setmetatable({
|
||||||
|
_next_interval = 1,
|
||||||
|
_timer = 0.0,
|
||||||
|
_intervals = {},
|
||||||
|
}, Schedule)
|
||||||
|
end
|
||||||
@ -470,8 +470,37 @@ function __vc_on_hud_open()
|
|||||||
hud.open_permanent("core:ingame_chat")
|
hud.open_permanent("core:ingame_chat")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local ScheduleGroup_mt = {
|
||||||
|
__index = {
|
||||||
|
publish = function(self, schedule)
|
||||||
|
local id = self._next_schedule
|
||||||
|
self._schedules[id] = schedule
|
||||||
|
self._next_schedule = id + 1
|
||||||
|
end,
|
||||||
|
tick = function(self, dt)
|
||||||
|
for id, schedule in pairs(self._schedules) do
|
||||||
|
schedule:tick(dt)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
remove = function(self, id)
|
||||||
|
self._schedules[id] = nil
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local function ScheduleGroup()
|
||||||
|
return setmetatable({
|
||||||
|
_next_schedule = 1,
|
||||||
|
_schedules = {},
|
||||||
|
}, ScheduleGroup_mt)
|
||||||
|
end
|
||||||
|
|
||||||
|
time.schedules = {}
|
||||||
|
|
||||||
local RULES_FILE = "world:rules.toml"
|
local RULES_FILE = "world:rules.toml"
|
||||||
function __vc_on_world_open()
|
function __vc_on_world_open()
|
||||||
|
time.schedules.world = ScheduleGroup()
|
||||||
|
|
||||||
if not file.exists(RULES_FILE) then
|
if not file.exists(RULES_FILE) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -481,6 +510,10 @@ function __vc_on_world_open()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function __vc_on_world_tick(tps)
|
||||||
|
time.schedules.world:tick(1.0 / tps)
|
||||||
|
end
|
||||||
|
|
||||||
function __vc_on_world_save()
|
function __vc_on_world_save()
|
||||||
local rule_values = {}
|
local rule_values = {}
|
||||||
for name, rule in pairs(rules.rules) do
|
for name, rule in pairs(rules.rules) do
|
||||||
|
|||||||
@ -20,6 +20,18 @@ if not ipairs_mt_supported then
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function await(co)
|
||||||
|
local res, err
|
||||||
|
while coroutine.status(co) ~= 'dead' do
|
||||||
|
coroutine.yield()
|
||||||
|
res, err = coroutine.resume(co)
|
||||||
|
if err then
|
||||||
|
return res, err
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return res, err
|
||||||
|
end
|
||||||
|
|
||||||
local _ffi = ffi
|
local _ffi = ffi
|
||||||
function __vc_Canvas_set_data(self, data)
|
function __vc_Canvas_set_data(self, data)
|
||||||
if type(data) == "cdata" then
|
if type(data) == "cdata" then
|
||||||
|
|||||||
@ -127,7 +127,7 @@ void BlocksController::update(float delta, uint padding) {
|
|||||||
onBlocksTick(blocksTickClock.getPart(), blocksTickClock.getParts());
|
onBlocksTick(blocksTickClock.getPart(), blocksTickClock.getParts());
|
||||||
}
|
}
|
||||||
if (worldTickClock.update(delta)) {
|
if (worldTickClock.update(delta)) {
|
||||||
scripting::on_world_tick();
|
scripting::on_world_tick(worldTickClock.getTickRate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -297,8 +297,12 @@ void scripting::on_world_load(LevelController* controller) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void scripting::on_world_tick() {
|
void scripting::on_world_tick(int tps) {
|
||||||
auto L = lua::get_main_state();
|
auto L = lua::get_main_state();
|
||||||
|
if (lua::getglobal(L, "__vc_on_world_tick")) {
|
||||||
|
lua::pushinteger(L, tps);
|
||||||
|
lua::call_nothrow(L, 1, 0);
|
||||||
|
}
|
||||||
for (auto& pack : content_control->getAllContentPacks()) {
|
for (auto& pack : content_control->getAllContentPacks()) {
|
||||||
lua::emit_event(L, pack.id + ":.worldtick");
|
lua::emit_event(L, pack.id + ":.worldtick");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -70,7 +70,7 @@ namespace scripting {
|
|||||||
);
|
);
|
||||||
|
|
||||||
void on_world_load(LevelController* controller);
|
void on_world_load(LevelController* controller);
|
||||||
void on_world_tick();
|
void on_world_tick(int tps);
|
||||||
void on_world_save();
|
void on_world_save();
|
||||||
void on_world_quit();
|
void on_world_quit();
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user