From ce5de12fede81414c4a05f24072d6bfd1cf3ca0c Mon Sep 17 00:00:00 2001 From: dunnoconz Date: Sat, 10 Aug 2024 18:19:00 -0500 Subject: [PATCH 1/5] modified: src/init.luau --- src/init.luau | 112 ++++++++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 49 deletions(-) diff --git a/src/init.luau b/src/init.luau index baf1553..b4bb8a7 100644 --- a/src/init.luau +++ b/src/init.luau @@ -444,6 +444,61 @@ local function archetype_traverse_add(world: World, id: i53, from: Archetype): A return add end +local world_get: (world: World, entityId: i53, a: i53, b: i53?, c: i53?, d: i53?, e: i53?) -> (...any) + do + -- Keeping the function as small as possible to enable inlining + local records + local columns + local row + + local function fetch(id): any + local tr = records[id] + + if not tr then + return nil + end + + return columns[tr.column][row] + end + + function world_get(world: World, entity: i53, a: i53, b: i53?, c: i53?, d: i53?, e: i53?): ...any + local record = world.entityIndex.sparse[entity] + if not record then + return nil + end + + local archetype = record.archetype + if not archetype then + return nil + end + + records = archetype.records + columns = archetype.columns + row = record.row + + local va = fetch(a) + + if not b then + return va + elseif not c then + return va, fetch(b) + elseif not d then + return va, fetch(b), fetch(c) + elseif not e then + return va, fetch(b), fetch(c), fetch(d) + else + error("args exceeded") + end + end + end + +local function notify_hook(world: World, hook: number, entity: i53, data: any) + local hook = world_get(world, entity, hook) + if hook then + hook(entity, data) + end +end + local function world_add(world: World, entity: i53, id: i53) local entityIndex = world.entityIndex local record = entityIndex.sparse[entity] @@ -459,6 +514,8 @@ local function world_add(world: World, entity: i53, id: i53) new_entity(entity, record, to) end end + + notify_hook(world, EcsOnAdd, entity) end -- Symmetric like `World.add` but idempotent @@ -488,6 +545,8 @@ local function world_set(world: World, entity: i53, id: i53, data: unknown) local tr = to.records[id] to.columns[tr.column][record.row] = data + + notify_hook(world, EcsOnSet, entity) end local function world_component(world: World): i53 @@ -534,6 +593,8 @@ local function world_remove(world: World, entity: i53, id: i53) if from and not (from == to) then entity_move(entity_index, entity, record, to) end + + notify_hook(world, EcsOnRemove, entity) end -- should reuse this logic in World.set instead of swap removing in transition archetype @@ -620,53 +681,7 @@ local function world_clear(world: World, entity: i53) entity_move(world.entityIndex, entity, record, ROOT_ARCHETYPE) end -local world_get: (world: World, entityId: i53, a: i53, b: i53?, c: i53?, d: i53?, e: i53?) -> (...any) -do - -- Keeping the function as small as possible to enable inlining - local records - local columns - local row - - local function fetch(id): any - local tr = records[id] - if not tr then - return nil - end - - return columns[tr.column][row] - end - - function world_get(world: World, entity: i53, a: i53, b: i53?, c: i53?, d: i53?, e: i53?): ...any - local record = world.entityIndex.sparse[entity] - if not record then - return nil - end - - local archetype = record.archetype - if not archetype then - return nil - end - - records = archetype.records - columns = archetype.columns - row = record.row - - local va = fetch(a) - - if not b then - return va - elseif not c then - return va, fetch(b) - elseif not d then - return va, fetch(b), fetch(c) - elseif not e then - return va, fetch(b), fetch(c), fetch(d) - else - error("args exceeded") - end - end -end local function world_has(world: World, entity: number, ...: i53): boolean local record = world.entityIndex.sparse[entity] @@ -1208,6 +1223,8 @@ do end end + + -- __nominal_type_dont_use could not be any or T as it causes a type error -- or produces a union export type Entity = number & { __DO_NOT_USE_OR_YOU_WILL_BE_FIRED: T } @@ -1372,9 +1389,6 @@ function World.new() dense = {} :: { [i24]: i53 }, sparse = {} :: { [i53]: Record }, } :: EntityIndex, - hooks = { - [EcsOnAdd] = {}, - }, nextArchetypeId = 0, nextComponentId = 0, nextEntityId = 0, From d14504e5dd4931fc4560719a173080ab0d6706a1 Mon Sep 17 00:00:00 2001 From: dunnoconz Date: Sat, 10 Aug 2024 18:21:49 -0500 Subject: [PATCH 2/5] modified: src/init.luau --- src/init.luau | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/init.luau b/src/init.luau index b4bb8a7..2db9fd8 100644 --- a/src/init.luau +++ b/src/init.luau @@ -492,8 +492,8 @@ local world_get: (world: World, entityId: i53, a: i53, b: i53?, c: i53?, d: i53? end end -local function notify_hook(world: World, hook: number, entity: i53, data: any) - local hook = world_get(world, entity, hook) +local function notify_hook(world: World, hook_identifier: number, id: i53, entity: i53, data: any) + local hook = world_get(world, id, hook_identifier) if hook then hook(entity, data) end @@ -515,7 +515,7 @@ local function world_add(world: World, entity: i53, id: i53) end end - notify_hook(world, EcsOnAdd, entity) + notify_hook(world, EcsOnAdd, id, entity) end -- Symmetric like `World.add` but idempotent @@ -546,7 +546,7 @@ local function world_set(world: World, entity: i53, id: i53, data: unknown) local tr = to.records[id] to.columns[tr.column][record.row] = data - notify_hook(world, EcsOnSet, entity) + notify_hook(world, EcsOnSet, id, entity) end local function world_component(world: World): i53 @@ -582,6 +582,8 @@ local function archetype_traverse_remove(world: World, id: i53, from: Archetype) end local function world_remove(world: World, entity: i53, id: i53) + notify_hook(world, EcsOnRemove, id, entity) + local entity_index = world.entityIndex local record = entity_index.sparse[entity] local from = record.archetype @@ -593,8 +595,6 @@ local function world_remove(world: World, entity: i53, id: i53) if from and not (from == to) then entity_move(entity_index, entity, record, to) end - - notify_hook(world, EcsOnRemove, entity) end -- should reuse this logic in World.set instead of swap removing in transition archetype From b67e08f875f0e36c81a37ef7a81795f32419b85f Mon Sep 17 00:00:00 2001 From: dunnoconz Date: Sat, 10 Aug 2024 18:39:05 -0500 Subject: [PATCH 3/5] modified: src/init.luau --- src/init.luau | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/init.luau b/src/init.luau index 2db9fd8..c571807 100644 --- a/src/init.luau +++ b/src/init.luau @@ -492,8 +492,8 @@ local world_get: (world: World, entityId: i53, a: i53, b: i53?, c: i53?, d: i53? end end -local function notify_hook(world: World, hook_identifier: number, id: i53, entity: i53, data: any) - local hook = world_get(world, id, hook_identifier) +local function notify_hook(world: World, hook_id: number, id: i53, entity: i53, data: any?) + local hook = world_get(world, id, hook_id) if hook then hook(entity, data) end @@ -529,7 +529,7 @@ local function world_set(world: World, entity: i53, id: i53, data: unknown) -- and just set the data directly. local tr = to.records[id] from.columns[tr.column][record.row] = data - -- Should fire an OnSet event here. + notify_hook(world, EcsOnSet, id, entity, data) return end @@ -546,7 +546,7 @@ local function world_set(world: World, entity: i53, id: i53, data: unknown) local tr = to.records[id] to.columns[tr.column][record.row] = data - notify_hook(world, EcsOnSet, id, entity) + notify_hook(world, EcsOnAdd, id, entity, data) end local function world_component(world: World): i53 From 0b32bc9f9b9ba927a8b1fb3ecee3a0aadd989132 Mon Sep 17 00:00:00 2001 From: dunnoconz Date: Sat, 10 Aug 2024 19:02:39 -0500 Subject: [PATCH 4/5] modified: src/init.luau --- src/init.luau | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.luau b/src/init.luau index c571807..19dcefa 100644 --- a/src/init.luau +++ b/src/init.luau @@ -492,7 +492,7 @@ local world_get: (world: World, entityId: i53, a: i53, b: i53?, c: i53?, d: i53? end end -local function notify_hook(world: World, hook_id: number, id: i53, entity: i53, data: any?) +local function invoke_hook(world: World, hook_id: number, id: i53, entity: i53, data: any?) local hook = world_get(world, id, hook_id) if hook then hook(entity, data) From 6d232c59c762b6ac62deafde88f4455f9495f908 Mon Sep 17 00:00:00 2001 From: dunnoconz Date: Sat, 10 Aug 2024 19:05:00 -0500 Subject: [PATCH 5/5] modified: src/init.luau --- src/init.luau | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/init.luau b/src/init.luau index 19dcefa..a3249ca 100644 --- a/src/init.luau +++ b/src/init.luau @@ -515,7 +515,7 @@ local function world_add(world: World, entity: i53, id: i53) end end - notify_hook(world, EcsOnAdd, id, entity) + invoke_hook(world, EcsOnAdd, id, entity) end -- Symmetric like `World.add` but idempotent @@ -529,7 +529,7 @@ local function world_set(world: World, entity: i53, id: i53, data: unknown) -- and just set the data directly. local tr = to.records[id] from.columns[tr.column][record.row] = data - notify_hook(world, EcsOnSet, id, entity, data) + invoke_hook(world, EcsOnSet, id, entity, data) return end @@ -546,7 +546,7 @@ local function world_set(world: World, entity: i53, id: i53, data: unknown) local tr = to.records[id] to.columns[tr.column][record.row] = data - notify_hook(world, EcsOnAdd, id, entity, data) + invoke_hook(world, EcsOnAdd, id, entity, data) end local function world_component(world: World): i53 @@ -582,7 +582,7 @@ local function archetype_traverse_remove(world: World, id: i53, from: Archetype) end local function world_remove(world: World, entity: i53, id: i53) - notify_hook(world, EcsOnRemove, id, entity) + invoke_hook(world, EcsOnRemove, id, entity) local entity_index = world.entityIndex local record = entity_index.sparse[entity]