mirror of
https://github.com/Ukendio/jecs.git
synced 2025-04-25 09:30:03 +00:00
Fix component overriding when in disorder
This commit is contained in:
parent
e5e1aec6b2
commit
051cacd3de
2 changed files with 50 additions and 31 deletions
64
lib/init.lua
64
lib/init.lua
|
@ -51,31 +51,38 @@ local REST = HI_COMPONENT_ID + 4
|
||||||
|
|
||||||
local function transitionArchetype(
|
local function transitionArchetype(
|
||||||
entityIndex: EntityIndex,
|
entityIndex: EntityIndex,
|
||||||
destinationArchetype: Archetype,
|
to: Archetype,
|
||||||
destinationRow: i24,
|
destinationRow: i24,
|
||||||
sourceArchetype: Archetype,
|
from: Archetype,
|
||||||
sourceRow: i24
|
sourceRow: i24
|
||||||
)
|
)
|
||||||
local columns = sourceArchetype.columns
|
local columns = from.columns
|
||||||
local sourceEntities = sourceArchetype.entities
|
local sourceEntities = from.entities
|
||||||
local destinationEntities = destinationArchetype.entities
|
local destinationEntities = to.entities
|
||||||
local destinationColumns = destinationArchetype.columns
|
local destinationColumns = to.columns
|
||||||
|
local tr = to.records
|
||||||
|
local types = from.types
|
||||||
|
|
||||||
for componentId, column in columns do
|
for i, column in columns do
|
||||||
local targetColumn = destinationColumns[componentId]
|
local targetColumn = destinationColumns[tr[types[i]]]
|
||||||
if targetColumn then
|
if targetColumn then
|
||||||
targetColumn[destinationRow] = column[sourceRow]
|
targetColumn[destinationRow] = column[sourceRow]
|
||||||
end
|
end
|
||||||
column[sourceRow] = column[#column]
|
if sourceRow ~= #column then
|
||||||
column[#column] = nil
|
column[sourceRow] = column[#column]
|
||||||
|
column[#column] = nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
destinationEntities[destinationRow] = sourceEntities[sourceRow]
|
destinationEntities[destinationRow] = sourceEntities[sourceRow]
|
||||||
entityIndex[sourceEntities[sourceRow]].row = destinationRow
|
entityIndex[sourceEntities[sourceRow]].row = destinationRow
|
||||||
|
|
||||||
local movedAway = #sourceEntities
|
local movedAway = #sourceEntities
|
||||||
sourceEntities[sourceRow] = sourceEntities[movedAway]
|
if sourceRow ~= movedAway then
|
||||||
entityIndex[sourceEntities[movedAway]].row = sourceRow
|
sourceEntities[sourceRow] = sourceEntities[movedAway]
|
||||||
|
entityIndex[sourceEntities[movedAway]].row = sourceRow
|
||||||
|
end
|
||||||
|
|
||||||
sourceEntities[movedAway] = nil
|
sourceEntities[movedAway] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -145,7 +152,9 @@ local function archetypeOf(world: World, types: { i24 }, prev: Archetype?): Arch
|
||||||
}
|
}
|
||||||
world.archetypeIndex[ty] = archetype
|
world.archetypeIndex[ty] = archetype
|
||||||
world.archetypes[id] = archetype
|
world.archetypes[id] = archetype
|
||||||
createArchetypeRecords(world.componentIndex, archetype, prev)
|
if #types > 0 then
|
||||||
|
createArchetypeRecords(world.componentIndex, archetype, prev)
|
||||||
|
end
|
||||||
|
|
||||||
return archetype
|
return archetype
|
||||||
end
|
end
|
||||||
|
@ -180,8 +189,6 @@ local function emit(world, eventDescription)
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local function onNotifyAdd(world, archetype, otherArchetype, row: number, added: Ty)
|
local function onNotifyAdd(world, archetype, otherArchetype, row: number, added: Ty)
|
||||||
if #added > 0 then
|
if #added > 0 then
|
||||||
emit(world, {
|
emit(world, {
|
||||||
|
@ -194,13 +201,13 @@ local function onNotifyAdd(world, archetype, otherArchetype, row: number, added:
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
export type World = typeof(World.new())
|
export type World = typeof(World.new())
|
||||||
|
|
||||||
local function ensureArchetype(world: World, types, prev)
|
local function ensureArchetype(world: World, types, prev)
|
||||||
if #types < 1 then
|
if #types < 1 then
|
||||||
return world.ROOT_ARCHETYPE
|
return world.ROOT_ARCHETYPE
|
||||||
end
|
end
|
||||||
|
|
||||||
local ty = hash(types)
|
local ty = hash(types)
|
||||||
local archetype = world.archetypeIndex[ty]
|
local archetype = world.archetypeIndex[ty]
|
||||||
if archetype then
|
if archetype then
|
||||||
|
@ -270,26 +277,25 @@ end
|
||||||
|
|
||||||
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.entityIndex, entityId)
|
||||||
local sourceArchetype = record.archetype
|
local from = record.archetype
|
||||||
local destinationArchetype = archetypeTraverseAdd(world, componentId, sourceArchetype)
|
local to = archetypeTraverseAdd(world, componentId, from)
|
||||||
|
|
||||||
if sourceArchetype == destinationArchetype then
|
if from == to then
|
||||||
local archetypeRecord = destinationArchetype.records[componentId]
|
local archetypeRecord = to.records[componentId]
|
||||||
destinationArchetype.columns[archetypeRecord][record.row] = data
|
from.columns[archetypeRecord][record.row] = data
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
if from then
|
||||||
if sourceArchetype then
|
moveEntity(world.entityIndex, entityId, record, to)
|
||||||
moveEntity(world.entityIndex, entityId, record, destinationArchetype)
|
|
||||||
else
|
else
|
||||||
if #destinationArchetype.types > 0 then
|
if #to.types > 0 then
|
||||||
newEntity(entityId, record, destinationArchetype)
|
newEntity(entityId, record, to)
|
||||||
onNotifyAdd(world, destinationArchetype, sourceArchetype, record.row, { componentId })
|
onNotifyAdd(world, to, from, record.row, { componentId })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local archetypeRecord = destinationArchetype.records[componentId]
|
local archetypeRecord = to.records[componentId]
|
||||||
destinationArchetype.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, archetype: Archetype?): Archetype
|
||||||
|
|
|
@ -6,7 +6,6 @@ local TEST, CASE, CHECK, FINISH, SKIP = testkit.test()
|
||||||
local N = 10
|
local N = 10
|
||||||
|
|
||||||
TEST("world:query", function()
|
TEST("world:query", function()
|
||||||
|
|
||||||
do CASE "should query all matching entities"
|
do CASE "should query all matching entities"
|
||||||
|
|
||||||
local world = jecs.World.new()
|
local world = jecs.World.new()
|
||||||
|
@ -83,6 +82,20 @@ TEST("world:query", function()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
do CASE "should allow setting components in arbitrary order"
|
||||||
|
local world = jecs.World.new()
|
||||||
|
|
||||||
|
local Health = world:component()
|
||||||
|
local Poison = world:component()
|
||||||
|
|
||||||
|
local id = world:entity()
|
||||||
|
world:set(id, Poison, 5)
|
||||||
|
world:set(id, Health, 50)
|
||||||
|
|
||||||
|
CHECK(world:get(id, Poison) == 5)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
FINISH()
|
FINISH()
|
Loading…
Reference in a new issue