mirror of
https://github.com/Ukendio/jecs.git
synced 2026-03-18 00:44:32 +00:00
Remove the exact terms lookup set and detect bulk operation for removal of pairs
This commit is contained in:
parent
5f76674723
commit
6552a5d2d1
2 changed files with 54 additions and 32 deletions
|
|
@ -152,11 +152,6 @@ local function monitors_new(query: jecs.Query<...any>): Monitor
|
||||||
|
|
||||||
local entity_index = world.entity_index :: any
|
local entity_index = world.entity_index :: any
|
||||||
|
|
||||||
local terms_lookup: { [jecs.Id<any>]: boolean } = {}
|
|
||||||
for _, term in terms do
|
|
||||||
terms_lookup[term] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
local callback_added: ((jecs.Entity) -> ())?
|
local callback_added: ((jecs.Entity) -> ())?
|
||||||
local callback_removed: ((jecs.Entity) -> ())?
|
local callback_removed: ((jecs.Entity) -> ())?
|
||||||
|
|
||||||
|
|
@ -176,7 +171,7 @@ local function monitors_new(query: jecs.Query<...any>): Monitor
|
||||||
local r = jecs.entity_index_try_get_fast(
|
local r = jecs.entity_index_try_get_fast(
|
||||||
entity_index, entity :: any) :: jecs.Record
|
entity_index, entity :: any) :: jecs.Record
|
||||||
if not archetypes[oldarchetype.id] and archetypes[r.archetype.id] then
|
if not archetypes[oldarchetype.id] and archetypes[r.archetype.id] then
|
||||||
if last_old_archetype == oldarchetype and last_entity == entity and terms_lookup[id] then
|
if last_old_archetype == oldarchetype and last_entity == entity then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -232,7 +227,7 @@ local function monitors_new(query: jecs.Query<...any>): Monitor
|
||||||
entity_index, entity :: any) :: jecs.Record
|
entity_index, entity :: any) :: jecs.Record
|
||||||
|
|
||||||
if not archetypes[oldarchetype.id] and archetypes[r.archetype.id] then
|
if not archetypes[oldarchetype.id] and archetypes[r.archetype.id] then
|
||||||
if last_old_archetype == oldarchetype and last_entity == entity and terms_lookup[id] then
|
if last_old_archetype == oldarchetype and last_entity == entity then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -253,10 +248,17 @@ local function monitors_new(query: jecs.Query<...any>): Monitor
|
||||||
end
|
end
|
||||||
|
|
||||||
local r = jecs.record(world, entity)
|
local r = jecs.record(world, entity)
|
||||||
if archetypes[r.archetype.id] then
|
local src = r.archetype
|
||||||
last_old_archetype = nil
|
|
||||||
callback_removed(entity)
|
if last_entity == entity and last_old_archetype == src then
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
if not archetypes[src.id] then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
last_entity = entity
|
||||||
|
last_old_archetype = src
|
||||||
|
callback_removed(entity)
|
||||||
end)
|
end)
|
||||||
table.insert(cleanup, onadded)
|
table.insert(cleanup, onadded)
|
||||||
table.insert(cleanup, onremoved)
|
table.insert(cleanup, onremoved)
|
||||||
|
|
@ -294,7 +296,7 @@ local function monitors_new(query: jecs.Query<...any>): Monitor
|
||||||
callback_removed(entity)
|
callback_removed(entity)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
local onremoved = world:removed(rel, function(entity, id, delete)
|
local onremoved = world:removed(rel, function(entity: jecs.Entity, id: jecs.Id, delete)
|
||||||
if delete then
|
if delete then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
@ -310,7 +312,7 @@ local function monitors_new(query: jecs.Query<...any>): Monitor
|
||||||
if not archetype then
|
if not archetype then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if last_old_archetype == archetype and terms_lookup[id] then
|
if last_old_archetype == archetype then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
44
test/ob.luau
44
test/ob.luau
|
|
@ -838,27 +838,47 @@ TEST("modules/ob::monitor", function()
|
||||||
do CASE "monitor with wildcard pair should handle bulk_insert"
|
do CASE "monitor with wildcard pair should handle bulk_insert"
|
||||||
local A = world:component()
|
local A = world:component()
|
||||||
local B = world:component()
|
local B = world:component()
|
||||||
local e1 = world:entity()
|
local C = world:component()
|
||||||
local e2 = world:entity()
|
local Relation = world:component()
|
||||||
local e3 = world:entity()
|
local entity1 = world:entity()
|
||||||
|
local entity = world:entity()
|
||||||
|
|
||||||
local monitor = ob.monitor(world:query(A, jecs.pair(B, jecs.w)))
|
local monitor = ob.monitor(world:query(A, B, C, jecs.pair(Relation, jecs.w)))
|
||||||
local c = 0
|
local c = 0
|
||||||
monitor.added(function()
|
monitor.added(function()
|
||||||
c += 1
|
c += 1
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local e = world:entity()
|
jecs.bulk_insert(world, entity, { A, B, C, jecs.pair(Relation, entity1) }, { 1, 2, 3, 4 })
|
||||||
world:add(e, A)
|
|
||||||
CHECK(c == 0)
|
|
||||||
world:add(e, jecs.pair(B, e1))
|
|
||||||
CHECK(c == 1)
|
|
||||||
world:add(e, jecs.pair(B, e2))
|
|
||||||
CHECK(c == 1)
|
|
||||||
world:add(e, jecs.pair(B, e3))
|
|
||||||
CHECK(c == 1)
|
CHECK(c == 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
do CASE "monitor with wildcard pair: bulk_remove reports removed exactly once"
|
||||||
|
local A = world:component()
|
||||||
|
local B = world:component()
|
||||||
|
local C = world:component()
|
||||||
|
local Relation = world:component()
|
||||||
|
local entity1 = world:entity()
|
||||||
|
local entity = world:entity()
|
||||||
|
|
||||||
|
local monitor = ob.monitor(world:query(A, B, C, jecs.pair(Relation, jecs.w)))
|
||||||
|
local added_count = 0
|
||||||
|
local removed_count = 0
|
||||||
|
monitor.added(function()
|
||||||
|
added_count += 1
|
||||||
|
end)
|
||||||
|
monitor.removed(function()
|
||||||
|
removed_count += 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
jecs.bulk_insert(world, entity, { A, B, C, jecs.pair(Relation, entity1) }, { 1, 2, 3, 4 })
|
||||||
|
CHECK(added_count == 1)
|
||||||
|
CHECK(removed_count == 0)
|
||||||
|
|
||||||
|
jecs.bulk_remove(world, entity, { A, B, C, jecs.pair(Relation, entity1) })
|
||||||
|
CHECK(removed_count == 1)
|
||||||
|
end
|
||||||
|
|
||||||
do CASE "monitor with multiple pairs should handle separate operations correctly"
|
do CASE "monitor with multiple pairs should handle separate operations correctly"
|
||||||
local A = world:component()
|
local A = world:component()
|
||||||
local B = world:component()
|
local B = world:component()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue