mirror of
https://github.com/Ukendio/jecs.git
synced 2025-04-25 09:30:03 +00:00
Merge branch 'main' of https://github.com/Ukendio/jecs into docs
This commit is contained in:
commit
c5505f095b
5 changed files with 266 additions and 228 deletions
|
@ -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()
|
||||||
|
|
BIN
image-3.png
BIN
image-3.png
Binary file not shown.
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 42 KiB |
BIN
image.png
BIN
image.png
Binary file not shown.
Before Width: | Height: | Size: 187 KiB |
460
src/init.luau
460
src/init.luau
|
@ -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,191 +775,193 @@ 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_iter_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
|
||||||
archetype = compatible_archetypes[lastArchetype]
|
archetype = compatible_archetypes[lastArchetype]
|
||||||
if not archetype then
|
if not archetype then
|
||||||
return nil
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
entities = archetype.entities
|
||||||
|
i = #entities
|
||||||
|
if i == 0 then
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
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
|
||||||
|
|
||||||
|
local row = i
|
||||||
|
i-=1
|
||||||
|
|
||||||
|
if queryLength == 1 then
|
||||||
|
return entityId, a[row]
|
||||||
|
elseif queryLength == 2 then
|
||||||
|
return entityId, a[row], b[row]
|
||||||
|
elseif queryLength == 3 then
|
||||||
|
return entityId, a[row], b[row], c[row]
|
||||||
|
elseif queryLength == 4 then
|
||||||
|
return entityId, a[row], b[row], c[row], d[row]
|
||||||
|
elseif queryLength == 5 then
|
||||||
|
return entityId,
|
||||||
|
a[row],
|
||||||
|
b[row],
|
||||||
|
c[row],
|
||||||
|
d[row],
|
||||||
|
e[row]
|
||||||
|
elseif queryLength == 6 then
|
||||||
|
return entityId,
|
||||||
|
a[row],
|
||||||
|
b[row],
|
||||||
|
c[row],
|
||||||
|
d[row],
|
||||||
|
e[row],
|
||||||
|
f[row]
|
||||||
|
elseif queryLength == 7 then
|
||||||
|
return entityId,
|
||||||
|
a[row],
|
||||||
|
b[row],
|
||||||
|
c[row],
|
||||||
|
d[row],
|
||||||
|
e[row],
|
||||||
|
f[row],
|
||||||
|
g[row]
|
||||||
|
elseif queryLength == 8 then
|
||||||
|
return entityId,
|
||||||
|
a[row],
|
||||||
|
b[row],
|
||||||
|
c[row],
|
||||||
|
d[row],
|
||||||
|
e[row],
|
||||||
|
f[row],
|
||||||
|
g[row],
|
||||||
|
h[row]
|
||||||
|
end
|
||||||
|
|
||||||
|
local field = archetype.records
|
||||||
|
for j, id in ids do
|
||||||
|
queryOutput[j] = columns[field[id]][row]
|
||||||
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
|
|
||||||
i = #entities
|
|
||||||
entityId = entities[i]
|
|
||||||
end
|
|
||||||
|
|
||||||
local row = i
|
return entityId, unpack(queryOutput, 1, queryLength)
|
||||||
i-=1
|
|
||||||
|
|
||||||
if queryLength == 1 then
|
|
||||||
return entityId, columns[a][row]
|
|
||||||
elseif queryLength == 2 then
|
|
||||||
return entityId, columns[a][row], columns[b][row]
|
|
||||||
elseif queryLength == 3 then
|
|
||||||
return entityId, columns[a][row], columns[b][row], columns[c][row]
|
|
||||||
elseif queryLength == 4 then
|
|
||||||
return entityId, columns[a][row], columns[b][row], columns[c][row], columns[d][row]
|
|
||||||
elseif queryLength == 5 then
|
|
||||||
return entityId,
|
|
||||||
columns[a][row],
|
|
||||||
columns[b][row],
|
|
||||||
columns[c][row],
|
|
||||||
columns[d][row],
|
|
||||||
columns[e][row]
|
|
||||||
elseif queryLength == 6 then
|
|
||||||
return entityId,
|
|
||||||
columns[a][row],
|
|
||||||
columns[b][row],
|
|
||||||
columns[c][row],
|
|
||||||
columns[d][row],
|
|
||||||
columns[e][row],
|
|
||||||
columns[f][row]
|
|
||||||
elseif queryLength == 7 then
|
|
||||||
return entityId,
|
|
||||||
columns[a][row],
|
|
||||||
columns[b][row],
|
|
||||||
columns[c][row],
|
|
||||||
columns[d][row],
|
|
||||||
columns[e][row],
|
|
||||||
columns[f][row],
|
|
||||||
columns[g][row]
|
|
||||||
elseif queryLength == 8 then
|
|
||||||
return entityId,
|
|
||||||
columns[a][row],
|
|
||||||
columns[b][row],
|
|
||||||
columns[c][row],
|
|
||||||
columns[d][row],
|
|
||||||
columns[e][row],
|
|
||||||
columns[f][row],
|
|
||||||
columns[g][row],
|
|
||||||
columns[h][row]
|
|
||||||
end
|
|
||||||
|
|
||||||
local field = archetype.records
|
|
||||||
for j, id in ids do
|
|
||||||
queryOutput[j] = columns[field[id]][row]
|
|
||||||
end
|
|
||||||
|
|
||||||
return entityId, unpack(queryOutput, 1, queryLength)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function world_query_without(self, ...)
|
local function world_query_without(self, ...)
|
||||||
local withoutComponents = { ... }
|
local withoutComponents = { ... }
|
||||||
for i = #compatible_archetypes, 1, -1 do
|
for i = #compatible_archetypes, 1, -1 do
|
||||||
local archetype = compatible_archetypes[i]
|
local archetype = compatible_archetypes[i]
|
||||||
local records = archetype.records
|
local records = archetype.records
|
||||||
local shouldRemove = false
|
local shouldRemove = false
|
||||||
|
|
||||||
for _, componentId in withoutComponents do
|
for _, componentId in withoutComponents do
|
||||||
if records[componentId] then
|
if records[componentId] then
|
||||||
shouldRemove = true
|
shouldRemove = true
|
||||||
break
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if shouldRemove then
|
||||||
|
local last = #compatible_archetypes
|
||||||
|
if last ~= i then
|
||||||
|
compatible_archetypes[i] = compatible_archetypes[last]
|
||||||
|
end
|
||||||
|
compatible_archetypes[last] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if shouldRemove then
|
return self
|
||||||
local last = #compatible_archetypes
|
|
||||||
if last ~= i then
|
|
||||||
compatible_archetypes[i] = compatible_archetypes[last]
|
|
||||||
end
|
|
||||||
compatible_archetypes[last] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function world_query_replace_values(row, columns, ...)
|
local function world_query_replace_values(row, columns, ...)
|
||||||
|
@ -961,72 +971,74 @@ do
|
||||||
end
|
end
|
||||||
|
|
||||||
local function world_query_replace(query, fn: (...any) -> (...any))
|
local function world_query_replace(query, fn: (...any) -> (...any))
|
||||||
query_init(query)
|
query_init(query)
|
||||||
|
|
||||||
for i, archetype in compatible_archetypes do
|
for i, archetype in compatible_archetypes do
|
||||||
local columns = archetype.columns
|
local columns = archetype.columns
|
||||||
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])
|
||||||
else
|
else
|
||||||
local field = archetype.records
|
local field = archetype.records
|
||||||
for j, id in ids do
|
for j, id in ids do
|
||||||
queryOutput[j] = columns[field[id]][row]
|
queryOutput[j] = columns[field[id]][row]
|
||||||
end
|
end
|
||||||
world_query_replace_values(row, columns,
|
world_query_replace_values(row, columns,
|
||||||
fn(unpack(queryOutput)))
|
fn(unpack(queryOutput)))
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function world_query_with(query, ...)
|
local function world_query_with(query, ...)
|
||||||
local ids = { ... }
|
local ids = { ... }
|
||||||
for i = #compatible_archetypes, 1, -1 do
|
for i = #compatible_archetypes, 1, -1 do
|
||||||
local archetype = compatible_archetypes[i]
|
local archetype = compatible_archetypes[i]
|
||||||
local records = archetype.records
|
local records = archetype.records
|
||||||
local shouldRemove = false
|
local shouldRemove = false
|
||||||
|
|
||||||
for _, id in ids do
|
for _, id in ids do
|
||||||
if not records[id] then
|
if not records[id] then
|
||||||
shouldRemove = true
|
shouldRemove = true
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if shouldRemove then
|
if shouldRemove then
|
||||||
local last = #compatible_archetypes
|
local last = #compatible_archetypes
|
||||||
if last ~= i then
|
if last ~= i then
|
||||||
compatible_archetypes[i] = compatible_archetypes[last]
|
compatible_archetypes[i] = compatible_archetypes[last]
|
||||||
end
|
end
|
||||||
compatible_archetypes[last] = nil
|
compatible_archetypes[last] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return query
|
query_init(query)
|
||||||
|
|
||||||
|
return query
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Meant for directly iterating over archetypes to minimize
|
-- Meant for directly iterating over archetypes to minimize
|
||||||
|
@ -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,9 +1055,7 @@ do
|
||||||
end
|
end
|
||||||
|
|
||||||
local function world_query_iter(query)
|
local function world_query_iter(query)
|
||||||
if not drain then
|
query_init(query)
|
||||||
query_init(query)
|
|
||||||
end
|
|
||||||
return world_query_iter_next
|
return world_query_iter_next
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1058,7 +1066,6 @@ do
|
||||||
return world_query_iter_next()
|
return world_query_iter_next()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local it = {
|
local it = {
|
||||||
__iter = world_query_iter,
|
__iter = world_query_iter,
|
||||||
drain = world_query_drain,
|
drain = world_query_drain,
|
||||||
|
@ -1121,6 +1128,7 @@ do
|
||||||
end
|
end
|
||||||
|
|
||||||
drain = false
|
drain = false
|
||||||
|
init = false
|
||||||
ids = components
|
ids = components
|
||||||
|
|
||||||
return it
|
return it
|
||||||
|
|
|
@ -282,6 +282,32 @@ TEST("world:query()", function()
|
||||||
CHECK(counter == 0)
|
CHECK(counter == 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
do CASE "query more than 8 components"
|
||||||
|
local world = jecs.World.new()
|
||||||
|
local components = {}
|
||||||
|
|
||||||
|
for i = 1, 9 do
|
||||||
|
local id = world:component()
|
||||||
|
components[i] = id
|
||||||
|
end
|
||||||
|
local e = world:entity()
|
||||||
|
for i, id in components do
|
||||||
|
world:set(e, id, 13^i)
|
||||||
|
end
|
||||||
|
|
||||||
|
for entity, a, b, c, d, e, f, g, h, i in world:query(unpack(components)) do
|
||||||
|
CHECK(a == 13^1)
|
||||||
|
CHECK(b == 13^2)
|
||||||
|
CHECK(c == 13^3)
|
||||||
|
CHECK(d == 13^4)
|
||||||
|
CHECK(e == 13^5)
|
||||||
|
CHECK(f == 13^6)
|
||||||
|
CHECK(g == 13^7)
|
||||||
|
CHECK(h == 13^8)
|
||||||
|
CHECK(i == 13^9)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
do CASE "should be able to get next results"
|
do CASE "should be able to get next results"
|
||||||
local world = jecs.World.new() :: World
|
local world = jecs.World.new() :: World
|
||||||
world:component()
|
world:component()
|
||||||
|
|
Loading…
Reference in a new issue