mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-13 11:38:15 +07:00
Merge branch 'dev'
This commit is contained in:
11
README.md
11
README.md
@@ -80,10 +80,15 @@ each :: entity -> {each_state? -> fragment?, component?}, each_state?
|
||||
execute :: query -> {execute_state? -> chunk?, entity[]?}, execute_state?
|
||||
```
|
||||
|
||||
```
|
||||
spawn_at :: chunk?, fragment[]?, component[]? -> entity, boolean
|
||||
spawn_with :: fragment[]?, component[]? -> entity, boolean
|
||||
```
|
||||
|
||||
```
|
||||
entity :: entity_builder
|
||||
entity_builder:set :: fragment, any... -> entity_builder
|
||||
entity_builder:build :: entity
|
||||
entity_builder:build :: entity, boolean
|
||||
```
|
||||
|
||||
```
|
||||
@@ -91,14 +96,14 @@ fragment :: fragment_builder
|
||||
fragment_builder:tag :: fragment_builder
|
||||
fragment_builder:default :: component -> fragment_builder
|
||||
fragment_builder:construct :: {any... -> component} -> fragment_builder
|
||||
fragment_builder:build :: fragment
|
||||
fragment_builder:build :: fragment, boolean
|
||||
```
|
||||
|
||||
```
|
||||
query :: query_builder
|
||||
query_builder:include :: fragment... -> query_builder
|
||||
query_builder:exclude :: fragment... -> query_builder
|
||||
query_builder:build :: query
|
||||
query_builder:build :: query, boolean
|
||||
```
|
||||
|
||||
## [License (MIT)](./LICENSE.md)
|
||||
|
||||
@@ -10,4 +10,3 @@
|
||||
- add REQUIRES fragment trait
|
||||
- try to keep entity_chunks/places tables as arrays
|
||||
- set/assign/insert/remove/destroy for lists?
|
||||
- add attach/detach functions?
|
||||
|
||||
70
develop/basics.lua
Normal file
70
develop/basics.lua
Normal file
@@ -0,0 +1,70 @@
|
||||
local basics = {}
|
||||
|
||||
local __table_pack = (function()
|
||||
return table.pack or function(...)
|
||||
return { n = select('#', ...), ... }
|
||||
end
|
||||
end)()
|
||||
|
||||
local __table_unpack = (function()
|
||||
return table.unpack or unpack
|
||||
end)()
|
||||
|
||||
---@param name string
|
||||
---@param loop fun(...): ...
|
||||
---@param init? fun(): ...
|
||||
function basics.describe_bench(name, loop, init)
|
||||
print(string.format('| %s ... |', name))
|
||||
|
||||
local state = init and __table_pack(init()) or {}
|
||||
|
||||
do
|
||||
local warmup_s = os.clock()
|
||||
|
||||
local success, result = pcall(function()
|
||||
repeat
|
||||
loop(__table_unpack(state))
|
||||
until os.clock() - warmup_s > 0.1
|
||||
end)
|
||||
|
||||
if not success then
|
||||
print('|-- FAIL: ' .. result)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
collectgarbage('collect')
|
||||
collectgarbage('stop')
|
||||
|
||||
do
|
||||
local iters = 0
|
||||
|
||||
local start_s = os.clock()
|
||||
local start_kb = collectgarbage('count')
|
||||
|
||||
local success, result = pcall(function()
|
||||
repeat
|
||||
iters = iters + 1
|
||||
loop(__table_unpack(state))
|
||||
until os.clock() - start_s > 0.1
|
||||
end)
|
||||
|
||||
local finish_s = os.clock()
|
||||
local finish_kb = collectgarbage('count')
|
||||
|
||||
if success then
|
||||
print(string.format('|-- PASS | us: %.2f | op/s: %.2f | kb/i: %.2f | iters: %d',
|
||||
(finish_s - start_s) * 1e6 / iters,
|
||||
iters / (finish_s - start_s),
|
||||
(finish_kb - start_kb) / iters,
|
||||
iters))
|
||||
else
|
||||
print('|-- FAIL: ' .. result)
|
||||
end
|
||||
end
|
||||
|
||||
collectgarbage('restart')
|
||||
collectgarbage('collect')
|
||||
end
|
||||
|
||||
return basics
|
||||
@@ -1 +1,926 @@
|
||||
package.loaded['evolved'] = nil
|
||||
local evo = require 'evolved'
|
||||
|
||||
local basics = require 'develop.basics'
|
||||
|
||||
local N = 1000
|
||||
local B = evo.entity()
|
||||
local F1, F2, F3, F4, F5 = evo.id(5)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('create %d tables', N),
|
||||
---@param tables table[]
|
||||
function(tables)
|
||||
for i = 1, N do
|
||||
local t = {}
|
||||
tables[i] = t
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and collect %d tables', N),
|
||||
---@param tables table[]
|
||||
function(tables)
|
||||
for i = 1, N do
|
||||
local t = {}
|
||||
tables[i] = t
|
||||
end
|
||||
|
||||
for i = 1, #tables do
|
||||
tables[i] = nil
|
||||
end
|
||||
|
||||
collectgarbage('collect')
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('create %d tables with 1 component / AoS', N),
|
||||
---@param tables table
|
||||
function(tables)
|
||||
for i = 1, N do
|
||||
local e = {}
|
||||
e[F1] = true
|
||||
tables[i] = e
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create %d tables with 2 component / AoS', N),
|
||||
---@param tables table
|
||||
function(tables)
|
||||
for i = 1, N do
|
||||
local e = {}
|
||||
e[F1] = true
|
||||
e[F2] = true
|
||||
tables[i] = e
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create %d tables with 3 component / AoS', N),
|
||||
---@param tables table
|
||||
function(tables)
|
||||
for i = 1, N do
|
||||
local e = {}
|
||||
e[F1] = true
|
||||
e[F2] = true
|
||||
e[F3] = true
|
||||
tables[i] = e
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create %d tables with 4 component / AoS', N),
|
||||
---@param tables table
|
||||
function(tables)
|
||||
for i = 1, N do
|
||||
local e = {}
|
||||
e[F1] = true
|
||||
e[F2] = true
|
||||
e[F3] = true
|
||||
e[F4] = true
|
||||
tables[i] = e
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create %d tables with 5 component / AoS', N),
|
||||
---@param tables table
|
||||
function(tables)
|
||||
for i = 1, N do
|
||||
local e = {}
|
||||
e[F1] = true
|
||||
e[F2] = true
|
||||
e[F3] = true
|
||||
e[F4] = true
|
||||
e[F5] = true
|
||||
tables[i] = e
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('create %d tables with 1 component / SoA', N),
|
||||
---@param tables table
|
||||
function(tables)
|
||||
local fs1 = {}
|
||||
for i = 1, N do
|
||||
local e = {}
|
||||
fs1[i] = true
|
||||
tables[i] = e
|
||||
end
|
||||
tables[F1] = fs1
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create %d tables with 2 component / SoA', N),
|
||||
---@param tables table
|
||||
function(tables)
|
||||
local fs1 = {}
|
||||
local fs2 = {}
|
||||
for i = 1, N do
|
||||
local e = {}
|
||||
fs1[i] = true
|
||||
fs2[i] = true
|
||||
tables[i] = e
|
||||
end
|
||||
tables[F1] = fs1
|
||||
tables[F2] = fs2
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create %d tables with 3 component / SoA', N),
|
||||
---@param tables table
|
||||
function(tables)
|
||||
local fs1 = {}
|
||||
local fs2 = {}
|
||||
local fs3 = {}
|
||||
for i = 1, N do
|
||||
local e = {}
|
||||
fs1[i] = true
|
||||
fs2[i] = true
|
||||
fs3[i] = true
|
||||
tables[i] = e
|
||||
end
|
||||
tables[F1] = fs1
|
||||
tables[F2] = fs2
|
||||
tables[F3] = fs3
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create %d tables with 4 component / SoA', N),
|
||||
---@param tables table
|
||||
function(tables)
|
||||
local fs1 = {}
|
||||
local fs2 = {}
|
||||
local fs3 = {}
|
||||
local fs4 = {}
|
||||
for i = 1, N do
|
||||
local e = {}
|
||||
fs1[i] = i
|
||||
fs2[i] = i
|
||||
fs3[i] = i
|
||||
fs4[i] = i
|
||||
tables[i] = e
|
||||
end
|
||||
tables[F1] = fs1
|
||||
tables[F2] = fs2
|
||||
tables[F3] = fs3
|
||||
tables[F4] = fs4
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create %d tables with 5 component / SoA', N),
|
||||
---@param tables table
|
||||
function(tables)
|
||||
local fs1 = {}
|
||||
local fs2 = {}
|
||||
local fs3 = {}
|
||||
local fs4 = {}
|
||||
local fs5 = {}
|
||||
for i = 1, N do
|
||||
local e = {}
|
||||
fs1[i] = i
|
||||
fs2[i] = i
|
||||
fs3[i] = i
|
||||
fs4[i] = i
|
||||
fs5[i] = i
|
||||
tables[i] = e
|
||||
end
|
||||
tables[F1] = fs1
|
||||
tables[F2] = fs2
|
||||
tables[F3] = fs3
|
||||
tables[F4] = fs4
|
||||
tables[F5] = fs5
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local id = evo.id
|
||||
local destroy = evo.destroy
|
||||
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
entities[i] = e
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 1 component', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local id = evo.id
|
||||
local insert = evo.insert
|
||||
local destroy = evo.destroy
|
||||
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
insert(e, F1)
|
||||
entities[i] = e
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 2 components', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local id = evo.id
|
||||
local insert = evo.insert
|
||||
local destroy = evo.destroy
|
||||
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
insert(e, F1)
|
||||
insert(e, F2)
|
||||
entities[i] = e
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 3 components', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local id = evo.id
|
||||
local insert = evo.insert
|
||||
local destroy = evo.destroy
|
||||
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
insert(e, F1)
|
||||
insert(e, F2)
|
||||
insert(e, F3)
|
||||
entities[i] = e
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 4 components', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local id = evo.id
|
||||
local insert = evo.insert
|
||||
local destroy = evo.destroy
|
||||
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
insert(e, F1)
|
||||
insert(e, F2)
|
||||
insert(e, F3)
|
||||
insert(e, F4)
|
||||
entities[i] = e
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 5 components', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local id = evo.id
|
||||
local insert = evo.insert
|
||||
local destroy = evo.destroy
|
||||
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
insert(e, F1)
|
||||
insert(e, F2)
|
||||
insert(e, F3)
|
||||
insert(e, F4)
|
||||
insert(e, F5)
|
||||
entities[i] = e
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 1 components / defer', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local id = evo.id
|
||||
local insert = evo.insert
|
||||
local destroy = evo.destroy
|
||||
|
||||
evo.defer()
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
insert(e, F1)
|
||||
entities[i] = e
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 2 components / defer', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local id = evo.id
|
||||
local insert = evo.insert
|
||||
local destroy = evo.destroy
|
||||
|
||||
evo.defer()
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
insert(e, F1)
|
||||
insert(e, F2)
|
||||
entities[i] = e
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 3 components / defer', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local id = evo.id
|
||||
local insert = evo.insert
|
||||
local destroy = evo.destroy
|
||||
|
||||
evo.defer()
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
insert(e, F1)
|
||||
insert(e, F2)
|
||||
insert(e, F3)
|
||||
entities[i] = e
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 4 components / defer', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local id = evo.id
|
||||
local insert = evo.insert
|
||||
local destroy = evo.destroy
|
||||
|
||||
evo.defer()
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
insert(e, F1)
|
||||
insert(e, F2)
|
||||
insert(e, F3)
|
||||
insert(e, F4)
|
||||
entities[i] = e
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 5 components / defer', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local id = evo.id
|
||||
local insert = evo.insert
|
||||
local destroy = evo.destroy
|
||||
|
||||
evo.defer()
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
insert(e, F1)
|
||||
insert(e, F2)
|
||||
insert(e, F3)
|
||||
insert(e, F4)
|
||||
insert(e, F5)
|
||||
entities[i] = e
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 1 components / builder', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local set = B.set
|
||||
local build = B.build
|
||||
local destroy = evo.destroy
|
||||
|
||||
for i = 1, N do
|
||||
set(B, F1)
|
||||
entities[i] = build(B)
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 2 components / builder', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local set = B.set
|
||||
local build = B.build
|
||||
local destroy = evo.destroy
|
||||
|
||||
for i = 1, N do
|
||||
set(B, F1)
|
||||
set(B, F2)
|
||||
entities[i] = build(B)
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 3 components / builder', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local set = B.set
|
||||
local build = B.build
|
||||
local destroy = evo.destroy
|
||||
|
||||
for i = 1, N do
|
||||
set(B, F1)
|
||||
set(B, F2)
|
||||
set(B, F3)
|
||||
entities[i] = build(B)
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 4 components / builder', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local set = B.set
|
||||
local build = B.build
|
||||
local destroy = evo.destroy
|
||||
|
||||
for i = 1, N do
|
||||
set(B, F1)
|
||||
set(B, F2)
|
||||
set(B, F3)
|
||||
set(B, F4)
|
||||
entities[i] = build(B)
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 5 components / builder', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local set = B.set
|
||||
local build = B.build
|
||||
local destroy = evo.destroy
|
||||
|
||||
for i = 1, N do
|
||||
set(B, F1)
|
||||
set(B, F2)
|
||||
set(B, F3)
|
||||
set(B, F4)
|
||||
set(B, F5)
|
||||
entities[i] = build(B)
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 1 components / multi-set', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local set = evo.multi_set
|
||||
local destroy = evo.destroy
|
||||
|
||||
for i = 1, N do
|
||||
local e = evo.id()
|
||||
set(e, { F1 })
|
||||
entities[i] = e
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 2 components / multi-set', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local set = evo.multi_set
|
||||
local destroy = evo.destroy
|
||||
|
||||
for i = 1, N do
|
||||
local e = evo.id()
|
||||
set(e, { F1, F2 })
|
||||
entities[i] = e
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 3 components / multi-set', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local set = evo.multi_set
|
||||
local destroy = evo.destroy
|
||||
|
||||
for i = 1, N do
|
||||
local e = evo.id()
|
||||
set(e, { F1, F2, F3 })
|
||||
entities[i] = e
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 4 components / multi-set', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local set = evo.multi_set
|
||||
local destroy = evo.destroy
|
||||
|
||||
for i = 1, N do
|
||||
local e = evo.id()
|
||||
set(e, { F1, F2, F3, F4 })
|
||||
entities[i] = e
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 5 components / multi-set', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local set = evo.multi_set
|
||||
local destroy = evo.destroy
|
||||
|
||||
for i = 1, N do
|
||||
local e = evo.id()
|
||||
set(e, { F1, F2, F3, F4, F5 })
|
||||
entities[i] = e
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities / spawn_at', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn_at = evo.spawn_at
|
||||
local destroy = evo.destroy
|
||||
|
||||
local fragments = {}
|
||||
local components = {}
|
||||
|
||||
local chunk = evo.chunk()
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = spawn_at(chunk, fragments, components)
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 1 components / spawn_at', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn_at = evo.spawn_at
|
||||
local destroy = evo.destroy
|
||||
|
||||
local fragments = { F1 }
|
||||
local components = { true }
|
||||
|
||||
local chunk = evo.chunk(F1)
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = spawn_at(chunk, fragments, components)
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 2 components / spawn_at', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn_at = evo.spawn_at
|
||||
local destroy = evo.destroy
|
||||
|
||||
local fragments = { F1, F2 }
|
||||
local components = { true, true }
|
||||
|
||||
local chunk = evo.chunk(F1, F2)
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = spawn_at(chunk, fragments, components)
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 3 components / spawn_at', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn_at = evo.spawn_at
|
||||
local destroy = evo.destroy
|
||||
|
||||
local fragments = { F1, F2, F3 }
|
||||
local components = { true, true, true }
|
||||
|
||||
local chunk = evo.chunk(F1, F2, F3)
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = spawn_at(chunk, fragments, components)
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 4 components / spawn_at', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn_at = evo.spawn_at
|
||||
local destroy = evo.destroy
|
||||
|
||||
local fragments = { F1, F2, F3, F4 }
|
||||
local components = { true, true, true, true }
|
||||
|
||||
local chunk = evo.chunk(F1, F2, F3, F4)
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = spawn_at(chunk, fragments, components)
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 5 components / spawn_at', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn_at = evo.spawn_at
|
||||
local destroy = evo.destroy
|
||||
|
||||
local fragments = { F1, F2, F3, F4, F5 }
|
||||
local components = { true, true, true, true, true }
|
||||
|
||||
local chunk = evo.chunk(F1, F2, F3, F4, F5)
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = spawn_at(chunk, fragments, components)
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities / spawn_with', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn_with = evo.spawn_with
|
||||
local destroy = evo.destroy
|
||||
|
||||
local fragments = {}
|
||||
local components = {}
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = spawn_with(fragments, components)
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 1 components / spawn_with', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn_with = evo.spawn_with
|
||||
local destroy = evo.destroy
|
||||
|
||||
local fragments = { F1 }
|
||||
local components = { true }
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = spawn_with(fragments, components)
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 2 components / spawn_with', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn_with = evo.spawn_with
|
||||
local destroy = evo.destroy
|
||||
|
||||
local fragments = { F1, F2 }
|
||||
local components = { true, true }
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = spawn_with(fragments, components)
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 3 components / spawn_with', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn_with = evo.spawn_with
|
||||
local destroy = evo.destroy
|
||||
|
||||
local fragments = { F1, F2, F3 }
|
||||
local components = { true, true, true }
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = spawn_with(fragments, components)
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 4 components / spawn_with', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn_with = evo.spawn_with
|
||||
local destroy = evo.destroy
|
||||
|
||||
local fragments = { F1, F2, F3, F4 }
|
||||
local components = { true, true, true, true }
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = spawn_with(fragments, components)
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 5 components / spawn_with', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn_with = evo.spawn_with
|
||||
local destroy = evo.destroy
|
||||
|
||||
local fragments = { F1, F2, F3, F4, F5 }
|
||||
local components = { true, true, true, true, true }
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = spawn_with(fragments, components)
|
||||
end
|
||||
|
||||
for i = 1, #entities do
|
||||
destroy(entities[i])
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
package.loaded['evolved'] = nil
|
||||
local evo = require 'evolved'
|
||||
|
||||
do
|
||||
@@ -3145,3 +3146,567 @@ do
|
||||
assert(evo.is_alive(e) and evo.is_empty(e))
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
|
||||
evo.set(f3, evo.TAG)
|
||||
|
||||
do
|
||||
local e = evo.spawn_with()
|
||||
assert(evo.is_alive(e) and evo.is_empty(e))
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.spawn_with({})
|
||||
assert(evo.is_alive(e) and evo.is_empty(e))
|
||||
end
|
||||
|
||||
do
|
||||
local e1 = evo.spawn_with({ f1 })
|
||||
assert(evo.has(e1, f1) and evo.get(e1, f1) == true)
|
||||
|
||||
local e2 = evo.spawn_with({ f1 }, {})
|
||||
assert(evo.has(e2, f1) and evo.get(e2, f1) == true)
|
||||
|
||||
local e3 = evo.spawn_with({ f1 }, { 41 })
|
||||
assert(evo.has(e3, f1) and evo.get(e3, f1) == 41)
|
||||
end
|
||||
|
||||
do
|
||||
local e1 = evo.spawn_with({ f1, f2 })
|
||||
assert(evo.has_all(e1, f1, f2))
|
||||
assert(evo.get(e1, f1) == true and evo.get(e1, f2) == true)
|
||||
|
||||
local e2 = evo.spawn_with({ f1, f2 }, {})
|
||||
assert(evo.has_all(e2, f1, f2))
|
||||
assert(evo.get(e2, f1) == true and evo.get(e2, f2) == true)
|
||||
|
||||
local e3 = evo.spawn_with({ f1, f2 }, { 41 })
|
||||
assert(evo.has_all(e3, f1, f2))
|
||||
assert(evo.get(e3, f1) == 41 and evo.get(e3, f2) == true)
|
||||
|
||||
local e4 = evo.spawn_with({ f1, f2 }, { nil, 42 })
|
||||
assert(evo.has_all(e4, f1, f2))
|
||||
assert(evo.get(e4, f1) == true and evo.get(e4, f2) == 42)
|
||||
|
||||
local e5 = evo.spawn_with({ f1, f2 }, { 41, 42 })
|
||||
assert(evo.has_all(e5, f1, f2))
|
||||
assert(evo.get(e5, f1) == 41 and evo.get(e5, f2) == 42)
|
||||
|
||||
local e6 = evo.spawn_with({ f1, f2 }, { 41, 42, 43 })
|
||||
assert(evo.has_all(e6, f1, f2))
|
||||
assert(evo.get(e6, f1) == 41 and evo.get(e6, f2) == 42)
|
||||
end
|
||||
|
||||
do
|
||||
local e1 = evo.spawn_with({ f3 })
|
||||
assert(evo.has(e1, f3))
|
||||
assert(evo.get(e1, f3) == nil)
|
||||
|
||||
local e2 = evo.spawn_with({ f2, f3 })
|
||||
assert(evo.has_all(e2, f2, f3))
|
||||
assert(evo.get(e2, f2) == true and evo.get(e2, f3) == nil)
|
||||
|
||||
local e3 = evo.spawn_with({ f2, f3 }, { 42 })
|
||||
assert(evo.has_all(e3, f2, f3))
|
||||
assert(evo.get(e3, f2) == 42 and evo.get(e3, f3) == nil)
|
||||
|
||||
local e4 = evo.spawn_with({ f2, f3 }, { 42, 43, 44 })
|
||||
assert(evo.has_all(e4, f2, f3))
|
||||
assert(evo.get(e4, f2) == 42 and evo.get(e4, f3) == nil)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
|
||||
evo.set(f2, evo.DEFAULT, 21)
|
||||
evo.set(f3, evo.TAG)
|
||||
|
||||
do
|
||||
local e = evo.spawn_with()
|
||||
assert(evo.is_alive(e) and evo.is_empty(e))
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.spawn_with({})
|
||||
assert(evo.is_alive(e) and evo.is_empty(e))
|
||||
end
|
||||
|
||||
do
|
||||
local e1 = evo.spawn_with({ f1 })
|
||||
assert(evo.has(e1, f1) and evo.get(e1, f1) == true)
|
||||
|
||||
local e2 = evo.spawn_with({ f1 }, {})
|
||||
assert(evo.has(e2, f1) and evo.get(e2, f1) == true)
|
||||
|
||||
local e3 = evo.spawn_with({ f1 }, { 41 })
|
||||
assert(evo.has(e3, f1) and evo.get(e3, f1) == 41)
|
||||
end
|
||||
|
||||
do
|
||||
local e1 = evo.spawn_with({ f1, f2 })
|
||||
assert(evo.has_all(e1, f1, f2))
|
||||
assert(evo.get(e1, f1) == true and evo.get(e1, f2) == 21)
|
||||
|
||||
local e2 = evo.spawn_with({ f1, f2 }, {})
|
||||
assert(evo.has_all(e2, f1, f2))
|
||||
assert(evo.get(e2, f1) == true and evo.get(e2, f2) == 21)
|
||||
|
||||
local e3 = evo.spawn_with({ f1, f2 }, { 41 })
|
||||
assert(evo.has_all(e3, f1, f2))
|
||||
assert(evo.get(e3, f1) == 41 and evo.get(e3, f2) == 21)
|
||||
|
||||
local e4 = evo.spawn_with({ f1, f2 }, { nil, 42 })
|
||||
assert(evo.has_all(e4, f1, f2))
|
||||
assert(evo.get(e4, f1) == true and evo.get(e4, f2) == 42)
|
||||
|
||||
local e5 = evo.spawn_with({ f1, f2 }, { 41, 42 })
|
||||
assert(evo.has_all(e5, f1, f2))
|
||||
assert(evo.get(e5, f1) == 41 and evo.get(e5, f2) == 42)
|
||||
|
||||
local e6 = evo.spawn_with({ f1, f2 }, { 41, 42, 43 })
|
||||
assert(evo.has_all(e6, f1, f2))
|
||||
assert(evo.get(e6, f1) == 41 and evo.get(e6, f2) == 42)
|
||||
end
|
||||
|
||||
do
|
||||
local e1 = evo.spawn_with({ f3 })
|
||||
assert(evo.has(e1, f3))
|
||||
assert(evo.get(e1, f3) == nil)
|
||||
|
||||
local e2 = evo.spawn_with({ f2, f3 })
|
||||
assert(evo.has_all(e2, f2, f3))
|
||||
assert(evo.get(e2, f2) == 21 and evo.get(e2, f3) == nil)
|
||||
|
||||
local e3 = evo.spawn_with({ f2, f3 }, { 42 })
|
||||
assert(evo.has_all(e3, f2, f3))
|
||||
assert(evo.get(e3, f2) == 42 and evo.get(e3, f3) == nil)
|
||||
|
||||
local e4 = evo.spawn_with({ f2, f3 }, { 42, 43, 44 })
|
||||
assert(evo.has_all(e4, f2, f3))
|
||||
assert(evo.get(e4, f2) == 42 and evo.get(e4, f3) == nil)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local cf = evo.id()
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
|
||||
evo.set(f1, cf)
|
||||
evo.set(f2, cf)
|
||||
evo.set(f3, cf)
|
||||
|
||||
evo.set(f2, evo.DEFAULT, 21)
|
||||
evo.set(f3, evo.TAG)
|
||||
|
||||
local set_count = 0
|
||||
local insert_count = 0
|
||||
|
||||
local last_set_entity = 0
|
||||
local last_set_component = 0
|
||||
local last_insert_entity = 0
|
||||
local last_insert_component = 0
|
||||
|
||||
local q = evo.query():include(cf):build()
|
||||
|
||||
evo.batch_set(q, evo.ON_SET, function(e, f, c)
|
||||
last_set_entity = e
|
||||
assert(f == f1 or f == f2 or f == f3)
|
||||
last_set_component = c
|
||||
set_count = set_count + 1
|
||||
end)
|
||||
|
||||
evo.batch_set(q, evo.ON_INSERT, function(e, f, c)
|
||||
last_insert_entity = e
|
||||
assert(f == f1 or f == f2 or f == f3)
|
||||
last_insert_component = c
|
||||
insert_count = insert_count + 1
|
||||
end)
|
||||
|
||||
assert(set_count == 0 and insert_count == 0)
|
||||
assert(last_set_entity == 0 and last_set_component == 0)
|
||||
assert(last_insert_entity == 0 and last_insert_component == 0)
|
||||
|
||||
do
|
||||
set_count, insert_count = 0, 0
|
||||
last_set_entity, last_set_component = 0, 0
|
||||
last_insert_entity, last_insert_component = 0, 0
|
||||
local e = evo.spawn_with({ f1 })
|
||||
assert(set_count == 1 and insert_count == 1)
|
||||
assert(last_set_entity == e and last_set_component == true)
|
||||
assert(last_insert_entity == e and last_insert_component == true)
|
||||
end
|
||||
|
||||
do
|
||||
set_count, insert_count = 0, 0
|
||||
last_set_entity, last_set_component = 0, 0
|
||||
last_insert_entity, last_insert_component = 0, 0
|
||||
local e = evo.spawn_with({ f2 })
|
||||
assert(set_count == 1 and insert_count == 1)
|
||||
assert(last_set_entity == e and last_set_component == 21)
|
||||
assert(last_insert_entity == e and last_insert_component == 21)
|
||||
end
|
||||
|
||||
do
|
||||
set_count, insert_count = 0, 0
|
||||
last_set_entity, last_set_component = 0, 0
|
||||
last_insert_entity, last_insert_component = 0, 0
|
||||
local e = evo.spawn_with({ f1, f2 })
|
||||
assert(set_count == 2 and insert_count == 2)
|
||||
assert(last_set_entity == e and last_set_component == 21)
|
||||
assert(last_insert_entity == e and last_insert_component == 21)
|
||||
end
|
||||
|
||||
do
|
||||
set_count, insert_count = 0, 0
|
||||
last_set_entity, last_set_component = 0, 0
|
||||
last_insert_entity, last_insert_component = 0, 0
|
||||
local e = evo.spawn_with({ f3 }, { 33 })
|
||||
assert(set_count == 1 and insert_count == 1)
|
||||
assert(last_set_entity == e and last_set_component == nil)
|
||||
assert(last_insert_entity == e and last_insert_component == nil)
|
||||
end
|
||||
|
||||
do
|
||||
set_count, insert_count = 0, 0
|
||||
last_set_entity, last_set_component = 0, 0
|
||||
last_insert_entity, last_insert_component = 0, 0
|
||||
local e = evo.spawn_with({ f3, f2 }, { 33, 22 })
|
||||
assert(set_count == 2 and insert_count == 2)
|
||||
assert(last_set_entity == e and last_set_component == nil)
|
||||
assert(last_insert_entity == e and last_insert_component == nil)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
|
||||
evo.set(f3, evo.DEFAULT, 33)
|
||||
evo.set(f4, evo.TAG)
|
||||
|
||||
do
|
||||
local e = evo.spawn_at()
|
||||
assert(evo.is_alive(e) and evo.is_empty(e))
|
||||
end
|
||||
|
||||
do
|
||||
local c = evo.chunk(f1)
|
||||
|
||||
local e1 = evo.spawn_at(c)
|
||||
assert(evo.has(e1, f1) and evo.get(e1, f1) == true)
|
||||
|
||||
local e2 = evo.spawn_at(c, { f1 })
|
||||
assert(evo.has(e2, f1) and evo.get(e2, f1) == true)
|
||||
|
||||
local e3 = evo.spawn_at(c, { f1, f2 })
|
||||
assert(evo.has(e3, f1) and evo.get(e3, f1) == true)
|
||||
assert(not evo.has(e3, f2) and evo.get(e3, f2) == nil)
|
||||
|
||||
local e4 = evo.spawn_at(c, { f1, f2 }, { 41 })
|
||||
assert(evo.has(e4, f1) and evo.get(e4, f1) == 41)
|
||||
assert(not evo.has(e4, f2) and evo.get(e4, f2) == nil)
|
||||
|
||||
local e5 = evo.spawn_at(c, { f1, f2 }, { 41, 42 })
|
||||
assert(evo.has(e5, f1) and evo.get(e5, f1) == 41)
|
||||
assert(not evo.has(e5, f2) and evo.get(e5, f2) == nil)
|
||||
|
||||
local e6 = evo.spawn_at(c, { f2 }, { 42 })
|
||||
assert(evo.has(e6, f1) and evo.get(e6, f1) == true)
|
||||
assert(not evo.has(e6, f2) and evo.get(e6, f2) == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local c = evo.chunk(f1, f2)
|
||||
|
||||
local e1 = evo.spawn_at(c)
|
||||
assert(evo.has(e1, f1) and evo.get(e1, f1) == true)
|
||||
assert(evo.has(e1, f2) and evo.get(e1, f2) == true)
|
||||
|
||||
local e2 = evo.spawn_at(c, { f1 })
|
||||
assert(evo.has(e2, f1) and evo.get(e2, f1) == true)
|
||||
assert(evo.has(e2, f2) and evo.get(e2, f2) == true)
|
||||
|
||||
local e3 = evo.spawn_at(c, { f1, f2 })
|
||||
assert(evo.has(e3, f1) and evo.get(e3, f1) == true)
|
||||
assert(evo.has(e3, f2) and evo.get(e3, f2) == true)
|
||||
|
||||
local e4 = evo.spawn_at(c, { f1, f2, f3 })
|
||||
assert(evo.has(e4, f1) and evo.get(e4, f1) == true)
|
||||
assert(evo.has(e4, f2) and evo.get(e4, f2) == true)
|
||||
assert(not evo.has(e4, f3) and evo.get(e4, f3) == nil)
|
||||
|
||||
local e5 = evo.spawn_at(c, { f1, f2 }, { 41 })
|
||||
assert(evo.has(e5, f1) and evo.get(e5, f1) == 41)
|
||||
assert(evo.has(e5, f2) and evo.get(e5, f2) == true)
|
||||
|
||||
local e6 = evo.spawn_at(c, { f1, f2 }, { 41, 42 })
|
||||
assert(evo.has(e6, f1) and evo.get(e6, f1) == 41)
|
||||
assert(evo.has(e6, f2) and evo.get(e6, f2) == 42)
|
||||
|
||||
local e7 = evo.spawn_at(c, { f1, f2, f3 }, { 41, 42, 43 })
|
||||
assert(evo.has(e7, f1) and evo.get(e7, f1) == 41)
|
||||
assert(evo.has(e7, f2) and evo.get(e7, f2) == 42)
|
||||
assert(not evo.has(e7, f3) and evo.get(e7, f3) == nil)
|
||||
|
||||
local e8 = evo.spawn_at(c, { f3 }, { 43 })
|
||||
assert(evo.has(e8, f1) and evo.get(e8, f1) == true)
|
||||
assert(evo.has(e8, f2) and evo.get(e8, f2) == true)
|
||||
assert(not evo.has(e8, f3) and evo.get(e8, f3) == nil)
|
||||
|
||||
local e9 = evo.spawn_at(c, { f2 }, { 42 })
|
||||
assert(evo.has(e9, f1) and evo.get(e9, f1) == true)
|
||||
assert(evo.has(e9, f2) and evo.get(e9, f2) == 42)
|
||||
assert(not evo.has(e9, f3) and evo.get(e9, f3) == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local c = evo.chunk(f2, f3, f4)
|
||||
|
||||
local e1 = evo.spawn_at(c)
|
||||
assert(evo.has(e1, f2) and evo.get(e1, f2) == true)
|
||||
assert(evo.has(e1, f3) and evo.get(e1, f3) == 33)
|
||||
assert(evo.has(e1, f4) and evo.get(e1, f4) == nil)
|
||||
|
||||
local e2 = evo.spawn_at(c, { f1 })
|
||||
assert(not evo.has(e2, f1) and evo.get(e2, f1) == nil)
|
||||
assert(evo.has(e2, f2) and evo.get(e2, f2) == true)
|
||||
assert(evo.has(e2, f3) and evo.get(e2, f3) == 33)
|
||||
assert(evo.has(e2, f4) and evo.get(e2, f4) == nil)
|
||||
|
||||
local e3 = evo.spawn_at(c, { f1 }, { 41 })
|
||||
assert(not evo.has(e3, f1) and evo.get(e3, f1) == nil)
|
||||
assert(evo.has(e3, f2) and evo.get(e3, f2) == true)
|
||||
assert(evo.has(e3, f3) and evo.get(e3, f3) == 33)
|
||||
assert(evo.has(e3, f4) and evo.get(e3, f4) == nil)
|
||||
|
||||
local e4 = evo.spawn_at(c, { f1, f3, f4 }, { 41, 43, 44 })
|
||||
assert(not evo.has(e4, f1) and evo.get(e4, f1) == nil)
|
||||
assert(evo.has(e4, f2) and evo.get(e4, f2) == true)
|
||||
assert(evo.has(e4, f3) and evo.get(e4, f3) == 43)
|
||||
assert(evo.has(e4, f4) and evo.get(e4, f4) == nil)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local cf = evo.id()
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
|
||||
evo.set(f1, cf)
|
||||
evo.set(f2, cf)
|
||||
evo.set(f3, cf)
|
||||
|
||||
evo.set(f2, evo.DEFAULT, 22)
|
||||
evo.set(f3, evo.TAG)
|
||||
|
||||
local set_count = 0
|
||||
local insert_count = 0
|
||||
|
||||
local last_set_entity = 0
|
||||
local last_set_component = 0
|
||||
local last_insert_entity = 0
|
||||
local last_insert_component = 0
|
||||
|
||||
local q = evo.query():include(cf):build()
|
||||
|
||||
evo.batch_set(q, evo.ON_SET, function(e, f, c)
|
||||
last_set_entity = e
|
||||
assert(f == f1 or f == f2 or f == f3)
|
||||
last_set_component = c
|
||||
set_count = set_count + 1
|
||||
end)
|
||||
|
||||
evo.batch_set(q, evo.ON_INSERT, function(e, f, c)
|
||||
last_insert_entity = e
|
||||
assert(f == f1 or f == f2 or f == f3)
|
||||
last_insert_component = c
|
||||
insert_count = insert_count + 1
|
||||
end)
|
||||
|
||||
assert(set_count == 0 and insert_count == 0)
|
||||
assert(last_set_entity == 0 and last_set_component == 0)
|
||||
assert(last_insert_entity == 0 and last_insert_component == 0)
|
||||
|
||||
do
|
||||
set_count, insert_count = 0, 0
|
||||
last_set_entity, last_set_component = 0, 0
|
||||
last_insert_entity, last_insert_component = 0, 0
|
||||
local c = evo.chunk(f1)
|
||||
local e = evo.spawn_at(c)
|
||||
assert(set_count == 1 and insert_count == 1)
|
||||
assert(last_set_entity == e and last_set_component == true)
|
||||
assert(last_insert_entity == e and last_insert_component == true)
|
||||
end
|
||||
|
||||
do
|
||||
set_count, insert_count = 0, 0
|
||||
last_set_entity, last_set_component = 0, 0
|
||||
last_insert_entity, last_insert_component = 0, 0
|
||||
local c = evo.chunk(f2)
|
||||
local e = evo.spawn_at(c)
|
||||
assert(set_count == 1 and insert_count == 1)
|
||||
assert(last_set_entity == e and last_set_component == 22)
|
||||
assert(last_insert_entity == e and last_insert_component == 22)
|
||||
end
|
||||
|
||||
do
|
||||
set_count, insert_count = 0, 0
|
||||
last_set_entity, last_set_component = 0, 0
|
||||
last_insert_entity, last_insert_component = 0, 0
|
||||
local c = evo.chunk(f2, f1)
|
||||
local e = evo.spawn_at(c)
|
||||
assert(set_count == 2 and insert_count == 2)
|
||||
assert(last_set_entity == e and last_set_component == 22)
|
||||
assert(last_insert_entity == e and last_insert_component == 22)
|
||||
end
|
||||
|
||||
do
|
||||
set_count, insert_count = 0, 0
|
||||
last_set_entity, last_set_component = 0, 0
|
||||
last_insert_entity, last_insert_component = 0, 0
|
||||
local c = evo.chunk(f3)
|
||||
local e = evo.spawn_at(c)
|
||||
assert(set_count == 1 and insert_count == 1)
|
||||
assert(last_set_entity == e and last_set_component == nil)
|
||||
assert(last_insert_entity == e and last_insert_component == nil)
|
||||
end
|
||||
|
||||
do
|
||||
set_count, insert_count = 0, 0
|
||||
last_set_entity, last_set_component = 0, 0
|
||||
last_insert_entity, last_insert_component = 0, 0
|
||||
local c = evo.chunk(f3, f2)
|
||||
local e = evo.spawn_at(c, { f3, f2 }, { 33, 22 })
|
||||
assert(set_count == 2 and insert_count == 2)
|
||||
assert(last_set_entity == e and last_set_component == nil)
|
||||
assert(last_insert_entity == e and last_insert_component == nil)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
|
||||
evo.set(f3, evo.DEFAULT, 3)
|
||||
evo.set(f4, evo.TAG)
|
||||
|
||||
do
|
||||
assert(evo.defer())
|
||||
local e, d = evo.spawn_with()
|
||||
assert(evo.is_alive(e) and evo.is_empty(e))
|
||||
assert(not d)
|
||||
assert(evo.commit())
|
||||
assert(evo.is_alive(e) and evo.is_empty(e))
|
||||
end
|
||||
|
||||
do
|
||||
assert(evo.defer())
|
||||
local e, d = evo.spawn_with({})
|
||||
assert(evo.is_alive(e) and evo.is_empty(e))
|
||||
assert(not d)
|
||||
assert(evo.commit())
|
||||
assert(evo.is_alive(e) and evo.is_empty(e))
|
||||
end
|
||||
|
||||
do
|
||||
assert(evo.defer())
|
||||
local e1, d1 = evo.spawn_with({ f1 })
|
||||
assert(evo.is_alive(e1) and evo.is_empty(e1))
|
||||
assert(d1)
|
||||
assert(evo.commit())
|
||||
assert(evo.is_alive(e1) and not evo.is_empty(e1))
|
||||
assert(evo.has(e1, f1) and evo.get(e1, f1) == true)
|
||||
|
||||
assert(evo.defer())
|
||||
local e2, d2 = evo.spawn_with({ f1 }, {})
|
||||
assert(evo.is_alive(e2) and evo.is_empty(e2))
|
||||
assert(d2)
|
||||
assert(evo.commit())
|
||||
assert(evo.is_alive(e2) and not evo.is_empty(e2))
|
||||
assert(evo.has(e2, f1) and evo.get(e2, f1) == true)
|
||||
|
||||
assert(evo.defer())
|
||||
local e3, d3 = evo.spawn_with({ f1 }, { 41 })
|
||||
assert(evo.is_alive(e3) and evo.is_empty(e3))
|
||||
assert(d3)
|
||||
assert(evo.commit())
|
||||
assert(evo.is_alive(e3) and not evo.is_empty(e3))
|
||||
assert(evo.has(e3, f1) and evo.get(e3, f1) == 41)
|
||||
end
|
||||
|
||||
do
|
||||
assert(evo.defer())
|
||||
local e1, d1 = evo.spawn_with({ f1, f2 })
|
||||
assert(evo.is_alive(e1) and evo.is_empty(e1))
|
||||
assert(d1)
|
||||
assert(evo.commit())
|
||||
assert(evo.is_alive(e1) and not evo.is_empty(e1))
|
||||
assert(evo.has(e1, f1) and evo.get(e1, f1) == true)
|
||||
assert(evo.has(e1, f2) and evo.get(e1, f2) == true)
|
||||
|
||||
assert(evo.defer())
|
||||
local e2, d2 = evo.spawn_with({ f1, f2 }, {})
|
||||
assert(evo.is_alive(e2) and evo.is_empty(e2))
|
||||
assert(d2)
|
||||
assert(evo.commit())
|
||||
assert(evo.is_alive(e2) and not evo.is_empty(e2))
|
||||
assert(evo.has(e2, f1) and evo.get(e2, f1) == true)
|
||||
assert(evo.has(e2, f2) and evo.get(e2, f2) == true)
|
||||
|
||||
assert(evo.defer())
|
||||
local e3, d3 = evo.spawn_with({ f1, f2 }, { 41 })
|
||||
assert(evo.is_alive(e3) and evo.is_empty(e3))
|
||||
assert(d3)
|
||||
assert(evo.commit())
|
||||
assert(evo.is_alive(e3) and not evo.is_empty(e3))
|
||||
assert(evo.has(e3, f1) and evo.get(e3, f1) == 41)
|
||||
assert(evo.has(e3, f2) and evo.get(e3, f2) == true)
|
||||
|
||||
assert(evo.defer())
|
||||
local e4, d4 = evo.spawn_with({ f1, f2 }, { nil, 42 })
|
||||
assert(evo.is_alive(e4) and evo.is_empty(e4))
|
||||
assert(d4)
|
||||
assert(evo.commit())
|
||||
assert(evo.is_alive(e4) and not evo.is_empty(e4))
|
||||
assert(evo.has(e4, f1) and evo.get(e4, f1) == true)
|
||||
assert(evo.has(e4, f2) and evo.get(e4, f2) == 42)
|
||||
|
||||
assert(evo.defer())
|
||||
local e5, d5 = evo.spawn_with({ f1, f2 }, { 41, 42 })
|
||||
assert(evo.is_alive(e5) and evo.is_empty(e5))
|
||||
assert(d5)
|
||||
assert(evo.commit())
|
||||
assert(evo.is_alive(e5) and not evo.is_empty(e5))
|
||||
assert(evo.has(e5, f1) and evo.get(e5, f1) == 41)
|
||||
assert(evo.has(e5, f2) and evo.get(e5, f2) == 42)
|
||||
|
||||
assert(evo.defer())
|
||||
local e6, d6 = evo.spawn_with({ f1, f2 }, { 41, 42, 43 })
|
||||
assert(evo.is_alive(e6) and evo.is_empty(e6))
|
||||
assert(d6)
|
||||
assert(evo.commit())
|
||||
assert(evo.is_alive(e6) and not evo.is_empty(e6))
|
||||
assert(evo.has(e6, f1) and evo.get(e6, f1) == 41)
|
||||
assert(evo.has(e6, f2) and evo.get(e6, f2) == 42)
|
||||
end
|
||||
|
||||
do
|
||||
assert(evo.defer())
|
||||
local e1, d1 = evo.spawn_with({ f3, f4 })
|
||||
assert(evo.is_alive(e1) and evo.is_empty(e1))
|
||||
assert(d1)
|
||||
assert(evo.commit())
|
||||
assert(evo.is_alive(e1) and not evo.is_empty(e1))
|
||||
assert(evo.has(e1, f3) and evo.get(e1, f3) == 3)
|
||||
assert(evo.has(e1, f4) and evo.get(e1, f4) == nil)
|
||||
|
||||
assert(evo.defer())
|
||||
local e2, d2 = evo.spawn_with({ f3, f4 }, { 33, 44 })
|
||||
assert(evo.is_alive(e2) and evo.is_empty(e2))
|
||||
assert(d2)
|
||||
assert(evo.commit())
|
||||
assert(evo.is_alive(e2) and not evo.is_empty(e2))
|
||||
assert(evo.has(e2, f3) and evo.get(e2, f3) == 33)
|
||||
assert(evo.has(e2, f4) and evo.get(e2, f4) == nil)
|
||||
end
|
||||
end
|
||||
|
||||
449
evolved.lua
449
evolved.lua
@@ -751,6 +751,58 @@ end
|
||||
---
|
||||
---
|
||||
|
||||
---@param ... evolved.fragment fragments
|
||||
---@return evolved.chunk?
|
||||
---@nodiscard
|
||||
local function __chunk_fragments(...)
|
||||
local fragment_count = select('#', ...)
|
||||
|
||||
if fragment_count == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local root_fragment = select(1, ...)
|
||||
local chunk = __root_chunks[root_fragment]
|
||||
or __root_chunk(root_fragment)
|
||||
|
||||
for i = 2, fragment_count do
|
||||
local child_fragment = select(i, ...)
|
||||
chunk = chunk.__with_fragment_edges[child_fragment]
|
||||
or __chunk_with_fragment(chunk, child_fragment)
|
||||
end
|
||||
|
||||
return chunk
|
||||
end
|
||||
|
||||
---@param fragment_list evolved.fragment[]
|
||||
---@return evolved.chunk?
|
||||
---@nodiscard
|
||||
local function __chunk_fragment_list(fragment_list)
|
||||
local fragment_count = #fragment_list
|
||||
|
||||
if fragment_count == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local root_fragment = fragment_list[1]
|
||||
local chunk = __root_chunks[root_fragment]
|
||||
or __root_chunk(root_fragment)
|
||||
|
||||
for i = 2, fragment_count do
|
||||
local child_fragment = fragment_list[i]
|
||||
chunk = chunk.__with_fragment_edges[child_fragment]
|
||||
or __chunk_with_fragment(chunk, child_fragment)
|
||||
end
|
||||
|
||||
return chunk
|
||||
end
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
---@param chunk evolved.chunk
|
||||
---@param fragment evolved.fragment
|
||||
---@return boolean
|
||||
@@ -1335,6 +1387,165 @@ local function __detach_entity(entity)
|
||||
__structural_changes = __structural_changes + 1
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param chunk evolved.chunk
|
||||
---@param fragments evolved.fragment[]
|
||||
---@param components evolved.component[]
|
||||
local function __spawn_entity_at(entity, chunk, fragments, components)
|
||||
local chunk_entities = chunk.__entities
|
||||
local chunk_fragment_list = chunk.__fragment_list
|
||||
local chunk_component_indices = chunk.__component_indices
|
||||
local chunk_component_storages = chunk.__component_storages
|
||||
|
||||
local place = #chunk_entities + 1
|
||||
chunk_entities[place] = entity
|
||||
|
||||
for i = 1, #chunk_fragment_list do
|
||||
local fragment = chunk_fragment_list[i]
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
|
||||
if component_index then
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
|
||||
if chunk.__has_defaults_or_constructs then
|
||||
local new_component = evolved.get(fragment, evolved.DEFAULT)
|
||||
|
||||
if new_component == nil then
|
||||
new_component = true
|
||||
end
|
||||
|
||||
component_storage[place] = new_component
|
||||
else
|
||||
local new_component = true
|
||||
|
||||
component_storage[place] = new_component
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, #fragments do
|
||||
local fragment = fragments[i]
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
|
||||
if component_index then
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
|
||||
if chunk.__has_defaults_or_constructs then
|
||||
local new_component = components[i]
|
||||
|
||||
if new_component == nil then
|
||||
new_component = evolved.get(fragment, evolved.DEFAULT)
|
||||
end
|
||||
|
||||
if new_component == nil then
|
||||
new_component = true
|
||||
end
|
||||
|
||||
component_storage[place] = new_component
|
||||
else
|
||||
local new_component = components[i]
|
||||
|
||||
if new_component == nil then
|
||||
new_component = true
|
||||
end
|
||||
|
||||
component_storage[place] = new_component
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if chunk.__has_set_or_insert_hooks then
|
||||
for i = 1, #chunk_fragment_list do
|
||||
local fragment = chunk_fragment_list[i]
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
|
||||
if component_index then
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
|
||||
local new_component = component_storage[place]
|
||||
|
||||
__fragment_call_set_and_insert_hooks(entity, fragment, new_component)
|
||||
else
|
||||
__fragment_call_set_and_insert_hooks(entity, fragment)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local entity_index = entity % 0x100000
|
||||
__entity_chunks[entity_index] = chunk
|
||||
__entity_places[entity_index] = place
|
||||
|
||||
__structural_changes = __structural_changes + 1
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param chunk evolved.chunk
|
||||
---@param fragments evolved.fragment[]
|
||||
---@param components evolved.component[]
|
||||
local function __spawn_entity_with(entity, chunk, fragments, components)
|
||||
local chunk_entities = chunk.__entities
|
||||
local chunk_fragment_list = chunk.__fragment_list
|
||||
local chunk_component_indices = chunk.__component_indices
|
||||
local chunk_component_storages = chunk.__component_storages
|
||||
|
||||
local place = #chunk_entities + 1
|
||||
chunk_entities[place] = entity
|
||||
|
||||
for i = 1, #fragments do
|
||||
local fragment = fragments[i]
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
|
||||
if component_index then
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
|
||||
if chunk.__has_defaults_or_constructs then
|
||||
local new_component = components[i]
|
||||
|
||||
if new_component == nil then
|
||||
new_component = evolved.get(fragment, evolved.DEFAULT)
|
||||
end
|
||||
|
||||
if new_component == nil then
|
||||
new_component = true
|
||||
end
|
||||
|
||||
component_storage[place] = new_component
|
||||
else
|
||||
local new_component = components[i]
|
||||
|
||||
if new_component == nil then
|
||||
new_component = true
|
||||
end
|
||||
|
||||
component_storage[place] = new_component
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if chunk.__has_set_or_insert_hooks then
|
||||
for i = 1, #chunk_fragment_list do
|
||||
local fragment = chunk_fragment_list[i]
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
|
||||
if component_index then
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
|
||||
local new_component = component_storage[place]
|
||||
|
||||
__fragment_call_set_and_insert_hooks(entity, fragment, new_component)
|
||||
else
|
||||
__fragment_call_set_and_insert_hooks(entity, fragment)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local entity_index = entity % 0x100000
|
||||
__entity_chunks[entity_index] = chunk
|
||||
__entity_places[entity_index] = place
|
||||
|
||||
__structural_changes = __structural_changes + 1
|
||||
end
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
@@ -1361,6 +1572,9 @@ local __defer_op = {
|
||||
batch_remove = 14,
|
||||
batch_clear = 15,
|
||||
batch_destroy = 16,
|
||||
|
||||
spawn_entity_at = 17,
|
||||
spawn_entity_with = 18,
|
||||
}
|
||||
|
||||
---@type table<evolved.defer_op, fun(bytes: any[], index: integer): integer>
|
||||
@@ -1473,6 +1687,26 @@ local __defer_ops = {
|
||||
evolved.batch_destroy(query)
|
||||
return 1
|
||||
end,
|
||||
[__defer_op.spawn_entity_at] = function(bytes, index)
|
||||
local entity = bytes[index + 0]
|
||||
local chunk = bytes[index + 1]
|
||||
local fragments = bytes[index + 2]
|
||||
local components = bytes[index + 3]
|
||||
__spawn_entity_at(entity, chunk, fragments, components)
|
||||
__release_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragments)
|
||||
__release_table(__TABLE_POOL_TAG__COMPONENT_LIST, components)
|
||||
return 4
|
||||
end,
|
||||
[__defer_op.spawn_entity_with] = function(bytes, index)
|
||||
local entity = bytes[index + 0]
|
||||
local chunk = bytes[index + 1]
|
||||
local fragments = bytes[index + 2]
|
||||
local components = bytes[index + 3]
|
||||
__spawn_entity_with(entity, chunk, fragments, components)
|
||||
__release_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragments)
|
||||
__release_table(__TABLE_POOL_TAG__COMPONENT_LIST, components)
|
||||
return 4
|
||||
end,
|
||||
}
|
||||
|
||||
---@return boolean started
|
||||
@@ -1809,6 +2043,56 @@ local function __defer_batch_destroy(query)
|
||||
__defer_length = length + 2
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param chunk evolved.chunk
|
||||
---@param fragments evolved.fragment[]
|
||||
---@param components evolved.component[]
|
||||
local function __defer_spawn_entity_at(entity, chunk, fragments, components)
|
||||
local fragment_count = #fragments
|
||||
local fragment_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragment_count, 0)
|
||||
__table_move(fragments, 1, fragment_count, 1, fragment_list)
|
||||
|
||||
local component_count = #components
|
||||
local component_list = __acquire_table(__TABLE_POOL_TAG__COMPONENT_LIST, component_count, 0)
|
||||
__table_move(components, 1, component_count, 1, component_list)
|
||||
|
||||
local length = __defer_length
|
||||
local bytecode = __defer_bytecode
|
||||
|
||||
bytecode[length + 1] = __defer_op.spawn_entity_at
|
||||
bytecode[length + 2] = entity
|
||||
bytecode[length + 3] = chunk
|
||||
bytecode[length + 4] = fragment_list
|
||||
bytecode[length + 5] = component_list
|
||||
|
||||
__defer_length = length + 5
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param chunk evolved.chunk
|
||||
---@param fragments evolved.fragment[]
|
||||
---@param components evolved.component[]
|
||||
local function __defer_spawn_entity_with(entity, chunk, fragments, components)
|
||||
local fragment_count = #fragments
|
||||
local fragment_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragment_count, 0)
|
||||
__table_move(fragments, 1, fragment_count, 1, fragment_list)
|
||||
|
||||
local component_count = #components
|
||||
local component_list = __acquire_table(__TABLE_POOL_TAG__COMPONENT_LIST, component_count, 0)
|
||||
__table_move(components, 1, component_count, 1, component_list)
|
||||
|
||||
local length = __defer_length
|
||||
local bytecode = __defer_bytecode
|
||||
|
||||
bytecode[length + 1] = __defer_op.spawn_entity_with
|
||||
bytecode[length + 2] = entity
|
||||
bytecode[length + 3] = chunk
|
||||
bytecode[length + 4] = fragment_list
|
||||
bytecode[length + 5] = component_list
|
||||
|
||||
__defer_length = length + 5
|
||||
end
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
@@ -3310,24 +3594,14 @@ end)
|
||||
|
||||
---@param ... evolved.fragment fragments
|
||||
---@return evolved.chunk? chunk
|
||||
---@return evolved.entity[]? chunk_entities
|
||||
---@return evolved.entity[]? entities
|
||||
function evolved.chunk(...)
|
||||
local fragment_count = select('#', ...)
|
||||
local chunk = __chunk_fragments(...)
|
||||
|
||||
if fragment_count == 0 then
|
||||
if not chunk then
|
||||
return
|
||||
end
|
||||
|
||||
local root_fragment = select(1, ...)
|
||||
local chunk = __root_chunks[root_fragment]
|
||||
or __root_chunk(root_fragment)
|
||||
|
||||
for i = 2, fragment_count do
|
||||
local child_fragment = select(i, ...)
|
||||
chunk = chunk.__with_fragment_edges[child_fragment]
|
||||
or __chunk_with_fragment(chunk, child_fragment)
|
||||
end
|
||||
|
||||
return chunk, chunk.__entities
|
||||
end
|
||||
|
||||
@@ -3468,9 +3742,85 @@ end
|
||||
---
|
||||
---
|
||||
|
||||
---@param chunk? evolved.chunk
|
||||
---@param fragments? evolved.fragment[]
|
||||
---@param components? evolved.component[]
|
||||
---@return evolved.entity entity
|
||||
---@return boolean is_deferred
|
||||
function evolved.spawn_at(chunk, fragments, components)
|
||||
if not fragments then
|
||||
fragments = __EMPTY_FRAGMENT_LIST
|
||||
end
|
||||
|
||||
if not components then
|
||||
components = __EMPTY_COMPONENT_LIST
|
||||
end
|
||||
|
||||
local entity = evolved.id()
|
||||
|
||||
if not chunk then
|
||||
return entity, false
|
||||
end
|
||||
|
||||
if __defer_depth > 0 then
|
||||
__defer_spawn_entity_at(entity, chunk, fragments, components)
|
||||
return entity, true
|
||||
end
|
||||
|
||||
__defer()
|
||||
|
||||
do
|
||||
__spawn_entity_at(entity, chunk, fragments, components)
|
||||
end
|
||||
|
||||
__defer_commit()
|
||||
return entity, false
|
||||
end
|
||||
|
||||
---@param fragments? evolved.fragment[]
|
||||
---@param components? evolved.component[]
|
||||
---@return evolved.entity entity
|
||||
---@return boolean is_deferred
|
||||
function evolved.spawn_with(fragments, components)
|
||||
if not fragments then
|
||||
fragments = __EMPTY_FRAGMENT_LIST
|
||||
end
|
||||
|
||||
if not components then
|
||||
components = __EMPTY_COMPONENT_LIST
|
||||
end
|
||||
|
||||
local entity, chunk = evolved.id(), __chunk_fragment_list(fragments)
|
||||
|
||||
if not chunk then
|
||||
return entity, false
|
||||
end
|
||||
|
||||
if __defer_depth > 0 then
|
||||
__defer_spawn_entity_with(entity, chunk, fragments, components)
|
||||
return entity, true
|
||||
end
|
||||
|
||||
__defer()
|
||||
|
||||
do
|
||||
__spawn_entity_with(entity, chunk, fragments, components)
|
||||
end
|
||||
|
||||
__defer_commit()
|
||||
return entity, false
|
||||
end
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
---@class (exact) evolved.__entity_builder
|
||||
---@field package __fragment_list? evolved.fragment[]
|
||||
---@field package __component_list? evolved.component[]
|
||||
---@field package __component_count integer
|
||||
|
||||
---@class evolved.entity_builder : evolved.__entity_builder
|
||||
local evolved_entity_builder = {}
|
||||
@@ -3483,6 +3833,7 @@ function evolved.entity()
|
||||
local builder = {
|
||||
__fragment_list = nil,
|
||||
__component_list = nil,
|
||||
__component_count = 0,
|
||||
}
|
||||
---@cast builder evolved.entity_builder
|
||||
return setmetatable(builder, evolved_entity_builder)
|
||||
@@ -3496,40 +3847,45 @@ function evolved_entity_builder:set(fragment, ...)
|
||||
|
||||
local fragment_list = self.__fragment_list
|
||||
local component_list = self.__component_list
|
||||
local component_count = self.__component_count
|
||||
|
||||
if not fragment_list then
|
||||
if component_count == 0 then
|
||||
fragment_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, 8, 0)
|
||||
component_list = __acquire_table(__TABLE_POOL_TAG__COMPONENT_LIST, 8, 0)
|
||||
self.__fragment_list = fragment_list
|
||||
self.__component_list = component_list
|
||||
end
|
||||
|
||||
fragment_list[#fragment_list + 1] = fragment
|
||||
component_list[#component_list + 1] = component
|
||||
component_count = component_count + 1
|
||||
self.__component_count = component_count
|
||||
|
||||
fragment_list[component_count] = fragment
|
||||
component_list[component_count] = component
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
---@return evolved.entity entity
|
||||
---@return boolean is_deferred
|
||||
function evolved_entity_builder:build()
|
||||
local fragment_list = self.__fragment_list
|
||||
local component_list = self.__component_list
|
||||
local component_count = self.__component_count
|
||||
|
||||
self.__fragment_list = nil
|
||||
self.__component_list = nil
|
||||
self.__component_count = 0
|
||||
|
||||
local entity = evolved.id()
|
||||
|
||||
if not fragment_list then
|
||||
return entity
|
||||
if component_count == 0 then
|
||||
return evolved.id(), false
|
||||
end
|
||||
|
||||
evolved.multi_set(entity, fragment_list, component_list)
|
||||
local entity, is_deferred = evolved.spawn_with(fragment_list, component_list)
|
||||
|
||||
__release_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragment_list)
|
||||
__release_table(__TABLE_POOL_TAG__COMPONENT_LIST, component_list)
|
||||
|
||||
return entity
|
||||
return entity, is_deferred
|
||||
end
|
||||
|
||||
---
|
||||
@@ -3581,6 +3937,7 @@ function evolved_fragment_builder:construct(construct)
|
||||
end
|
||||
|
||||
---@return evolved.fragment fragment
|
||||
---@return boolean is_deferred
|
||||
function evolved_fragment_builder:build()
|
||||
local tag = self.__tag
|
||||
local default = self.__default
|
||||
@@ -3590,32 +3947,38 @@ function evolved_fragment_builder:build()
|
||||
self.__default = nil
|
||||
self.__construct = nil
|
||||
|
||||
local fragment = evolved.id()
|
||||
|
||||
local fragment_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, 3, 0)
|
||||
local component_list = __acquire_table(__TABLE_POOL_TAG__COMPONENT_LIST, 3, 0)
|
||||
local component_count = 0
|
||||
|
||||
if tag then
|
||||
fragment_list[#fragment_list + 1] = evolved.TAG
|
||||
component_list[#component_list + 1] = true
|
||||
component_count = component_count + 1
|
||||
fragment_list[component_count] = evolved.TAG
|
||||
component_list[component_count] = true
|
||||
end
|
||||
|
||||
if default ~= nil then
|
||||
fragment_list[#fragment_list + 1] = evolved.DEFAULT
|
||||
component_list[#component_list + 1] = default
|
||||
component_count = component_count + 1
|
||||
fragment_list[component_count] = evolved.DEFAULT
|
||||
component_list[component_count] = default
|
||||
end
|
||||
|
||||
if construct ~= nil then
|
||||
fragment_list[#fragment_list + 1] = evolved.CONSTRUCT
|
||||
component_list[#component_list + 1] = construct
|
||||
component_count = component_count + 1
|
||||
fragment_list[component_count] = evolved.CONSTRUCT
|
||||
component_list[component_count] = construct
|
||||
end
|
||||
|
||||
evolved.multi_set(fragment, fragment_list, component_list)
|
||||
if component_count == 0 then
|
||||
return evolved.id(), false
|
||||
end
|
||||
|
||||
local fragment, is_deferred = evolved.spawn_with(fragment_list, component_list)
|
||||
|
||||
__release_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragment_list)
|
||||
__release_table(__TABLE_POOL_TAG__COMPONENT_LIST, component_list)
|
||||
|
||||
return fragment
|
||||
return fragment, is_deferred
|
||||
end
|
||||
|
||||
---
|
||||
@@ -3697,6 +4060,7 @@ function evolved_query_builder:exclude(...)
|
||||
end
|
||||
|
||||
---@return evolved.query query
|
||||
---@return boolean is_deferred
|
||||
function evolved_query_builder:build()
|
||||
local include_list = self.__include_list
|
||||
local exclude_list = self.__exclude_list
|
||||
@@ -3704,27 +4068,32 @@ function evolved_query_builder:build()
|
||||
self.__include_list = nil
|
||||
self.__exclude_list = nil
|
||||
|
||||
local query = evolved.id()
|
||||
|
||||
local fragment_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, 2, 0)
|
||||
local component_list = __acquire_table(__TABLE_POOL_TAG__COMPONENT_LIST, 2, 0)
|
||||
local component_count = 0
|
||||
|
||||
if include_list then
|
||||
fragment_list[#fragment_list + 1] = evolved.INCLUDES
|
||||
component_list[#component_list + 1] = include_list
|
||||
component_count = component_count + 1
|
||||
fragment_list[component_count] = evolved.INCLUDES
|
||||
component_list[component_count] = include_list
|
||||
end
|
||||
|
||||
if exclude_list then
|
||||
fragment_list[#fragment_list + 1] = evolved.EXCLUDES
|
||||
component_list[#component_list + 1] = exclude_list
|
||||
component_count = component_count + 1
|
||||
fragment_list[component_count] = evolved.EXCLUDES
|
||||
component_list[component_count] = exclude_list
|
||||
end
|
||||
|
||||
evolved.multi_set(query, fragment_list, component_list)
|
||||
if component_count == 0 then
|
||||
return evolved.id(), false
|
||||
end
|
||||
|
||||
local query, is_deferred = evolved.spawn_with(fragment_list, component_list)
|
||||
|
||||
__release_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragment_list)
|
||||
__release_table(__TABLE_POOL_TAG__COMPONENT_LIST, component_list)
|
||||
|
||||
return query
|
||||
return query, is_deferred
|
||||
end
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user