Update scheduler

This commit is contained in:
Ukendio 2024-08-27 21:27:26 +02:00
parent dcfa34df4e
commit 8d83bd6322

View file

@ -6,7 +6,10 @@ type World = jecs.World
type Entity<T=nil> = jecs.Entity<T> type Entity<T=nil> = jecs.Entity<T>
type System = { type System = {
callback: (world: World) -> () callback: (world: World) -> (),
name: string,
rate: number?,
interval: number?
} }
type Systems = { System } type Systems = { System }
@ -31,7 +34,7 @@ export type Scheduler = {
}, },
systems: { systems: {
begin: (events: Events) -> (), begin: (events: Events) -> { [Entity]: thread },
new: (callback: (dt: number) -> (), phase: Entity) -> Entity new: (callback: (dt: number) -> (), phase: Entity) -> Entity
}, },
@ -59,7 +62,7 @@ do
local PreAnimation local PreAnimation
local PreSimulation local PreSimulation
local system local system: System
local dt local dt
local function run() local function run()
debug.profilebegin(system.name) debug.profilebegin(system.name)
@ -70,44 +73,46 @@ do
-- We don't want to interrupt the loop when we error -- We don't want to interrupt the loop when we error
task.spawn(error, str) task.spawn(error, str)
end end
local function begin(events) local function begin(events: { Systems })
local connections = {} local threads = {}
for event, systems in events do for event, systems in events do
if not event then continue end if not event then continue end
local event_name = tostring(event) local event_name = tostring(event)
connections[event] = event:Connect(function(last) threads[event] = task.spawn(function()
debug.profilebegin(event_name) while true do
for _, sys in systems do dt = event:Wait()
system = sys
dt = last
local didNotYield, why = xpcall(function() debug.profilebegin(event_name)
for _ in run do end for _, sys in systems do
end, debug.traceback) system = sys
if didNotYield then local didNotYield, why = xpcall(function()
continue for _ in run do end
end end, debug.traceback)
if string.find(why, "thread is not yieldable") then if didNotYield then
panic("Not allowed to yield in the systems.") continue
else end
panic(why)
end if string.find(why, "thread is not yieldable") then
panic("Not allowed to yield in the systems.")
else
panic(why)
end
end
debug.profileend()
end end
debug.profileend()
end) end)
end end
return connections return threads
end end
local function scheduler_collect_systems_under_phase_recursive(systems, phase) local function scheduler_collect_systems_under_phase_recursive(systems, phase)
for _, system in world:query(System):with(pair(DependsOn, phase)) do for _, system in world:query(System):with(pair(DependsOn, phase)) do
table.insert(systems, system) table.insert(systems, system)
end end
for dependant in world:query(Phase):with(pair(DependsOn, phase)) do for after in world:query(Phase):with(pair(DependsOn, phase)) do
scheduler_collect_systems_under_phase_recursive(systems, dependant) scheduler_collect_systems_under_phase_recursive(systems, after)
end end
end end