diff --git a/CHANGELOG.md b/CHANGELOG.md index ebdb06f..19a8ef1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/jecs.luau b/jecs.luau index 4815c9a..8080a5b 100644 --- a/jecs.luau +++ b/jecs.luau @@ -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 diff --git a/test/tests.luau b/test/tests.luau index 2b3ada8..7091be0 100644 --- a/test/tests.luau +++ b/test/tests.luau @@ -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