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
|
|
@ -9,7 +9,7 @@ local function duplicate(query: jecs.Query<...any>): jecs.CachedQuery<...any>
|
|||
local world = (query :: jecs.Query<any> & { world: World }).world
|
||||
local dup = world:query()
|
||||
dup.filter_with = table.clone(query.filter_with)
|
||||
if query.filter_without then
|
||||
if query.filter_without then
|
||||
dup.filter_without = query.filter_without
|
||||
end
|
||||
return dup:cached()
|
||||
|
|
@ -152,11 +152,6 @@ local function monitors_new(query: jecs.Query<...any>): Monitor
|
|||
|
||||
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_removed: ((jecs.Entity) -> ())?
|
||||
|
||||
|
|
@ -176,7 +171,7 @@ local function monitors_new(query: jecs.Query<...any>): Monitor
|
|||
local r = jecs.entity_index_try_get_fast(
|
||||
entity_index, entity :: any) :: jecs.Record
|
||||
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
|
||||
end
|
||||
|
||||
|
|
@ -193,13 +188,13 @@ local function monitors_new(query: jecs.Query<...any>): Monitor
|
|||
if callback_removed == nil then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local r = jecs.record(world, entity)
|
||||
if not r then return end
|
||||
|
||||
|
||||
local src = r.archetype
|
||||
if not src then return end
|
||||
|
||||
|
||||
if not archetypes[src.id] then return end
|
||||
|
||||
if last_entity == entity and last_old_archetype == src then
|
||||
|
|
@ -232,7 +227,7 @@ local function monitors_new(query: jecs.Query<...any>): Monitor
|
|||
entity_index, entity :: any) :: jecs.Record
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
|
|
@ -253,10 +248,17 @@ local function monitors_new(query: jecs.Query<...any>): Monitor
|
|||
end
|
||||
|
||||
local r = jecs.record(world, entity)
|
||||
if archetypes[r.archetype.id] then
|
||||
last_old_archetype = nil
|
||||
callback_removed(entity)
|
||||
local src = r.archetype
|
||||
|
||||
if last_entity == entity and last_old_archetype == src then
|
||||
return
|
||||
end
|
||||
if not archetypes[src.id] then
|
||||
return
|
||||
end
|
||||
last_entity = entity
|
||||
last_old_archetype = src
|
||||
callback_removed(entity)
|
||||
end)
|
||||
table.insert(cleanup, onadded)
|
||||
table.insert(cleanup, onremoved)
|
||||
|
|
@ -294,7 +296,7 @@ local function monitors_new(query: jecs.Query<...any>): Monitor
|
|||
callback_removed(entity)
|
||||
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
|
||||
return
|
||||
end
|
||||
|
|
@ -310,7 +312,7 @@ local function monitors_new(query: jecs.Query<...any>): Monitor
|
|||
if not archetype then
|
||||
return
|
||||
end
|
||||
if last_old_archetype == archetype and terms_lookup[id] then
|
||||
if last_old_archetype == archetype then
|
||||
return
|
||||
end
|
||||
|
||||
|
|
|
|||
52
test/ob.luau
52
test/ob.luau
|
|
@ -309,19 +309,19 @@ TEST("modules/ob::monitor", function()
|
|||
local A = world:component()
|
||||
local B = world:component()
|
||||
local C = world:component()
|
||||
|
||||
|
||||
local count = 0
|
||||
ob.monitor(world:query(A, C)).removed(function()
|
||||
ob.monitor(world:query(A, C)).removed(function()
|
||||
count += 1
|
||||
end)
|
||||
|
||||
|
||||
local e = world:entity()
|
||||
jecs.bulk_insert(world, e, {A, B}, {0,0})
|
||||
CHECK(count==0)
|
||||
world:remove(e, A)
|
||||
CHECK(count==0)
|
||||
end
|
||||
|
||||
|
||||
do CASE [[should not invoke monitor.added callback multiple times in a bulk_move
|
||||
]]
|
||||
local A = world:component()
|
||||
|
|
@ -838,27 +838,47 @@ TEST("modules/ob::monitor", function()
|
|||
do CASE "monitor with wildcard pair should handle bulk_insert"
|
||||
local A = world:component()
|
||||
local B = world:component()
|
||||
local e1 = world:entity()
|
||||
local e2 = world:entity()
|
||||
local e3 = world:entity()
|
||||
local C = world:component()
|
||||
local Relation = world:component()
|
||||
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
|
||||
monitor.added(function()
|
||||
c += 1
|
||||
end)
|
||||
|
||||
local e = world:entity()
|
||||
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))
|
||||
jecs.bulk_insert(world, entity, { A, B, C, jecs.pair(Relation, entity1) }, { 1, 2, 3, 4 })
|
||||
CHECK(c == 1)
|
||||
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"
|
||||
local A = world:component()
|
||||
local B = world:component()
|
||||
|
|
|
|||
Loading…
Reference in a new issue