mirror of
https://github.com/Ukendio/jecs.git
synced 2026-03-18 00:44:32 +00:00
emplace the iD
This commit is contained in:
parent
99c2b1b56e
commit
4d76e28425
4 changed files with 60 additions and 52 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@rbxts/jecs",
|
"name": "@rbxts/jecs",
|
||||||
"version": "0.10.3",
|
"version": "0.10.4",
|
||||||
"description": "Stupidly fast Entity Component System",
|
"description": "Stupidly fast Entity Component System",
|
||||||
"main": "src/jecs.luau",
|
"main": "src/jecs.luau",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
|
||||||
|
|
@ -572,12 +572,14 @@ local function ENTITY_INDEX_NEW_ID(entity_index: entityindex): i53
|
||||||
local alive_count = entity_index.alive_count
|
local alive_count = entity_index.alive_count
|
||||||
local sparse_array = entity_index.sparse_array
|
local sparse_array = entity_index.sparse_array
|
||||||
local max_id = entity_index.max_id
|
local max_id = entity_index.max_id
|
||||||
|
local next_count = alive_count + 1
|
||||||
|
|
||||||
if alive_count < max_id then
|
if alive_count < max_id then
|
||||||
alive_count += 1
|
local id = dense_array[next_count]
|
||||||
entity_index.alive_count = alive_count
|
if id then
|
||||||
local id = dense_array[alive_count]
|
entity_index.alive_count = next_count
|
||||||
return id
|
return id
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local id = max_id + 1
|
local id = max_id + 1
|
||||||
|
|
@ -585,10 +587,9 @@ local function ENTITY_INDEX_NEW_ID(entity_index: entityindex): i53
|
||||||
ecs_assert(range_end == nil or id < range_end, ECS_INTERNAL_ERROR_INCOMPATIBLE_ENTITY)
|
ecs_assert(range_end == nil or id < range_end, ECS_INTERNAL_ERROR_INCOMPATIBLE_ENTITY)
|
||||||
|
|
||||||
entity_index.max_id = id
|
entity_index.max_id = id
|
||||||
alive_count += 1
|
entity_index.alive_count = next_count
|
||||||
entity_index.alive_count = alive_count
|
dense_array[next_count] = id
|
||||||
dense_array[alive_count] = id
|
sparse_array[id] = { dense = next_count } :: record
|
||||||
sparse_array[id] = { dense = alive_count } :: record
|
|
||||||
|
|
||||||
return id
|
return id
|
||||||
end
|
end
|
||||||
|
|
@ -2702,12 +2703,12 @@ local function world_new(DEBUG: boolean?)
|
||||||
local eindex_dense_array = {} :: { i53 }
|
local eindex_dense_array = {} :: { i53 }
|
||||||
local eindex_sparse_array = {} :: { record }
|
local eindex_sparse_array = {} :: { record }
|
||||||
|
|
||||||
local entity_index = {
|
local entity_index: entityindex = {
|
||||||
dense_array = eindex_dense_array,
|
dense_array = eindex_dense_array,
|
||||||
sparse_array = eindex_sparse_array,
|
sparse_array = eindex_sparse_array,
|
||||||
alive_count = 0,
|
alive_count = 0,
|
||||||
max_id = 0,
|
max_id = 0,
|
||||||
} :: entityindex
|
}
|
||||||
|
|
||||||
-- NOTE(marcus): with the way the component index is accessed, we want to
|
-- NOTE(marcus): with the way the component index is accessed, we want to
|
||||||
-- ensure that components range has fast access.
|
-- ensure that components range has fast access.
|
||||||
|
|
@ -2747,31 +2748,6 @@ local function world_new(DEBUG: boolean?)
|
||||||
signals = signals,
|
signals = signals,
|
||||||
} :: world
|
} :: world
|
||||||
|
|
||||||
|
|
||||||
local function entity_index_new_id(entity_index: entityindex): i53
|
|
||||||
local alive_count = entity_index.alive_count
|
|
||||||
local max_id = entity_index.max_id
|
|
||||||
|
|
||||||
if alive_count < max_id then
|
|
||||||
alive_count += 1
|
|
||||||
entity_index.alive_count = alive_count
|
|
||||||
local id = eindex_dense_array[alive_count]
|
|
||||||
return id
|
|
||||||
end
|
|
||||||
|
|
||||||
local id = max_id + 1
|
|
||||||
local range_end = entity_index.range_end
|
|
||||||
ecs_assert(range_end == nil or id < range_end, ECS_INTERNAL_ERROR_INCOMPATIBLE_ENTITY)
|
|
||||||
|
|
||||||
entity_index.max_id = id
|
|
||||||
alive_count += 1
|
|
||||||
entity_index.alive_count = alive_count
|
|
||||||
eindex_dense_array[alive_count] = id
|
|
||||||
eindex_sparse_array[id] = { dense = alive_count } :: record
|
|
||||||
|
|
||||||
return id
|
|
||||||
end
|
|
||||||
|
|
||||||
local ROOT_ARCHETYPE = archetype_create(world, {}, "")
|
local ROOT_ARCHETYPE = archetype_create(world, {}, "")
|
||||||
world.ROOT_ARCHETYPE = ROOT_ARCHETYPE
|
world.ROOT_ARCHETYPE = ROOT_ARCHETYPE
|
||||||
|
|
||||||
|
|
@ -3326,10 +3302,13 @@ local function world_new(DEBUG: boolean?)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function world_entity(world: world, entity: i53?): i53
|
local function world_entity(world: world, entity: i53?): i53
|
||||||
|
local sparse_array = eindex_sparse_array
|
||||||
|
local dense_array = eindex_dense_array
|
||||||
|
|
||||||
if entity then
|
if entity then
|
||||||
local index = ECS_ID(entity)
|
local index = ECS_ID(entity)
|
||||||
local alive_count = entity_index.alive_count
|
local alive_count = entity_index.alive_count
|
||||||
local r = eindex_sparse_array[index]
|
local r = sparse_array[index]
|
||||||
if r then
|
if r then
|
||||||
local dense = r.dense
|
local dense = r.dense
|
||||||
|
|
||||||
|
|
@ -3339,17 +3318,17 @@ local function world_new(DEBUG: boolean?)
|
||||||
alive_count += 1
|
alive_count += 1
|
||||||
entity_index.alive_count = alive_count
|
entity_index.alive_count = alive_count
|
||||||
r.dense = alive_count
|
r.dense = alive_count
|
||||||
eindex_dense_array[alive_count] = entity
|
dense_array[alive_count] = entity
|
||||||
return entity
|
return entity
|
||||||
end
|
end
|
||||||
|
|
||||||
-- If dense > 0, check if there's an existing entity at that position
|
-- If dense > 0, check if there's an existing entity at that position
|
||||||
local existing_entity = eindex_dense_array[dense]
|
local existing_entity = dense_array[dense]
|
||||||
if existing_entity and existing_entity ~= entity then
|
if existing_entity and existing_entity ~= entity then
|
||||||
alive_count += 1
|
alive_count += 1
|
||||||
entity_index.alive_count = alive_count
|
entity_index.alive_count = alive_count
|
||||||
r.dense = alive_count
|
r.dense = alive_count
|
||||||
eindex_dense_array[alive_count] = entity
|
dense_array[alive_count] = entity
|
||||||
return entity
|
return entity
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -3360,28 +3339,46 @@ local function world_new(DEBUG: boolean?)
|
||||||
if index > max_id then
|
if index > max_id then
|
||||||
-- Pre-populate all intermediate IDs to keep sparse_array as an array
|
-- Pre-populate all intermediate IDs to keep sparse_array as an array
|
||||||
for i = max_id + 1, index - 1 do
|
for i = max_id + 1, index - 1 do
|
||||||
if not eindex_sparse_array[i] then
|
-- if not sparse_array[i] then
|
||||||
-- NOTE(marcus): We have to do this check to see if
|
-- -- NOTE(marcus): We have to do this check to see if
|
||||||
-- they exist first because world:range() may have
|
-- -- they exist first because world:range() may have
|
||||||
-- pre-populated some slots already.
|
-- -- pre-populated some slots already.
|
||||||
end
|
-- end
|
||||||
|
|
||||||
eindex_sparse_array[i] = { dense = 0 } :: record
|
sparse_array[i] = { dense = 0 } :: record
|
||||||
end
|
end
|
||||||
entity_index.max_id = index
|
entity_index.max_id = index
|
||||||
end
|
end
|
||||||
|
|
||||||
alive_count += 1
|
alive_count += 1
|
||||||
entity_index.alive_count = alive_count
|
entity_index.alive_count = alive_count
|
||||||
eindex_dense_array[alive_count] = entity
|
dense_array[alive_count] = entity
|
||||||
|
|
||||||
r = { dense = alive_count } :: record
|
r = { dense = alive_count } :: record
|
||||||
eindex_sparse_array[index] = r
|
sparse_array[index] = r
|
||||||
|
|
||||||
return entity
|
return entity
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return entity_index_new_id(entity_index)
|
|
||||||
|
local alive_count = entity_index.alive_count
|
||||||
|
local max_id = entity_index.max_id
|
||||||
|
local next_count = alive_count + 1
|
||||||
|
if alive_count < max_id then
|
||||||
|
entity = dense_array[next_count]
|
||||||
|
if entity then
|
||||||
|
entity_index.alive_count = next_count
|
||||||
|
return entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local id = max_id + 1
|
||||||
|
local range_end = entity_index.range_end
|
||||||
|
ecs_assert(range_end == nil or id < range_end, ECS_INTERNAL_ERROR_INCOMPATIBLE_ENTITY)
|
||||||
|
entity_index.max_id = id
|
||||||
|
entity_index.alive_count = next_count
|
||||||
|
dense_array[next_count] = id
|
||||||
|
sparse_array[id] = { dense = next_count } :: record
|
||||||
|
return id
|
||||||
end
|
end
|
||||||
|
|
||||||
local function world_remove(world: world, entity: i53, id: i53)
|
local function world_remove(world: world, entity: i53, id: i53)
|
||||||
|
|
@ -3873,7 +3870,7 @@ local function world_new(DEBUG: boolean?)
|
||||||
end
|
end
|
||||||
|
|
||||||
for i = 1, EcsRest do
|
for i = 1, EcsRest do
|
||||||
entity_index_new_id(entity_index)
|
ENTITY_INDEX_NEW_ID(entity_index)
|
||||||
end
|
end
|
||||||
|
|
||||||
for i = 1, max_component_id do
|
for i = 1, max_component_id do
|
||||||
|
|
@ -3909,7 +3906,7 @@ local function world_new(DEBUG: boolean?)
|
||||||
world_add(world, EcsOnDeleteTarget, EcsExclusive)
|
world_add(world, EcsOnDeleteTarget, EcsExclusive)
|
||||||
|
|
||||||
for i = EcsRest + 1, ecs_max_tag_id do
|
for i = EcsRest + 1, ecs_max_tag_id do
|
||||||
entity_index_new_id(entity_index)
|
ENTITY_INDEX_NEW_ID(entity_index)
|
||||||
end
|
end
|
||||||
|
|
||||||
for i, bundle in ecs_metadata do
|
for i, bundle in ecs_metadata do
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,17 @@ type Id<T=unknown> = jecs.Id<T>
|
||||||
local entity_visualiser = require("@modules/entity_visualiser")
|
local entity_visualiser = require("@modules/entity_visualiser")
|
||||||
local dwi = entity_visualiser.stringify
|
local dwi = entity_visualiser.stringify
|
||||||
|
|
||||||
|
-- FOCUS()
|
||||||
|
TEST("e2 is nil", function()
|
||||||
|
local world = jecs.world(true)
|
||||||
|
local e1 = world:entity(1000)
|
||||||
|
print("-----")
|
||||||
|
local e2 = world:entity()
|
||||||
|
print("-----")
|
||||||
|
|
||||||
|
CHECK(e1 and world:contains(e1))
|
||||||
|
CHECK(e2 and world:contains(e2))
|
||||||
|
end)
|
||||||
TEST("reproduce idr_t nil archetype bug", function()
|
TEST("reproduce idr_t nil archetype bug", function()
|
||||||
local world = jecs.world(true)
|
local world = jecs.world(true)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "ukendio/jecs"
|
name = "ukendio/jecs"
|
||||||
version = "0.10.3"
|
version = "0.10.4"
|
||||||
registry = "https://github.com/UpliftGames/wally-index"
|
registry = "https://github.com/UpliftGames/wally-index"
|
||||||
realm = "shared"
|
realm = "shared"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue