This repository was archived by the owner on Aug 14, 2026. It is now read-only.
forked from TeJota1337/DramaticShapeVoxelMod
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBuildBudget.lua
More file actions
68 lines (59 loc) · 2.34 KB
/
Copy pathBuildBudget.lua
File metadata and controls
68 lines (59 loc) · 2.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
-- Voxel world mode: the cooperative build budget.
--
-- Mesh building runs inside a plain coroutine that ChunkMesher pumps for
-- a few milliseconds a frame (there is no worker thread: LOVE's graphics
-- objects are main-thread only, and the build is pure Lua that slices
-- cleanly). The long loops in Structures and ChunkMesher call tick() as
-- they go; when the frame's slice is spent, tick() suspends the build
-- coroutine and the frame carries on rendering whatever is already
-- cached.
--
-- tick() is deliberately safe to call from ANY context: outside the pump
-- (headless tests, the pure geometry API, a driver poking a build
-- function directly) it recognises it is not inside the build coroutine
-- and does nothing, so synchronous callers keep their synchronous
-- behavior.
local B = { n = 0 }
local clock = (love and love.timer and love.timer.getTime) or os.clock
local deadline = math.huge
local buildCo = nil
local checkEvery = 32
-- Enter/leave a pumped slice. `co` is the coroutine being resumed, so
-- tick() can tell the build apart from any other coroutine the engine
-- happens to be running (drivers are coroutines too).
function B.begin(co, seconds)
buildCo = co
deadline = clock() + seconds
-- Visible NORMAL/SMOOTH/MIN slices are all at most 12 ms. Their deadline
-- has to be strict: one Structures iteration can take several milliseconds,
-- so batching 32 checks let a nominal 5-ms neighbour slice run for 100+ ms.
-- Covered/loading slices are deliberately wide and may keep the cheaper
-- sampled clock check.
checkEvery = seconds <= 0.015 and 1 or 32
end
function B.finish()
buildCo = nil
deadline = math.huge
checkEvery = 32
end
function B.expired()
return clock() > deadline
end
-- Visible streaming checks every call; hidden loading work checks every 32nd.
function B.tick()
local n = B.n + 1
B.n = n
if checkEvery > 1 and n % checkEvery ~= 0 then return end
if buildCo and coroutine.running() == buildCo and clock() > deadline then
coroutine.yield("budget")
end
end
-- Like tick() but consults the clock every call -- for coarse loops
-- whose single iteration already costs milliseconds (mesh upload
-- slices), where tick()'s 1-in-32 sampling would never fire.
function B.check()
if buildCo and coroutine.running() == buildCo and clock() > deadline then
coroutine.yield("budget")
end
end
return B