diff --git a/src/jecs.luau b/src/jecs.luau index a8cb226..a9f355d 100755 --- a/src/jecs.luau +++ b/src/jecs.luau @@ -3342,16 +3342,16 @@ local function world_new(DEBUG: boolean?) local end_count = nth + count local archetype_types = archetype.types - local sparse_array = entity_index.sparse_array - local dense_array = entity_index.dense_array return function(): i53? - if nth == end_count then - return nil + while nth ~= end_count do + local target = entity_index_get_alive(entity_index, ECS_PAIR_SECOND(archetype_types[nth])) + nth += 1 + if target then + return target + end end - local target = dense_array[sparse_array[ECS_PAIR_SECOND(archetype_types[nth])].dense] - nth += 1 - return target + return nil end end diff --git a/test/tests.luau b/test/tests.luau index 7aeab8e..086f3d3 100755 --- a/test/tests.luau +++ b/test/tests.luau @@ -3300,6 +3300,29 @@ TEST("world:targets()", function() CHECK(count == #alive) end + do CASE "should skip targets deleted after the iterator is created" + local world = jecs.world() + + local ROOT = world:entity() + local e = world:entity() + local a, b, c = world:entity(), world:entity(), world:entity() + world:add(e, pair(ROOT, a)) + world:add(e, pair(ROOT, b)) + world:add(e, pair(ROOT, c)) + + local iter = world:targets(e, ROOT) + world:delete(b) + + local seen = {} + for t in iter do + CHECK(world:contains(t)) + seen[#seen + 1] = t + end + + CHECK(#seen == 2) + CHECK(seen[1] == a) + CHECK(seen[2] == c) + end do CASE "should properly handle rapid add/remove calls" local world = jecs.world()