Creator specific iterators for returns

This commit is contained in:
Ukendio 2024-04-24 01:14:43 +02:00
parent a6b592727e
commit a5302a14fb

View file

@ -322,8 +322,6 @@ function World.archetypesWith(world: World, componentId: i53)
return compatibleArchetypes return compatibleArchetypes
end end
function World.query(world: World, ...: i53): () -> (number, ...any) function World.query(world: World, ...: i53): () -> (number, ...any)
local compatibleArchetypes = {} local compatibleArchetypes = {}
local components = { ... } local components = { ... }
@ -332,6 +330,61 @@ function World.query(world: World, ...: i53): () -> (number, ...any)
local a, b, c, d, e = ... local a, b, c, d, e = ...
local firstArchetypeMap = world.componentIndex[components[1]] local firstArchetypeMap = world.componentIndex[components[1]]
if queryLength == 1 then
local function single()
local id = next(firstArchetypeMap)
local archetype = archetypes[id :: number]
local lastRow
return function(): any
local row, entity = next(archetype.entities, lastRow)
while row == nil do
id = next(firstArchetypeMap, id)
if id == nil then
return
end
archetype = archetypes[id]
row = next(archetype.entities, row)
end
lastRow = row
return entity, archetype.columns[archetype.records[a]]
end
end
return single()
elseif queryLength == 2 then
for id in firstArchetypeMap do
local archetype = archetypes[id]
if archetype.records[b] then
table.insert(compatibleArchetypes, archetype)
end
end
local function double(): any
local lastArchetype, archetype = next(compatibleArchetypes)
local lastRow
return function(): any
local row = next(archetype.entities, lastRow)
while row == nil do
lastArchetype, archetype = next(compatibleArchetypes, lastArchetype)
if lastArchetype == nil then
return
end
row = next(archetype.entities, row)
end
lastRow = row
local entity = archetype.entities[row::number]
local columns = archetype.columns
local archetypeRecords = archetype.records
return entity, columns[archetypeRecords[a]], columns[archetypeRecords[b]]
end
end
return double()
end
for id in firstArchetypeMap do for id in firstArchetypeMap do
local archetype = archetypes[id] local archetype = archetypes[id]
local archetypeRecords = archetype.records local archetypeRecords = archetype.records
@ -346,30 +399,27 @@ function World.query(world: World, ...: i53): () -> (number, ...any)
table.insert(compatibleArchetypes, archetype) table.insert(compatibleArchetypes, archetype)
end end
end end
local lastArchetype, archetype = next(compatibleArchetypes)
local lastRow local lastArchetype, archetype = next(compatibleArchetypes)
local function queryNext(): (...any) local lastRow
local row = next(archetype.entities, lastRow)
while row == nil do local function queryNext(): (...any)
lastArchetype, archetype = next(compatibleArchetypes, lastArchetype) local row = next(archetype.entities, lastRow)
if lastArchetype == nil then while row == nil do
return lastArchetype, archetype = next(compatibleArchetypes, lastArchetype)
end if lastArchetype == nil then
row = next(archetype.entities, row) return
end end
lastRow = row row = next(archetype.entities, row)
end
lastRow = row
local columns = archetype.columns local columns = archetype.columns
local entityId = archetype.entities[row :: number] local entityId = archetype.entities[row :: number]
local archetypeRecords = archetype.records local archetypeRecords = archetype.records
if queryLength == 1 then if queryLength == 3 then
return entityId, columns[archetypeRecords[a]]
elseif queryLength == 2 then
return entityId, columns[archetypeRecords[a]], columns[archetypeRecords[b]]
elseif queryLength == 3 then
return entityId, return entityId,
columns[archetypeRecords[a]], columns[archetypeRecords[a]],
columns[archetypeRecords[b]], columns[archetypeRecords[b]],
@ -395,12 +445,12 @@ function World.query(world: World, ...: i53): () -> (number, ...any)
end end
return entityId, unpack(queryOutput, 1, queryLength) return entityId, unpack(queryOutput, 1, queryLength)
end
return function()
-- consider this to be the iterator that gets invoked each iteration step
return queryNext()
end end
return function()
return queryNext()
end
end end
return { return {