mirror of
https://github.com/Ukendio/jecs.git
synced 2025-08-04 03:09:18 +00:00
Make ChildOf exclusive
This commit is contained in:
parent
b1c788a677
commit
0f7fd78285
2 changed files with 50 additions and 41 deletions
68
jecs.luau
68
jecs.luau
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
--!optimize 2
|
--!optimize 2
|
||||||
--!native
|
--!native
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -935,10 +934,12 @@ local function find_archetype_with(world: World, id: Id, from: Archetype): Arche
|
||||||
local idr = world.component_index[ECS_PAIR(first, EcsWildcard)]
|
local idr = world.component_index[ECS_PAIR(first, EcsWildcard)]
|
||||||
if idr and bit32.btest(idr.flags, EcsExclusive) then
|
if idr and bit32.btest(idr.flags, EcsExclusive) then
|
||||||
local cr = idr.records[from.id]
|
local cr = idr.records[from.id]
|
||||||
|
if cr then
|
||||||
dst[cr] = id
|
dst[cr] = id
|
||||||
return archetype_ensure(world, dst)
|
return archetype_ensure(world, dst)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local at = find_insert(id_types :: { number } , id :: number)
|
local at = find_insert(id_types :: { number } , id :: number)
|
||||||
|
|
||||||
|
@ -2203,37 +2204,6 @@ local function world_new()
|
||||||
return r
|
return r
|
||||||
end
|
end
|
||||||
|
|
||||||
local function inner_world_add<T, a>(
|
|
||||||
world: World,
|
|
||||||
entity: Entity<T>,
|
|
||||||
id: Id<a>
|
|
||||||
): ()
|
|
||||||
local entity_index = world.entity_index
|
|
||||||
local record = inner_entity_index_try_get_unsafe(entity :: number)
|
|
||||||
if not record then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local from = record.archetype
|
|
||||||
local to = archetype_traverse_add(world, id, from)
|
|
||||||
if from == to then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if from then
|
|
||||||
entity_move(entity_index, entity, record, to)
|
|
||||||
else
|
|
||||||
if #to.types > 0 then
|
|
||||||
new_entity(entity, record, to)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local idr = world.component_index[id]
|
|
||||||
local on_add = idr.hooks.on_add
|
|
||||||
|
|
||||||
if on_add then
|
|
||||||
on_add(entity, id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function inner_world_get(world: World, entity: Entity,
|
local function inner_world_get(world: World, entity: Entity,
|
||||||
a: Id, b: Id?, c: Id?, d: Id?, e: Id?): ...any
|
a: Id, b: Id?, c: Id?, d: Id?, e: Id?): ...any
|
||||||
|
@ -2349,6 +2319,38 @@ local function world_new()
|
||||||
return to
|
return to
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function inner_world_add<T, a>(
|
||||||
|
world: World,
|
||||||
|
entity: Entity<T>,
|
||||||
|
id: Id<a>
|
||||||
|
): ()
|
||||||
|
local entity_index = world.entity_index
|
||||||
|
local record = inner_entity_index_try_get_unsafe(entity :: number)
|
||||||
|
if not record then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local from = record.archetype
|
||||||
|
local to = archetype_traverse_add(world, id, from)
|
||||||
|
if from == to then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if from then
|
||||||
|
entity_move(entity_index, entity, record, to)
|
||||||
|
else
|
||||||
|
if #to.types > 0 then
|
||||||
|
new_entity(entity, record, to)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local idr = world.component_index[id]
|
||||||
|
local on_add = idr.hooks.on_add
|
||||||
|
|
||||||
|
if on_add then
|
||||||
|
on_add(entity, id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function inner_world_set<T, a>(world: World, entity: Entity<T>, id: Id<a>, data: a): ()
|
local function inner_world_set<T, a>(world: World, entity: Entity<T>, id: Id<a>, data: a): ()
|
||||||
local record = inner_entity_index_try_get_unsafe(entity :: number)
|
local record = inner_entity_index_try_get_unsafe(entity :: number)
|
||||||
if not record then
|
if not record then
|
||||||
|
@ -2571,7 +2573,6 @@ local function world_new()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function inner_world_delete<T>(world: World, entity: Entity<T>)
|
local function inner_world_delete<T>(world: World, entity: Entity<T>)
|
||||||
|
@ -2858,6 +2859,7 @@ local function world_new()
|
||||||
inner_world_set(world, EcsRest, EcsRest, "jecs.Rest")
|
inner_world_set(world, EcsRest, EcsRest, "jecs.Rest")
|
||||||
|
|
||||||
inner_world_add(world, EcsChildOf, ECS_PAIR(EcsOnDeleteTarget, EcsDelete))
|
inner_world_add(world, EcsChildOf, ECS_PAIR(EcsOnDeleteTarget, EcsDelete))
|
||||||
|
inner_world_add(world, EcsChildOf, 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)
|
||||||
|
|
|
@ -1686,7 +1686,9 @@ end)
|
||||||
TEST("#repro2", function()
|
TEST("#repro2", function()
|
||||||
local world = jecs.world()
|
local world = jecs.world()
|
||||||
local Lifetime = world:component() :: Id<number>
|
local Lifetime = world:component() :: Id<number>
|
||||||
|
world:set(Lifetime, jecs.Name, "Lifetime")
|
||||||
local Particle = world:entity()
|
local Particle = world:entity()
|
||||||
|
world:set(Particle, jecs.Name, "Particle")
|
||||||
local Beam = world:entity()
|
local Beam = world:entity()
|
||||||
|
|
||||||
local entity = world:entity()
|
local entity = world:entity()
|
||||||
|
@ -1694,19 +1696,24 @@ TEST("#repro2", function()
|
||||||
world:set(entity, pair(Lifetime, Beam), 2)
|
world:set(entity, pair(Lifetime, Beam), 2)
|
||||||
world:set(entity, pair(4 :: any, 5 :: any), 6) -- noise
|
world:set(entity, pair(4 :: any, 5 :: any), 6) -- noise
|
||||||
|
|
||||||
|
CHECK(world:get(entity, pair(Lifetime, Particle)) == 1)
|
||||||
|
CHECK(world:get(entity, pair(Lifetime, Beam)) == 2)
|
||||||
|
|
||||||
|
CHECK(world:target(entity, Lifetime, 0) == Particle)
|
||||||
|
CHECK(world:target(entity, Lifetime, 1) == Beam)
|
||||||
|
|
||||||
-- entity_visualizer.components(world, entity)
|
-- entity_visualizer.components(world, entity)
|
||||||
|
|
||||||
|
-- print(CHECK(world:has(jecs.ChildOf, jecs.Exclusive)))
|
||||||
|
|
||||||
for e in world:each(pair(Lifetime, __)) do
|
for e in world:each(pair(Lifetime, __)) do
|
||||||
local i = 0
|
local i = 0
|
||||||
local nth = world:target(e, Lifetime, i)
|
local nth = world:target(e, Lifetime, i)
|
||||||
while nth do
|
while nth do
|
||||||
-- entity_visualizer.components(world, e)
|
-- entity_visualizer.components(world, e)
|
||||||
|
|
||||||
local data = world:get(e, pair(Lifetime, nth)) :: number
|
local data = world:get(e, pair(Lifetime, nth)) :: number
|
||||||
|
if data > 0 then
|
||||||
data -= 1
|
data -= 1
|
||||||
if data <= 0 then
|
|
||||||
world:remove(e, pair(Lifetime, nth))
|
|
||||||
else
|
|
||||||
world:set(e, pair(Lifetime, nth), data)
|
world:set(e, pair(Lifetime, nth), data)
|
||||||
end
|
end
|
||||||
i += 1
|
i += 1
|
||||||
|
@ -1714,7 +1721,7 @@ TEST("#repro2", function()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
CHECK(not world:has(entity, pair(Lifetime, Particle)))
|
CHECK(world:get(entity, pair(Lifetime, Particle)) == 0)
|
||||||
CHECK(world:get(entity, pair(Lifetime, Beam)) == 1)
|
CHECK(world:get(entity, pair(Lifetime, Beam)) == 1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue