mirror of
https://github.com/Ukendio/jecs.git
synced 2025-04-24 17:10:03 +00:00
Fix bits arrangement in IDs
Some checks failed
Some checks failed
This commit is contained in:
parent
e073a570b7
commit
9d83c3bc13
3 changed files with 95 additions and 120 deletions
|
@ -28,22 +28,22 @@ local B6 = ecr.component()
|
|||
local B7 = ecr.component()
|
||||
local B8 = ecr.component()
|
||||
|
||||
local C1 = ecs:entity()
|
||||
local C2 = ecs:entity()
|
||||
local C3 = ecs:entity()
|
||||
local C4 = ecs:entity()
|
||||
local C5 = ecs:entity()
|
||||
local C6 = ecs:entity()
|
||||
local C7 = ecs:entity()
|
||||
local C8 = ecs:entity()
|
||||
local E1 = mcs:entity()
|
||||
local E2 = mcs:entity()
|
||||
local E3 = mcs:entity()
|
||||
local E4 = mcs:entity()
|
||||
local E5 = mcs:entity()
|
||||
local E6 = mcs:entity()
|
||||
local E7 = mcs:entity()
|
||||
local E8 = mcs:entity()
|
||||
local C1 = ecs:component()
|
||||
local C2 = ecs:component()
|
||||
local C3 = ecs:component()
|
||||
local C4 = ecs:component()
|
||||
local C5 = ecs:component()
|
||||
local C6 = ecs:component()
|
||||
local C7 = ecs:component()
|
||||
local C8 = ecs:component()
|
||||
local E1 = mcs:component()
|
||||
local E2 = mcs:component()
|
||||
local E3 = mcs:component()
|
||||
local E4 = mcs:component()
|
||||
local E5 = mcs:component()
|
||||
local E6 = mcs:component()
|
||||
local E7 = mcs:component()
|
||||
local E8 = mcs:component()
|
||||
|
||||
local registry2 = ecr.registry()
|
||||
return {
|
||||
|
@ -52,48 +52,30 @@ return {
|
|||
end,
|
||||
|
||||
Functions = {
|
||||
Matter = function()
|
||||
local e = newWorld:spawn()
|
||||
Mirror = function()
|
||||
local e = mcs:entity()
|
||||
for i = 1, 5000 do
|
||||
newWorld:insert(
|
||||
e,
|
||||
A1({ value = true }),
|
||||
A2({ value = true }),
|
||||
A3({ value = true }),
|
||||
A4({ value = true }),
|
||||
A5({ value = true }),
|
||||
A6({ value = true }),
|
||||
A7({ value = true }),
|
||||
A8({ value = true })
|
||||
)
|
||||
mcs:set(e, E1, false)
|
||||
mcs:set(e, E2, false)
|
||||
mcs:set(e, E3, false)
|
||||
mcs:set(e, E4, false)
|
||||
mcs:set(e, E5, false)
|
||||
mcs:set(e, E6, false)
|
||||
mcs:set(e, E7, false)
|
||||
mcs:set(e, E8, false)
|
||||
end
|
||||
end,
|
||||
|
||||
ECR = function()
|
||||
local e = registry2.create()
|
||||
for i = 1, 5000 do
|
||||
registry2:set(e, B1, { value = false })
|
||||
registry2:set(e, B2, { value = false })
|
||||
registry2:set(e, B3, { value = false })
|
||||
registry2:set(e, B4, { value = false })
|
||||
registry2:set(e, B5, { value = false })
|
||||
registry2:set(e, B6, { value = false })
|
||||
registry2:set(e, B7, { value = false })
|
||||
registry2:set(e, B8, { value = false })
|
||||
end
|
||||
end,
|
||||
|
||||
Jecs = function()
|
||||
local e = ecs:entity()
|
||||
for i = 1, 5000 do
|
||||
ecs:set(e, C1, { value = false })
|
||||
ecs:set(e, C2, { value = false })
|
||||
ecs:set(e, C3, { value = false })
|
||||
ecs:set(e, C4, { value = false })
|
||||
ecs:set(e, C5, { value = false })
|
||||
ecs:set(e, C6, { value = false })
|
||||
ecs:set(e, C7, { value = false })
|
||||
ecs:set(e, C8, { value = false })
|
||||
ecs:set(e, C1, false)
|
||||
ecs:set(e, C2, false)
|
||||
ecs:set(e, C3, false)
|
||||
ecs:set(e, C4, false)
|
||||
ecs:set(e, C5, false)
|
||||
ecs:set(e, C6, false)
|
||||
ecs:set(e, C7, false)
|
||||
ecs:set(e, C8, false)
|
||||
end
|
||||
end,
|
||||
},
|
||||
|
|
80
jecs.luau
80
jecs.luau
|
@ -90,60 +90,35 @@ local EcsOnArchetypeCreate = HI_COMPONENT_ID + 12
|
|||
local EcsOnArchetypeDelete = HI_COMPONENT_ID + 13
|
||||
local EcsRest = HI_COMPONENT_ID + 14
|
||||
|
||||
local ECS_PAIR_FLAG = 0x8
|
||||
local ECS_ID_FLAGS_MASK = 0x10
|
||||
local ECS_ENTITY_MASK = bit32.lshift(1, 24)
|
||||
local ECS_GENERATION_MASK = bit32.lshift(1, 16)
|
||||
|
||||
local ECS_ID_DELETE = 0b0000_0001
|
||||
local ECS_ID_IS_TAG = 0b0000_0010
|
||||
local ECS_ID_HAS_ON_ADD = 0b0000_0100
|
||||
local ECS_ID_HAS_ON_SET = 0b0000_1000
|
||||
local ECS_ID_HAS_ON_REMOVE = 0b0001_0000
|
||||
local ECS_ID_MASK = 0b0000_0000
|
||||
-- stylua: ignore end
|
||||
local NULL_ARRAY = table.freeze({}) :: Column
|
||||
|
||||
local function FLAGS_ADD(is_pair: boolean): number
|
||||
local flags = 0x0
|
||||
local ECS_ENTITY_MASK = bit32.lshift(1, 24)
|
||||
local ECS_GENERATION_MASK = bit32.lshift(1, 16)
|
||||
|
||||
if is_pair then
|
||||
flags = bit32.bor(flags, ECS_PAIR_FLAG) -- HIGHEST bit in the ID.
|
||||
end
|
||||
if false then
|
||||
flags = bit32.bor(flags, 0x4) -- Set the second flag to true
|
||||
end
|
||||
if false then
|
||||
flags = bit32.bor(flags, 0x2) -- Set the third flag to true
|
||||
end
|
||||
if false then
|
||||
flags = bit32.bor(flags, 0x1) -- LAST BIT in the ID.
|
||||
end
|
||||
local NULL_ARRAY = table.freeze({})
|
||||
|
||||
return flags
|
||||
end
|
||||
|
||||
local function ECS_COMBINE(source: number, target: number): i53
|
||||
return (source * 268435456) + (target * ECS_ID_FLAGS_MASK)
|
||||
|
||||
local function ECS_COMBINE(id: number, generation: number): i53
|
||||
return id + (generation * ECS_ENTITY_MASK)
|
||||
end
|
||||
local ECS_PAIR_OFFSET = 2^48
|
||||
|
||||
local function ECS_IS_PAIR(e: number): boolean
|
||||
return if e > ECS_ENTITY_MASK then (e % ECS_ID_FLAGS_MASK) // ECS_PAIR_FLAG ~= 0 else false
|
||||
end
|
||||
|
||||
-- HIGH 24 bits LOW 24 bits
|
||||
local function ECS_GENERATION(e: i53): i24
|
||||
return if e > ECS_ENTITY_MASK then (e // ECS_ID_FLAGS_MASK) % ECS_GENERATION_MASK else 0
|
||||
return e > ECS_PAIR_OFFSET
|
||||
end
|
||||
|
||||
local function ECS_GENERATION_INC(e: i53)
|
||||
if e > ECS_ENTITY_MASK then
|
||||
local flags = e // ECS_ID_FLAGS_MASK
|
||||
local id = flags // ECS_ENTITY_MASK
|
||||
local generation = flags % ECS_GENERATION_MASK
|
||||
local id = e % ECS_ENTITY_MASK
|
||||
local generation = e // ECS_ENTITY_MASK
|
||||
|
||||
local next_gen = generation + 1
|
||||
if next_gen > ECS_GENERATION_MASK then
|
||||
if next_gen >= ECS_GENERATION_MASK then
|
||||
return id
|
||||
end
|
||||
|
||||
|
@ -152,22 +127,23 @@ local function ECS_GENERATION_INC(e: i53)
|
|||
return ECS_COMBINE(e, 1)
|
||||
end
|
||||
|
||||
-- FIRST gets the high ID
|
||||
local function ECS_ENTITY_T_HI(e: i53): i24
|
||||
return if e > ECS_ENTITY_MASK then (e // ECS_ID_FLAGS_MASK) % ECS_ENTITY_MASK else e
|
||||
end
|
||||
|
||||
-- SECOND
|
||||
local function ECS_ENTITY_T_LO(e: i53): i24
|
||||
return if e > ECS_ENTITY_MASK then (e // ECS_ID_FLAGS_MASK) // ECS_ENTITY_MASK else e
|
||||
return e % ECS_ENTITY_MASK
|
||||
end
|
||||
|
||||
local function _STRIP_GENERATION(e: i53): i24
|
||||
return ECS_ENTITY_T_LO(e)
|
||||
local function ECS_GENERATION(e: i53)
|
||||
return e // ECS_ENTITY_MASK
|
||||
end
|
||||
|
||||
local function ECS_ENTITY_T_HI(e: i53): i24
|
||||
return e // ECS_ENTITY_MASK
|
||||
end
|
||||
|
||||
local function ECS_PAIR(pred: i53, obj: i53): i53
|
||||
return ECS_COMBINE(ECS_ENTITY_T_LO(pred), ECS_ENTITY_T_LO(obj)) + FLAGS_ADD(--[[isPair]] true) :: i53
|
||||
pred %= ECS_ENTITY_MASK
|
||||
obj %= ECS_ENTITY_MASK
|
||||
|
||||
return obj + (pred * 2^24) + ECS_PAIR_OFFSET
|
||||
end
|
||||
|
||||
local function entity_index_try_get_any(entity_index: EntityIndex, entity: number): Record?
|
||||
|
@ -236,14 +212,14 @@ local function entity_index_new_id(entity_index: EntityIndex): i53
|
|||
return id
|
||||
end
|
||||
|
||||
-- ECS_PAIR_FIRST, gets the relationship target / obj / HIGH bits
|
||||
local function ecs_pair_first(world, e)
|
||||
return entity_index_get_alive(world.entity_index, ECS_ENTITY_T_LO(e))
|
||||
local pred = (e - ECS_PAIR_OFFSET) // ECS_ENTITY_MASK
|
||||
return entity_index_get_alive(world.entity_index, pred)
|
||||
end
|
||||
|
||||
-- ECS_PAIR_SECOND gets the relationship / pred / LOW bits
|
||||
local function ecs_pair_second(world, e)
|
||||
return entity_index_get_alive(world.entity_index, ECS_ENTITY_T_HI(e))
|
||||
local obj = (e - ECS_PAIR_OFFSET) % ECS_ENTITY_MASK
|
||||
return entity_index_get_alive(world.entity_index, obj)
|
||||
end
|
||||
|
||||
local function query_match(query, archetype: Archetype)
|
||||
|
@ -476,8 +452,8 @@ local function world_target(world: World, entity: i53, relation: i24, index: num
|
|||
return nil
|
||||
end
|
||||
|
||||
if nth >= count then
|
||||
nth = nth + count + 1
|
||||
if nth > count then
|
||||
nth = nth + count
|
||||
end
|
||||
|
||||
local tr = idr.cache[archetype_id]
|
||||
|
|
|
@ -241,19 +241,6 @@ local pe = require("@tools/entity_visualiser").prettify
|
|||
local lifetime_tracker_add = require("@tools/lifetime_tracker")
|
||||
|
||||
TEST("world:entity()", function()
|
||||
do CASE "ensure id"
|
||||
local w = world_new()
|
||||
w = lifetime_tracker_add(w, {padding_enabled=false})
|
||||
local id = w:entity()
|
||||
CHECK(id == w:entity(id))
|
||||
CHECK(w:entity(999 :: any) == 999 :: any)
|
||||
w:print_snapshot()
|
||||
local id1 = w:entity(999)
|
||||
CHECK(w:contains(999))
|
||||
CHECK(not w:contains(998))
|
||||
print(w:entity(), "newest id after 999")
|
||||
end
|
||||
|
||||
do
|
||||
CASE("unique IDs")
|
||||
local world = jecs.World.new()
|
||||
|
@ -1388,10 +1375,15 @@ TEST("world:target", function()
|
|||
world:add(e, pair(C, D))
|
||||
|
||||
CHECK(pair(A, B) < pair(A, C))
|
||||
CHECK(pair(A, E) < pair(B, C))
|
||||
CHECK(pair(A, C) < pair(A, D))
|
||||
CHECK(pair(C, A) < pair(C, D))
|
||||
|
||||
local records = debug_world_inspect(world).records(e)
|
||||
CHECK(jecs.pair_first(world, pair(B, C)) == B)
|
||||
local r = jecs.entity_index_try_get(world.entity_index, e)
|
||||
local archetype = r.archetype
|
||||
local counts = archetype.counts
|
||||
CHECK(counts[pair(A, __)] == 4)
|
||||
CHECK(records[pair(B, C)] > records[pair(A, E)])
|
||||
CHECK(world:target(e, A, 0) == B)
|
||||
CHECK(world:target(e, A, 1) == C)
|
||||
|
@ -1401,6 +1393,28 @@ TEST("world:target", function()
|
|||
CHECK(world:target(e, B, 1) == D)
|
||||
CHECK(world:target(e, C, 0) == D)
|
||||
CHECK(world:target(e, C, 1) == nil)
|
||||
|
||||
-- for id in archetype.records do
|
||||
-- local f = world:get(ecs_pair_first(world, id), jecs.Name)
|
||||
-- local s = world:get(ecs_pair_second(world, id), jecs.Name)
|
||||
-- print(`({f}, {s})`)
|
||||
-- end
|
||||
--
|
||||
|
||||
CHECK(archetype.records[pair(A, B)] == 1)
|
||||
CHECK(archetype.records[pair(A, C)] == 2)
|
||||
CHECK(archetype.records[pair(A, D)] == 3)
|
||||
CHECK(archetype.records[pair(A, E)] == 4)
|
||||
-- print("(A, B)", archetype.records[pair(A, B)])
|
||||
-- print("(A, C)", archetype.records[pair(A, C)])
|
||||
-- print("(A, D)", archetype.records[pair(A, D)])
|
||||
-- print("(A, E)", archetype.records[pair(A, E)])
|
||||
|
||||
-- print(pair(A, D), pair(B, C))
|
||||
-- print("(B, C)", archetype.records[pair(B, C)])
|
||||
|
||||
CHECK(world:target(e, C, 0) == D)
|
||||
CHECK(world:target(e, C, 1) == nil)
|
||||
end
|
||||
|
||||
do
|
||||
|
@ -1516,7 +1530,7 @@ TEST("Hooks", function()
|
|||
world:set(e, A, true)
|
||||
world:remove(e, A)
|
||||
CHECK(not world:get(e, A))
|
||||
CHECK(not world:get(e, B))
|
||||
CHECK(world:get(e, B))
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
@ -1596,7 +1610,6 @@ TEST("repro", function()
|
|||
|
||||
if cooldown <= 0 then
|
||||
table.insert(toRemove, id)
|
||||
print("removing")
|
||||
-- world:remove(id, components.Cooldown)
|
||||
else
|
||||
world:set(id, components.Cooldown, cooldown)
|
||||
|
@ -1645,6 +1658,10 @@ TEST("wildcard query", function()
|
|||
|
||||
local entity = world:entity()
|
||||
|
||||
local p = pair(Relation, A)
|
||||
CHECK(jecs.pair_first(world, p) == Relation)
|
||||
CHECK(jecs.pair_second(world, p) == A)
|
||||
local w = dwi(world)
|
||||
world:add(entity, pair(Relation, A))
|
||||
|
||||
local counter = 0
|
||||
|
|
Loading…
Reference in a new issue