2024-08-21 15:57:40 +00:00
|
|
|
--!native
|
|
|
|
--!optimize 2
|
2024-08-29 13:45:49 +00:00
|
|
|
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
2024-12-26 05:15:41 +00:00
|
|
|
local RunService = game:GetService("RunService")
|
2024-08-29 13:45:49 +00:00
|
|
|
local jabby = require(ReplicatedStorage.Packages.jabby)
|
|
|
|
local jecs = require(ReplicatedStorage.ecs)
|
2024-08-21 15:57:40 +00:00
|
|
|
local pair = jecs.pair
|
2024-09-09 01:22:20 +00:00
|
|
|
local Name = jecs.Name
|
|
|
|
|
2024-08-21 15:57:40 +00:00
|
|
|
type World = jecs.World
|
2024-10-12 20:18:11 +00:00
|
|
|
type Entity<T = nil> = jecs.Entity<T>
|
2024-12-26 05:15:41 +00:00
|
|
|
type Id<T = unknown> = jecs.Id<T>
|
2024-08-21 15:57:40 +00:00
|
|
|
|
|
|
|
type System = {
|
2024-10-12 20:18:11 +00:00
|
|
|
callback: (world: World) -> (),
|
|
|
|
id: number,
|
2024-08-21 15:57:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type Systems = { System }
|
|
|
|
|
|
|
|
type Events = {
|
2024-10-12 20:18:11 +00:00
|
|
|
RenderStepped: Systems,
|
|
|
|
Heartbeat: Systems,
|
2024-08-21 15:57:40 +00:00
|
|
|
}
|
|
|
|
|
2024-12-26 05:15:41 +00:00
|
|
|
local world = require(script.Parent.world)
|
|
|
|
local Disabled = world:entity()
|
|
|
|
local System = world:component() :: Id<{ callback: (any) -> (), name: string}>
|
|
|
|
local DependsOn = world:entity()
|
|
|
|
local Event = world:component() :: Id<RBXScriptSignal>
|
|
|
|
local Phase = world:entity()
|
2024-10-12 20:18:11 +00:00
|
|
|
|
2024-12-26 05:15:41 +00:00
|
|
|
local PreRender = world:entity()
|
|
|
|
local Heartbeat = world:entity()
|
|
|
|
local PreAnimation = world:entity()
|
|
|
|
local PreSimulation = world:entity()
|
2024-10-12 20:18:11 +00:00
|
|
|
|
2024-12-26 05:15:41 +00:00
|
|
|
local sys: System
|
|
|
|
local dt: number
|
2024-10-12 20:18:11 +00:00
|
|
|
|
2024-12-26 05:15:41 +00:00
|
|
|
local jabby_scheduler = jabby.scheduler.create("Scheduler")
|
2024-10-12 20:18:11 +00:00
|
|
|
|
2024-12-26 05:15:41 +00:00
|
|
|
local a, b, c, d
|
|
|
|
local function run()
|
|
|
|
local id = sys.id
|
|
|
|
jabby_scheduler:run(id, sys.callback, a, b, c, d)
|
|
|
|
return nil
|
|
|
|
end
|
2024-10-12 20:18:11 +00:00
|
|
|
|
2024-12-26 05:15:41 +00:00
|
|
|
world:add(Heartbeat, Phase)
|
|
|
|
world:set(Heartbeat, Event, RunService.Heartbeat)
|
2024-08-21 15:57:40 +00:00
|
|
|
|
2024-12-26 05:15:41 +00:00
|
|
|
world:add(PreSimulation, Phase)
|
|
|
|
world:set(PreSimulation, Event, RunService.PreSimulation)
|
2024-08-21 15:57:40 +00:00
|
|
|
|
2024-12-26 05:15:41 +00:00
|
|
|
world:add(PreAnimation, Phase)
|
|
|
|
world:set(PreAnimation, Event, RunService.PreAnimation)
|
2024-10-12 20:18:11 +00:00
|
|
|
|
2025-02-21 01:49:59 +00:00
|
|
|
jabby.register({
|
|
|
|
applet = jabby.applets.world,
|
2024-12-26 05:15:41 +00:00
|
|
|
name = "MyWorld",
|
2025-02-21 01:49:59 +00:00
|
|
|
configuration = {
|
2024-12-26 05:15:41 +00:00
|
|
|
world = world,
|
2025-02-21 01:49:59 +00:00
|
|
|
},
|
2024-12-26 05:15:41 +00:00
|
|
|
})
|
2024-10-12 20:18:11 +00:00
|
|
|
|
2025-02-21 01:49:59 +00:00
|
|
|
jabby.register({
|
|
|
|
applet = jabby.applets.scheduler,
|
|
|
|
name = "Scheduler",
|
|
|
|
configuration = {
|
|
|
|
scheduler = jabby_scheduler,
|
|
|
|
},
|
|
|
|
})
|
2024-10-12 20:18:11 +00:00
|
|
|
|
2024-12-26 05:15:41 +00:00
|
|
|
if RunService:IsClient() then
|
|
|
|
world:add(PreRender, Phase)
|
|
|
|
world:set(PreRender, Event, (RunService :: RunService).PreRender)
|
|
|
|
end
|
2024-10-12 20:18:11 +00:00
|
|
|
|
2024-12-26 05:15:41 +00:00
|
|
|
local function begin(events: { [RBXScriptSignal]: Systems })
|
|
|
|
local connections = {}
|
|
|
|
for event, systems in events do
|
|
|
|
if not event then
|
|
|
|
continue
|
2024-10-12 20:18:11 +00:00
|
|
|
end
|
2024-12-26 05:15:41 +00:00
|
|
|
local event_name = tostring(event)
|
|
|
|
connections[event] = event:Connect(function(...)
|
|
|
|
debug.profilebegin(event_name)
|
|
|
|
for _, s in systems do
|
|
|
|
sys = s
|
|
|
|
a, b, c, d = ...
|
|
|
|
|
|
|
|
for _ in run do
|
|
|
|
break
|
|
|
|
end
|
2024-10-12 20:18:11 +00:00
|
|
|
|
2024-12-26 05:15:41 +00:00
|
|
|
end
|
|
|
|
debug.profileend()
|
|
|
|
end)
|
2024-10-12 20:18:11 +00:00
|
|
|
end
|
2024-12-26 05:15:41 +00:00
|
|
|
return connections
|
|
|
|
end
|
2024-10-12 20:18:11 +00:00
|
|
|
|
2024-12-26 05:15:41 +00:00
|
|
|
local function scheduler_collect_systems_under_phase_recursive(systems, phase: Entity)
|
|
|
|
local phase_name = world:get(phase, Name)
|
|
|
|
for _, s in world:query(System):with(pair(DependsOn, phase)) do
|
|
|
|
table.insert(systems, {
|
|
|
|
id = jabby_scheduler:register_system({
|
|
|
|
name = s.name,
|
|
|
|
phase = phase_name,
|
|
|
|
} :: any),
|
|
|
|
callback = s.callback,
|
|
|
|
})
|
|
|
|
end
|
|
|
|
for after in world:query(Phase):with(pair(DependsOn, phase)):iter() do
|
|
|
|
scheduler_collect_systems_under_phase_recursive(systems, after)
|
2024-10-12 20:18:11 +00:00
|
|
|
end
|
2024-12-26 05:15:41 +00:00
|
|
|
end
|
2024-10-12 20:18:11 +00:00
|
|
|
|
2024-12-26 05:15:41 +00:00
|
|
|
local function scheduler_collect_systems_under_event(event)
|
|
|
|
local systems = {}
|
|
|
|
scheduler_collect_systems_under_phase_recursive(systems, event)
|
|
|
|
return systems
|
|
|
|
end
|
|
|
|
|
|
|
|
local function scheduler_collect_systems_all()
|
|
|
|
local events = {}
|
|
|
|
for phase, event in world:query(Event):with(Phase) do
|
|
|
|
events[event] = scheduler_collect_systems_under_event(phase)
|
2024-10-12 20:18:11 +00:00
|
|
|
end
|
2024-12-26 05:15:41 +00:00
|
|
|
return events
|
|
|
|
end
|
2024-10-12 20:18:11 +00:00
|
|
|
|
2024-12-26 05:15:41 +00:00
|
|
|
local function scheduler_phase_new(d: { after: Entity?, event: RBXScriptSignal? })
|
|
|
|
local phase = world:entity()
|
|
|
|
world:add(phase, Phase)
|
|
|
|
local after = d.after
|
|
|
|
if after then
|
|
|
|
local dependency = pair(DependsOn, after :: Entity)
|
2024-10-12 20:18:11 +00:00
|
|
|
world:add(phase, dependency)
|
|
|
|
end
|
2024-12-26 05:15:41 +00:00
|
|
|
|
|
|
|
local event = d.event
|
|
|
|
if event then
|
|
|
|
world:set(phase, Event, event)
|
2024-10-12 20:18:11 +00:00
|
|
|
end
|
2024-12-26 05:15:41 +00:00
|
|
|
return phase
|
|
|
|
end
|
2024-10-12 20:18:11 +00:00
|
|
|
|
2024-12-26 05:15:41 +00:00
|
|
|
local function scheduler_systems_new(callback: (any) -> (), phase: Entity?)
|
|
|
|
local system = world:entity()
|
|
|
|
world:set(system, System, { callback = callback, name = debug.info(callback, "n") })
|
|
|
|
local depends_on = DependsOn :: jecs.Entity
|
|
|
|
local p: Entity = phase or Heartbeat
|
|
|
|
world:add(system, pair(depends_on, p))
|
|
|
|
|
|
|
|
return system
|
2024-08-07 16:45:56 +00:00
|
|
|
end
|
|
|
|
|
2024-08-21 15:57:40 +00:00
|
|
|
return {
|
2024-12-26 05:15:41 +00:00
|
|
|
SYSTEM = scheduler_systems_new,
|
|
|
|
BEGIN = begin,
|
|
|
|
PHASE = scheduler_phase_new,
|
|
|
|
COLLECT = scheduler_collect_systems_all,
|
|
|
|
phases = {
|
|
|
|
Heartbeat = Heartbeat,
|
|
|
|
PreSimulation = PreSimulation,
|
|
|
|
PreAnimation = PreAnimation,
|
|
|
|
PreRender = PreRender
|
|
|
|
}
|
2024-08-21 15:57:40 +00:00
|
|
|
}
|