From 0e4f40ced7cfc671abe7ca9b22689bd449b1ee9f Mon Sep 17 00:00:00 2001 From: Ukendio Date: Wed, 12 Mar 2025 17:12:25 +0100 Subject: [PATCH] Improved emit for devtools --- test/devtools_test.luau | 8 ++-- tools/entity_visualiser.luau | 7 --- tools/lifetime_tracker.luau | 83 +++++++++++++++++++++++++++--------- 3 files changed, 68 insertions(+), 30 deletions(-) diff --git a/test/devtools_test.luau b/test/devtools_test.luau index 90edb98..a0f4745 100644 --- a/test/devtools_test.luau +++ b/test/devtools_test.luau @@ -4,15 +4,15 @@ local ChildOf = jecs.ChildOf local lifetime_tracker_add = require("@tools/lifetime_tracker") local world = lifetime_tracker_add(jecs.world()) world:print_snapshot() -local e = world:entity() local e1 = world:entity() -world:delete(e) +local e2 = world:entity() +world:delete(e2) world:print_snapshot() -local e2 = world:entity() -world:add(e2, pair(ChildOf, e1)) local e3 = world:entity() world:add(e3, pair(ChildOf, e1)) +local e4 = world:entity() +world:add(e4, pair(ChildOf, e4)) world:print_snapshot() world:delete(e1) world:delete(e2) diff --git a/tools/entity_visualiser.luau b/tools/entity_visualiser.luau index 3797c33..081caad 100644 --- a/tools/entity_visualiser.luau +++ b/tools/entity_visualiser.luau @@ -37,13 +37,6 @@ local function components(world: jecs.World, entity: any) return true end -local world = jecs.world() -local A = world:component() -world:set(A, jecs.Name, "A") -local e = world:entity() -world:set(e, A, true) -components(world, e) - return { components = components, prettify = pe diff --git a/tools/lifetime_tracker.luau b/tools/lifetime_tracker.luau index 567949e..a1f2b62 100644 --- a/tools/lifetime_tracker.luau +++ b/tools/lifetime_tracker.luau @@ -5,6 +5,7 @@ local __ = jecs.Wildcard local pair = jecs.pair local pe = require("@tools/entity_visualiser").prettify +local ansi = require("@tools/ansi") function print_centered_entity(entity, width: number) local entity_str = tostring(entity) @@ -20,37 +21,29 @@ function print_centered_entity(entity, width: number) print("|" .. centered_str .. "|") end +local function name(world, e) + return world:get(world, e, jecs.Name) or pe(e) +end + local function lifetime_tracker_add(world: jecs.World) local entity_index = world.entity_index local dense_array = entity_index.dense_array - local world_delete = world.delete - local world_entity = world.entity local component_index = world.component_index local ENTITY_RANGE = (jecs.Rest :: any) + 1 local w = setmetatable({}, { __index = world }) - w.delete = function(self, e) - print(`*deleting {pe(e)}`) - local idr_t = component_index[pair(__, e)] - if idr_t then - print(`{pe(e)} has the following dependencies:`) - for archetype_id in idr_t.cache do - local archetype = world.archetypes[archetype_id] - local entities = {} - for _, dependency in archetype.entities do - print(` {pe(dependency)}`) - end - end - end - world_delete(world, e) - print(`*deleted {pe(e)}`) - end + local world_entity = world.entity w.entity = function(self) + local will_recycle = entity_index.max_id ~= entity_index.alive_count local e = world_entity(world) - print(`*created {pe(e)}`) + if will_recycle then + print(`*recycled {pe(e)}`) + else + print(`*created {pe(e)}`) + end return e end w.print_entity_index = function(self) @@ -151,6 +144,58 @@ local function lifetime_tracker_add(world: jecs.World) end print("-------------------------------------------------------------------") end + local world_add = world.add + local relations = {} + w.add = function(self, entity: any, component: any) + world_add(world, entity, component) + if jecs.IS_PAIR(component) then + local relation = jecs.pair_first(world, component) + local target = jecs.pair_second(world, component) + print(`*added ({pe(relation)}, {pe(target)}) to {pe(entity)}`) + local rs = relations[relation] + if not rs then + local flags = component_index[component].flags + rs = { + fragmenting = bit32.band(flags, 0b0000_0010) ~= 0 + } + relations[relation] = rs + end + local ts = rs[target] + if not ts then + ts = {} + rs[target] = ts + end + table.insert(ts, entity) + end + + end + + local world_delete = world.delete + w.delete = function(self, e) + local idr_t = component_index[pair(__, e)] + if idr_t then + for relation, ts in relations do + local targets = ts[e] + if not targets then + continue + end + for _, target in targets do + if type(target) == "boolean" then + continue + end + if targets.fragmenting then + print(`*deleted dependant {pe(target)}`) + else + local t = pe(target) + print(`*removed dependency {ansi.red("(*, ")}{t}{ansi.green(")")} from {pe(e)}`) + end + end + end + end + + world_delete(world, e) + print(`*deleted {pe(e)}`) + end return w end