mirror of
https://github.com/Ukendio/jecs.git
synced 2025-04-25 01:20:04 +00:00
Merge branch 'main' of https://github.com/Ukendio/jecs
This commit is contained in:
commit
14507ac775
6 changed files with 130 additions and 41 deletions
|
@ -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()
|
||||||
|
|
81
lib/init.lua
81
lib/init.lua
|
@ -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
88
tests/test1.lua
Normal 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()
|
Loading…
Reference in a new issue