jecs/modules/Jabby/server/watch.luau

129 lines
2.9 KiB
Text
Raw Normal View History

2026-02-18 00:29:34 +00:00
local types = require(script.Parent.Parent.modules.types)
local world_hook = require(script.Parent.world_hook)
local NIL = newproxy()
type ChangeTypes = "remove" | "clear" | "delete" | "add" | "set" | "entity" | "component"
type Changes = types.WatchLoggedChanges
export type SystemWatch = {
--- enables Lua Object Notation.
--- incurs a significant performance penalty.
enable_lon: boolean,
--- the current frame to process
frame: number,
frames: {[number]: Changes}
}
local function create_changes()
return {
types = {},
entities = {},
component = {},
values = {},
worlds = {}
}
end
local function step_watch(watch: SystemWatch)
watch.frame += 1
watch.frames[watch.frame] = create_changes()
end
local function track_watch(watch: SystemWatch)
local hooks = {
world_hook.hook_onto("remove", function(self, id, component)
local frame = watch.frames[watch.frame]
table.insert(frame.types, "remove")
table.insert(frame.entities, id)
table.insert(frame.component, component)
table.insert(frame.values, NIL)
table.insert(frame.worlds, self)
end),
world_hook.hook_onto("clear", function(self, id)
local frame = watch.frames[watch.frame]
table.insert(frame.types, "clear")
table.insert(frame.entities, id)
table.insert(frame.component, NIL)
table.insert(frame.values, NIL)
table.insert(frame.worlds, self)
end),
world_hook.hook_onto("delete", function(self, id)
local frame = watch.frames[watch.frame]
table.insert(frame.types, "delete")
table.insert(frame.entities, id)
table.insert(frame.component, NIL)
table.insert(frame.values, NIL)
table.insert(frame.worlds, self)
end),
world_hook.hook_onto("add", function(self, id, component)
local frame = watch.frames[watch.frame]
table.insert(frame.types, "add")
table.insert(frame.entities, id)
table.insert(frame.component, component)
table.insert(frame.values, NIL)
table.insert(frame.worlds, self)
end),
world_hook.hook_onto("set", function(self, entity, component, value)
if self:has(entity, component) then
local frame = watch.frames[watch.frame]
table.insert(frame.types, "change")
table.insert(frame.entities, entity)
table.insert(frame.component, component)
table.insert(frame.values, value)
table.insert(frame.worlds, self)
else
local frame = watch.frames[watch.frame]
table.insert(frame.types, "move")
table.insert(frame.entities, entity)
table.insert(frame.component, component)
table.insert(frame.values, value)
table.insert(frame.worlds, self)
end
end)
}
--- stops all hooks
local function stop_hook()
for _, destroy in hooks do
destroy()
end
end
return stop_hook
end
local function create_watch()
local watch: SystemWatch = {
enable_lon = false,
frame = 0,
frames = {}
}
return watch
end
return {
create_watch = create_watch,
track_watch = track_watch,
step_watch = step_watch,
NIL = NIL
}