mirror of
https://github.com/Ukendio/jecs.git
synced 2025-04-25 01:20:04 +00:00
invoke OnRemove hooks when overwritten
This commit is contained in:
parent
f6cac301db
commit
31e364afdf
2 changed files with 74 additions and 13 deletions
22
jecs.luau
22
jecs.luau
|
@ -923,7 +923,19 @@ local function world_add(
|
||||||
if from == to then
|
if from == to then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local idr = world.component_index[id]
|
||||||
|
local idr_hooks = idr.hooks
|
||||||
|
local on_add = idr_hooks.on_add
|
||||||
|
|
||||||
if from then
|
if from then
|
||||||
|
if ECS_IS_PAIR(id) and bit32.band(idr.flags, ECS_ID_EXCLUSIVE) ~= 0 then
|
||||||
|
local on_remove = idr_hooks.on_remove
|
||||||
|
if on_remove then
|
||||||
|
on_remove(entity)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
entity_move(entity_index, entity, record, to)
|
entity_move(entity_index, entity, record, to)
|
||||||
else
|
else
|
||||||
if #to.types > 0 then
|
if #to.types > 0 then
|
||||||
|
@ -931,9 +943,6 @@ local function world_add(
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local idr = world.component_index[id]
|
|
||||||
local on_add = idr.hooks.on_add
|
|
||||||
|
|
||||||
if on_add then
|
if on_add then
|
||||||
on_add(entity)
|
on_add(entity)
|
||||||
end
|
end
|
||||||
|
@ -966,6 +975,13 @@ local function world_set(world: ecs_world_t, entity: i53, id: i53, data: unknown
|
||||||
end
|
end
|
||||||
|
|
||||||
if from then
|
if from then
|
||||||
|
if ECS_IS_PAIR(id) and bit32.band(idr.flags, ECS_ID_EXCLUSIVE) ~= 0 then
|
||||||
|
local on_remove = idr_hooks.on_remove
|
||||||
|
if on_remove then
|
||||||
|
on_remove(entity)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- If there was a previous archetype, then the entity needs to move the archetype
|
-- If there was a previous archetype, then the entity needs to move the archetype
|
||||||
entity_move(entity_index, entity, record, to)
|
entity_move(entity_index, entity, record, to)
|
||||||
else
|
else
|
||||||
|
|
|
@ -1949,22 +1949,67 @@ TEST("world:delete() invokes OnRemove hook", function()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
TEST("exclusive relationships", function()
|
TEST("exclusive relationships", function()
|
||||||
|
do CASE "enforce exclusivity"
|
||||||
local world = world_new()
|
local world = world_new()
|
||||||
local pair = jecs.pair
|
local pair = jecs.pair
|
||||||
|
|
||||||
local child = world:entity()
|
local e = world:entity()
|
||||||
|
|
||||||
for _ = 1, 10 do
|
for _ = 1, 10 do
|
||||||
local A = world:entity()
|
local A = world:entity()
|
||||||
local B = world:entity()
|
local B = world:entity()
|
||||||
|
|
||||||
world:add(child, pair(world:entity(), child)) -- noise
|
world:add(e, pair(world:entity(), e)) -- noise
|
||||||
world:add(child, pair(ChildOf, A))
|
world:add(e, pair(ChildOf, A))
|
||||||
world:add(child, pair(child, world:entity())) -- noise
|
world:add(e, pair(ChildOf, B))
|
||||||
world:add(child, pair(ChildOf, B))
|
|
||||||
|
|
||||||
CHECK(world:has(child, pair(ChildOf, B)))
|
CHECK(not world:has(e, pair(ChildOf, A)))
|
||||||
CHECK(not world:has(child, pair(ChildOf, A)))
|
CHECK(world:has(e, pair(ChildOf, B)))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
do CASE "invoke OnRemove when overwritten using world:add()"
|
||||||
|
local world = world_new()
|
||||||
|
local pair = jecs.pair
|
||||||
|
|
||||||
|
local relation = world:component()
|
||||||
|
world:add(relation, jecs.Exclusive)
|
||||||
|
|
||||||
|
local e = world:entity()
|
||||||
|
local A = world:entity()
|
||||||
|
local B = world:entity()
|
||||||
|
|
||||||
|
local called = false
|
||||||
|
world:set(relation, jecs.OnRemove, function(e)
|
||||||
|
called = true
|
||||||
|
CHECK(world:target(e, relation) == A)
|
||||||
|
end)
|
||||||
|
|
||||||
|
world:add(e, pair(relation, A))
|
||||||
|
world:add(e, pair(relation, B))
|
||||||
|
|
||||||
|
CHECK(called)
|
||||||
|
end
|
||||||
|
do CASE "invoke OnRemove when overwritten using world:set()"
|
||||||
|
local world = world_new()
|
||||||
|
local pair = jecs.pair
|
||||||
|
|
||||||
|
local relation = world:component()
|
||||||
|
world:add(relation, jecs.Exclusive)
|
||||||
|
|
||||||
|
local e = world:entity()
|
||||||
|
local A = world:entity()
|
||||||
|
local B = world:entity()
|
||||||
|
|
||||||
|
local called = false
|
||||||
|
world:set(relation, jecs.OnRemove, function(e)
|
||||||
|
called = true
|
||||||
|
CHECK(world:target(e, relation) == A)
|
||||||
|
end)
|
||||||
|
|
||||||
|
world:set(e, pair(relation, A), nil)
|
||||||
|
world:set(e, pair(relation, B), nil)
|
||||||
|
|
||||||
|
CHECK(called)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue