mirror of
https://github.com/luanti-org/luanti.git
synced 2025-08-01 17:38:41 +00:00
Reduce minetest.after
time complexity and provide ordering guarantee
--------- Co-authored-by: Lars Mueller <appgurulars@gmx.de>
This commit is contained in:
parent
ceaa7e2fb0
commit
e7dd9737bd
5 changed files with 280 additions and 33 deletions
113
builtin/common/tests/after_spec.lua
Normal file
113
builtin/common/tests/after_spec.lua
Normal file
|
@ -0,0 +1,113 @@
|
|||
_G.core = {}
|
||||
_G.vector = {metatable = {}}
|
||||
|
||||
dofile("builtin/common/vector.lua")
|
||||
dofile("builtin/common/misc_helpers.lua")
|
||||
|
||||
function core.get_last_run_mod() return "*test*" end
|
||||
function core.set_last_run_mod() end
|
||||
|
||||
local do_step
|
||||
function core.register_globalstep(func)
|
||||
do_step = func
|
||||
end
|
||||
|
||||
dofile("builtin/common/after.lua")
|
||||
|
||||
describe("after", function()
|
||||
it("executes callbacks when expected", function()
|
||||
local result = ""
|
||||
core.after(0, function()
|
||||
result = result .. "a"
|
||||
end)
|
||||
core.after(1, function()
|
||||
result = result .. "b"
|
||||
end)
|
||||
core.after(1, function()
|
||||
result = result .. "c"
|
||||
end)
|
||||
core.after(2, function()
|
||||
result = result .. "d"
|
||||
end)
|
||||
local cancel = core.after(2, function()
|
||||
result = result .. "e"
|
||||
end)
|
||||
do_step(0)
|
||||
assert.same("a", result)
|
||||
|
||||
do_step(1)
|
||||
assert.same("abc", result)
|
||||
|
||||
core.after(2, function()
|
||||
result = result .. "f"
|
||||
end)
|
||||
core.after(1, function()
|
||||
result = result .. "g"
|
||||
end)
|
||||
core.after(-1, function()
|
||||
result = result .. "h"
|
||||
end)
|
||||
cancel:cancel()
|
||||
do_step(1)
|
||||
assert.same("abchdg", result)
|
||||
|
||||
do_step(1)
|
||||
assert.same("abchdgf", result)
|
||||
end)
|
||||
|
||||
it("defers jobs with delay 0", function()
|
||||
local result = ""
|
||||
core.after(0, function()
|
||||
core.after(0, function()
|
||||
result = result .. "b"
|
||||
end)
|
||||
result = result .. "a"
|
||||
end)
|
||||
do_step(1)
|
||||
assert.same("a", result)
|
||||
do_step(1)
|
||||
assert.same("ab", result)
|
||||
end)
|
||||
|
||||
it("passes arguments", function()
|
||||
core.after(0, function(...)
|
||||
assert.same(0, select("#", ...))
|
||||
end)
|
||||
core.after(0, function(...)
|
||||
assert.same(4, select("#", ...))
|
||||
assert.same(1, (select(1, ...)))
|
||||
assert.same(nil, (select(2, ...)))
|
||||
assert.same("a", (select(3, ...)))
|
||||
assert.same(nil, (select(4, ...)))
|
||||
end, 1, nil, "a", nil)
|
||||
do_step(0)
|
||||
end)
|
||||
|
||||
it("rejects invalid arguments", function()
|
||||
assert.has.errors(function() core.after() end)
|
||||
assert.has.errors(function() core.after(nil, nil) end)
|
||||
assert.has.errors(function() core.after(0) end)
|
||||
assert.has.errors(function() core.after(0, nil) end)
|
||||
assert.has.errors(function() core.after(nil, function() end) end)
|
||||
assert.has.errors(function() core.after(0 / 0, function() end) end)
|
||||
end)
|
||||
|
||||
-- Make sure that the underlying heap is working correctly
|
||||
it("can be abused as a heapsort", function()
|
||||
local t = {}
|
||||
for i = 1, 1000 do
|
||||
t[i] = math.random(100)
|
||||
end
|
||||
local sorted = table.copy(t)
|
||||
table.sort(sorted)
|
||||
local i = 0
|
||||
for _, v in ipairs(t) do
|
||||
core.after(v, function()
|
||||
i = i + 1
|
||||
assert.equal(v, sorted[i])
|
||||
end)
|
||||
end
|
||||
do_step(math.max(unpack(t)))
|
||||
assert.equal(#t, i)
|
||||
end)
|
||||
end)
|
Loading…
Add table
Add a link
Reference in a new issue