mirror of
https://github.com/Ukendio/jecs.git
synced 2025-06-20 08:19:18 +00:00
Remove allocations per compatible archetype to optimize fragmented iterations
This commit is contained in:
parent
bc43ee336b
commit
6b4597ab96
1 changed files with 18 additions and 17 deletions
|
@ -640,13 +640,15 @@ export type Query = typeof(EmptyQuery)
|
||||||
|
|
||||||
type CompatibleArchetype = { archetype: Archetype, indices: { number } }
|
type CompatibleArchetype = { archetype: Archetype, indices: { number } }
|
||||||
|
|
||||||
local function PreparedQuery(compatibleArchetypes: { CompatibleArchetype } , components: { i53 })
|
local function PreparedQuery(
|
||||||
|
compatibleArchetypes: { Archetype } , components: { i53 }, indices: { [number]: number })
|
||||||
|
|
||||||
local queryLength = #components
|
local queryLength = #components
|
||||||
|
|
||||||
local lastArchetype = 1
|
local lastArchetype = 1
|
||||||
local compatibleArchetype: CompatibleArchetype = compatibleArchetypes[lastArchetype]
|
local archetype: Archetype = compatibleArchetypes[lastArchetype]
|
||||||
|
|
||||||
if not compatibleArchetype then
|
if not archetype then
|
||||||
return EmptyQuery
|
return EmptyQuery
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -657,17 +659,17 @@ local function PreparedQuery(compatibleArchetypes: { CompatibleArchetype } , com
|
||||||
|
|
||||||
local i = 1
|
local i = 1
|
||||||
|
|
||||||
|
local length = #compatibleArchetypes
|
||||||
|
|
||||||
local function queryNext(): ...any
|
local function queryNext(): ...any
|
||||||
local archetype = compatibleArchetype.archetype
|
|
||||||
local entityId = archetype.entities[i]
|
local entityId = archetype.entities[i]
|
||||||
|
|
||||||
while entityId == nil do
|
while entityId == nil do
|
||||||
lastArchetype += 1
|
lastArchetype += 1
|
||||||
if lastArchetype > #compatibleArchetypes then
|
archetype = compatibleArchetypes[lastArchetype]
|
||||||
|
if lastArchetype > length then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
compatibleArchetype = compatibleArchetypes[lastArchetype]
|
|
||||||
archetype = compatibleArchetype.archetype
|
|
||||||
i = 1
|
i = 1
|
||||||
entityId = archetype.entities[i]
|
entityId = archetype.entities[i]
|
||||||
end
|
end
|
||||||
|
@ -676,7 +678,7 @@ local function PreparedQuery(compatibleArchetypes: { CompatibleArchetype } , com
|
||||||
i+=1
|
i+=1
|
||||||
|
|
||||||
local columns = archetype.columns
|
local columns = archetype.columns
|
||||||
local tr = compatibleArchetype.indices
|
local tr = indices[lastArchetype]
|
||||||
|
|
||||||
if queryLength == 1 then
|
if queryLength == 1 then
|
||||||
return entityId, columns[tr[1]][row]
|
return entityId, columns[tr[1]][row]
|
||||||
|
@ -740,7 +742,7 @@ local function PreparedQuery(compatibleArchetypes: { CompatibleArchetype } , com
|
||||||
function preparedQuery:without(...: any): Query
|
function preparedQuery:without(...: any): Query
|
||||||
local withoutComponents = { ... }
|
local withoutComponents = { ... }
|
||||||
for i = #compatibleArchetypes, 1, -1 do
|
for i = #compatibleArchetypes, 1, -1 do
|
||||||
local archetype = compatibleArchetypes[i].archetype
|
local archetype = compatibleArchetypes[i]
|
||||||
local records = archetype.records
|
local records = archetype.records
|
||||||
local shouldRemove = false
|
local shouldRemove = false
|
||||||
|
|
||||||
|
@ -756,7 +758,7 @@ local function PreparedQuery(compatibleArchetypes: { CompatibleArchetype } , com
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
lastArchetype, compatibleArchetype = next(compatibleArchetypes)
|
lastArchetype, archetype = next(compatibleArchetypes)
|
||||||
if not lastArchetype then
|
if not lastArchetype then
|
||||||
return EmptyQuery
|
return EmptyQuery
|
||||||
end
|
end
|
||||||
|
@ -773,6 +775,7 @@ function World.query(world: World, ...: any): Query
|
||||||
error("Missing components")
|
error("Missing components")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local columns = {}
|
||||||
local compatibleArchetypes: { CompatibleArchetype } = {}
|
local compatibleArchetypes: { CompatibleArchetype } = {}
|
||||||
local length = 0
|
local length = 0
|
||||||
|
|
||||||
|
@ -797,7 +800,7 @@ function World.query(world: World, ...: any): Query
|
||||||
local archetype = archetypes[id]
|
local archetype = archetypes[id]
|
||||||
local archetypeRecords = archetype.records
|
local archetypeRecords = archetype.records
|
||||||
|
|
||||||
local indices = {}
|
local records = {}
|
||||||
local skip = false
|
local skip = false
|
||||||
|
|
||||||
for i, componentId in components do
|
for i, componentId in components do
|
||||||
|
@ -807,7 +810,7 @@ function World.query(world: World, ...: any): Query
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
-- index should be index.offset
|
-- index should be index.offset
|
||||||
indices[i] = index
|
records[i] = index
|
||||||
end
|
end
|
||||||
|
|
||||||
if skip then
|
if skip then
|
||||||
|
@ -815,13 +818,11 @@ function World.query(world: World, ...: any): Query
|
||||||
end
|
end
|
||||||
|
|
||||||
length += 1
|
length += 1
|
||||||
compatibleArchetypes[length] = {
|
compatibleArchetypes[length] = archetype
|
||||||
archetype = archetype,
|
columns[length] = records
|
||||||
indices = indices,
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return PreparedQuery(compatibleArchetypes, components)
|
return PreparedQuery(compatibleArchetypes, components, columns)
|
||||||
end
|
end
|
||||||
|
|
||||||
type WorldIterator = (() -> (i53, { [unknown]: unknown? })) & (() -> ()) & (() -> i53)
|
type WorldIterator = (() -> (i53, { [unknown]: unknown? })) & (() -> ()) & (() -> i53)
|
||||||
|
|
Loading…
Reference in a new issue