component Hooks (#98)

Co-authored-by: Marcus <ukendio@gmail.com>
This commit is contained in:
Conz 2024-08-10 20:30:58 -05:00 committed by GitHub
parent e6983a3356
commit 71569bba60
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -465,6 +465,61 @@ local function archetype_traverse_add(world: World, id: i53, from: Archetype): A
return add return add
end 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 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)
end
end
local function world_add(world: World, entity: i53, id: i53) local function world_add(world: World, entity: i53, id: i53)
local entityIndex = world.entityIndex local entityIndex = world.entityIndex
local record = entityIndex.sparse[entity] local record = entityIndex.sparse[entity]
@ -480,6 +535,8 @@ local function world_add(world: World, entity: i53, id: i53)
new_entity(entity, record, to) new_entity(entity, record, to)
end end
end end
invoke_hook(world, EcsOnAdd, id, entity)
end end
-- Symmetric like `World.add` but idempotent -- Symmetric like `World.add` but idempotent
@ -493,7 +550,7 @@ local function world_set(world: World, entity: i53, id: i53, data: unknown)
-- and just set the data directly. -- and just set the data directly.
local tr = to.records[id] local tr = to.records[id]
from.columns[tr.column][record.row] = data from.columns[tr.column][record.row] = data
-- Should fire an OnSet event here. invoke_hook(world, EcsOnSet, id, entity, data)
return return
end end
@ -509,6 +566,8 @@ local function world_set(world: World, entity: i53, id: i53, data: unknown)
local tr = to.records[id] local tr = to.records[id]
to.columns[tr.column][record.row] = data to.columns[tr.column][record.row] = data
invoke_hook(world, EcsOnAdd, id, entity, data)
end end
local function world_component(world: World): i53 local function world_component(world: World): i53
@ -544,6 +603,8 @@ local function archetype_traverse_remove(world: World, id: i53, from: Archetype)
end end
local function world_remove(world: World, entity: i53, id: i53) local function world_remove(world: World, entity: i53, id: i53)
invoke_hook(world, EcsOnRemove, id, entity)
local entity_index = world.entityIndex local entity_index = world.entityIndex
local record = entity_index.sparse[entity] local record = entity_index.sparse[entity]
local from = record.archetype local from = record.archetype
@ -641,7 +702,6 @@ local function world_clear(world: World, entity: i53)
entity_move(world.entityIndex, entity, record, ROOT_ARCHETYPE) entity_move(world.entityIndex, entity, record, ROOT_ARCHETYPE)
end end
type CompatibleArchetype = { archetype: Archetype, indices: { number } } type CompatibleArchetype = { archetype: Archetype, indices: { number } }
local noop: Item = function() local noop: Item = function()
@ -1172,9 +1232,6 @@ function World.new()
dense = {} :: { [i24]: i53 }, dense = {} :: { [i24]: i53 },
sparse = {} :: { [i53]: Record }, sparse = {} :: { [i53]: Record },
} :: EntityIndex, } :: EntityIndex,
hooks = {
[EcsOnAdd] = {},
},
nextArchetypeId = 0, nextArchetypeId = 0,
nextComponentId = 0, nextComponentId = 0,
nextEntityId = 0, nextEntityId = 0,
@ -1247,6 +1304,7 @@ export type World = {
& (<A, B, C, D, E, F, G, H>(World, Entity<A>, Entity<B>, Entity<C>, & (<A, B, C, D, E, F, G, H>(World, Entity<A>, Entity<B>, Entity<C>,
Entity<D>, Entity<E>, Entity<F>, Entity<G>, Entity<H>) -> Query<A, B, C, D, E, F, G, H>) Entity<D>, Entity<E>, Entity<F>, Entity<G>, Entity<H>) -> Query<A, B, C, D, E, F, G, H>)
} }
return { return {
World = World , World = World ,