Add Task.wait to combine multiple tasks into one
Add TestRunner for running asynchronous tests with update support Add test for Task.wait to verify concurrent task completion Add set method to Counter for explicit value assignment
This commit is contained in:
parent
e02c221e31
commit
403ba5a03f
@ -4,6 +4,7 @@
|
||||
--- @field private isAlive boolean
|
||||
--- @field push fun():nil добавить 1 к счетчику
|
||||
--- @field pop fun():nil убавить 1 у счетчика
|
||||
--- @field set fun(count: integer): nil установить значение на счетчике
|
||||
local counter = {}
|
||||
counter.__index = counter
|
||||
|
||||
@ -31,6 +32,7 @@ local function new(onFinish)
|
||||
}
|
||||
t.push = function() counter._push(t) end
|
||||
t.pop = function() counter._pop(t) end
|
||||
t.set = function(count) t.count = count end
|
||||
|
||||
return setmetatable(t, counter)
|
||||
end
|
||||
|
||||
@ -34,3 +34,33 @@
|
||||
--- ```
|
||||
--- @generic T
|
||||
--- @alias Task<T> fun(callback: fun(value: T): nil): nil
|
||||
|
||||
--- Возвращает новый Task, который завершится после завершения всех переданных `tasks`.
|
||||
---
|
||||
--- Значение созданного Task будет содержать список значений `tasks` в том же порядке.
|
||||
---
|
||||
--- См. также https://api.dart.dev/dart-async/Future/wait.html
|
||||
--- @generic T
|
||||
--- @param tasks Task[]
|
||||
--- @return Task<T[]>
|
||||
local function wait(tasks)
|
||||
local count = #tasks
|
||||
local results = {}
|
||||
|
||||
return function(callback)
|
||||
for i, task in ipairs(tasks) do
|
||||
task(
|
||||
function(result)
|
||||
results[i] = result
|
||||
|
||||
count = count - 1
|
||||
if count == 0 then callback(results) end
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
wait = wait,
|
||||
}
|
||||
|
||||
4
main.lua
4
main.lua
@ -2,6 +2,8 @@
|
||||
|
||||
local character = require "lib/character/character"
|
||||
local testLayout
|
||||
local TestRunner = require "test.runner"
|
||||
TestRunner:register(require "test.task")
|
||||
|
||||
function love.conf(t)
|
||||
t.console = true
|
||||
@ -67,6 +69,8 @@ end
|
||||
|
||||
local lt = "0"
|
||||
function love.update(dt)
|
||||
TestRunner:update(dt) -- закомментировать для отключения тестов
|
||||
|
||||
local t1 = love.timer.getTime()
|
||||
Tree.controls:poll()
|
||||
Tree.level.camera:update(dt) -- сначала логика камеры, потому что на нее завязан UI
|
||||
|
||||
46
test/runner.lua
Normal file
46
test/runner.lua
Normal file
@ -0,0 +1,46 @@
|
||||
--- @class Test
|
||||
local test = {}
|
||||
function test:run(complete) end
|
||||
|
||||
function test:update(dt) end
|
||||
|
||||
--- @class TestRunner
|
||||
--- @field private tests Test[]
|
||||
--- @field private state "loading" | "running" | "completed"
|
||||
--- @field private completedCount integer
|
||||
local runner = {}
|
||||
runner.tests = {}
|
||||
runner.state = "loading"
|
||||
runner.completedCount = 0
|
||||
|
||||
--- глобальный update для тестов, нужен для тестирования фич, зависимых от времени
|
||||
function runner:update(dt)
|
||||
if self.state == "loading" then
|
||||
print("[TestRunner]: running " .. #self.tests .. " tests")
|
||||
|
||||
for _, t in ipairs(self.tests) do
|
||||
t:run(
|
||||
function()
|
||||
self.completedCount = self.completedCount + 1
|
||||
if self.completedCount == #self.tests then
|
||||
self.state = "completed"
|
||||
print("[TestRunner]: tests completed")
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
self.state = "running"
|
||||
end
|
||||
|
||||
for _, t in ipairs(self.tests) do
|
||||
if t.update then t:update(dt) end
|
||||
end
|
||||
end
|
||||
|
||||
--- добавляет тест для прохождения
|
||||
--- @param t Test
|
||||
function runner:register(t)
|
||||
table.insert(self.tests, t)
|
||||
end
|
||||
|
||||
return runner
|
||||
61
test/task.lua
Normal file
61
test/task.lua
Normal file
@ -0,0 +1,61 @@
|
||||
local task = require "lib.utils.task"
|
||||
|
||||
local test = {}
|
||||
|
||||
local t0
|
||||
local task1Start, task2Start
|
||||
local task1Callback, task2Callback
|
||||
|
||||
--- @return Task<number>
|
||||
local function task1()
|
||||
return function(callback)
|
||||
task1Start = love.timer.getTime()
|
||||
task1Callback = callback
|
||||
end
|
||||
end
|
||||
|
||||
--- @return Task<number>
|
||||
local function task2()
|
||||
return function(callback)
|
||||
task2Start = love.timer.getTime()
|
||||
task2Callback = callback
|
||||
end
|
||||
end
|
||||
|
||||
function test:run(complete)
|
||||
t0 = love.timer.getTime()
|
||||
|
||||
task.wait {
|
||||
task1(),
|
||||
task2()
|
||||
} (function(values)
|
||||
local tWait = love.timer.getTime()
|
||||
local dt = tWait - t0
|
||||
|
||||
local t1 = values[1]
|
||||
local t2 = values[2]
|
||||
|
||||
assert(type(t1) == "number" and type(t2) == "number")
|
||||
assert(t2 > t1)
|
||||
assert(dt >= 2, "dt = " .. dt)
|
||||
|
||||
print("task.wait completed in " .. dt .. " sec", "t1 = " .. t1 - t0, "t2 = " .. t2 - t0)
|
||||
|
||||
complete()
|
||||
end)
|
||||
end
|
||||
|
||||
function test:update(dt)
|
||||
local t = love.timer.getTime()
|
||||
if task1Start and t - task1Start >= 1 then
|
||||
task1Callback(t)
|
||||
task1Start = nil
|
||||
end
|
||||
|
||||
if task2Start and t - task2Start >= 2 then
|
||||
task2Callback(t)
|
||||
task2Start = nil
|
||||
end
|
||||
end
|
||||
|
||||
return test
|
||||
Loading…
x
Reference in New Issue
Block a user