Add without (#3)

This commit is contained in:
Marcus 2024-04-28 21:00:00 +02:00 committed by GitHub
parent b75dc91a6a
commit 13c703211d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 106 additions and 81 deletions

View file

@ -196,21 +196,21 @@ return {
Functions = {
Mater = function()
local matched = 0
for entityId, firstComponent in newWorld:query(A2, A4, A6, A8) do
for entityId, firstComponent in newWorld:query(A1, A4, A6, A8) do
matched += 1
end
end,
ECR = function()
local matched = 0
for entityId, firstComponent in registry2:view(B2, B4, B6, B8) do
for entityId, firstComponent in registry2:view(B1, B4, B6, B8) do
matched += 1
end
end,
Jecs = function()
local matched = 0
for entityId, firstComponent in ecs:query(D2, D4, D6, D8) do
for entityId, firstComponent in ecs:query(D1, D4, D6, D8) do
matched += 1
end

View file

@ -361,8 +361,7 @@ local function getSmallestMap(componentIndex, components)
return s.sparse
end
function World.query(world: World, ...: i53): (() -> (number, ...any)) | () -> ()
function World.query(world: World, ...: i53): any
local compatibleArchetypes = {}
local components = { ... }
local archetypes = world.archetypes
@ -398,88 +397,114 @@ function World.query(world: World, ...: i53): (() -> (number, ...any)) | () -> (
indices = indices
})
end
local lastArchetype, compatibleArchetype = next(compatibleArchetypes)
if not compatibleArchetype then
if not lastArchetype then
return noop()
end
local lastRow
return function()
local archetype = compatibleArchetype.archetype
local indices = compatibleArchetype.indices
local row = next(archetype.entities, lastRow)
while row == nil do
lastArchetype, compatibleArchetype = next(compatibleArchetypes, lastArchetype)
if lastArchetype == nil then
return
local preparedQuery = {}
preparedQuery.__index = preparedQuery
function preparedQuery:without(...)
local components = { ... }
for i, component in components do
components[i] = #component
end
for i = #compatibleArchetypes, 1, - 1 do
local archetype = compatibleArchetypes[i].archetype
local shouldRemove = false
for _, componentId in components do
if archetype.records[componentId] then
shouldRemove = true
break
end
end
archetype = compatibleArchetype.archetype
row = next(archetype.entities, row)
end
lastRow = row
local entityId = archetype.entities[row :: number]
if queryLength == 1 then
return entityId, indices[1][row]
elseif queryLength == 2 then
return entityId, indices[1][row], indices[2][row]
elseif queryLength == 3 then
return entityId,
indices[1][row],
indices[2][row],
indices[3][row]
elseif queryLength == 4 then
return entityId,
indices[1][row],
indices[2][row],
indices[3][row],
indices[4][row]
elseif queryLength == 5 then
return entityId,
indices[1][row],
indices[2][row],
indices[3][row],
indices[4][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]
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]
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]
end
local queryOutput = {}
for i, componentId in components do
queryOutput[i] = indices[i][row]
end
return entityId, unpack(queryOutput, 1, queryLength)
if shouldRemove then
table.remove(compatibleArchetypes, i)
end
end
end
local lastRow
function preparedQuery:__iter()
return function()
local archetype = compatibleArchetype.archetype
local indices = compatibleArchetype.indices
local row = next(archetype.entities, lastRow)
while row == nil do
lastArchetype, compatibleArchetype = next(compatibleArchetypes, lastArchetype)
if lastArchetype == nil then
return
end
archetype = compatibleArchetype.archetype
row = next(archetype.entities, row)
end
lastRow = row
local entityId = archetype.entities[row :: number]
if queryLength == 1 then
return entityId, indices[1][row]
elseif queryLength == 2 then
return entityId, indices[1][row], indices[2][row]
elseif queryLength == 3 then
return entityId,
indices[1][row],
indices[2][row],
indices[3][row]
elseif queryLength == 4 then
return entityId,
indices[1][row],
indices[2][row],
indices[3][row],
indices[4][row]
elseif queryLength == 5 then
return entityId,
indices[1][row],
indices[2][row],
indices[3][row],
indices[4][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]
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]
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]
end
local queryOutput = {}
for i, componentId in components do
queryOutput[i] = indices[i][row]
end
return entityId, unpack(queryOutput, 1, queryLength)
end
end
return setmetatable({}, preparedQuery)
end
function World.component(world: World)