diff --git a/lib/init.lua b/lib/init.lua index 35a9b9c..5aaeeac 100644 --- a/lib/init.lua +++ b/lib/init.lua @@ -322,14 +322,17 @@ function World.set(world: World, entityId: i53, componentId: i53, data: unknown) to.columns[archetypeRecord][record.row] = data end -local function archetypeTraverseRemove(world: World, componentId: i53, archetype: Archetype?): Archetype +local function archetypeTraverseRemove(world: World, componentId: i53, archetype: Archetype?): Archetype? local from = (archetype or world.ROOT_ARCHETYPE) :: Archetype local edge = ensureEdge(from, componentId) - if not edge.remove then local to = table.clone(from.types) - table.remove(to, table.find(to, componentId)) + local at = table.find(to, componentId) + if not at then + return + end + table.remove(to, at) edge.remove = ensureArchetype(world, to, from) end @@ -340,8 +343,11 @@ function World.remove(world: World, entityId: i53, componentId: i53) local record = ensureRecord(world.entityIndex, entityId) local sourceArchetype = record.archetype local destinationArchetype = archetypeTraverseRemove(world, componentId, sourceArchetype) + if not sourceArchetype or not destinationArchetype then + return + end - if sourceArchetype and not (sourceArchetype == destinationArchetype) then + if not (sourceArchetype == destinationArchetype) then moveEntity(world.entityIndex, entityId, record, destinationArchetype) end end diff --git a/tests/test1.lua b/tests/test1.lua index 0b031d3..419c42a 100644 --- a/tests/test1.lua +++ b/tests/test1.lua @@ -35,14 +35,17 @@ TEST("world:query", function() local world = jecs.World.new() local A = world:component() local B = world:component() + local C = world:component() local entities = {} for i = 1, N do local id = world:entity() - world:set(id, A, true) + -- specifically put them in disorder to track regression + -- https://github.com/Ukendio/jecs/pull/15 world:set(id, B, true) - if i > 5 then world:remove(id, B, true) end + world:set(id, A, true) + if i > 5 then world:remove(id, B) end entities[i] = id end @@ -110,6 +113,19 @@ TEST("world:query", function() CHECK(world:get(id, Health) == nil) end + do CASE "show allow remove that doesn't exist on entity" + local world = jecs.World.new() + + local Health = world:entity() + local Poison = world:component() + + local id = world:entity() + world:set(id, Health, 50) + world:remove(id, Poison) + + CHECK(world:get(id, Poison) == nil) + CHECK(world:get(id, Health) == 50) + end end) FINISH() \ No newline at end of file