From b26fc39fce9a80869106e85673615486b9affa4c Mon Sep 17 00:00:00 2001 From: Ukendio Date: Wed, 12 Mar 2025 18:49:18 +0100 Subject: [PATCH] Add options to lifetime tracker --- jecs.luau | 2 ++ test/devtools_test.luau | 17 +++++----- tools/entity_visualiser.luau | 2 +- tools/lifetime_tracker.luau | 66 +++++++++++++++++++++--------------- 4 files changed, 50 insertions(+), 37 deletions(-) diff --git a/jecs.luau b/jecs.luau index a2b2e06..2e2833c 100644 --- a/jecs.luau +++ b/jecs.luau @@ -2512,6 +2512,8 @@ return { ECS_GENERATION = ECS_GENERATION, ECS_ID_IS_WILDCARD = ECS_ID_IS_WILDCARD, + ECS_ID_DELETE = ECS_ID_DELETE, + IS_PAIR = ECS_IS_PAIR, pair_first = ecs_pair_first, pair_second = ecs_pair_second, diff --git a/test/devtools_test.luau b/test/devtools_test.luau index a0f4745..1e24f88 100644 --- a/test/devtools_test.luau +++ b/test/devtools_test.luau @@ -2,23 +2,24 @@ local jecs = require("@jecs") local pair = jecs.pair local ChildOf = jecs.ChildOf local lifetime_tracker_add = require("@tools/lifetime_tracker") -local world = lifetime_tracker_add(jecs.world()) -world:print_snapshot() +local pe = require("@tools/entity_visualiser").prettify +local world = lifetime_tracker_add(jecs.world(), {padding_enabled=false}) +local FriendsWith = world:component() +local _1 = world:print_snapshot() local e1 = world:entity() local e2 = world:entity() world:delete(e2) -world:print_snapshot() +local _2 = world:print_snapshot() local e3 = world:entity() world:add(e3, pair(ChildOf, e1)) local e4 = world:entity() -world:add(e4, pair(ChildOf, e4)) -world:print_snapshot() +world:add(e4, pair(FriendsWith, e3)) +local _3 = world:print_snapshot() world:delete(e1) -world:delete(e2) world:delete(e3) -world:print_snapshot() +local _4 = world:print_snapshot() world:print_entity_index() world:entity() world:entity() -world:print_snapshot() +local _5 = world:print_snapshot() diff --git a/tools/entity_visualiser.luau b/tools/entity_visualiser.luau index 081caad..6a2e41a 100644 --- a/tools/entity_visualiser.luau +++ b/tools/entity_visualiser.luau @@ -39,5 +39,5 @@ end return { components = components, - prettify = pe + prettify = pe, } diff --git a/tools/lifetime_tracker.luau b/tools/lifetime_tracker.luau index a1f2b62..4bad5a2 100644 --- a/tools/lifetime_tracker.luau +++ b/tools/lifetime_tracker.luau @@ -4,7 +4,9 @@ local ECS_ID = jecs.ECS_ID local __ = jecs.Wildcard local pair = jecs.pair -local pe = require("@tools/entity_visualiser").prettify +local prettify = require("@tools/entity_visualiser").prettify + +local pe = prettify local ansi = require("@tools/ansi") function print_centered_entity(entity, width: number) @@ -24,8 +26,14 @@ end local function name(world, e) return world:get(world, e, jecs.Name) or pe(e) end +local padding_enabled = false +local function pad() + if padding_enabled then + print("") + end +end -local function lifetime_tracker_add(world: jecs.World) +local function lifetime_tracker_add(world: jecs.World, opt) local entity_index = world.entity_index local dense_array = entity_index.dense_array local component_index = world.component_index @@ -34,6 +42,7 @@ local function lifetime_tracker_add(world: jecs.World) local w = setmetatable({}, { __index = world }) + padding_enabled = opt.padding_enabled local world_entity = world.entity w.entity = function(self) @@ -44,6 +53,7 @@ local function lifetime_tracker_add(world: jecs.World) else print(`*created {pe(e)}`) end + pad() return e end w.print_entity_index = function(self) @@ -70,6 +80,7 @@ local function lifetime_tracker_add(world: jecs.World) print(sep) end end + pad() end local timelines = {} w.print_snapshot = function(self) @@ -143,6 +154,7 @@ local function lifetime_tracker_add(world: jecs.World) print(row) end print("-------------------------------------------------------------------") + pad() end local world_add = world.add local relations = {} @@ -152,49 +164,47 @@ local function lifetime_tracker_add(world: jecs.World) 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) + pad() end end local world_delete = world.delete w.delete = function(self, e) + world_delete(world, 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 + for archetype_id in idr_t.cache do + local archetype = world.archetypes[archetype_id] + for _, id in archetype.types do + if not jecs.IS_PAIR(id) then continue end - if targets.fragmenting then - print(`*deleted dependant {pe(target)}`) + local object = jecs.pair_second(world, id) + if object ~= e then + continue + end + local id_record = component_index[id] + local flags = id_record.flags + local flags_delete_mask: number = bit32.band(flags, jecs.ECS_ID_DELETE) + if flags_delete_mask ~= 0 then + for _, entity in archetype.entities do + print(`*deleted dependant {pe(entity)} of {pe(e)}`) + pad() + end + break else - local t = pe(target) - print(`*removed dependency {ansi.red("(*, ")}{t}{ansi.green(")")} from {pe(e)}`) + for _, entity in archetype.entities do + print(`*removed dependency ({pe(jecs.pair_first(world, id))}, {pe(object)}) from {pe(entity)}`) + end end end end end - world_delete(world, e) print(`*deleted {pe(e)}`) + pad() end return w end