Save column indexing

This commit is contained in:
Ukendio 2024-07-30 19:36:53 +02:00
parent d5baf52977
commit 023e7ace5b
5 changed files with 162 additions and 137 deletions

View file

@ -170,10 +170,14 @@ return {
end, end,
Functions = { Functions = {
Mirror = function() Matter = function()
for entityId, firstComponent in mcs:query(E1, E2, E3, E4) do for entityId, firstComponent in newWorld:query(A1, A2, A3, A4) do
end end
end,
ECR = function()
for entityId, firstComponent in registry2:view(B1, B2, B3, B3) do
end
end, end,
Jecs = function() Jecs = function()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 80 KiB

BIN
image.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

View file

@ -750,7 +750,15 @@ do
local A, B, C, D, E, F, G, H local A, B, C, D, E, F, G, H
local a, b, c, d, e, f, g, h local a, b, c, d, e, f, g, h
local init
local drain
local function query_init(query) local function query_init(query)
if init and drain then
return
end
init = true
lastArchetype = 1 lastArchetype = 1
archetype = compatible_archetypes[lastArchetype] archetype = compatible_archetypes[lastArchetype]
@ -767,53 +775,52 @@ do
local records = archetype.records local records = archetype.records
if not B then if not B then
a = records[A] a = columns[records[A]]
elseif not C then elseif not C then
a = records[A] a = columns[records[A]]
b = records[B] b = columns[records[B]]
elseif not D then elseif not D then
a = records[A] a = columns[records[A]]
b = records[B] b = columns[records[B]]
c = records[C] c = columns[records[C]]
elseif not E then elseif not E then
a = records[A] a = columns[records[A]]
b = records[B] b = columns[records[B]]
c = records[C] c = columns[records[C]]
d = records[D] d = columns[records[D]]
elseif not F then elseif not F then
a = records[A] a = columns[records[A]]
b = records[B] b = columns[records[B]]
c = records[C] c = columns[records[C]]
d = records[D] d = columns[records[D]]
e = records[E] e = columns[records[E]]
elseif not G then elseif not G then
a = records[A] a = columns[records[A]]
b = records[B] b = columns[records[B]]
c = records[C] c = columns[records[C]]
d = records[D] d = columns[records[D]]
e = records[E] e = columns[records[E]]
f = records[F] f = columns[records[F]]
elseif not H then elseif not H then
a = records[A] a = columns[records[A]]
b = records[B] b = columns[records[B]]
c = records[C] c = columns[records[C]]
d = records[D] d = columns[records[D]]
e = records[E] e = columns[records[E]]
f = records[F] f = columns[records[F]]
g = records[G] g = columns[records[G]]
elseif H then elseif H then
a = records[A] a = columns[records[A]]
b = records[B] b = columns[records[B]]
c = records[C] c = columns[records[D]]
d = records[D] e = columns[records[E]]
e = records[E] f = columns[records[F]]
f = records[F] g = columns[records[G]]
g = records[G] h = columns[records[H]]
h = records[H]
end end
end end
local function world_query_next(): any local function world_query_iter_next(): any
local entityId = entities[i] local entityId = entities[i]
while entityId == nil do while entityId == nil do
lastArchetype += 1 lastArchetype += 1
@ -821,103 +828,106 @@ do
if not archetype then if not archetype then
return nil return nil
end end
local records = archetype.records
if not B then
a = records[A]
elseif not C then
a = records[A]
b = records[B]
elseif not D then
a = records[A]
b = records[B]
c = records[C]
elseif not E then
a = records[A]
b = records[B]
c = records[C]
d = records[D]
elseif not F then
a = records[A]
b = records[B]
c = records[C]
d = records[D]
e = records[E]
elseif not G then
a = records[A]
b = records[B]
c = records[C]
d = records[D]
e = records[E]
f = records[F]
elseif not H then
a = records[A]
b = records[B]
c = records[C]
d = records[D]
e = records[E]
f = records[F]
g = records[G]
elseif H then
a = records[A]
b = records[B]
c = records[C]
d = records[D]
e = records[E]
f = records[F]
g = records[G]
h = records[H]
end
columns = archetype.columns
entities = archetype.entities entities = archetype.entities
i = #entities i = #entities
if i == 0 then
continue
end
entityId = entities[i] entityId = entities[i]
columns = archetype.columns
local records = archetype.records
if not B then
a = columns[records[A]]
elseif not C then
a = columns[records[A]]
b = columns[records[B]]
elseif not D then
a = columns[records[A]]
b = columns[records[B]]
c = columns[records[C]]
elseif not E then
a = columns[records[A]]
b = columns[records[B]]
c = columns[records[C]]
d = columns[records[D]]
elseif not F then
a = columns[records[A]]
b = columns[records[B]]
c = columns[records[C]]
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 H then
a = columns[records[A]]
b = columns[records[B]]
c = 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 queryLength == 1 then if queryLength == 1 then
return entityId, columns[a][row] return entityId, a[row]
elseif queryLength == 2 then elseif queryLength == 2 then
return entityId, columns[a][row], columns[b][row] return entityId, a[row], b[row]
elseif queryLength == 3 then elseif queryLength == 3 then
return entityId, columns[a][row], columns[b][row], columns[c][row] return entityId, a[row], b[row], c[row]
elseif queryLength == 4 then elseif queryLength == 4 then
return entityId, columns[a][row], columns[b][row], columns[c][row], columns[d][row] return entityId, a[row], b[row], c[row], d[row]
elseif queryLength == 5 then elseif queryLength == 5 then
return entityId, return entityId,
columns[a][row], a[row],
columns[b][row], b[row],
columns[c][row], c[row],
columns[d][row], d[row],
columns[e][row] e[row]
elseif queryLength == 6 then elseif queryLength == 6 then
return entityId, return entityId,
columns[a][row], a[row],
columns[b][row], b[row],
columns[c][row], c[row],
columns[d][row], d[row],
columns[e][row], e[row],
columns[f][row] f[row]
elseif queryLength == 7 then elseif queryLength == 7 then
return entityId, return entityId,
columns[a][row], a[row],
columns[b][row], b[row],
columns[c][row], c[row],
columns[d][row], d[row],
columns[e][row], e[row],
columns[f][row], f[row],
columns[g][row] g[row]
elseif queryLength == 8 then elseif queryLength == 8 then
return entityId, return entityId,
columns[a][row], a[row],
columns[b][row], b[row],
columns[c][row], c[row],
columns[d][row], d[row],
columns[e][row], e[row],
columns[f][row], f[row],
columns[g][row], g[row],
columns[h][row] h[row]
end end
local field = archetype.records local field = archetype.records
@ -968,26 +978,26 @@ do
local tr = archetype.records local tr = archetype.records
for row in archetype.entities do for row in archetype.entities do
if queryLength == 1 then if queryLength == 1 then
local va = columns[tr[a]] local va = columns[tr[A]]
local pa = fn(va[row]) local pa = fn(va[row])
va[row] = pa va[row] = pa
elseif queryLength == 2 then elseif queryLength == 2 then
local va = columns[tr[a]] local va = columns[tr[A]]
local vb = columns[tr[b]] local vb = columns[tr[B]]
va[row], vb[row] = fn(va[row], vb[row]) va[row], vb[row] = fn(va[row], vb[row])
elseif queryLength == 3 then elseif queryLength == 3 then
local va = columns[tr[a]] local va = columns[tr[A]]
local vb = columns[tr[b]] local vb = columns[tr[B]]
local vc = columns[tr[c]] local vc = columns[tr[C]]
va[row], vb[row], vc[row] = fn(va[row], vb[row], vc[row]) va[row], vb[row], vc[row] = fn(va[row], vb[row], vc[row])
elseif queryLength == 4 then elseif queryLength == 4 then
local va = columns[tr[a]] local va = columns[tr[A]]
local vb = columns[tr[b]] local vb = columns[tr[B]]
local vc = columns[tr[c]] local vc = columns[tr[C]]
local vd = columns[tr[d]] local vd = columns[tr[D]]
va[row], vb[row], vc[row], vd[row] = fn( va[row], vb[row], vc[row], vd[row] = fn(
va[row], vb[row], vc[row], vd[row]) va[row], vb[row], vc[row], vd[row])
@ -1026,6 +1036,8 @@ do
end end
end end
query_init(query)
return query return query
end end
@ -1036,8 +1048,6 @@ do
return compatible_archetypes return compatible_archetypes
end end
local drain
local function world_query_drain(query) local function world_query_drain(query)
drain = true drain = true
query_init(query) query_init(query)
@ -1045,10 +1055,15 @@ do
end end
local function world_query_iter(query) local function world_query_iter(query)
query_init(query)
return world_query_iter_next
end
local function world_query_next()
if not drain then if not drain then
query_init(query) error("Did you forget to call query:drain()?")
end end
return world_query_next return world_query_iter_next()
end end
local it = { local it = {
@ -1113,6 +1128,7 @@ do
end end
drain = false drain = false
init = false
ids = components ids = components
return it return it

View file

@ -296,14 +296,19 @@ TEST("world:query()", function()
world:set(eAB, A, true) world:set(eAB, A, true)
world:set(eAB, B, true) world:set(eAB, B, true)
local q = world:query(A) local q = world:query(A):drain()
local e, data = q:next() local e, data = q.next()
while e do while e do
if e ~= eA and e ~= eAB then if e == eA then
CHECK(data)
elseif e == eAB then
CHECK(data)
else
CHECK(false) CHECK(false)
end end
e, data = q:next()
e, data = q.next()
end end
CHECK(true) CHECK(true)
end end
@ -743,7 +748,7 @@ do
added = true added = true
local q = world:query(T):without(PreviousT):drain() local q = world:query(T):without(PreviousT):drain()
return function() return function()
local id, data = q:next() local id, data = q.next()
if not id then if not id then
return nil return nil
end end
@ -762,7 +767,7 @@ do
local q = world:query(T, PreviousT):drain() local q = world:query(T, PreviousT):drain()
return function() return function()
local id, new, old = q:next() local id, new, old = q.next()
while true do while true do
if not id then if not id then
return nil return nil
@ -788,7 +793,7 @@ do
local q = world:query(PreviousT):without(T):drain() local q = world:query(PreviousT):without(T):drain()
return function() return function()
local id = q:next() local id = q.next()
if id then if id then
world:remove(id, PreviousT) world:remove(id, PreviousT)
end end