Omit onNotifyAdd

This commit is contained in:
Ukendio 2024-05-08 00:56:21 +02:00
parent 79f821ff72
commit 4ebcc82309

View file

@ -287,23 +287,31 @@ local function archetypeTraverseAdd(world: World, componentId: i53, from: Archet
return add return add
end end
local function ensureRecord(entityIndex, entityId: i53): Record local function ensureRecord(world, entityId: i53): Record
local entityIndex = world.entityIndex
local record = entityIndex[entityId] local record = entityIndex[entityId]
if not record then if record then
record = {} return record
entityIndex[entityId] = record
end end
return record :: Record local ROOT = world.ROOT_ARCHETYPE
local row = #ROOT.entities + 1
ROOT.entities[row] = entityId
record = {
archetype = ROOT,
row = row
}
entityIndex[entityId] = record
return record
end end
function World.add(world: World, entityId: i53, componentId: i53) function World.add(world: World, entityId: i53, componentId: i53)
local record = ensureRecord(world.entityIndex, entityId) local record = ensureRecord(world, entityId)
local from = record.archetype local from = record.archetype
local to = archetypeTraverseAdd(world, componentId, from) local to = archetypeTraverseAdd(world, componentId, from)
if from then if from and not (from == world.ROOT_ARCHETYPE) then
moveEntity(world.entityIndex, entityId, record, to) moveEntity(world.entityIndex, entityId, record, to)
else else
if #to.types > 0 then if #to.types > 0 then
@ -315,19 +323,20 @@ end
-- Symmetric like `World.add` but idempotent -- Symmetric like `World.add` but idempotent
function World.set(world: World, entityId: i53, componentId: i53, data: unknown) function World.set(world: World, entityId: i53, componentId: i53, data: unknown)
local record = ensureRecord(world.entityIndex, entityId) local record = ensureRecord(world, entityId)
local from = record.archetype local from = record.archetype
local to = archetypeTraverseAdd(world, componentId, from)
if from == to then local archetypeRecord = from.records[componentId]
if archetypeRecord then
-- If the archetypes are the same it can avoid moving the entity -- If the archetypes are the same it can avoid moving the entity
-- and just set the data directly. -- and just set the data directly.
local archetypeRecord = to.records[componentId]
from.columns[archetypeRecord][record.row] = data from.columns[archetypeRecord][record.row] = data
-- Should fire an OnSet event here. -- Should fire an OnSet event here.
return return
end end
local to = archetypeTraverseAdd(world, componentId, from)
if from then if from then
-- If there was a previous archetype, then the entity needs to move the archetype -- If there was a previous archetype, then the entity needs to move the archetype
moveEntity(world.entityIndex, entityId, record, to) moveEntity(world.entityIndex, entityId, record, to)
@ -335,16 +344,15 @@ function World.set(world: World, entityId: i53, componentId: i53, data: unknown)
if #to.types > 0 then if #to.types > 0 then
-- When there is no previous archetype it should create the archetype -- When there is no previous archetype it should create the archetype
newEntity(entityId, record, to) newEntity(entityId, record, to)
onNotifyAdd(world, to, from, record.row, {componentId}) --onNotifyAdd(world, to, from, record.row, {componentId})
end end
end end
local archetypeRecord = to.records[componentId] archetypeRecord = to.records[componentId]
to.columns[archetypeRecord][record.row] = data to.columns[archetypeRecord][record.row] = data
end end
local function archetypeTraverseRemove(world: World, componentId: i53, archetype: Archetype?): Archetype? local function archetypeTraverseRemove(world: World, componentId: i53, from: Archetype): Archetype
local from = (archetype or world.ROOT_ARCHETYPE) :: Archetype
local edge = ensureEdge(from, componentId) local edge = ensureEdge(from, componentId)
local remove = edge.remove local remove = edge.remove
@ -354,7 +362,7 @@ local function archetypeTraverseRemove(world: World, componentId: i53, archetype
if not at then if not at then
return from return from
end end
table.remove(to, at, component) table.remove(to, at)
remove = ensureArchetype(world, to, from) remove = ensureArchetype(world, to, from)
edge.remove = remove :: never edge.remove = remove :: never
end end
@ -363,16 +371,12 @@ local function archetypeTraverseRemove(world: World, componentId: i53, archetype
end end
function World.remove(world: World, entityId: i53, componentId: i53) function World.remove(world: World, entityId: i53, componentId: i53)
local entityIndex = world.entityIndex local record = ensureRecord(world, entityId)
local record = ensureRecord(entityIndex, entityId)
local sourceArchetype = record.archetype local sourceArchetype = record.archetype
local destinationArchetype = archetypeTraverseRemove(world, componentId, sourceArchetype) local destinationArchetype = archetypeTraverseRemove(world, componentId, sourceArchetype)
if not destinationArchetype then
return
end
if sourceArchetype and not (sourceArchetype == destinationArchetype) then if sourceArchetype and not (sourceArchetype == destinationArchetype) then
moveEntity(entityIndex, entityId, record, destinationArchetype) moveEntity(world.entityIndex, entityId, record, destinationArchetype)
end end
end end
@ -739,4 +743,4 @@ return table.freeze({
ON_ADD = ON_ADD; ON_ADD = ON_ADD;
ON_REMOVE = ON_REMOVE; ON_REMOVE = ON_REMOVE;
ON_SET = ON_SET; ON_SET = ON_SET;
}) })