diff --git a/mods/CORE/vl_scheduler/init.lua b/mods/CORE/vl_scheduler/init.lua index 8a5989ddc..47b006f68 100644 --- a/mods/CORE/vl_scheduler/init.lua +++ b/mods/CORE/vl_scheduler/init.lua @@ -220,20 +220,34 @@ local function queue_task(when, priority, task) end vl_scheduler.queue_task = queue_task +local task_metatable = { + __index = { + cancel = function(self) + self.real_func = function() end + end, + func = function(self) + self.real_func(unpack(self.args)) + end, + } +} + local function vl_scheduler_after(time, priority, func, ...) local task = new_task() task.args = {...} task.next = nil task.real_func = func - task.func = function(task) task.real_func(unpack(task.args)) end + setmetatable(task, task_metatable) local timesteps = math.round(time / 0.05) queue_task(timesteps, priority, task) + + -- Return a job handle that can cancel + return task end vl_scheduler.after = vl_scheduler_after -- Hijack core.after and redirect to this scheduler function core.after(time, func, ...) - vl_scheduler_after(time, 2, func, ...) + return vl_scheduler_after(time, 2, func, ...) end return vl_scheduler diff --git a/mods/CORE/vl_scheduler/unit-test.lua b/mods/CORE/vl_scheduler/unit-test.lua index 873b306b4..332aa7b4a 100644 --- a/mods/CORE/vl_scheduler/unit-test.lua +++ b/mods/CORE/vl_scheduler/unit-test.lua @@ -201,5 +201,18 @@ describe('vl_scheduler',function() call_globalstep(0.05) end) end) + it('can provide cancellable jobs from core.after()',function() + local after = _G.core.after + local ran = false + local job = after(1,function() + ran = true + end) + call_globalstep(0.5) + assert.no_error(function() + job:cancel() + end) + for i = 1,10 do call_globalstep(0.5) end + assert.is_false(ran) + end) end)