From 90ef6db72cc94b3f0a9d2779cb5bfca9ca0b8ddd Mon Sep 17 00:00:00 2001 From: Ukendio Date: Sun, 24 Dec 2023 17:20:26 +0100 Subject: [PATCH] Handle filter iteratively --- lib/World.lua | 16 ++++++++++++---- lib/World.spec.lua | 6 +++--- lib/query.lua | 4 +++- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/lib/World.lua b/lib/World.lua index 3d1fd08..daa65b8 100644 --- a/lib/World.lua +++ b/lib/World.lua @@ -196,14 +196,20 @@ function World:_newQueryArchetype(queryArchetype) for entityArchetype in storage do local archetype = string.split(queryArchetype, "||") local negatedArchetype = archetype[1] - local exclude = archetype[2] + local filter = { unpack(archetype, 2, #archetype) } - if exclude then + local skip = false + for _, exclude in filter do if areArchetypesCompatible(exclude, entityArchetype) then - continue + skip = true + break end end + if skip then + continue + end + if areArchetypesCompatible(negatedArchetype, entityArchetype) then self._queryCache[queryArchetype][entityArchetype] = true end @@ -410,7 +416,9 @@ local noopQuery = setmetatable({ without = noop, view = noop, }, { - __iter = noop, + __iter = function() + return noop + end, }) function World:query(...) diff --git a/lib/World.spec.lua b/lib/World.spec.lua index 1e70740..036d7a2 100644 --- a/lib/World.spec.lua +++ b/lib/World.spec.lua @@ -138,7 +138,7 @@ return function() expect(world:size()).to.equal(1) end) - it("without prototype", function() + it("should not find any entities", function() local world = World.new() local Hello = component() @@ -149,11 +149,11 @@ return function() local _helloShirley = world:spawn(Hello(), Shirley()) local withoutCount = 0 - for _ in world:query(Hello):without(Bob) do + for _ in world:query(Hello):without(Bob, Shirley) do withoutCount += 1 end - expect(withoutCount).to.equal(1) + expect(withoutCount).to.equal(0) end) it("should be queryable", function() diff --git a/lib/query.lua b/lib/query.lua index 581e4e6..1703bd9 100644 --- a/lib/query.lua +++ b/lib/query.lua @@ -205,7 +205,9 @@ end function QueryResult:without(...) local world = self.world - local negativeArchetype = `{self._queryArchetype}||{archetypeOf(...)}` + local filter = table.concat(string.split(archetypeOf(...), "_"), "||") + + local negativeArchetype = `{self._queryArchetype}||{filter}` if world._queryCache[negativeArchetype] == nil then world:_newQueryArchetype(negativeArchetype)