This commit is contained in:
Ukendio 2024-05-01 14:43:05 +02:00
commit 14507ac775
6 changed files with 130 additions and 41 deletions

View file

@ -1,7 +1,7 @@
--!optimize 2 --!optimize 2
--!native --!native
local testkit = require('../test') local testkit = require('../testkit')
local BENCH, START = testkit.benchmark() local BENCH, START = testkit.benchmark()
local function TITLE(title: string) local function TITLE(title: string)
print() print()

View file

@ -390,7 +390,6 @@ function World.query(world: World, ...: i53): Query
for id in firstArchetypeMap.sparse do for id in firstArchetypeMap.sparse do
local archetype = archetypes[id] local archetype = archetypes[id]
local columns = archetype.columns
local archetypeRecords = archetype.records local archetypeRecords = archetype.records
local indices = {} local indices = {}
local skip = false local skip = false
@ -401,7 +400,7 @@ function World.query(world: World, ...: i53): Query
skip = true skip = true
break break
end end
indices[i] = columns[index] indices[i] = archetypeRecords[componentId]
end end
if skip then if skip then
@ -449,10 +448,11 @@ function World.query(world: World, ...: i53): Query
local lastRow local lastRow
local queryOutput = {} local queryOutput = {}
function preparedQuery:__iter() function preparedQuery:__iter()
return function() return function()
local archetype = compatibleArchetype.archetype local archetype = compatibleArchetype.archetype
local indices = compatibleArchetype.indices local tr = compatibleArchetype.indices
local row = next(archetype.entities, lastRow) local row = next(archetype.entities, lastRow)
while row == nil do while row == nil do
lastArchetype, compatibleArchetype = next(compatibleArchetypes, lastArchetype) lastArchetype, compatibleArchetype = next(compatibleArchetypes, lastArchetype)
@ -465,60 +465,61 @@ function World.query(world: World, ...: i53): Query
lastRow = row lastRow = row
local entityId = archetype.entities[row :: number] local entityId = archetype.entities[row :: number]
local columns = archetype.columns
if queryLength == 1 then if queryLength == 1 then
return entityId, indices[1][row] return entityId, columns[tr[1]][row]
elseif queryLength == 2 then 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 elseif queryLength == 3 then
return entityId, return entityId,
indices[1][row], columns[tr[1]][row],
indices[2][row], columns[tr[2]][row],
indices[3][row] columns[tr[3]][row]
elseif queryLength == 4 then elseif queryLength == 4 then
return entityId, return entityId,
indices[1][row], columns[tr[1]][row],
indices[2][row], columns[tr[2]][row],
indices[3][row], columns[tr[3]][row],
indices[4][row] columns[tr[4]][row]
elseif queryLength == 5 then elseif queryLength == 5 then
return entityId, return entityId,
indices[1][row], columns[tr[1]][row],
indices[2][row], columns[tr[2]][row],
indices[3][row], columns[tr[3]][row],
indices[4][row] columns[tr[4]][row],
columns[tr[5]][row]
elseif queryLength == 6 then elseif queryLength == 6 then
return entityId, return entityId,
indices[1][row], columns[tr[1]][row],
indices[2][row], columns[tr[2]][row],
indices[3][row], columns[tr[3]][row],
indices[4][row], columns[tr[4]][row],
indices[5][row], columns[tr[5]][row],
indices[6][row] columns[tr[6]][row]
elseif queryLength == 7 then elseif queryLength == 7 then
return entityId, return entityId,
indices[1][row], columns[tr[1]][row],
indices[2][row], columns[tr[2]][row],
indices[3][row], columns[tr[3]][row],
indices[4][row], columns[tr[4]][row],
indices[5][row], columns[tr[5]][row],
indices[6][row], columns[tr[6]][row],
indices[7][row] columns[tr[7]][row]
elseif queryLength == 8 then elseif queryLength == 8 then
return entityId, return entityId,
indices[1][row], columns[tr[1]][row],
indices[2][row], columns[tr[2]][row],
indices[3][row], columns[tr[3]][row],
indices[4][row], columns[tr[4]][row],
indices[5][row], columns[tr[5]][row],
indices[6][row], columns[tr[6]][row],
indices[7][row], columns[tr[7]][row],
indices[8][row] columns[tr[8]][row]
end end
for i, componentId in components do for i in components do
queryOutput[i] = indices[i][row] queryOutput[i] = tr[i][row]
end end
return entityId, unpack(queryOutput, 1, queryLength) return entityId, unpack(queryOutput, 1, queryLength)

88
tests/test1.lua Normal file
View file

@ -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()