Optimized queries for more than 4 components
Some checks failed
analysis / Run Luau Analyze (push) Has been cancelled
deploy-docs / build (push) Has been cancelled
publish-npm / publish (push) Has been cancelled
unit-testing / Run Luau Tests (push) Has been cancelled
deploy-docs / Deploy (push) Has been cancelled

This commit is contained in:
Ukendio 2025-02-26 17:26:11 +01:00
parent c9b07433aa
commit 1bfcba7422

424
jecs.luau
View file

@ -340,17 +340,17 @@ local function archetype_append(entity: number, archetype: Archetype): number
return length return length
end end
local function new_entity(entityId: i53, record: Record, archetype: Archetype): Record local function new_entity(entity: i53, record: Record, archetype: Archetype): Record
local row = archetype_append(entityId, archetype) local row = archetype_append(entity, archetype)
record.archetype = archetype record.archetype = archetype
record.row = row record.row = row
return record return record
end end
local function entity_move(entity_index: EntityIndex, entityId: i53, record: Record, to: Archetype) local function entity_move(entity_index: EntityIndex, entity: i53, record: Record, to: Archetype)
local sourceRow = record.row local sourceRow = record.row
local from = record.archetype local from = record.archetype
local dst_row = archetype_append(entityId, to) local dst_row = archetype_append(entity, to)
archetype_move(entity_index, to, dst_row, from, sourceRow) archetype_move(entity_index, to, dst_row, from, sourceRow)
record.archetype = to record.archetype = to
record.row = dst_row record.row = dst_row
@ -1320,8 +1320,8 @@ local function query_iter_init(query: QueryInner): () -> (number, ...any)
if not B then if not B then
function world_query_iter_next(): any function world_query_iter_next(): any
local entityId = entities[i] local entity = entities[i]
while entityId == nil do while entity == nil do
lastArchetype += 1 lastArchetype += 1
archetype = compatible_archetypes[lastArchetype] archetype = compatible_archetypes[lastArchetype]
if not archetype then if not archetype then
@ -1333,7 +1333,7 @@ local function query_iter_init(query: QueryInner): () -> (number, ...any)
if i == 0 then if i == 0 then
continue continue
end end
entityId = entities[i] entity = entities[i]
columns = archetype.columns columns = archetype.columns
records = archetype.records records = archetype.records
a = columns[records[A]] a = columns[records[A]]
@ -1342,12 +1342,12 @@ local function query_iter_init(query: QueryInner): () -> (number, ...any)
local row = i local row = i
i -= 1 i -= 1
return entityId, a[row] return entity, a[row]
end end
elseif not C then elseif not C then
function world_query_iter_next(): any function world_query_iter_next(): any
local entityId = entities[i] local entity = entities[i]
while entityId == nil do while entity == nil do
lastArchetype += 1 lastArchetype += 1
archetype = compatible_archetypes[lastArchetype] archetype = compatible_archetypes[lastArchetype]
if not archetype then if not archetype then
@ -1359,7 +1359,7 @@ local function query_iter_init(query: QueryInner): () -> (number, ...any)
if i == 0 then if i == 0 then
continue continue
end end
entityId = entities[i] entity = entities[i]
columns = archetype.columns columns = archetype.columns
records = archetype.records records = archetype.records
a = columns[records[A]] a = columns[records[A]]
@ -1369,12 +1369,12 @@ local function query_iter_init(query: QueryInner): () -> (number, ...any)
local row = i local row = i
i -= 1 i -= 1
return entityId, a[row], b[row] return entity, a[row], b[row]
end end
elseif not D then elseif not D then
function world_query_iter_next(): any function world_query_iter_next(): any
local entityId = entities[i] local entity = entities[i]
while entityId == nil do while entity == nil do
lastArchetype += 1 lastArchetype += 1
archetype = compatible_archetypes[lastArchetype] archetype = compatible_archetypes[lastArchetype]
if not archetype then if not archetype then
@ -1386,7 +1386,7 @@ local function query_iter_init(query: QueryInner): () -> (number, ...any)
if i == 0 then if i == 0 then
continue continue
end end
entityId = entities[i] entity = entities[i]
columns = archetype.columns columns = archetype.columns
records = archetype.records records = archetype.records
a = columns[records[A]] a = columns[records[A]]
@ -1397,12 +1397,12 @@ local function query_iter_init(query: QueryInner): () -> (number, ...any)
local row = i local row = i
i -= 1 i -= 1
return entityId, a[row], b[row], c[row] return entity, a[row], b[row], c[row]
end end
elseif not E then elseif not E then
function world_query_iter_next(): any function world_query_iter_next(): any
local entityId = entities[i] local entity = entities[i]
while entityId == nil do while entity == nil do
lastArchetype += 1 lastArchetype += 1
archetype = compatible_archetypes[lastArchetype] archetype = compatible_archetypes[lastArchetype]
if not archetype then if not archetype then
@ -1414,7 +1414,7 @@ local function query_iter_init(query: QueryInner): () -> (number, ...any)
if i == 0 then if i == 0 then
continue continue
end end
entityId = entities[i] entity = entities[i]
columns = archetype.columns columns = archetype.columns
records = archetype.records records = archetype.records
a = columns[records[A]] a = columns[records[A]]
@ -1426,13 +1426,12 @@ local function query_iter_init(query: QueryInner): () -> (number, ...any)
local row = i local row = i
i -= 1 i -= 1
return entityId, a[row], b[row], c[row], d[row] return entity, a[row], b[row], c[row], d[row]
end end
else elseif not F then
local queryOutput = {}
function world_query_iter_next(): any function world_query_iter_next(): any
local entityId = entities[i] local entity = entities[i]
while entityId == nil do while entity == nil do
lastArchetype += 1 lastArchetype += 1
archetype = compatible_archetypes[lastArchetype] archetype = compatible_archetypes[lastArchetype]
if not archetype then if not archetype then
@ -1444,61 +1443,146 @@ local function query_iter_init(query: QueryInner): () -> (number, ...any)
if i == 0 then if i == 0 then
continue continue
end end
entityId = entities[i] entity = entities[i]
columns = archetype.columns columns = archetype.columns
records = archetype.records records = archetype.records
a = columns[records[A]]
if not F then b = columns[records[B]]
a = columns[records[A]] c = columns[records[C]]
b = columns[records[B]] d = columns[records[D]]
c = columns[records[C]] e = columns[records[E]]
d = columns[records[D]]
e = columns[records[E]]
elseif not G then
a = columns[records[A]]
b = columns[records[B]]
c = columns[records[C]]
d = columns[records[D]]
e = columns[records[E]]
f = columns[records[F]]
elseif not H then
a = columns[records[A]]
b = columns[records[B]]
c = columns[records[C]]
d = columns[records[D]]
e = columns[records[E]]
f = columns[records[F]]
g = columns[records[G]]
elseif not I then
a = columns[records[A]]
b = columns[records[B]]
c = columns[records[C]]
d = columns[records[D]]
e = columns[records[E]]
f = columns[records[F]]
g = columns[records[G]]
h = columns[records[H]]
end
end end
local row = i local row = i
i -= 1 i -= 1
if not F then return entity, a[row], b[row], c[row], d[row], e[row]
return entityId, a[row], b[row], c[row], d[row], e[row] end
elseif not G then elseif not G then
return entityId, a[row], b[row], c[row], d[row], e[row], f[row] function world_query_iter_next(): any
elseif not H then local entity = entities[i]
return entityId, a[row], b[row], c[row], d[row], e[row], f[row], g[row] while entity == nil do
elseif not I then lastArchetype += 1
return entityId, a[row], b[row], c[row], d[row], e[row], f[row], g[row], h[row] archetype = compatible_archetypes[lastArchetype]
if not archetype then
return nil
end
entities = archetype.entities
i = #entities
if i == 0 then
continue
end
entity = entities[i]
columns = archetype.columns
records = archetype.records
a = columns[records[A]]
b = columns[records[B]]
c = columns[records[C]]
d = columns[records[D]]
e = columns[records[E]]
f = columns[records[F]]
end end
local row = i
i -= 1
return entity, a[row], b[row], c[row], d[row], e[row], f[row]
end
elseif not H then
function world_query_iter_next(): any
local entity = entities[i]
while entity == nil do
lastArchetype += 1
archetype = compatible_archetypes[lastArchetype]
if not archetype then
return nil
end
entities = archetype.entities
i = #entities
if i == 0 then
continue
end
entity = entities[i]
columns = archetype.columns
records = archetype.records
a = columns[records[A]]
b = columns[records[B]]
c = columns[records[C]]
d = columns[records[D]]
e = columns[records[E]]
f = columns[records[F]]
g = columns[records[G]]
end
local row = i
i -= 1
return entity, a[row], b[row], c[row], d[row], e[row], f[row], g[row]
end
elseif not I then
function world_query_iter_next(): any
local entity = entities[i]
while entity == nil do
lastArchetype += 1
archetype = compatible_archetypes[lastArchetype]
if not archetype then
return nil
end
entities = archetype.entities
i = #entities
if i == 0 then
continue
end
entity = entities[i]
columns = archetype.columns
records = archetype.records
a = columns[records[A]]
b = columns[records[B]]
c = columns[records[C]]
d = columns[records[D]]
e = columns[records[E]]
f = columns[records[F]]
g = columns[records[G]]
h = columns[records[H]]
end
local row = i
i -= 1
return entity, a[row], b[row], c[row], d[row], e[row], f[row], g[row], h[row]
end
else
local output = {}
function world_query_iter_next(): any
local entity = entities[i]
while entity == nil do
lastArchetype += 1
archetype = compatible_archetypes[lastArchetype]
if not archetype then
return nil
end
entities = archetype.entities
i = #entities
if i == 0 then
continue
end
entity = entities[i]
columns = archetype.columns
records = archetype.records
end
local row = i
i -= 1
for j, id in ids do for j, id in ids do
queryOutput[j] = columns[records[id]][row] output[j] = columns[records[id]][row]
end end
return entityId, unpack(queryOutput) return entity, unpack(output)
end end
end end
@ -1710,8 +1794,8 @@ local function query_cached(query: QueryInner)
if not B then if not B then
function world_query_iter_next(): any function world_query_iter_next(): any
local entityId = entities[i] local entity = entities[i]
while entityId == nil do while entity == nil do
lastArchetype += 1 lastArchetype += 1
archetype = compatible_archetypes[lastArchetype] archetype = compatible_archetypes[lastArchetype]
if not archetype then if not archetype then
@ -1723,7 +1807,7 @@ local function query_cached(query: QueryInner)
if i == 0 then if i == 0 then
continue continue
end end
entityId = entities[i] entity = entities[i]
columns = archetype.columns columns = archetype.columns
records = archetype.records records = archetype.records
a = columns[records[A]] a = columns[records[A]]
@ -1732,12 +1816,12 @@ local function query_cached(query: QueryInner)
local row = i local row = i
i -= 1 i -= 1
return entityId, a[row] return entity, a[row]
end end
elseif not C then elseif not C then
function world_query_iter_next(): any function world_query_iter_next(): any
local entityId = entities[i] local entity = entities[i]
while entityId == nil do while entity == nil do
lastArchetype += 1 lastArchetype += 1
archetype = compatible_archetypes[lastArchetype] archetype = compatible_archetypes[lastArchetype]
if not archetype then if not archetype then
@ -1749,7 +1833,7 @@ local function query_cached(query: QueryInner)
if i == 0 then if i == 0 then
continue continue
end end
entityId = entities[i] entity = entities[i]
columns = archetype.columns columns = archetype.columns
records = archetype.records records = archetype.records
a = columns[records[A]] a = columns[records[A]]
@ -1759,12 +1843,12 @@ local function query_cached(query: QueryInner)
local row = i local row = i
i -= 1 i -= 1
return entityId, a[row], b[row] return entity, a[row], b[row]
end end
elseif not D then elseif not D then
function world_query_iter_next(): any function world_query_iter_next(): any
local entityId = entities[i] local entity = entities[i]
while entityId == nil do while entity == nil do
lastArchetype += 1 lastArchetype += 1
archetype = compatible_archetypes[lastArchetype] archetype = compatible_archetypes[lastArchetype]
if not archetype then if not archetype then
@ -1776,7 +1860,7 @@ local function query_cached(query: QueryInner)
if i == 0 then if i == 0 then
continue continue
end end
entityId = entities[i] entity = entities[i]
columns = archetype.columns columns = archetype.columns
records = archetype.records records = archetype.records
a = columns[records[A]] a = columns[records[A]]
@ -1787,12 +1871,12 @@ local function query_cached(query: QueryInner)
local row = i local row = i
i -= 1 i -= 1
return entityId, a[row], b[row], c[row] return entity, a[row], b[row], c[row]
end end
elseif not E then elseif not E then
function world_query_iter_next(): any function world_query_iter_next(): any
local entityId = entities[i] local entity = entities[i]
while entityId == nil do while entity == nil do
lastArchetype += 1 lastArchetype += 1
archetype = compatible_archetypes[lastArchetype] archetype = compatible_archetypes[lastArchetype]
if not archetype then if not archetype then
@ -1804,7 +1888,7 @@ local function query_cached(query: QueryInner)
if i == 0 then if i == 0 then
continue continue
end end
entityId = entities[i] entity = entities[i]
columns = archetype.columns columns = archetype.columns
records = archetype.records records = archetype.records
a = columns[records[A]] a = columns[records[A]]
@ -1816,13 +1900,12 @@ local function query_cached(query: QueryInner)
local row = i local row = i
i -= 1 i -= 1
return entityId, a[row], b[row], c[row], d[row] return entity, a[row], b[row], c[row], d[row]
end end
else elseif not F then
local queryOutput = {}
function world_query_iter_next(): any function world_query_iter_next(): any
local entityId = entities[i] local entity = entities[i]
while entityId == nil do while entity == nil do
lastArchetype += 1 lastArchetype += 1
archetype = compatible_archetypes[lastArchetype] archetype = compatible_archetypes[lastArchetype]
if not archetype then if not archetype then
@ -1834,61 +1917,156 @@ local function query_cached(query: QueryInner)
if i == 0 then if i == 0 then
continue continue
end end
entityId = entities[i] entity = entities[i]
columns = archetype.columns columns = archetype.columns
records = archetype.records records = archetype.records
a = columns[records[A]]
b = columns[records[B]]
c = columns[records[C]]
d = columns[records[D]]
e = columns[records[E]]
end
if not F then local row = i
a = columns[records[A]] i -= 1
b = columns[records[B]]
c = columns[records[C]] return entity, a[row], b[row], c[row], d[row], e[row]
d = columns[records[D]] end
e = columns[records[E]] elseif not G then
elseif not G then function world_query_iter_next(): any
a = columns[records[A]] local entity = entities[i]
b = columns[records[B]] while entity == nil do
c = columns[records[C]] lastArchetype += 1
d = columns[records[D]] archetype = compatible_archetypes[lastArchetype]
e = columns[records[E]] if not archetype then
f = columns[records[F]] return nil
elseif not H then
a = columns[records[A]]
b = columns[records[B]]
c = columns[records[C]]
d = columns[records[D]]
e = columns[records[E]]
f = columns[records[F]]
g = columns[records[G]]
elseif not I then
a = columns[records[A]]
b = columns[records[B]]
c = columns[records[C]]
d = columns[records[D]]
e = columns[records[E]]
f = columns[records[F]]
g = columns[records[G]]
h = columns[records[H]]
end end
entities = archetype.entities
i = #entities
if i == 0 then
continue
end
entity = entities[i]
columns = archetype.columns
records = archetype.records
a = columns[records[A]]
b = columns[records[B]]
c = columns[records[C]]
d = columns[records[D]]
e = columns[records[E]]
f = columns[records[F]]
end
local row = i
i -= 1
return entity, a[row], b[row], c[row], d[row], e[row], f[row]
end
elseif not H then
function world_query_iter_next(): any
local entity = entities[i]
while entity == nil do
lastArchetype += 1
archetype = compatible_archetypes[lastArchetype]
if not archetype then
return nil
end
entities = archetype.entities
i = #entities
if i == 0 then
continue
end
entity = entities[i]
columns = archetype.columns
records = archetype.records
a = columns[records[A]]
b = columns[records[B]]
c = columns[records[C]]
d = columns[records[D]]
e = columns[records[E]]
f = columns[records[F]]
g = columns[records[G]]
end
local row = i
i -= 1
return entity, a[row], b[row], c[row], d[row], e[row], f[row], g[row]
end
elseif not I then
function world_query_iter_next(): any
local entity = entities[i]
while entity == nil do
lastArchetype += 1
archetype = compatible_archetypes[lastArchetype]
if not archetype then
return nil
end
entities = archetype.entities
i = #entities
if i == 0 then
continue
end
entity = entities[i]
columns = archetype.columns
records = archetype.records
a = columns[records[A]]
b = columns[records[B]]
c = columns[records[C]]
d = columns[records[D]]
e = columns[records[E]]
f = columns[records[F]]
g = columns[records[G]]
h = columns[records[H]]
end
local row = i
i -= 1
return entity, a[row], b[row], c[row], d[row], e[row], f[row], g[row], h[row]
end
else
local queryOutput = {}
function world_query_iter_next(): any
local entity = entities[i]
while entity == nil do
lastArchetype += 1
archetype = compatible_archetypes[lastArchetype]
if not archetype then
return nil
end
entities = archetype.entities
i = #entities
if i == 0 then
continue
end
entity = entities[i]
columns = archetype.columns
records = archetype.records
end end
local row = i local row = i
i -= 1 i -= 1
if not F then if not F then
return entityId, a[row], b[row], c[row], d[row], e[row] return entity, a[row], b[row], c[row], d[row], e[row]
elseif not G then elseif not G then
return entityId, a[row], b[row], c[row], d[row], e[row], f[row] return entity, a[row], b[row], c[row], d[row], e[row], f[row]
elseif not H then elseif not H then
return entityId, a[row], b[row], c[row], d[row], e[row], f[row], g[row] return entity, a[row], b[row], c[row], d[row], e[row], f[row], g[row]
elseif not I then elseif not I then
return entityId, a[row], b[row], c[row], d[row], e[row], f[row], g[row], h[row] return entity, a[row], b[row], c[row], d[row], e[row], f[row], g[row], h[row]
end end
for j, id in ids do for j, id in ids do
queryOutput[j] = columns[records[id]][row] queryOutput[j] = columns[records[id]][row]
end end
return entityId, unpack(queryOutput) return entity, unpack(queryOutput)
end end
end end