diff --git a/benches/query.lua b/benches/query.lua index 783f8f8..74f4559 100644 --- a/benches/query.lua +++ b/benches/query.lua @@ -1,7 +1,7 @@ --!optimize 2 --!native -local testkit = require('../test') +local testkit = require('../testkit') local BENCH, START = testkit.benchmark() local function TITLE(title: string) print() diff --git a/benches/insertion.bench.lua b/benches/visual/insertion.bench.lua similarity index 100% rename from benches/insertion.bench.lua rename to benches/visual/insertion.bench.lua diff --git a/benches/query.bench.lua b/benches/visual/query.bench.lua similarity index 100% rename from benches/query.bench.lua rename to benches/visual/query.bench.lua diff --git a/benches/spawn.bench.lua b/benches/visual/spawn.bench.lua similarity index 100% rename from benches/spawn.bench.lua rename to benches/visual/spawn.bench.lua diff --git a/lib/init.lua b/lib/init.lua index 907f821..697f01f 100644 --- a/lib/init.lua +++ b/lib/init.lua @@ -390,7 +390,6 @@ function World.query(world: World, ...: i53): Query for id in firstArchetypeMap.sparse do local archetype = archetypes[id] - local columns = archetype.columns local archetypeRecords = archetype.records local indices = {} local skip = false @@ -401,7 +400,7 @@ function World.query(world: World, ...: i53): Query skip = true break end - indices[i] = columns[index] + indices[i] = archetypeRecords[componentId] end if skip then @@ -449,10 +448,11 @@ function World.query(world: World, ...: i53): Query local lastRow local queryOutput = {} + function preparedQuery:__iter() return function() local archetype = compatibleArchetype.archetype - local indices = compatibleArchetype.indices + local tr = compatibleArchetype.indices local row = next(archetype.entities, lastRow) while row == nil do lastArchetype, compatibleArchetype = next(compatibleArchetypes, lastArchetype) @@ -465,60 +465,61 @@ function World.query(world: World, ...: i53): Query lastRow = row local entityId = archetype.entities[row :: number] + local columns = archetype.columns if queryLength == 1 then - return entityId, indices[1][row] + return entityId, columns[tr[1]][row] elseif queryLength == 2 then - return entityId, indices[1][row], indices[2][row] + return entityId, columns[tr[1]][row], columns[tr[2]][row] elseif queryLength == 3 then return entityId, - indices[1][row], - indices[2][row], - indices[3][row] + columns[tr[1]][row], + columns[tr[2]][row], + columns[tr[3]][row] elseif queryLength == 4 then return entityId, - indices[1][row], - indices[2][row], - indices[3][row], - indices[4][row] + columns[tr[1]][row], + columns[tr[2]][row], + columns[tr[3]][row], + columns[tr[4]][row] elseif queryLength == 5 then return entityId, - indices[1][row], - indices[2][row], - indices[3][row], - indices[4][row] + columns[tr[1]][row], + columns[tr[2]][row], + columns[tr[3]][row], + columns[tr[4]][row], + columns[tr[5]][row] elseif queryLength == 6 then return entityId, - indices[1][row], - indices[2][row], - indices[3][row], - indices[4][row], - indices[5][row], - indices[6][row] + columns[tr[1]][row], + columns[tr[2]][row], + columns[tr[3]][row], + columns[tr[4]][row], + columns[tr[5]][row], + columns[tr[6]][row] elseif queryLength == 7 then return entityId, - indices[1][row], - indices[2][row], - indices[3][row], - indices[4][row], - indices[5][row], - indices[6][row], - indices[7][row] - + columns[tr[1]][row], + columns[tr[2]][row], + columns[tr[3]][row], + columns[tr[4]][row], + columns[tr[5]][row], + columns[tr[6]][row], + columns[tr[7]][row] elseif queryLength == 8 then return entityId, - indices[1][row], - indices[2][row], - indices[3][row], - indices[4][row], - indices[5][row], - indices[6][row], - indices[7][row], - indices[8][row] + columns[tr[1]][row], + columns[tr[2]][row], + columns[tr[3]][row], + columns[tr[4]][row], + columns[tr[5]][row], + columns[tr[6]][row], + columns[tr[7]][row], + columns[tr[8]][row] end - for i, componentId in components do - queryOutput[i] = indices[i][row] + for i in components do + queryOutput[i] = tr[i][row] end return entityId, unpack(queryOutput, 1, queryLength) diff --git a/tests/test1.lua b/tests/test1.lua new file mode 100644 index 0000000..b982532 --- /dev/null +++ b/tests/test1.lua @@ -0,0 +1,88 @@ +local testkit = require("../testkit") +local jecs = require("../lib/init") + +local TEST, CASE, CHECK, FINISH, SKIP = testkit.test() + +local N = 10 + +TEST("world:query", function() + + do CASE "should query all matching entities" + + local world = jecs.World.new() + local A = world:component() + local B = world:component() + + local entities = {} + for i = 1, N do + local id = world:entity() + + + world:set(id, A, true) + if i > 5 then world:set(id, B, true) end + entities[i] = id + end + + for id in world:query(A) do + table.remove(entities, CHECK(table.find(entities, id))) + end + + CHECK(#entities == 0) + + end + + do CASE "should query all matching entities when irrelevant component is removed" + + local world = jecs.World.new() + local A = world:component() + local B = world:component() + + local entities = {} + for i = 1, N do + local id = world:entity() + + world:set(id, A, true) + world:set(id, B, true) + if i > 5 then world:remove(id, B, true) end + entities[i] = id + end + + local added = 0 + for id in world:query(A) do + added += 1 + table.remove(entities, CHECK(table.find(entities, id))) + end + + CHECK(added == N) + end + + do CASE "should query all entities without B" + + local world = jecs.World.new() + local A = world:component() + local B = world:component() + + local entities = {} + for i = 1, N do + local id = world:entity() + + world:set(id, A, true) + if i < 5 then + entities[i] = id + else + world:set(id, B, true) + end + + end + + for id in world:query(A):without(B) do + table.remove(entities, CHECK(table.find(entities, id))) + end + + CHECK(#entities == 0) + + end + +end) + +FINISH() \ No newline at end of file