Make world:set idempotent for tags

This commit is contained in:
Ukendio 2024-08-31 05:31:58 +02:00
parent d6179637af
commit aa3e0258e3
2 changed files with 152 additions and 144 deletions

View file

@ -9,6 +9,9 @@ The format is based on [Keep a Changelog][kac], and this project adheres to
[semver]: https://semver.org/spec/v2.0.0.html [semver]: https://semver.org/spec/v2.0.0.html
## [Unreleased] ## [Unreleased]
- `[world]`:
- Improved performance for hooks
- Changed `world:set` to be idempotent when setting tags
- `[traits]`: - `[traits]`:
- Added cleanup condition `jecs.OnDelete` for when the entity or component is deleted - Added cleanup condition `jecs.OnDelete` for when the entity or component is deleted
- Added cleanup action `jecs.Remove` which removes instances of the specified (component) id from all entities - Added cleanup action `jecs.Remove` which removes instances of the specified (component) id from all entities

View file

@ -630,7 +630,7 @@ local function world_set(world: World, entity: i53, id: i53, data: unknown)
local idr = world.componentIndex[id] local idr = world.componentIndex[id]
local flags = idr.flags local flags = idr.flags
local is_tag = bit32.band(flags, ECS_ID_IS_TAG) ~= 0 local is_tag = bit32.band(flags, ECS_ID_IS_TAG) ~= 0
local has_on_set = bit32.band(idr.flags, ECS_ID_HAS_ON_SET) ~= 0 local has_on_set = bit32.band(flags, ECS_ID_HAS_ON_SET) ~= 0
if from == to then if from == to then
if is_tag then if is_tag then
@ -657,18 +657,23 @@ local function world_set(world: World, entity: i53, id: i53, data: unknown)
end end
end end
local tr = to.records[id] local has_on_add = bit32.band(flags, ECS_ID_HAS_ON_ADD) ~= 0
local column = to.columns[tr.column]
if has_on_add then
invoke_hook(world, EcsOnAdd, id, entity)
end
if is_tag then if is_tag then
return return
end end
if not has_on_set then
column[record.row] = data local tr = to.records[id]
else local column = to.columns[tr.column]
invoke_hook(world, EcsOnAdd, id, entity, data)
column[record.row] = data column[record.row] = data
invoke_hook(world, EcsOnSet, id, entity, data)
if has_on_set then
invoke_hook(world, EcsOnSet, id, entity, data)
end end
end end