diff --git a/jecs.luau b/jecs.luau index dc6ab65..3a1352c 100644 --- a/jecs.luau +++ b/jecs.luau @@ -772,15 +772,17 @@ local function world_entity(world: ecs_world_t, entity: i53?): i53 local r = sparse_array[index] if r then local dense = r.dense - if dense and r.dense ~= 0 then - if dense < alive_count then - return entity - end - else + + if not dense or r.dense == 0 then r.dense = index dense = index end + local any = dense_array[dense] + if dense <= alive_count then + return any + end + local e_swap = dense_array[dense] local r_swap = entity_index_try_get_any(entity_index, e_swap) :: ecs_record_t alive_count += 1 @@ -788,8 +790,9 @@ local function world_entity(world: ecs_world_t, entity: i53?): i53 r_swap.dense = dense r.dense = alive_count dense_array[dense] = e_swap - dense_array[alive_count] = entity - return entity + dense_array[alive_count] = any + + return any else for i = max_id + 1, index do sparse_array[i] = { dense = i } :: ecs_record_t diff --git a/test/tests.luau b/test/tests.luau index 7043226..c87c7b6 100644 --- a/test/tests.luau +++ b/test/tests.luau @@ -634,37 +634,50 @@ TEST("world:each()", function() end) TEST("world:range()", function() - do CASE "" - local world = jecs.world() - world = lifetime_tracker_add(world, {}) - world:range(1000, 2000) - local e = world:entity() - CHECK(e == 1000) - - world:entity(1590) - - CHECK(world:entity(5000) == 5000) - - CHECK(world:contains(1590)) - world:set(591, jecs.Name, "9888") - CHECK(not world:contains(591)) - CHECK(world:contains(5000)) - CHECK(not world:contains(988)) - - local e = world:entity(2000) - CHECK(e == 2000) - end -end) - -TEST("world:entity()", function() - do CASE "desired id" + do CASE "under range start" local world = jecs.world() world:range(400, 1000) local id = world:entity() local e = world:entity(id + 5) CHECK(e == id + 5) CHECK(world:contains(e)) - local e2 = world:entity() + local e2 = world:entity(399) + CHECK(world:contains(e2)) + world:delete(e2) + CHECK(not world:contains(e2)) + local e2v1 = world:entity(399) + CHECK(world:contains(e2v1)) + CHECK(ECS_ID(e2v1) == 399) + CHECK(ECS_GENERATION(e2v1) == 1) + end + + do CASE "over range start" + local world = jecs.world() + world:range(400, 1000) + local e2 = world:entity(405) + CHECK(world:contains(e2)) + world:delete(e2) + CHECK(not world:contains(e2)) + local e2v1 = world:entity(405) + CHECK(world:contains(e2v1)) + CHECK(ECS_ID(e2v1) == 405) + CHECK(ECS_GENERATION(e2v1) == 1) + + do + local _e2v1 = world:entity(405) + CHECK(_e2v1 == e2v1) + end + end +end) + +TEST("world:entity()", function() + do CASE "desired id" + local world = jecs.world() + local id = world:entity() + local e = world:entity(id + 5) + CHECK(e == id + 5) + CHECK(world:contains(e)) + local e2 = world:entity(399) CHECK(world:contains(e2)) end local N = 2^8