diff --git a/demo.rbxl b/demo.rbxl index b0961d8..d768ff4 100644 Binary files a/demo.rbxl and b/demo.rbxl differ diff --git a/demo/src/ReplicatedStorage/std/changetracker.luau b/demo/src/ReplicatedStorage/std/changetracker.luau index bd5051a..d6cfe58 100644 --- a/demo/src/ReplicatedStorage/std/changetracker.luau +++ b/demo/src/ReplicatedStorage/std/changetracker.luau @@ -1,8 +1,5 @@ local jecs = require(game:GetService("ReplicatedStorage").ecs) - -local world = require(script.Parent.world) -local sparse = ((world :: any) :: jecs.World).entityIndex.sparse -type World = world.World +type World = jecs.World type Tracker = { track: (world: World, fn: (changes: { added: () -> () -> (number, T), @@ -32,7 +29,8 @@ local function diff(a, b) return false end -local function ChangeTracker(T: Entity): Tracker +local function ChangeTracker(world: World, T: Entity): Tracker + local sparse = world.entityIndex.sparse local PreviousT = jecs.pair(jecs.Rest, T) local add = {} local added diff --git a/demo/src/ReplicatedStorage/std/init.luau b/demo/src/ReplicatedStorage/std/init.luau index ae777b4..54734fc 100644 --- a/demo/src/ReplicatedStorage/std/init.luau +++ b/demo/src/ReplicatedStorage/std/init.luau @@ -3,12 +3,9 @@ local jecs = require(game:GetService("ReplicatedStorage").ecs) local world = require(script.world) :: jecs.World export type World = jecs.World -local scheduler = require(script.scheduler) -export type Scheduler = scheduler.Scheduler - local std = { ChangeTracker = require(script.changetracker), - Scheduler = scheduler.new(world), + Scheduler = require(script.scheduler), bt = require(script.bt), collect = require(script.collect), components = require(script.components), @@ -19,6 +16,7 @@ local std = { world = world :: World, pair = jecs.pair, __ = jecs.w, + start = require(script.start) } return std diff --git a/demo/src/ReplicatedStorage/std/scheduler.luau b/demo/src/ReplicatedStorage/std/scheduler.luau index 22274c6..fa6054d 100644 --- a/demo/src/ReplicatedStorage/std/scheduler.luau +++ b/demo/src/ReplicatedStorage/std/scheduler.luau @@ -10,9 +10,7 @@ type Entity = jecs.Entity type System = { callback: (world: World) -> (), - name: string, - rate: number?, - interval: number? + id: number, } type Systems = { System } @@ -71,9 +69,14 @@ do local system: System local dt local function run() - debug.profilebegin(system.name) + local id = system.id + local system_data = scheduler.system_data[id] + if system_data.paused then return end + + scheduler:mark_system_frame_start(id) system.callback(dt) - debug.profileend() + scheduler:mark_system_frame_end(id) + end local function panic(str) -- We don't want to interrupt the loop when we error @@ -90,7 +93,25 @@ do debug.profilebegin(event_name) for _, sys in systems do - scheduler:run(sys.id, sys.system, dt) + system = sys + local didNotYield, why = xpcall(function() + for _ in run do end + end, debug.traceback) + + if didNotYield then + continue + end + + if string.find(why, "thread is not yieldable") then + panic("Not allowed to yield in the systems." + .. "\n" + .. "System: " + .. debug.info(system.callback, "n") + .. " has been ejected" + ) + continue + end + panic(why) end debug.profileend() end @@ -107,7 +128,7 @@ do name = system.name, phase = phase_name }), - system = system.callback + callback = system.callback }) end for after in world:query(Phase):with(pair(DependsOn, phase)) do @@ -166,7 +187,6 @@ do end world:add(Heartbeat, Phase) - world:set(Heartbeat, Name) world:set(Heartbeat, Event, RunService.Heartbeat) world:add(PreSimulation, Phase) @@ -174,20 +194,20 @@ do world:add(PreAnimation, Phase) world:set(PreAnimation, Event, RunService.PreAnimation) + for name, component in components do + world:set(component, Name, name) + end - jabby.public.updated = true table.insert(jabby.public, { class_name = "World", name = "MyWorld", world = world, debug = Name, entities = {} - }) - for name, component in components do - world:set(component, Name, name) - print(Name, name) - end + } ) + + jabby.public.updated = true scheduler = jabby.scheduler.create("scheduler") table.insert(jabby.public, scheduler) diff --git a/demo/src/ReplicatedStorage/std/start.luau b/demo/src/ReplicatedStorage/std/start.luau new file mode 100644 index 0000000..192d9c4 --- /dev/null +++ b/demo/src/ReplicatedStorage/std/start.luau @@ -0,0 +1,31 @@ +local RunService = game:GetService("RunService") +local UserInputService = game:GetService("UserInputService") +local ReplicatedStorage = game:GetService("ReplicatedStorage") +local jabby = require(ReplicatedStorage.Packages.jabby) +local Scheduler = require(ReplicatedStorage.std.scheduler) +local world = require(ReplicatedStorage.std.world) + +local function start(modules) + local scheduler = Scheduler.new(world) + for _, module in modules do + require(module)(scheduler) + end + local events = scheduler.collect.all() + scheduler.systems.begin(events) + if RunService:IsClient() then + local client = jabby.obtain_client() + local player = game:GetService("Players").LocalPlayer + local apps = player:WaitForChild("PlayerGui") + local dtor + UserInputService.InputBegan:Connect(function(input) + if input.KeyCode == Enum.KeyCode.F4 then + if dtor then + dtor() + end + dtor = client.spawn_app(client.apps.home) + end + end ) + end +end + +return start diff --git a/demo/src/ServerScriptService/main.server.luau b/demo/src/ServerScriptService/main.server.luau index be9fa9c..409f8ab 100644 --- a/demo/src/ServerScriptService/main.server.luau +++ b/demo/src/ServerScriptService/main.server.luau @@ -1,11 +1,4 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage") -local std = require(ReplicatedStorage.std) -local components = std.components -local world = std.world +local start = require(ReplicatedStorage.std.start) -local scheduler = std.Scheduler -for _, module in script.Parent.systems:GetChildren() do - require(module)(scheduler) -end -local events = scheduler.collect.all() -scheduler.systems.begin(events) +start(script.Parent:WaitForChild("systems"):GetChildren()) diff --git a/demo/src/StarterPlayer/StarterPlayerScripts/main.client.luau b/demo/src/StarterPlayer/StarterPlayerScripts/main.client.luau index b3212ae..409f8ab 100644 --- a/demo/src/StarterPlayer/StarterPlayerScripts/main.client.luau +++ b/demo/src/StarterPlayer/StarterPlayerScripts/main.client.luau @@ -1,12 +1,4 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage") -local std = require(ReplicatedStorage.std) -local scheduler = std.Scheduler -for _, module in script.Parent:WaitForChild("systems"):GetChildren() do - require(module)(scheduler) -end -local events = scheduler.collect.all() +local start = require(ReplicatedStorage.std.start) -scheduler.systems.begin(events) -local jabby = require(ReplicatedStorage.Packages.jabby) -local client = jabby.obtain_client() -client.spawn_app(client.apps.home) +start(script.Parent:WaitForChild("systems"):GetChildren())