OnChange should invoke after data has been set
Some checks are pending
analysis / Run Luau Analyze (push) Waiting to run
deploy-docs / build (push) Waiting to run
deploy-docs / Deploy (push) Blocked by required conditions
publish-npm / publish (push) Waiting to run
unit-testing / Run Luau Tests (push) Waiting to run

This commit is contained in:
Ukendio 2025-03-30 22:49:11 +02:00
parent 7bcd6bd220
commit 41ebde415f
3 changed files with 18 additions and 13 deletions

View file

@ -18,7 +18,7 @@ The format is based on [Keep a Changelog][kac], and this project adheres to
- Specifically happened when you had at least two pairs of different relations with multiple targets each
- `[hooks]`:
- Replaced `OnSet` with `OnChange`
- The former was used to detect emplace/move actions. Now the behaviour for `OnChange` is that it will run only when the value is about to be changed allowing you to retrieve the old value when needed
- The former was used to detect emplace/move actions. Now the behaviour for `OnChange` is that it will run only when the value has changed
- Changed `OnAdd` to specifically run after the data has been set for non-zero-sized components. Also returns the value that the component was set to
- This should allow a more lenient window for modifying data
- Changed `OnRemove` to lazily lookup which archetype the entity will move to

View file

@ -124,12 +124,9 @@ local EcsOnArchetypeCreate = HI_COMPONENT_ID + 12
local EcsOnArchetypeDelete = HI_COMPONENT_ID + 13
local EcsRest = HI_COMPONENT_ID + 14
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
local ECS_ID_DELETE = 0b01
local ECS_ID_IS_TAG = 0b10
local ECS_ID_MASK = 0b00
local ECS_ENTITY_MASK = bit32.lshift(1, 24)
local ECS_GENERATION_MASK = bit32.lshift(1, 16)
@ -930,6 +927,10 @@ local function world_set(world: ecs_world_t, entity: i53, id: i53, data: unknown
local idr_hooks = idr.hooks
if from == to then
local tr = to.records[id]
local column = from.columns[tr]
column[record.row] = data
-- If the archetypes are the same it can avoid moving the entity
-- and just set the data directly.
local on_change = idr_hooks.on_change
@ -937,9 +938,6 @@ local function world_set(world: ecs_world_t, entity: i53, id: i53, data: unknown
on_change(entity, data)
end
local tr = to.records[id]
local column = from.columns[tr]
column[record.row] = data
return
end
@ -962,8 +960,6 @@ local function world_set(world: ecs_world_t, entity: i53, id: i53, data: unknown
if on_add then
on_add(entity, data)
end
end
local function world_component(world: World): i53

View file

@ -1665,11 +1665,20 @@ TEST("Hooks", function()
local Number = world:component()
local e1 = world:entity()
local call = 0
world:set(Number, jecs.OnChange, function(entity, data)
CHECK(e1 == entity)
CHECK(world:get(entity, Number) == nil)
if call == 1 then
CHECK(false)
elseif call == 2 then
CHECK(world:get(entity, Number) == data)
end
CHECK(data == 1)
end)
call = 1
world:set(e1, Number, 1)
call = 2
world:set(e1, Number, 1)
end