mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-13 11:38:15 +07:00
Compare commits
172 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5895c6ee8f | ||
|
|
1c02ba5468 | ||
|
|
760b477564 | ||
|
|
fc910881bd | ||
|
|
71a7c84a67 | ||
|
|
582a09a6db | ||
|
|
de73881f63 | ||
|
|
55e444ca63 | ||
|
|
e499c701ef | ||
|
|
789f167bf4 | ||
|
|
00367ce07e | ||
|
|
07902eb184 | ||
| ecdbfe660f | |||
|
|
cfd68767cf | ||
|
|
f1ba9ab909 | ||
|
|
77ff3e77db | ||
|
|
825eba5328 | ||
|
|
67002503ed | ||
|
|
1bb0089e9f | ||
|
|
dc642f5294 | ||
|
|
a81a8646e9 | ||
|
|
aa6d2c1c48 | ||
|
|
5fe48de890 | ||
| 0d7adcb5fd | |||
|
|
f48f1bb290 | ||
|
|
6f1a85165f | ||
|
|
bd87e593e9 | ||
|
|
0eac310fd5 | ||
|
|
22cedd26bb | ||
|
|
d298be4188 | ||
|
|
24933e6a04 | ||
|
|
6841bb42fe | ||
|
|
dc912eb6da | ||
|
|
8d3c4633fb | ||
|
|
8704fb0c39 | ||
|
|
86c9ef7cf2 | ||
|
|
bd5f9bb61f | ||
|
|
cfa5dc7a9f | ||
|
|
243adc1a93 | ||
|
|
cf19fba9e4 | ||
|
|
784b9c6a15 | ||
| 2903b077fe | |||
|
|
d3b14a6741 | ||
|
|
fdf5a03a02 | ||
|
|
9221da6ea7 | ||
|
|
0aa57f6b5b | ||
|
|
7e38e43d7c | ||
|
|
b1b627b677 | ||
|
|
281866cf6e | ||
|
|
4ad7fec26d | ||
|
|
f15118be05 | ||
|
|
964ea45f48 | ||
|
|
b2c08e1127 | ||
|
|
2250bd64ce | ||
|
|
e564be46fb | ||
|
|
521ad94278 | ||
|
|
7f6909e48c | ||
|
|
ec745f6ad7 | ||
|
|
b3eec59f8b | ||
|
|
1635dd66b1 | ||
|
|
b420085ed5 | ||
|
|
6d5f810d45 | ||
|
|
5447f50090 | ||
|
|
e6d79dc600 | ||
| 7b6ac89c8a | |||
|
|
91b3910eda | ||
|
|
7f5ac62a79 | ||
|
|
327a6bcbce | ||
|
|
5184b39f4e | ||
|
|
de7d1a6674 | ||
|
|
632232b9b1 | ||
|
|
fbc61a8895 | ||
|
|
e3ed2d89a6 | ||
|
|
bb7f469288 | ||
|
|
8417cecbbe | ||
|
|
eb31ed247b | ||
|
|
9400401161 | ||
|
|
59fb4d8ea4 | ||
|
|
001e6f2956 | ||
|
|
fb6d13ca74 | ||
|
|
8f61a14db6 | ||
|
|
0c016f1b67 | ||
|
|
26bf586140 | ||
|
|
46f1516a55 | ||
|
|
4cd8393546 | ||
|
|
22302cee75 | ||
|
|
d4a7c7b77c | ||
|
|
12beee6eec | ||
|
|
71a7d382c1 | ||
|
|
f2a8ee5b83 | ||
|
|
81bf1d91e9 | ||
|
|
6b4c6f2a9a | ||
|
|
7eb4bfd62d | ||
|
|
1b49f4fcd0 | ||
|
|
77bc6c298e | ||
|
|
008df17ee6 | ||
|
|
ba3018213e | ||
|
|
66aec17052 | ||
|
|
91edfa9da9 | ||
|
|
9b796b2a8d | ||
|
|
dcc5190466 | ||
|
|
9e74ddf9c3 | ||
|
|
26de93405e | ||
|
|
be64359177 | ||
|
|
3b411cce25 | ||
|
|
4a2088e833 | ||
|
|
e9084f818b | ||
|
|
0e6f23d30b | ||
|
|
3f7ab3cf4d | ||
|
|
bd337cefe1 | ||
|
|
2ed3be7a4a | ||
|
|
a8fda4a22a | ||
|
|
3e4b0d02c1 | ||
|
|
676aae4402 | ||
|
|
35c6592418 | ||
|
|
dbca453bbb | ||
|
|
025a9d4d8c | ||
|
|
b6e4bfe608 | ||
|
|
90e7bb25ef | ||
|
|
d6b16df401 | ||
|
|
d86c85d522 | ||
|
|
f7e4dfb30c | ||
|
|
f4671e5a64 | ||
|
|
6603399ee6 | ||
|
|
d91b087c76 | ||
|
|
041777eb23 | ||
|
|
b8e0345e02 | ||
|
|
aa3717d290 | ||
|
|
83e09183a2 | ||
|
|
837302c533 | ||
|
|
27b134e6c0 | ||
|
|
1c89e3853c | ||
|
|
5eb8902d5a | ||
|
|
b5d8ced4c8 | ||
|
|
d24ec1ac8e | ||
|
|
8d7435064d | ||
|
|
3291ad7479 | ||
|
|
71cfdff3b7 | ||
|
|
04b36f901b | ||
|
|
063acc778b | ||
|
|
78ad8bd53e | ||
|
|
14055fbadf | ||
|
|
697a041832 | ||
|
|
9a2a62ec89 | ||
|
|
4f33796b97 | ||
|
|
1e9005e468 | ||
|
|
c7402cbb05 | ||
|
|
5375c0bdea | ||
|
|
44d2572530 | ||
|
|
56a5fb8265 | ||
|
|
21aae4ae86 | ||
|
|
be22c2c85b | ||
| 6bf13890ef | |||
|
|
9a5ea20778 | ||
|
|
0112d0747a | ||
|
|
c222a49257 | ||
|
|
fbd9f9f970 | ||
|
|
d8c9481f13 | ||
|
|
47fcc9cc13 | ||
|
|
cb98a4e461 | ||
|
|
a559c73c35 | ||
|
|
ba5ee22f5d | ||
|
|
50afb722d1 | ||
|
|
8eccd461fd | ||
|
|
c323131d1e | ||
|
|
8038031b51 | ||
|
|
1399820d71 | ||
|
|
3a64bac8e2 | ||
|
|
5ae0e77f20 | ||
|
|
e78c4e8d6b | ||
| db191b805f | |||
|
|
9c6e53e610 |
5
.luacov
Normal file
5
.luacov
Normal file
@@ -0,0 +1,5 @@
|
||||
modules = {
|
||||
['evolved'] = 'evolved.lua'
|
||||
}
|
||||
reporter = 'html'
|
||||
reportfile = 'luacov.report.html'
|
||||
@@ -28,6 +28,9 @@
|
||||
"ignoreDir": [
|
||||
".vscode",
|
||||
"develop/3rdparty"
|
||||
],
|
||||
"library": [
|
||||
"${3rd}/love2d/library"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
11
.vscode/launch.json
vendored
11
.vscode/launch.json
vendored
@@ -27,6 +27,17 @@
|
||||
"lua": "luajit",
|
||||
"file": "${workspaceFolder}/develop/all.lua"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Launch Evolved Example (LÖVE)",
|
||||
"type": "lua-local",
|
||||
"request": "launch",
|
||||
"program": {
|
||||
"command": "love"
|
||||
},
|
||||
"args": [
|
||||
"${workspaceFolder}/example"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
@@ -1,8 +1,14 @@
|
||||
{
|
||||
"[json][jsonc][lua][markdown][yaml]": {
|
||||
"[json][jsonc][lua][markdown][teal][yaml]": {
|
||||
"editor.formatOnSave": true,
|
||||
"files.insertFinalNewline": true,
|
||||
"files.trimFinalNewlines": true,
|
||||
"files.trimTrailingWhitespace": true
|
||||
},
|
||||
"markdown.extension.toc.levels": "2..6",
|
||||
"markdown.extension.toc.omittedFromToc": {
|
||||
"README.md": [
|
||||
"# API Reference"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
12
ROADMAP.md
12
ROADMAP.md
@@ -1,12 +0,0 @@
|
||||
# Roadmap
|
||||
|
||||
## Backlog
|
||||
|
||||
## After first release
|
||||
|
||||
- cached queries
|
||||
- observers and events
|
||||
- add INDEX fragment trait
|
||||
- add REQUIRES fragment trait
|
||||
- use compact prefix-tree for chunks
|
||||
- optional ffi component storages
|
||||
22
develop/GUIDES.md
Normal file
22
develop/GUIDES.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Guidelines
|
||||
|
||||
## Checklists
|
||||
|
||||
### New Version Releasing
|
||||
|
||||
1. Ensure all tests pass on CI.
|
||||
2. Update the version number in `evolved.lua`.
|
||||
3. Update the **Changelog** section in `README.md`.
|
||||
4. Create a new rockspec file in `rockspecs`.
|
||||
5. Commit the changes with a message like `vX.Y.Z`.
|
||||
6. Push and merge the changes to the `main` branch.
|
||||
7. Create the release on GitHub.
|
||||
8. Upload the new package to LuaRocks.
|
||||
|
||||
### Adding a New Top-Level Function
|
||||
1. Insert the new function into the `evolved` table in `evolved.lua`.
|
||||
2. Create tests for the function in `develop/testing/function_name_tests.lua`.
|
||||
3. Add the new test to `develop/all.lua`.
|
||||
4. Document the function in the **Cheat Sheet** and **API Reference** sections of `README.md`.
|
||||
5. Provide a description in the **Overview** section of `README.md`.
|
||||
6. Describe the update in the **Changelog** section of `README.md`.
|
||||
18
develop/ROADMAP.md
Normal file
18
develop/ROADMAP.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Roadmap
|
||||
|
||||
## Backlog
|
||||
|
||||
- observers and events
|
||||
- add INDEX fragment trait
|
||||
- use compact prefix-tree for chunks
|
||||
- optional ffi component storages
|
||||
|
||||
## Thoughts
|
||||
|
||||
- We can return deferred status from modifying operations and spawn/clone methods.
|
||||
- We should have a way to not copy components on deferred spawn/clone.
|
||||
|
||||
## Known Issues
|
||||
|
||||
- Required fragments are slower than they should be
|
||||
- Errors in hooks are cannot be handled properly right now
|
||||
@@ -1,15 +1,34 @@
|
||||
require 'develop.example'
|
||||
require 'develop.unbench'
|
||||
require 'develop.untests'
|
||||
require 'develop.usbench'
|
||||
require 'develop.testing.build_tests'
|
||||
require 'develop.testing.cancel_tests'
|
||||
require 'develop.testing.clone_tests'
|
||||
require 'develop.testing.locate_tests'
|
||||
require 'develop.testing.main_tests'
|
||||
require 'develop.testing.multi_spawn_tests'
|
||||
require 'develop.testing.name_tests'
|
||||
require 'develop.testing.requires_fragment_tests'
|
||||
require 'develop.testing.spawn_tests'
|
||||
require 'develop.testing.system_as_query_tests'
|
||||
|
||||
require 'develop.benchmarks.clone_bmarks'
|
||||
require 'develop.benchmarks.common_bmarks'
|
||||
require 'develop.benchmarks.migration_bmarks'
|
||||
require 'develop.benchmarks.process_bmarks'
|
||||
require 'develop.benchmarks.spawn_bmarks'
|
||||
require 'develop.benchmarks.table_bmarks'
|
||||
|
||||
local basics = require 'develop.basics'
|
||||
|
||||
print '----------------------------------------'
|
||||
basics.describe_fuzz 'develop.fuzzing.destroy_fuzz'
|
||||
print '----------------------------------------'
|
||||
basics.describe_fuzz 'develop.fuzzing.execute_fuzz'
|
||||
print '----------------------------------------'
|
||||
basics.describe_fuzz 'develop.fuzzing.batch_destroy_fuzz'
|
||||
print '----------------------------------------'
|
||||
basics.describe_fuzz 'develop.fuzzing.explicit_fuzz'
|
||||
print '----------------------------------------'
|
||||
basics.describe_fuzz 'develop.fuzzing.pack_unpack_fuzz'
|
||||
print '----------------------------------------'
|
||||
basics.describe_fuzz 'develop.fuzzing.requires_fuzz'
|
||||
print '----------------------------------------'
|
||||
basics.describe_fuzz 'develop.fuzzing.unique_fuzz'
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
local basics = {}
|
||||
|
||||
local MIN_FUZZ_SECS = 0.5
|
||||
local MIN_BENCH_SECS = 0.1
|
||||
local MIN_WARMUP_SECS = 0.1
|
||||
|
||||
local MIN_FUZZ_ITERS = 100
|
||||
local MIN_BENCH_ITERS = 100
|
||||
local MIN_WARMUP_ITERS = 100
|
||||
|
||||
local __table_pack = (function()
|
||||
---@diagnostic disable-next-line: deprecated
|
||||
return table.pack or function(...)
|
||||
@@ -23,8 +31,13 @@ end
|
||||
|
||||
---@param modname string
|
||||
function basics.describe_fuzz(modname)
|
||||
basics.unload('evolved')
|
||||
|
||||
print(string.format('| %s ... |', modname))
|
||||
|
||||
collectgarbage('collect')
|
||||
collectgarbage('stop')
|
||||
|
||||
do
|
||||
local iters = 0
|
||||
|
||||
@@ -36,7 +49,7 @@ function basics.describe_fuzz(modname)
|
||||
iters = iters + 1
|
||||
basics.unload(modname)
|
||||
require(modname)
|
||||
until os.clock() - start_s > 0.5
|
||||
until iters >= MIN_FUZZ_ITERS and os.clock() - start_s >= MIN_FUZZ_SECS
|
||||
end)
|
||||
|
||||
local finish_s = os.clock()
|
||||
@@ -52,6 +65,9 @@ function basics.describe_fuzz(modname)
|
||||
print('|-- FUZZ FAIL: ' .. result)
|
||||
end
|
||||
end
|
||||
|
||||
collectgarbage('restart')
|
||||
collectgarbage('collect')
|
||||
end
|
||||
|
||||
---@param name string
|
||||
@@ -59,17 +75,22 @@ end
|
||||
---@param init? fun(): ...
|
||||
---@param fini? fun(...): ...
|
||||
function basics.describe_bench(name, loop, init, fini)
|
||||
basics.unload('evolved')
|
||||
|
||||
print(string.format('| %s ... |', name))
|
||||
|
||||
local state = init and __table_pack(init()) or {}
|
||||
|
||||
do
|
||||
local iters = 0
|
||||
|
||||
local warmup_s = os.clock()
|
||||
|
||||
local success, result = pcall(function()
|
||||
repeat
|
||||
iters = iters + 1
|
||||
loop(__table_unpack(state))
|
||||
until os.clock() - warmup_s > 0.1
|
||||
until iters >= MIN_WARMUP_ITERS and os.clock() - warmup_s > MIN_WARMUP_SECS
|
||||
end)
|
||||
|
||||
if not success then
|
||||
@@ -91,7 +112,7 @@ function basics.describe_bench(name, loop, init, fini)
|
||||
repeat
|
||||
iters = iters + 1
|
||||
loop(__table_unpack(state))
|
||||
until os.clock() - start_s > 0.1
|
||||
until iters >= MIN_BENCH_ITERS and os.clock() - start_s > MIN_BENCH_SECS
|
||||
end)
|
||||
|
||||
local finish_s = os.clock()
|
||||
|
||||
532
develop/benchmarks/clone_bmarks.lua
Normal file
532
develop/benchmarks/clone_bmarks.lua
Normal file
@@ -0,0 +1,532 @@
|
||||
local evo = require 'evolved'
|
||||
local basics = require 'develop.basics'
|
||||
|
||||
evo.debug_mode(false)
|
||||
|
||||
local N = 1000
|
||||
|
||||
local F1, F2, F3, F4, F5 = evo.id(5)
|
||||
local D1, D2, D3, D4, D5 = evo.id(5)
|
||||
|
||||
evo.set(D1, evo.DEFAULT, true)
|
||||
evo.set(D2, evo.DEFAULT, true)
|
||||
evo.set(D3, evo.DEFAULT, true)
|
||||
evo.set(D4, evo.DEFAULT, true)
|
||||
evo.set(D5, evo.DEFAULT, true)
|
||||
|
||||
evo.set(D1, evo.DUPLICATE, function(v) return not v end)
|
||||
evo.set(D2, evo.DUPLICATE, function(v) return not v end)
|
||||
evo.set(D3, evo.DUPLICATE, function(v) return not v end)
|
||||
evo.set(D4, evo.DUPLICATE, function(v) return not v end)
|
||||
evo.set(D5, evo.DUPLICATE, function(v) return not v end)
|
||||
|
||||
local QF1 = evo.builder():include(F1):spawn()
|
||||
local QD1 = evo.builder():include(D1):spawn()
|
||||
|
||||
local RF1 = evo.builder():require(F1):spawn()
|
||||
local RF123 = evo.builder():require(F1, F2, F3):spawn()
|
||||
local RF12345 = evo.builder():require(F1, F2, F3, F4, F5):spawn()
|
||||
|
||||
local RD1 = evo.builder():require(D1):spawn()
|
||||
local RD123 = evo.builder():require(D1, D2, D3):spawn()
|
||||
local RD12345 = evo.builder():require(D1, D2, D3, D4, D5):spawn()
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Simple Clone | %d entities with 1 component', N),
|
||||
function()
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [F1] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 1 component', N),
|
||||
function()
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [F1] = true }
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Simple Clone With Defaults | %d entities with 1 component', N),
|
||||
function()
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [D1] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Simple Clone | %d entities with 3 components', N),
|
||||
function()
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [F1] = true, [F2] = true, [F3] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 3 components', N),
|
||||
function()
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [F1] = true, [F2] = true, [F3] = true }
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Simple Clone With Defaults | %d entities with 3 components', N),
|
||||
function()
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [D1] = true, [D2] = true, [D3] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Simple Clone | %d entities with 5 components', N),
|
||||
function()
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 5 components', N),
|
||||
function()
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true }
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Simple Clone With Defaults | %d entities with 5 components', N),
|
||||
function()
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [D1] = true, [D2] = true, [D3] = true, [D4] = true, [D5] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Simple Clone | %d entities with 1 required component', N),
|
||||
function()
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [RF1] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 1 required component', N),
|
||||
function()
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [RF1] = true }
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Simple Clone With Defaults | %d entities with 1 required component', N),
|
||||
function()
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [RD1] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Simple Clone | %d entities with 3 required components', N),
|
||||
function()
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [RF123] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 3 required components', N),
|
||||
function()
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [RF123] = true }
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Simple Clone With Defaults | %d entities with 3 required components', N),
|
||||
function()
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [RD123] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Simple Clone | %d entities with 5 required components', N),
|
||||
function()
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [RF12345] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 5 required components', N),
|
||||
function()
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [RF12345] = true }
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Simple Clone With Defaults | %d entities with 5 required components', N),
|
||||
function()
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn { [RD12345] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Multi Clone | %d entities with 1 component', N),
|
||||
function()
|
||||
local multi_clone = evo.multi_clone
|
||||
|
||||
local prefab = evo.spawn { [F1] = true }
|
||||
|
||||
multi_clone(N, prefab)
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 1 component', N),
|
||||
function()
|
||||
local multi_clone = evo.multi_clone
|
||||
|
||||
local prefab = evo.spawn { [F1] = true }
|
||||
|
||||
evo.defer()
|
||||
multi_clone(N, prefab)
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Multi Clone With Defaults | %d entities with 1 component', N),
|
||||
function()
|
||||
local multi_clone = evo.multi_clone
|
||||
|
||||
local prefab = evo.spawn { [D1] = true }
|
||||
|
||||
multi_clone(N, prefab)
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Multi Clone | %d entities with 3 components', N),
|
||||
function()
|
||||
local multi_clone = evo.multi_clone
|
||||
|
||||
local prefab = evo.spawn { [F1] = true, [F2] = true, [F3] = true }
|
||||
|
||||
multi_clone(N, prefab)
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 3 components', N),
|
||||
function()
|
||||
local multi_clone = evo.multi_clone
|
||||
|
||||
local prefab = evo.spawn { [F1] = true, [F2] = true, [F3] = true }
|
||||
|
||||
evo.defer()
|
||||
multi_clone(N, prefab)
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Multi Clone With Defaults | %d entities with 3 components', N),
|
||||
function()
|
||||
local multi_clone = evo.multi_clone
|
||||
|
||||
local prefab = evo.spawn { [D1] = true, [D2] = true, [D3] = true }
|
||||
|
||||
multi_clone(N, prefab)
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Multi Clone | %d entities with 5 components', N),
|
||||
function()
|
||||
local multi_clone = evo.multi_clone
|
||||
|
||||
local prefab = evo.spawn { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true }
|
||||
|
||||
multi_clone(N, prefab)
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 5 components', N),
|
||||
function()
|
||||
local multi_clone = evo.multi_clone
|
||||
|
||||
local prefab = evo.spawn { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true }
|
||||
|
||||
evo.defer()
|
||||
multi_clone(N, prefab)
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Multi Clone With Defaults | %d entities with 5 components', N),
|
||||
function()
|
||||
local multi_clone = evo.multi_clone
|
||||
|
||||
local prefab = evo.spawn { [D1] = true, [D2] = true, [D3] = true, [D4] = true, [D5] = true }
|
||||
|
||||
multi_clone(N, prefab)
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Multi Clone | %d entities with 1 required component', N),
|
||||
function()
|
||||
local multi_clone = evo.multi_clone
|
||||
|
||||
local prefab = evo.spawn { [RF1] = true }
|
||||
|
||||
multi_clone(N, prefab)
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 1 required component', N),
|
||||
function()
|
||||
local multi_clone = evo.multi_clone
|
||||
|
||||
local prefab = evo.spawn { [RF1] = true }
|
||||
|
||||
evo.defer()
|
||||
multi_clone(N, prefab)
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Multi Clone With Defaults | %d entities with 1 required component', N),
|
||||
function()
|
||||
local multi_clone = evo.multi_clone
|
||||
|
||||
local prefab = evo.spawn { [RD1] = true }
|
||||
|
||||
multi_clone(N, prefab)
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Multi Clone | %d entities with 3 required components', N),
|
||||
function()
|
||||
local multi_clone = evo.multi_clone
|
||||
|
||||
local prefab = evo.spawn { [RF123] = true }
|
||||
|
||||
multi_clone(N, prefab)
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 3 required components', N),
|
||||
function()
|
||||
local multi_clone = evo.multi_clone
|
||||
|
||||
local prefab = evo.spawn { [RF123] = true }
|
||||
|
||||
evo.defer()
|
||||
multi_clone(N, prefab)
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Multi Clone With Defaults | %d entities with 3 required components', N),
|
||||
function()
|
||||
local multi_clone = evo.multi_clone
|
||||
|
||||
local prefab = evo.spawn { [RD123] = true }
|
||||
|
||||
multi_clone(N, prefab)
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Multi Clone | %d entities with 5 required components', N),
|
||||
function()
|
||||
local multi_clone = evo.multi_clone
|
||||
|
||||
local prefab = evo.spawn { [RF12345] = true }
|
||||
|
||||
multi_clone(N, prefab)
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 5 required components', N),
|
||||
function()
|
||||
local multi_clone = evo.multi_clone
|
||||
|
||||
local prefab = evo.spawn { [RF12345] = true }
|
||||
|
||||
evo.defer()
|
||||
multi_clone(N, prefab)
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Clone Benchmarks: Multi Clone With Defaults | %d entities with 5 required components', N),
|
||||
function()
|
||||
local multi_clone = evo.multi_clone
|
||||
|
||||
local prefab = evo.spawn { [RD12345] = true }
|
||||
|
||||
multi_clone(N, prefab)
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
340
develop/benchmarks/common_bmarks.lua
Normal file
340
develop/benchmarks/common_bmarks.lua
Normal file
@@ -0,0 +1,340 @@
|
||||
local evo = require 'evolved'
|
||||
local basics = require 'develop.basics'
|
||||
|
||||
local tiny = require 'develop.3rdparty.tiny'
|
||||
|
||||
evo.debug_mode(false)
|
||||
|
||||
local N = 1000
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Common Benchmarks: Tiny Entity Cycle | %d entities', N),
|
||||
function(world)
|
||||
world:update()
|
||||
end, function()
|
||||
local world = tiny.world()
|
||||
|
||||
for _ = 1, N do
|
||||
world:addEntity({ a = 0 })
|
||||
end
|
||||
|
||||
local A = tiny.processingSystem()
|
||||
A.filter = tiny.requireAll('a')
|
||||
A.process = function(_, e) world:addEntity({ b = e.a }) end
|
||||
A.postProcess = function(_) world:refresh() end
|
||||
|
||||
local B = tiny.processingSystem()
|
||||
B.filter = tiny.requireAll('b')
|
||||
B.process = function(_, e) world:removeEntity(e) end
|
||||
B.postProcess = function(_) world:refresh() end
|
||||
|
||||
world:addSystem(A)
|
||||
world:addSystem(B)
|
||||
|
||||
world:refresh()
|
||||
|
||||
return world
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Common Benchmarks: Evolved Entity Cycle | %d entities', N),
|
||||
function(world)
|
||||
evo.process(world)
|
||||
end, function()
|
||||
local world = evo.builder()
|
||||
:destruction_policy(evo.DESTRUCTION_POLICY_DESTROY_ENTITY)
|
||||
:spawn()
|
||||
|
||||
local a = evo.builder():set(world):spawn()
|
||||
local b = evo.builder():set(world):spawn()
|
||||
|
||||
local query_a = evo.builder():set(world):include(a):spawn()
|
||||
local query_b = evo.builder():set(world):include(b):spawn()
|
||||
|
||||
local prefab_a = evo.builder():prefab():set(world):set(a, 0):spawn()
|
||||
local prefab_b = evo.builder():prefab():set(world):set(b, 0):spawn()
|
||||
|
||||
evo.multi_clone(N, prefab_a)
|
||||
|
||||
evo.builder()
|
||||
:set(world):group(world):query(query_a)
|
||||
:execute(function(chunk, _, entity_count)
|
||||
local as = chunk:components(a)
|
||||
local entity_bs = evo.multi_clone(entity_count, prefab_b)
|
||||
for i = 1, entity_count do evo.set(entity_bs[i], b, as[i]) end
|
||||
end):spawn()
|
||||
|
||||
evo.builder()
|
||||
:set(world):group(world):query(query_b)
|
||||
:prologue(function()
|
||||
evo.batch_destroy(query_b)
|
||||
end):spawn()
|
||||
|
||||
return world
|
||||
end, function(world)
|
||||
evo.destroy(world)
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Common Benchmarks: Tiny Simple Iteration | %d entities', N),
|
||||
function(world)
|
||||
world:update()
|
||||
end, function()
|
||||
local world = tiny.world()
|
||||
|
||||
for _ = 1, N do
|
||||
world:addEntity({ a = 0, b = 0 })
|
||||
world:addEntity({ a = 0, b = 0, c = 0 })
|
||||
world:addEntity({ a = 0, b = 0, c = 0, d = 0 })
|
||||
world:addEntity({ a = 0, b = 0, c = 0, e = 0 })
|
||||
end
|
||||
|
||||
local AB = tiny.processingSystem()
|
||||
AB.filter = tiny.requireAll('a', 'b')
|
||||
AB.process = function(_, e) e.a, e.b = e.b, e.a end
|
||||
|
||||
local CD = tiny.processingSystem()
|
||||
CD.filter = tiny.requireAll('c', 'd')
|
||||
CD.process = function(_, e) e.c, e.d = e.d, e.c end
|
||||
|
||||
local CE = tiny.processingSystem()
|
||||
CE.filter = tiny.requireAll('c', 'e')
|
||||
CE.process = function(_, e) e.c, e.e = e.e, e.c end
|
||||
|
||||
world:addSystem(AB)
|
||||
world:addSystem(CD)
|
||||
world:addSystem(CE)
|
||||
|
||||
world:refresh()
|
||||
|
||||
return world
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Common Benchmarks: Evolved Simple Iteration | %d entities', N),
|
||||
function(world)
|
||||
evo.process(world)
|
||||
end, function()
|
||||
local world = evo.builder()
|
||||
:destruction_policy(evo.DESTRUCTION_POLICY_DESTROY_ENTITY)
|
||||
:spawn()
|
||||
|
||||
local a = evo.builder():set(world):spawn()
|
||||
local b = evo.builder():set(world):spawn()
|
||||
local c = evo.builder():set(world):spawn()
|
||||
local d = evo.builder():set(world):spawn()
|
||||
local e = evo.builder():set(world):spawn()
|
||||
|
||||
local query_ab = evo.builder():set(world):include(a, b):spawn()
|
||||
local query_cd = evo.builder():set(world):include(c, d):spawn()
|
||||
local query_ce = evo.builder():set(world):include(c, e):spawn()
|
||||
|
||||
evo.multi_spawn(N, { [world] = true, [a] = 0, [b] = 0 })
|
||||
evo.multi_spawn(N, { [world] = true, [a] = 0, [b] = 0, [c] = 0 })
|
||||
evo.multi_spawn(N, { [world] = true, [a] = 0, [b] = 0, [c] = 0, [d] = 0 })
|
||||
evo.multi_spawn(N, { [world] = true, [a] = 0, [b] = 0, [c] = 0, [e] = 0 })
|
||||
|
||||
evo.builder()
|
||||
:set(world):group(world):query(query_ab)
|
||||
:execute(function(chunk, _, entity_count)
|
||||
local as, bs = chunk:components(a, b)
|
||||
for i = 1, entity_count do as[i], bs[i] = bs[i], as[i] end
|
||||
end):spawn()
|
||||
|
||||
evo.builder()
|
||||
:set(world):group(world):query(query_cd)
|
||||
:execute(function(chunk, _, entity_count)
|
||||
local cs, ds = chunk:components(c, d)
|
||||
for i = 1, entity_count do cs[i], ds[i] = ds[i], cs[i] end
|
||||
end):spawn()
|
||||
|
||||
evo.builder()
|
||||
:set(world):group(world):query(query_ce)
|
||||
:execute(function(chunk, _, entity_count)
|
||||
local cs, es = chunk:components(c, e)
|
||||
for i = 1, entity_count do cs[i], es[i] = es[i], cs[i] end
|
||||
end):spawn()
|
||||
|
||||
return world
|
||||
end, function(world)
|
||||
evo.destroy(world)
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Common Benchmarks: Tiny Packed Iteration | %d entities', N),
|
||||
function(world)
|
||||
world:update()
|
||||
end, function()
|
||||
local world = tiny.world()
|
||||
|
||||
for _ = 1, N do
|
||||
world:addEntity({ a = 0, b = 0, c = 0, d = 0, e = 0 })
|
||||
end
|
||||
|
||||
local A = tiny.processingSystem()
|
||||
A.filter = tiny.requireAll('a')
|
||||
A.process = function(_, e) e.a = e.a * 2 end
|
||||
|
||||
local B = tiny.processingSystem()
|
||||
B.filter = tiny.requireAll('b')
|
||||
B.process = function(_, e) e.b = e.b * 2 end
|
||||
|
||||
local C = tiny.processingSystem()
|
||||
C.filter = tiny.requireAll('c')
|
||||
C.process = function(_, e) e.c = e.c * 2 end
|
||||
|
||||
local D = tiny.processingSystem()
|
||||
D.filter = tiny.requireAll('d')
|
||||
D.process = function(_, e) e.d = e.d * 2 end
|
||||
|
||||
local E = tiny.processingSystem()
|
||||
E.filter = tiny.requireAll('e')
|
||||
E.process = function(_, e) e.e = e.e * 2 end
|
||||
|
||||
world:addSystem(A)
|
||||
world:addSystem(B)
|
||||
world:addSystem(C)
|
||||
world:addSystem(D)
|
||||
world:addSystem(E)
|
||||
|
||||
world:refresh()
|
||||
|
||||
return world
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Common Benchmarks: Evolved Packed Iteration | %d entities', N),
|
||||
function(world)
|
||||
evo.process(world)
|
||||
end, function()
|
||||
local world = evo.builder()
|
||||
:destruction_policy(evo.DESTRUCTION_POLICY_DESTROY_ENTITY)
|
||||
:spawn()
|
||||
|
||||
local a = evo.builder():set(world):spawn()
|
||||
local b = evo.builder():set(world):spawn()
|
||||
local c = evo.builder():set(world):spawn()
|
||||
local d = evo.builder():set(world):spawn()
|
||||
local e = evo.builder():set(world):spawn()
|
||||
|
||||
local query_a = evo.builder():set(world):include(a):spawn()
|
||||
local query_b = evo.builder():set(world):include(b):spawn()
|
||||
local query_c = evo.builder():set(world):include(c):spawn()
|
||||
local query_d = evo.builder():set(world):include(d):spawn()
|
||||
local query_e = evo.builder():set(world):include(e):spawn()
|
||||
|
||||
evo.multi_spawn(N, { [world] = true, [a] = 0, [b] = 0, [c] = 0, [d] = 0, [e] = 0 })
|
||||
|
||||
evo.builder()
|
||||
:set(world):group(world):query(query_a)
|
||||
:execute(function(chunk, _, entity_count)
|
||||
local as = chunk:components(a)
|
||||
for i = 1, entity_count do as[i] = as[i] * 2 end
|
||||
end):spawn()
|
||||
|
||||
evo.builder()
|
||||
:set(world):group(world):query(query_b)
|
||||
:execute(function(chunk, _, entity_count)
|
||||
local bs = chunk:components(b)
|
||||
for i = 1, entity_count do bs[i] = bs[i] * 2 end
|
||||
end):spawn()
|
||||
|
||||
evo.builder()
|
||||
:set(world):group(world):query(query_c)
|
||||
:execute(function(chunk, _, entity_count)
|
||||
local cs = chunk:components(c)
|
||||
for i = 1, entity_count do cs[i] = cs[i] * 2 end
|
||||
end):spawn()
|
||||
|
||||
evo.builder()
|
||||
:set(world):group(world):query(query_d)
|
||||
:execute(function(chunk, _, entity_count)
|
||||
local ds = chunk:components(d)
|
||||
for i = 1, entity_count do ds[i] = ds[i] * 2 end
|
||||
end):spawn()
|
||||
|
||||
evo.builder()
|
||||
:set(world):group(world):query(query_e)
|
||||
:execute(function(chunk, _, entity_count)
|
||||
local es = chunk:components(e)
|
||||
for i = 1, entity_count do es[i] = es[i] * 2 end
|
||||
end):spawn()
|
||||
|
||||
return world
|
||||
end, function(world)
|
||||
evo.destroy(world)
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Common Benchmarks: Tiny Fragmented Iteration | %d entities', N),
|
||||
function(world)
|
||||
world:update()
|
||||
end, function()
|
||||
local world = tiny.world()
|
||||
|
||||
---@type string[]
|
||||
local chars = {}
|
||||
|
||||
for i = 1, 26 do
|
||||
chars[i] = string.char(string.byte('a') + i - 1)
|
||||
end
|
||||
|
||||
for i, char in ipairs(chars) do
|
||||
for _ = 1, N do
|
||||
world:addEntity({ [char] = i, data = i })
|
||||
end
|
||||
end
|
||||
|
||||
local Data = tiny.processingSystem()
|
||||
Data.filter = tiny.requireAll('data')
|
||||
Data.process = function(_, e) e.data = e.data * 2 end
|
||||
|
||||
local Last = tiny.processingSystem()
|
||||
Last.filter = tiny.requireAll('z')
|
||||
Last.process = function(_, e) e.z = e.z * 2 end
|
||||
|
||||
world:addSystem(Data)
|
||||
world:addSystem(Last)
|
||||
|
||||
world:refresh()
|
||||
|
||||
return world
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Common Benchmarks: Evolved Fragmented Iteration | %d entities', N),
|
||||
function(world)
|
||||
evo.process(world)
|
||||
end, function()
|
||||
local world = evo.builder()
|
||||
:destruction_policy(evo.DESTRUCTION_POLICY_DESTROY_ENTITY)
|
||||
:spawn()
|
||||
|
||||
local data = evo.spawn { [world] = true }
|
||||
local chars = evo.multi_spawn(26, { [world] = true })
|
||||
|
||||
local query_data = evo.builder():set(world):include(data):spawn()
|
||||
local query_z = evo.builder():set(world):include(chars[#chars]):spawn()
|
||||
|
||||
for i = 1, #chars do
|
||||
evo.multi_spawn(N, { [world] = true, [chars[i]] = i, [data] = i })
|
||||
end
|
||||
|
||||
evo.builder()
|
||||
:set(world):group(world):query(query_data)
|
||||
:execute(function(chunk, _, entity_count)
|
||||
local datas = chunk:components(data)
|
||||
for i = 1, entity_count do datas[i] = datas[i] * 2 end
|
||||
end):spawn()
|
||||
|
||||
evo.builder()
|
||||
:set(world):group(world):query(query_z)
|
||||
:execute(function(chunk, _, entity_count)
|
||||
local zs = chunk:components(chars[#chars])
|
||||
for i = 1, entity_count do zs[i] = zs[i] * 2 end
|
||||
end):spawn()
|
||||
|
||||
return world
|
||||
end, function(world)
|
||||
evo.destroy(world)
|
||||
end)
|
||||
104
develop/benchmarks/migration_bmarks.lua
Normal file
104
develop/benchmarks/migration_bmarks.lua
Normal file
@@ -0,0 +1,104 @@
|
||||
local evo = require 'evolved'
|
||||
local basics = require 'develop.basics'
|
||||
|
||||
evo.debug_mode(false)
|
||||
|
||||
local N = 1000
|
||||
|
||||
local F1, F2, F3, F4, F5 = evo.id(5)
|
||||
|
||||
local Q1 = evo.builder():include(F1):spawn()
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Migration Benchmarks: Defer Set | %d entities with 1 component', N),
|
||||
function()
|
||||
local id, set = evo.id, evo.set
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
local e = id()
|
||||
set(e, F1)
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Migration Benchmarks: Defer Set | %d entities with 3 components', N),
|
||||
function()
|
||||
local id, set = evo.id, evo.set
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
local e = id()
|
||||
set(e, F1)
|
||||
set(e, F2)
|
||||
set(e, F3)
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Migration Benchmarks: Defer Set | %d entities with 5 components', N),
|
||||
function()
|
||||
local id, set = evo.id, evo.set
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
local e = id()
|
||||
set(e, F1)
|
||||
set(e, F2)
|
||||
set(e, F3)
|
||||
set(e, F4)
|
||||
set(e, F5)
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Migration Benchmarks: Simple Set | %d entities with 1 component', N),
|
||||
function()
|
||||
local id, set = evo.id, evo.set
|
||||
|
||||
for _ = 1, N do
|
||||
local e = id()
|
||||
set(e, F1)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Migration Benchmarks: Simple Set | %d entities with 3 components', N),
|
||||
function()
|
||||
local id, set = evo.id, evo.set
|
||||
|
||||
for _ = 1, N do
|
||||
local e = id()
|
||||
set(e, F1)
|
||||
set(e, F2)
|
||||
set(e, F3)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Migration Benchmarks: Simple Set | %d entities with 5 components', N),
|
||||
function()
|
||||
local id, set = evo.id, evo.set
|
||||
|
||||
for _ = 1, N do
|
||||
local e = id()
|
||||
set(e, F1)
|
||||
set(e, F2)
|
||||
set(e, F3)
|
||||
set(e, F4)
|
||||
set(e, F5)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end)
|
||||
102
develop/benchmarks/process_bmarks.lua
Normal file
102
develop/benchmarks/process_bmarks.lua
Normal file
@@ -0,0 +1,102 @@
|
||||
local evo = require 'evolved'
|
||||
local basics = require 'develop.basics'
|
||||
|
||||
evo.debug_mode(false)
|
||||
|
||||
local N = 10000
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Process Benchmarks: Evolved AoS Processing | %d entities', N),
|
||||
function(w)
|
||||
evo.process(w)
|
||||
end,
|
||||
|
||||
function()
|
||||
local wf = evo.builder()
|
||||
:set(evo.DESTRUCTION_POLICY, evo.DESTRUCTION_POLICY_DESTROY_ENTITY)
|
||||
:spawn()
|
||||
|
||||
local pf = evo.builder():set(wf):spawn()
|
||||
local vf = evo.builder():set(wf):spawn()
|
||||
|
||||
evo.multi_spawn(N, {
|
||||
[wf] = true,
|
||||
[pf] = { x = 0, y = 0, z = 0, w = 0 },
|
||||
[vf] = { x = 0, y = 0, z = 0, w = 0 },
|
||||
})
|
||||
|
||||
evo.builder()
|
||||
:set(wf)
|
||||
:set(evo.GROUP, wf)
|
||||
:set(evo.QUERY, evo.builder():set(wf):include(pf, vf):spawn())
|
||||
:set(evo.EXECUTE, function(chunk, _, entity_count)
|
||||
local ps, vs = chunk:components(pf, vf)
|
||||
|
||||
for i = 1, entity_count do
|
||||
local p, s = ps[i], vs[i]
|
||||
p.x = p.x + s.x
|
||||
p.y = p.y + s.y
|
||||
end
|
||||
end)
|
||||
:spawn()
|
||||
|
||||
return wf
|
||||
end,
|
||||
|
||||
function(w)
|
||||
evo.destroy(w)
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Process Benchmarks: Evolved SoA Processing | %d entities', N),
|
||||
function(w)
|
||||
evo.process(w)
|
||||
end,
|
||||
|
||||
function()
|
||||
local wf = evo.builder()
|
||||
:set(evo.DESTRUCTION_POLICY, evo.DESTRUCTION_POLICY_DESTROY_ENTITY)
|
||||
:spawn()
|
||||
|
||||
local pxf = evo.builder():set(wf):spawn()
|
||||
local pyf = evo.builder():set(wf):spawn()
|
||||
local pzf = evo.builder():set(wf):spawn()
|
||||
local pwf = evo.builder():set(wf):spawn()
|
||||
local vxf = evo.builder():set(wf):spawn()
|
||||
local vyf = evo.builder():set(wf):spawn()
|
||||
local vzf = evo.builder():set(wf):spawn()
|
||||
local vwf = evo.builder():set(wf):spawn()
|
||||
|
||||
evo.multi_spawn(N, {
|
||||
[wf] = true,
|
||||
[pxf] = 0,
|
||||
[pyf] = 0,
|
||||
[pzf] = 0,
|
||||
[pwf] = 0,
|
||||
[vxf] = 0,
|
||||
[vyf] = 0,
|
||||
[vzf] = 0,
|
||||
[vwf] = 0,
|
||||
})
|
||||
|
||||
evo.builder()
|
||||
:set(wf)
|
||||
:set(evo.GROUP, wf)
|
||||
:set(evo.QUERY, evo.builder():set(wf):include(pxf, pyf, vxf, vyf):spawn())
|
||||
:set(evo.EXECUTE, function(chunk, _, entity_count)
|
||||
local pxs, pys = chunk:components(pxf, pyf)
|
||||
local vxs, vys = chunk:components(vxf, vyf)
|
||||
|
||||
for i = 1, entity_count do
|
||||
pxs[i] = pxs[i] + vxs[i]
|
||||
pys[i] = pys[i] + vys[i]
|
||||
end
|
||||
end)
|
||||
:spawn()
|
||||
|
||||
return wf
|
||||
end,
|
||||
|
||||
function(w)
|
||||
evo.destroy(w)
|
||||
end)
|
||||
764
develop/benchmarks/spawn_bmarks.lua
Normal file
764
develop/benchmarks/spawn_bmarks.lua
Normal file
@@ -0,0 +1,764 @@
|
||||
local evo = require 'evolved'
|
||||
local basics = require 'develop.basics'
|
||||
|
||||
evo.debug_mode(false)
|
||||
|
||||
local N = 1000
|
||||
|
||||
local F1, F2, F3, F4, F5 = evo.id(5)
|
||||
local D1, D2, D3, D4, D5 = evo.id(5)
|
||||
|
||||
evo.set(D1, evo.DEFAULT, true)
|
||||
evo.set(D2, evo.DEFAULT, true)
|
||||
evo.set(D3, evo.DEFAULT, true)
|
||||
evo.set(D4, evo.DEFAULT, true)
|
||||
evo.set(D5, evo.DEFAULT, true)
|
||||
|
||||
evo.set(D1, evo.DUPLICATE, function(v) return not v end)
|
||||
evo.set(D2, evo.DUPLICATE, function(v) return not v end)
|
||||
evo.set(D3, evo.DUPLICATE, function(v) return not v end)
|
||||
evo.set(D4, evo.DUPLICATE, function(v) return not v end)
|
||||
evo.set(D5, evo.DUPLICATE, function(v) return not v end)
|
||||
|
||||
local QF1 = evo.builder():include(F1):spawn()
|
||||
local QD1 = evo.builder():include(D1):spawn()
|
||||
|
||||
local RF1 = evo.builder():require(F1):spawn()
|
||||
local RF123 = evo.builder():require(F1, F2, F3):spawn()
|
||||
local RF12345 = evo.builder():require(F1, F2, F3, F4, F5):spawn()
|
||||
|
||||
local RD1 = evo.builder():require(D1):spawn()
|
||||
local RD123 = evo.builder():require(D1, D2, D3):spawn()
|
||||
local RD12345 = evo.builder():require(D1, D2, D3, D4, D5):spawn()
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Simple Spawn | %d entities with 1 component', N),
|
||||
function()
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [F1] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 1 component', N),
|
||||
function()
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [F1] = true }
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Simple Spawn With Defaults | %d entities with 1 component', N),
|
||||
function()
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [D1] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Simple Spawn | %d entities with 3 components', N),
|
||||
function()
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [F1] = true, [F2] = true, [F3] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 3 components', N),
|
||||
function()
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [F1] = true, [F2] = true, [F3] = true }
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Simple Spawn With Defaults | %d entities with 3 components', N),
|
||||
function()
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [D1] = true, [D2] = true, [D3] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Simple Spawn | %d entities with 5 components', N),
|
||||
function()
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 5 components', N),
|
||||
function()
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true }
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Simple Spawn With Defaults | %d entities with 5 components', N),
|
||||
function()
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [D1] = true, [D2] = true, [D3] = true, [D4] = true, [D5] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Simple Spawn | %d entities with 1 required component', N),
|
||||
function()
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [RF1] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 1 required component', N),
|
||||
function()
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [RF1] = true }
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Simple Spawn With Defaults | %d entities with 1 required component', N),
|
||||
function()
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [RD1] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Simple Spawn | %d entities with 3 required components', N),
|
||||
function()
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [RF123] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 3 required components', N),
|
||||
function()
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [RF123] = true }
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Simple Spawn With Defaults | %d entities with 3 required components', N),
|
||||
function()
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [RD123] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Simple Spawn | %d entities with 5 required components', N),
|
||||
function()
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [RF12345] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 5 required components', N),
|
||||
function()
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [RF12345] = true }
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Simple Spawn With Defaults | %d entities with 5 required components', N),
|
||||
function()
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [RD12345] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Builder Spawn | %d entities with 1 component', N),
|
||||
function()
|
||||
local builder = evo.builder():set(F1)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 1 component', N),
|
||||
function()
|
||||
local builder = evo.builder():set(F1)
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Builder Spawn With Defaults | %d entities with 1 component', N),
|
||||
function()
|
||||
local builder = evo.builder():set(D1)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Builder Spawn | %d entities with 3 components', N),
|
||||
function()
|
||||
local builder = evo.builder():set(F1):set(F2):set(F3)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 3 components', N),
|
||||
function()
|
||||
local builder = evo.builder():set(F1):set(F2):set(F3)
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Builder Spawn With Defaults | %d entities with 3 components', N),
|
||||
function()
|
||||
local builder = evo.builder():set(D1):set(D2):set(D3)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Builder Spawn | %d entities with 5 components', N),
|
||||
function()
|
||||
local builder = evo.builder():set(F1):set(F2):set(F3):set(F4):set(F5)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 5 components', N),
|
||||
function()
|
||||
local builder = evo.builder():set(F1):set(F2):set(F3):set(F4):set(F5)
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Builder Spawn With Defaults | %d entities with 5 components', N),
|
||||
function()
|
||||
local builder = evo.builder():set(D1):set(D2):set(D3):set(D4):set(D5)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Builder Spawn | %d entities with 1 required component', N),
|
||||
function()
|
||||
local builder = evo.builder():set(RF1)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 1 required component', N),
|
||||
function()
|
||||
local builder = evo.builder():set(RF1)
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Builder Spawn With Defaults | %d entities with 1 required component', N),
|
||||
function()
|
||||
local builder = evo.builder():set(RD1)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Builder Spawn | %d entities with 3 required components', N),
|
||||
function()
|
||||
local builder = evo.builder():set(RF123)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 3 required components', N),
|
||||
function()
|
||||
local builder = evo.builder():set(RF123)
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Builder Spawn With Defaults | %d entities with 3 required components', N),
|
||||
function()
|
||||
local builder = evo.builder():set(RD123)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Builder Spawn | %d entities with 5 required components', N),
|
||||
function()
|
||||
local builder = evo.builder():set(RF12345)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 5 required components', N),
|
||||
function()
|
||||
local builder = evo.builder():set(RF12345)
|
||||
|
||||
evo.defer()
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Builder Spawn With Defaults | %d entities with 5 required components', N),
|
||||
function()
|
||||
local builder = evo.builder():set(RD12345)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Multi Spawn | %d entities with 1 component', N),
|
||||
function()
|
||||
local multi_spawn = evo.multi_spawn
|
||||
|
||||
local components = { [F1] = true }
|
||||
|
||||
multi_spawn(N, components)
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 1 component', N),
|
||||
function()
|
||||
local multi_spawn = evo.multi_spawn
|
||||
|
||||
local components = { [F1] = true }
|
||||
|
||||
evo.defer()
|
||||
multi_spawn(N, components)
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Multi Spawn With Defaults | %d entities with 1 component', N),
|
||||
function()
|
||||
local multi_spawn = evo.multi_spawn
|
||||
|
||||
local components = { [D1] = true }
|
||||
|
||||
multi_spawn(N, components)
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Multi Spawn | %d entities with 3 components', N),
|
||||
function()
|
||||
local multi_spawn = evo.multi_spawn
|
||||
|
||||
local components = { [F1] = true, [F2] = true, [F3] = true }
|
||||
|
||||
multi_spawn(N, components)
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 3 components', N),
|
||||
function()
|
||||
local multi_spawn = evo.multi_spawn
|
||||
|
||||
local components = { [F1] = true, [F2] = true, [F3] = true }
|
||||
|
||||
evo.defer()
|
||||
multi_spawn(N, components)
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Multi Spawn With Defaults | %d entities with 3 components', N),
|
||||
function()
|
||||
local multi_spawn = evo.multi_spawn
|
||||
|
||||
local components = { [D1] = true, [D2] = true, [D3] = true }
|
||||
|
||||
multi_spawn(N, components)
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Multi Spawn | %d entities with 5 components', N),
|
||||
function()
|
||||
local multi_spawn = evo.multi_spawn
|
||||
|
||||
local components = { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true }
|
||||
|
||||
multi_spawn(N, components)
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 5 components', N),
|
||||
function()
|
||||
local multi_spawn = evo.multi_spawn
|
||||
|
||||
local components = { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true }
|
||||
|
||||
evo.defer()
|
||||
multi_spawn(N, components)
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Multi Spawn With Defaults | %d entities with 5 components', N),
|
||||
function()
|
||||
local multi_spawn = evo.multi_spawn
|
||||
|
||||
local components = { [D1] = true, [D2] = true, [D3] = true, [D4] = true, [D5] = true }
|
||||
|
||||
multi_spawn(N, components)
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Multi Spawn | %d entities with 1 required component', N),
|
||||
function()
|
||||
local multi_spawn = evo.multi_spawn
|
||||
|
||||
local components = { [F1] = true }
|
||||
|
||||
multi_spawn(N, components)
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 1 required component', N),
|
||||
function()
|
||||
local multi_spawn = evo.multi_spawn
|
||||
|
||||
local components = { [F1] = true }
|
||||
|
||||
evo.defer()
|
||||
multi_spawn(N, components)
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Multi Spawn With Defaults | %d entities with 1 required component', N),
|
||||
function()
|
||||
local multi_spawn = evo.multi_spawn
|
||||
|
||||
local components = { [D1] = true }
|
||||
|
||||
multi_spawn(N, components)
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Multi Spawn | %d entities with 3 required components', N),
|
||||
function()
|
||||
local multi_spawn = evo.multi_spawn
|
||||
|
||||
local components = { [RF123] = true }
|
||||
|
||||
multi_spawn(N, components)
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 3 required components', N),
|
||||
function()
|
||||
local multi_spawn = evo.multi_spawn
|
||||
|
||||
local components = { [RF123] = true }
|
||||
|
||||
evo.defer()
|
||||
multi_spawn(N, components)
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Multi Spawn With Defaults | %d entities with 3 required components', N),
|
||||
function()
|
||||
local multi_spawn = evo.multi_spawn
|
||||
|
||||
local components = { [RD123] = true }
|
||||
|
||||
multi_spawn(N, components)
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Multi Spawn | %d entities with 5 required components', N),
|
||||
function()
|
||||
local multi_spawn = evo.multi_spawn
|
||||
|
||||
local components = { [RF12345] = true }
|
||||
|
||||
multi_spawn(N, components)
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 5 required components', N),
|
||||
function()
|
||||
local multi_spawn = evo.multi_spawn
|
||||
|
||||
local components = { [RF12345] = true }
|
||||
|
||||
evo.defer()
|
||||
multi_spawn(N, components)
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(QF1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(
|
||||
string.format('Spawn Benchmarks: Multi Spawn With Defaults | %d entities with 5 required components', N),
|
||||
function()
|
||||
local multi_spawn = evo.multi_spawn
|
||||
|
||||
local components = { [RD12345] = true }
|
||||
|
||||
multi_spawn(N, components)
|
||||
|
||||
evo.batch_destroy(QD1)
|
||||
end)
|
||||
136
develop/benchmarks/table_bmarks.lua
Normal file
136
develop/benchmarks/table_bmarks.lua
Normal file
@@ -0,0 +1,136 @@
|
||||
local evo = require 'evolved'
|
||||
local basics = require 'develop.basics'
|
||||
|
||||
evo.debug_mode(false)
|
||||
|
||||
local N = 1000
|
||||
|
||||
local F1, F2, F3, F4, F5 = evo.id(5)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Table Benchmarks: Allocate %d tables', N),
|
||||
function(tables)
|
||||
for i = 1, N do
|
||||
local t = {}
|
||||
tables[i] = t
|
||||
end
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Table Benchmarks: Allocate and Collect %d tables', N),
|
||||
function(tables)
|
||||
for i = 1, N do
|
||||
local t = {}
|
||||
tables[i] = t
|
||||
end
|
||||
|
||||
for i = 1, N do
|
||||
tables[i] = nil
|
||||
end
|
||||
|
||||
collectgarbage('collect')
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Table Benchmarks: Allocate %d tables with 1 component / AoS', N),
|
||||
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('Table Benchmarks: Allocate %d tables with 3 components / AoS', N),
|
||||
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('Table Benchmarks: Allocate %d tables with 5 components / AoS', N),
|
||||
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('Table Benchmarks: Allocate %d tables with 1 component / SoA', N),
|
||||
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('Table Benchmarks: Allocate %d tables with 3 components / SoA', N),
|
||||
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('Table Benchmarks: Allocate %d tables with 5 components / SoA', N),
|
||||
function(tables)
|
||||
local fs1 = {}
|
||||
local fs2 = {}
|
||||
local fs3 = {}
|
||||
local fs4 = {}
|
||||
local fs5 = {}
|
||||
for i = 1, N do
|
||||
local e = {}
|
||||
fs1[i] = true
|
||||
fs2[i] = true
|
||||
fs3[i] = true
|
||||
fs4[i] = true
|
||||
fs5[i] = true
|
||||
tables[i] = e
|
||||
end
|
||||
tables[F1] = fs1
|
||||
tables[F2] = fs2
|
||||
tables[F3] = fs3
|
||||
tables[F4] = fs4
|
||||
tables[F5] = fs5
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
@@ -1,129 +0,0 @@
|
||||
---@diagnostic disable: unused-local
|
||||
|
||||
local evo = require 'evolved'
|
||||
|
||||
evo.debug_mode(true)
|
||||
|
||||
---@class evolved.vector2
|
||||
---@field x number
|
||||
---@field y number
|
||||
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@return evolved.vector2
|
||||
---@nodiscard
|
||||
local function vector2(x, y)
|
||||
---@type evolved.vector2
|
||||
return { x = x, y = y }
|
||||
end
|
||||
|
||||
local consts = {
|
||||
delta_time = 0.016,
|
||||
physics_gravity = vector2(0, 9.81),
|
||||
}
|
||||
|
||||
local groups = {
|
||||
awake = evo.spawn(),
|
||||
physics = evo.spawn(),
|
||||
graphics = evo.spawn(),
|
||||
shutdown = evo.spawn(),
|
||||
}
|
||||
|
||||
local fragments = {
|
||||
force = evo.spawn(),
|
||||
position = evo.spawn(),
|
||||
velocity = evo.spawn(),
|
||||
}
|
||||
|
||||
local queries = {
|
||||
physics_bodies = evo.builder()
|
||||
:include(fragments.force, fragments.position, fragments.velocity)
|
||||
:spawn(),
|
||||
}
|
||||
|
||||
local awake_system = evo.builder()
|
||||
:group(groups.awake)
|
||||
:prologue(function()
|
||||
print '-= | Awake | =-'
|
||||
evo.builder()
|
||||
:set(fragments.force, vector2(0, 0))
|
||||
:set(fragments.position, vector2(0, 0))
|
||||
:set(fragments.velocity, vector2(0, 0))
|
||||
:spawn()
|
||||
end):spawn()
|
||||
|
||||
local integrate_forces_system = evo.builder()
|
||||
:group(groups.physics)
|
||||
:query(queries.physics_bodies)
|
||||
:execute(function(chunk, entities, entity_count)
|
||||
local delta_time, physics_gravity =
|
||||
consts.delta_time, consts.physics_gravity
|
||||
|
||||
---@type evolved.vector2[], evolved.vector2[]
|
||||
local forces, velocities = chunk:components(
|
||||
fragments.force, fragments.velocity)
|
||||
|
||||
for i = 1, entity_count do
|
||||
local force, velocity = forces[i], velocities[i]
|
||||
|
||||
velocity.x = velocity.x + (physics_gravity.x + force.x) * delta_time
|
||||
velocity.y = velocity.y + (physics_gravity.y + force.y) * delta_time
|
||||
end
|
||||
end):spawn()
|
||||
|
||||
local integrate_velocities_system = evo.builder()
|
||||
:group(groups.physics)
|
||||
:query(queries.physics_bodies)
|
||||
:execute(function(chunk, entities, entity_count)
|
||||
local delta_time =
|
||||
consts.delta_time
|
||||
|
||||
---@type evolved.vector2[], evolved.vector2[], evolved.vector2[]
|
||||
local forces, positions, velocities = chunk:components(
|
||||
fragments.force, fragments.position, fragments.velocity)
|
||||
|
||||
for i = 1, entity_count do
|
||||
local force, position, velocity = forces[i], positions[i], velocities[i]
|
||||
|
||||
position.x = position.x + velocity.x * delta_time
|
||||
position.y = position.y + velocity.y * delta_time
|
||||
|
||||
force.x = 0
|
||||
force.y = 0
|
||||
end
|
||||
end):spawn()
|
||||
|
||||
local graphics_system = evo.builder()
|
||||
:group(groups.graphics)
|
||||
:query(queries.physics_bodies)
|
||||
:execute(function(chunk, entities, entity_count)
|
||||
---@type evolved.vector2[]
|
||||
local positions = chunk:components(
|
||||
fragments.position)
|
||||
|
||||
for i = 1, entity_count do
|
||||
local entity, position = entities[i], positions[i]
|
||||
|
||||
print(string.format(
|
||||
'|-> {entity %d} at {%.4f, %.4f}',
|
||||
entity, position.x, position.y))
|
||||
end
|
||||
end):spawn()
|
||||
|
||||
local shutdown_system = evo.builder()
|
||||
:group(groups.shutdown)
|
||||
:epilogue(function()
|
||||
print '-= | Shutdown | =-'
|
||||
evo.batch_destroy(queries.physics_bodies)
|
||||
end):spawn()
|
||||
|
||||
do
|
||||
evo.process(groups.awake)
|
||||
|
||||
for _ = 1, 10 do
|
||||
evo.process(groups.physics)
|
||||
evo.process(groups.graphics)
|
||||
end
|
||||
|
||||
evo.process(groups.shutdown)
|
||||
end
|
||||
@@ -117,5 +117,12 @@ end
|
||||
---
|
||||
---
|
||||
|
||||
if math.random(1, 2) == 1 then
|
||||
evo.collect_garbage()
|
||||
end
|
||||
|
||||
evo.destroy(__table_unpack(all_entity_list))
|
||||
evo.collect_garbage()
|
||||
|
||||
if math.random(1, 2) == 1 then
|
||||
evo.collect_garbage()
|
||||
end
|
||||
|
||||
@@ -123,5 +123,12 @@ end
|
||||
---
|
||||
---
|
||||
|
||||
if math.random(1, 2) == 1 then
|
||||
evo.collect_garbage()
|
||||
end
|
||||
|
||||
evo.destroy(__table_unpack(all_entity_list))
|
||||
evo.collect_garbage()
|
||||
|
||||
if math.random(1, 2) == 1 then
|
||||
evo.collect_garbage()
|
||||
end
|
||||
|
||||
267
develop/fuzzing/execute_fuzz.lua
Normal file
267
develop/fuzzing/execute_fuzz.lua
Normal file
@@ -0,0 +1,267 @@
|
||||
local evo = require 'evolved'
|
||||
|
||||
evo.debug_mode(true)
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
local __table_unpack = (function()
|
||||
---@diagnostic disable-next-line: deprecated
|
||||
return table.unpack or unpack
|
||||
end)()
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
local all_fragment_list = {} ---@type evolved.fragment[]
|
||||
|
||||
for i = 1, math.random(1, 10) do
|
||||
local fragment = evo.id()
|
||||
all_fragment_list[i] = fragment
|
||||
end
|
||||
|
||||
---@param query evolved.query
|
||||
local function generate_query(query)
|
||||
local include_set = {}
|
||||
local include_list = {}
|
||||
local include_count = 0
|
||||
|
||||
for _ = 1, math.random(0, #all_fragment_list) do
|
||||
local include = all_fragment_list[math.random(1, #all_fragment_list)]
|
||||
|
||||
if not include_set[include] then
|
||||
include_count = include_count + 1
|
||||
include_set[include] = include_count
|
||||
include_list[include_count] = include
|
||||
end
|
||||
end
|
||||
|
||||
local exclude_set = {}
|
||||
local exclude_list = {}
|
||||
local exclude_count = 0
|
||||
|
||||
for _ = 1, math.random(0, #all_fragment_list) do
|
||||
local exclude = all_fragment_list[math.random(1, #all_fragment_list)]
|
||||
|
||||
if not exclude_set[exclude] then
|
||||
exclude_count = exclude_count + 1
|
||||
exclude_set[exclude] = exclude_count
|
||||
exclude_list[exclude_count] = exclude
|
||||
end
|
||||
end
|
||||
|
||||
if include_count > 0 then
|
||||
evo.set(query, evo.INCLUDES, include_list)
|
||||
end
|
||||
|
||||
if exclude_count > 0 then
|
||||
evo.set(query, evo.EXCLUDES, exclude_list)
|
||||
end
|
||||
end
|
||||
|
||||
---@param query_count integer
|
||||
---@return evolved.query[] query_list
|
||||
---@return integer query_count
|
||||
---@nodiscard
|
||||
local function generate_queries(query_count)
|
||||
local query_list = {} ---@type evolved.query[]
|
||||
|
||||
for i = 1, query_count do
|
||||
local query = evo.id()
|
||||
query_list[i] = query
|
||||
generate_query(query)
|
||||
end
|
||||
|
||||
return query_list, query_count
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
local function generate_entity(entity)
|
||||
for _ = 0, math.random(0, #all_fragment_list) do
|
||||
local fragment = all_fragment_list[math.random(1, #all_fragment_list)]
|
||||
evo.set(entity, fragment)
|
||||
end
|
||||
end
|
||||
|
||||
---@param entity_count integer
|
||||
---@return evolved.entity[] entity_list
|
||||
---@return integer entity_count
|
||||
local function generate_entities(entity_count)
|
||||
local entity_list = {} ---@type evolved.entity[]
|
||||
|
||||
for i = 1, entity_count do
|
||||
local entity = evo.id()
|
||||
entity_list[i] = entity
|
||||
generate_entity(entity)
|
||||
end
|
||||
|
||||
return entity_list, entity_count
|
||||
end
|
||||
|
||||
local pre_query_list, pre_query_count = generate_queries(math.random(1, 10))
|
||||
local pre_entity_list, pre_entity_count = generate_entities(math.random(1, 10))
|
||||
|
||||
for _ = 1, math.random(1, 5) do
|
||||
local fragment = all_fragment_list[math.random(1, #all_fragment_list)]
|
||||
|
||||
evo.set(fragment, evo.EXPLICIT)
|
||||
end
|
||||
|
||||
for _ = 1, math.random(1, 5) do
|
||||
local query = pre_query_list[math.random(1, pre_query_count)]
|
||||
|
||||
if math.random(1, 2) == 1 then
|
||||
generate_query(query)
|
||||
else
|
||||
if math.random(1, 2) == 1 then
|
||||
evo.remove(query, evo.INCLUDES)
|
||||
else
|
||||
evo.remove(query, evo.EXCLUDES)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local post_query_list, post_query_count = generate_queries(math.random(1, 10))
|
||||
local post_entity_list, post_entity_count = generate_entities(math.random(1, 10))
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
local all_query_list = {}
|
||||
local all_query_count = 0
|
||||
local all_entity_list = {}
|
||||
local all_entity_count = 0
|
||||
|
||||
for i = 1, pre_query_count do
|
||||
all_query_count = all_query_count + 1
|
||||
all_query_list[all_query_count] = pre_query_list[i]
|
||||
end
|
||||
|
||||
for i = 1, post_query_count do
|
||||
all_query_count = all_query_count + 1
|
||||
all_query_list[all_query_count] = post_query_list[i]
|
||||
end
|
||||
|
||||
for i = 1, pre_entity_count do
|
||||
all_entity_count = all_entity_count + 1
|
||||
all_entity_list[all_entity_count] = pre_entity_list[i]
|
||||
end
|
||||
|
||||
for i = 1, post_entity_count do
|
||||
all_entity_count = all_entity_count + 1
|
||||
all_entity_list[all_entity_count] = post_entity_list[i]
|
||||
end
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
local function execute_query(query)
|
||||
local query_chunk_set = {}
|
||||
local query_entity_set = {}
|
||||
|
||||
local query_include_list = evo.get(query, evo.INCLUDES) or {}
|
||||
local query_exclude_list = evo.get(query, evo.EXCLUDES) or {}
|
||||
|
||||
local query_include_set = {}
|
||||
for _, include in ipairs(query_include_list) do
|
||||
query_include_set[include] = true
|
||||
end
|
||||
|
||||
for chunk, entity_list, entity_count in evo.execute(query) do
|
||||
assert(not query_chunk_set[chunk])
|
||||
query_chunk_set[chunk] = true
|
||||
|
||||
for i = 1, entity_count do
|
||||
local entity = entity_list[i]
|
||||
assert(not query_entity_set[entity])
|
||||
query_entity_set[entity] = true
|
||||
end
|
||||
|
||||
assert(chunk:has_all(__table_unpack(query_include_list)))
|
||||
assert(not chunk:has_any(__table_unpack(query_exclude_list)))
|
||||
end
|
||||
|
||||
for i = 1, all_entity_count do
|
||||
local entity = all_entity_list[i]
|
||||
|
||||
local is_entity_matched =
|
||||
evo.has_all(entity, __table_unpack(query_include_list))
|
||||
and not evo.has_any(entity, __table_unpack(query_exclude_list))
|
||||
|
||||
for fragment in evo.each(entity) do
|
||||
if evo.has(fragment, evo.EXPLICIT) and not query_include_set[fragment] then
|
||||
is_entity_matched = false
|
||||
end
|
||||
end
|
||||
|
||||
if is_entity_matched then
|
||||
assert(query_entity_set[entity])
|
||||
else
|
||||
assert(not query_entity_set[entity])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, all_query_count do
|
||||
execute_query(all_query_list[i])
|
||||
end
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
for _ = 1, math.random(1, 5) do
|
||||
local fragment = all_fragment_list[math.random(1, #all_fragment_list)]
|
||||
|
||||
evo.set(fragment, evo.EXPLICIT)
|
||||
end
|
||||
|
||||
for _ = 1, math.random(1, 5) do
|
||||
local query = pre_query_list[math.random(1, pre_query_count)]
|
||||
|
||||
if math.random(1, 2) == 1 then
|
||||
generate_query(query)
|
||||
else
|
||||
if math.random(1, 2) == 1 then
|
||||
evo.remove(query, evo.INCLUDES)
|
||||
else
|
||||
evo.remove(query, evo.EXCLUDES)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, all_query_count do
|
||||
execute_query(all_query_list[i])
|
||||
end
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
if math.random(1, 2) == 1 then
|
||||
evo.collect_garbage()
|
||||
end
|
||||
|
||||
evo.destroy(__table_unpack(all_query_list))
|
||||
evo.destroy(__table_unpack(all_entity_list))
|
||||
evo.destroy(__table_unpack(all_fragment_list))
|
||||
|
||||
if math.random(1, 2) == 1 then
|
||||
evo.collect_garbage()
|
||||
end
|
||||
@@ -77,5 +77,12 @@ end
|
||||
---
|
||||
---
|
||||
|
||||
if math.random(1, 2) == 1 then
|
||||
evo.collect_garbage()
|
||||
end
|
||||
|
||||
evo.destroy(__table_unpack(all_entity_list))
|
||||
evo.collect_garbage()
|
||||
|
||||
if math.random(1, 2) == 1 then
|
||||
evo.collect_garbage()
|
||||
end
|
||||
|
||||
20
develop/fuzzing/pack_unpack_fuzz.lua
Normal file
20
develop/fuzzing/pack_unpack_fuzz.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
local evo = require 'evolved'
|
||||
|
||||
evo.debug_mode(true)
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
for _ = 1, 1000 do
|
||||
local initial_primary = math.random(1, 2 ^ 20 - 1)
|
||||
local initial_secondary = math.random(1, 2 ^ 20 - 1)
|
||||
|
||||
local packed_id = evo.pack(initial_primary, initial_secondary)
|
||||
local unpacked_primary, unpacked_secondary = evo.unpack(packed_id)
|
||||
|
||||
assert(initial_primary == unpacked_primary)
|
||||
assert(initial_secondary == unpacked_secondary)
|
||||
end
|
||||
131
develop/fuzzing/requires_fuzz.lua
Normal file
131
develop/fuzzing/requires_fuzz.lua
Normal file
@@ -0,0 +1,131 @@
|
||||
local evo = require 'evolved'
|
||||
|
||||
evo.debug_mode(true)
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
local __table_unpack = (function()
|
||||
---@diagnostic disable-next-line: deprecated
|
||||
return table.unpack or unpack
|
||||
end)()
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
local all_fragment_list = {} ---@type evolved.fragment[]
|
||||
|
||||
for i = 1, math.random(1, 10) do
|
||||
local fragment = evo.builder()
|
||||
:default(42)
|
||||
:spawn()
|
||||
all_fragment_list[i] = fragment
|
||||
end
|
||||
|
||||
for _, fragment in ipairs(all_fragment_list) do
|
||||
if math.random(1, 2) == 1 then
|
||||
for _ = 0, math.random(0, #all_fragment_list) do
|
||||
local require_list = evo.get(fragment, evo.REQUIRES) or {}
|
||||
require_list[#require_list + 1] = all_fragment_list[math.random(1, #all_fragment_list)]
|
||||
evo.set(fragment, evo.REQUIRES, require_list)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local all_entity_list = {} ---@type evolved.entity[]
|
||||
|
||||
for i = 1, math.random(1, 10) do
|
||||
local entity = evo.id()
|
||||
all_entity_list[i] = entity
|
||||
|
||||
for _ = 0, math.random(0, #all_fragment_list) do
|
||||
local fragment = all_fragment_list[math.random(1, #all_fragment_list)]
|
||||
|
||||
if math.random(1, 2) == 1 then
|
||||
evo.set(entity, fragment, 42)
|
||||
else
|
||||
local query = evo.builder()
|
||||
:include(all_fragment_list[math.random(1, #all_fragment_list)])
|
||||
:spawn()
|
||||
evo.batch_set(query, fragment, 42)
|
||||
evo.destroy(query)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _ = 1, math.random(1, #all_entity_list) do
|
||||
local components = {}
|
||||
for _ = 1, math.random(1, #all_fragment_list) do
|
||||
local fragment = all_fragment_list[math.random(1, #all_fragment_list)]
|
||||
components[fragment] = 42
|
||||
end
|
||||
all_entity_list[#all_entity_list + 1] = evo.spawn(components)
|
||||
end
|
||||
|
||||
for _ = 1, math.random(1, #all_entity_list) do
|
||||
local prefab = all_entity_list[math.random(1, #all_entity_list)]
|
||||
all_entity_list[#all_entity_list + 1] = evo.clone(prefab)
|
||||
end
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
local function collect_required_fragments_for(fragment, req_fragment_set, req_fragment_list)
|
||||
local fragment_requires = evo.get(fragment, evo.REQUIRES) or {}
|
||||
for _, required_fragment in ipairs(fragment_requires) do
|
||||
if not req_fragment_set[required_fragment] then
|
||||
req_fragment_set[required_fragment] = true
|
||||
req_fragment_list[#req_fragment_list + 1] = required_fragment
|
||||
collect_required_fragments_for(required_fragment, req_fragment_set, req_fragment_list)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, entity in ipairs(all_entity_list) do
|
||||
for fragment in evo.each(entity) do
|
||||
local req_fragment_list = {}
|
||||
collect_required_fragments_for(fragment, {}, req_fragment_list)
|
||||
for _, required_fragment in ipairs(req_fragment_list) do
|
||||
assert(evo.has(entity, required_fragment))
|
||||
local required_component = evo.get(entity, required_fragment)
|
||||
assert(required_component == 42)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
if math.random(1, 2) == 1 then
|
||||
evo.collect_garbage()
|
||||
end
|
||||
|
||||
if math.random(1, 2) == 1 then
|
||||
evo.destroy(__table_unpack(all_entity_list))
|
||||
if math.random(1, 2) == 1 then
|
||||
evo.collect_garbage()
|
||||
end
|
||||
evo.destroy(__table_unpack(all_fragment_list))
|
||||
else
|
||||
evo.destroy(__table_unpack(all_fragment_list))
|
||||
if math.random(1, 2) == 1 then
|
||||
evo.collect_garbage()
|
||||
end
|
||||
evo.destroy(__table_unpack(all_entity_list))
|
||||
end
|
||||
|
||||
if math.random(1, 2) == 1 then
|
||||
evo.collect_garbage()
|
||||
end
|
||||
@@ -63,5 +63,12 @@ end
|
||||
---
|
||||
---
|
||||
|
||||
if math.random(1, 2) == 1 then
|
||||
evo.collect_garbage()
|
||||
end
|
||||
|
||||
evo.destroy(__table_unpack(all_entity_list))
|
||||
evo.collect_garbage()
|
||||
|
||||
if math.random(1, 2) == 1 then
|
||||
evo.collect_garbage()
|
||||
end
|
||||
|
||||
41
develop/testing/build_tests.lua
Normal file
41
develop/testing/build_tests.lua
Normal file
@@ -0,0 +1,41 @@
|
||||
local evo = require 'evolved'
|
||||
|
||||
do
|
||||
local f1, f2 = evo.id(2)
|
||||
|
||||
do
|
||||
local e = evo.builder():set(f1, 42):set(f2, 'hello'):build()
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 'hello')
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.builder():set(f1, 42):build()
|
||||
local e = evo.builder():set(f2, 'hello'):build(p)
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 'hello')
|
||||
end
|
||||
|
||||
do
|
||||
local entity_list, entity_count = evo.builder():set(f1, 42):set(f2, 'hello'):multi_build(5)
|
||||
assert(entity_count == 5)
|
||||
|
||||
for i = 1, entity_count do
|
||||
local e = entity_list[i]
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 'hello')
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.builder():set(f1, 42):build()
|
||||
local entity_list, entity_count = evo.builder():set(f2, 'hello'):multi_build(5, p)
|
||||
assert(entity_count == 5)
|
||||
|
||||
for i = 1, entity_count do
|
||||
local e = entity_list[i]
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 'hello')
|
||||
end
|
||||
end
|
||||
end
|
||||
105
develop/testing/cancel_tests.lua
Normal file
105
develop/testing/cancel_tests.lua
Normal file
@@ -0,0 +1,105 @@
|
||||
local evo = require 'evolved'
|
||||
|
||||
do
|
||||
assert(evo.defer())
|
||||
assert(evo.cancel())
|
||||
end
|
||||
|
||||
do
|
||||
assert(evo.defer())
|
||||
assert(not evo.defer())
|
||||
assert(not evo.cancel())
|
||||
assert(evo.commit())
|
||||
end
|
||||
|
||||
do
|
||||
assert(evo.defer())
|
||||
assert(not evo.defer())
|
||||
assert(not evo.cancel())
|
||||
assert(evo.cancel())
|
||||
end
|
||||
|
||||
do
|
||||
assert(evo.defer())
|
||||
assert(not evo.defer())
|
||||
assert(not evo.cancel())
|
||||
assert(not evo.defer())
|
||||
assert(not evo.cancel())
|
||||
assert(evo.commit())
|
||||
end
|
||||
|
||||
do
|
||||
local e, f = evo.id(2)
|
||||
|
||||
assert(evo.defer())
|
||||
do
|
||||
evo.set(e, f)
|
||||
assert(not evo.has(e, f))
|
||||
end
|
||||
assert(evo.cancel())
|
||||
|
||||
assert(not evo.has(e, f))
|
||||
end
|
||||
|
||||
do
|
||||
local e, f1, f2 = evo.id(3)
|
||||
|
||||
assert(evo.defer())
|
||||
do
|
||||
evo.set(e, f1)
|
||||
assert(not evo.has(e, f1))
|
||||
|
||||
assert(not evo.defer())
|
||||
do
|
||||
evo.set(e, f2)
|
||||
assert(not evo.has(e, f2))
|
||||
end
|
||||
assert(not evo.cancel())
|
||||
end
|
||||
assert(evo.commit())
|
||||
|
||||
assert(evo.has(e, f1))
|
||||
assert(not evo.has(e, f2))
|
||||
end
|
||||
|
||||
do
|
||||
local e, f1, f2 = evo.id(3)
|
||||
|
||||
assert(evo.defer())
|
||||
do
|
||||
evo.set(e, f1)
|
||||
assert(not evo.has(e, f1))
|
||||
|
||||
assert(not evo.defer())
|
||||
do
|
||||
evo.set(e, f2)
|
||||
assert(not evo.has(e, f2))
|
||||
end
|
||||
assert(not evo.cancel())
|
||||
end
|
||||
assert(evo.cancel())
|
||||
|
||||
assert(not evo.has(e, f1))
|
||||
assert(not evo.has(e, f2))
|
||||
end
|
||||
|
||||
do
|
||||
local e, f1, f2 = evo.id(3)
|
||||
|
||||
assert(evo.defer())
|
||||
do
|
||||
evo.set(e, f1)
|
||||
assert(not evo.has(e, f1))
|
||||
|
||||
assert(not evo.defer())
|
||||
do
|
||||
evo.set(e, f2)
|
||||
assert(not evo.has(e, f2))
|
||||
end
|
||||
assert(not evo.commit())
|
||||
end
|
||||
assert(evo.cancel())
|
||||
|
||||
assert(not evo.has(e, f1))
|
||||
assert(not evo.has(e, f2))
|
||||
end
|
||||
397
develop/testing/clone_tests.lua
Normal file
397
develop/testing/clone_tests.lua
Normal file
@@ -0,0 +1,397 @@
|
||||
local evo = require 'evolved'
|
||||
|
||||
do
|
||||
do
|
||||
local p = evo.spawn()
|
||||
local e = evo.clone(p)
|
||||
assert(evo.alive(e) and evo.empty(e))
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.spawn()
|
||||
local e = evo.clone(p, {})
|
||||
assert(evo.alive(e) and evo.empty(e))
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2 = evo.id(2)
|
||||
evo.set(f1, evo.REQUIRES, { f2 })
|
||||
evo.set(f2, evo.DEFAULT, 42)
|
||||
|
||||
local p = evo.spawn()
|
||||
local e = evo.clone(p, { [f1] = 'hello' })
|
||||
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 'hello')
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 42)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
evo.set(f1, evo.TAG)
|
||||
evo.set(f1, evo.REQUIRES, { f2, f3 })
|
||||
evo.set(f4, evo.UNIQUE)
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f4] = 'unique' }
|
||||
local e = evo.clone(p)
|
||||
assert(evo.alive(e) and evo.empty(e))
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f4] = 'unique' }
|
||||
local e = evo.clone(p, {})
|
||||
assert(evo.alive(e) and evo.empty(e))
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f4] = 'unique' }
|
||||
local e = evo.clone(p, { [f4] = 'another' })
|
||||
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f4))
|
||||
assert(evo.has(e, f4) and evo.get(e, f4) == 'another')
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||
local e = evo.clone(p, { [f4] = 'another' })
|
||||
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f2, f4))
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 100)
|
||||
assert(evo.has(e, f4) and evo.get(e, f4) == 'another')
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||
local e = evo.clone(p, { [f1] = 'hello', [f3] = 10 })
|
||||
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2, f3))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == nil)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 100)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == 10)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
do
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
evo.set(f4, evo.TAG)
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f2] = 21, [f3] = 'hello', [f4] = true }
|
||||
local e = evo.clone(p, { [f1] = 'world', [f2] = 10 })
|
||||
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2, f3, f4))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 'world')
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 10)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == 'hello')
|
||||
assert(evo.has(e, f4) and evo.get(e, f4) == nil)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
evo.set(f2, evo.DEFAULT, 42)
|
||||
evo.set(f3, evo.DUPLICATE, function() return nil end)
|
||||
evo.set(f4, evo.TAG)
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f2] = 21, [f3] = 'hello', [f4] = true }
|
||||
local e = evo.clone(p, { [f1] = 'world', [f2] = 10 })
|
||||
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2, f3, f4))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 'world')
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 10)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == true)
|
||||
assert(evo.has(e, f4) and evo.get(e, f4) == nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
evo.set(f1, evo.TAG)
|
||||
evo.set(f1, evo.REQUIRES, { f2, f3 })
|
||||
evo.set(f2, evo.DEFAULT, 42)
|
||||
evo.set(f2, evo.DUPLICATE, function(v) return v * 2 end)
|
||||
evo.set(f3, evo.DUPLICATE, function() return nil end)
|
||||
evo.set(f4, evo.UNIQUE)
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f4] = 'unique' }
|
||||
local e = evo.clone(p)
|
||||
assert(evo.alive(e) and evo.empty(e))
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f4] = 'unique' }
|
||||
local e = evo.clone(p, {})
|
||||
assert(evo.alive(e) and evo.empty(e))
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f4] = 'unique' }
|
||||
local e = evo.clone(p, { [f4] = 'another' })
|
||||
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f4))
|
||||
assert(evo.has(e, f4) and evo.get(e, f4) == 'another')
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||
local e = evo.clone(p, { [f4] = 'another' })
|
||||
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f2, f4))
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 200 * 2)
|
||||
assert(evo.has(e, f4) and evo.get(e, f4) == 'another')
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||
local e = evo.clone(p, { [f1] = 'hello', [f2] = 10 })
|
||||
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2, f3))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == nil)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 10 * 2)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == true)
|
||||
end
|
||||
|
||||
local f1_set_count, f1_inserted_count = 0, 0
|
||||
local f2_set_sum, f3_inserted_count = 0, 0
|
||||
|
||||
evo.set(f1, evo.ON_SET, function(e, f, c)
|
||||
assert(evo.get(e, f) == c)
|
||||
f1_set_count = f1_set_count + 1
|
||||
end)
|
||||
|
||||
evo.set(f1, evo.ON_INSERT, function(e, f, c)
|
||||
assert(evo.get(e, f) == c)
|
||||
f1_inserted_count = f1_inserted_count + 1
|
||||
end)
|
||||
|
||||
evo.set(f2, evo.ON_SET, function(e, f, c)
|
||||
assert(evo.get(e, f) == c)
|
||||
f2_set_sum = f2_set_sum + c
|
||||
end)
|
||||
|
||||
evo.set(f3, evo.ON_INSERT, function(e, f, c)
|
||||
assert(evo.get(e, f) == c)
|
||||
f3_inserted_count = f3_inserted_count + 1
|
||||
end)
|
||||
|
||||
do
|
||||
f1_set_count, f1_inserted_count = 0, 0
|
||||
f2_set_sum, f3_inserted_count = 0, 0
|
||||
|
||||
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||
local e = evo.clone(p, { [f1] = 'hello', [f2] = 10 })
|
||||
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2, f3))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == nil)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 10 * 2)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == true)
|
||||
|
||||
assert(f1_set_count == 1)
|
||||
assert(f1_inserted_count == 1)
|
||||
assert(f2_set_sum == 100 * 2 + 10 * 2)
|
||||
assert(f3_inserted_count == 1)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
evo.set(f1, evo.TAG)
|
||||
evo.set(f1, evo.REQUIRES, { f2, f3 })
|
||||
evo.set(f4, evo.UNIQUE)
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f4] = 'unique' }
|
||||
local es, ec = evo.multi_clone(1, p)
|
||||
assert(#es == 1 and ec == 1)
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and evo.empty(es[i]))
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f4] = 'unique' }
|
||||
local es, ec = evo.multi_clone(2, p, {})
|
||||
assert(#es == 2 and ec == 2)
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and evo.empty(es[i]))
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f4] = 'unique' }
|
||||
local es, ec = evo.multi_clone(3, p, { [f4] = 'another' })
|
||||
assert(#es == 3 and ec == 3)
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f4))
|
||||
assert(evo.has(es[i], f4) and evo.get(es[i], f4) == 'another')
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||
local es, ec = evo.multi_clone(4, p, { [f4] = 'another' })
|
||||
assert(#es == 4 and ec == 4)
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f2, f4))
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 100)
|
||||
assert(evo.has(es[i], f4) and evo.get(es[i], f4) == 'another')
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||
local es, ec = evo.multi_clone(5, p, { [f1] = 'hello', [f3] = 10 })
|
||||
assert(#es == 5 and ec == 5)
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2, f3))
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == nil)
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 100)
|
||||
assert(evo.has(es[i], f3) and evo.get(es[i], f3) == 10)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
do
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
evo.set(f4, evo.TAG)
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f2] = 21, [f3] = 'hello', [f4] = true }
|
||||
local es, ec = evo.multi_clone(2, p, { [f1] = 'world', [f2] = 10 })
|
||||
assert(#es == 2 and ec == 2)
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2, f3, f4))
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 'world')
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 10)
|
||||
assert(evo.has(es[i], f3) and evo.get(es[i], f3) == 'hello')
|
||||
assert(evo.has(es[i], f4) and evo.get(es[i], f4) == nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
evo.set(f2, evo.DEFAULT, 42)
|
||||
evo.set(f3, evo.DUPLICATE, function() return nil end)
|
||||
evo.set(f4, evo.TAG)
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f2] = 21, [f3] = 'hello', [f4] = true }
|
||||
local es, ec = evo.multi_clone(2, p, { [f1] = 'world', [f2] = 10 })
|
||||
assert(#es == 2 and ec == 2)
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2, f3, f4))
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 'world')
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 10)
|
||||
assert(evo.has(es[i], f3) and evo.get(es[i], f3) == true)
|
||||
assert(evo.has(es[i], f4) and evo.get(es[i], f4) == nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
evo.set(f1, evo.TAG)
|
||||
evo.set(f1, evo.REQUIRES, { f2, f3 })
|
||||
evo.set(f2, evo.DEFAULT, 42)
|
||||
evo.set(f2, evo.DUPLICATE, function(v) return v * 2 end)
|
||||
evo.set(f3, evo.DUPLICATE, function() return nil end)
|
||||
evo.set(f4, evo.UNIQUE)
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f4] = 'unique' }
|
||||
local es, ec = evo.multi_clone(3, p)
|
||||
assert(#es == 3 and ec == 3)
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and evo.empty(es[i]))
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f4] = 'unique' }
|
||||
local es, ec = evo.multi_clone(3, p, {})
|
||||
assert(#es == 3 and ec == 3)
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and evo.empty(es[i]))
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f4] = 'unique' }
|
||||
local es, ec = evo.multi_clone(2, p, { [f4] = 'another' })
|
||||
assert(#es == 2 and ec == 2)
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f4))
|
||||
assert(evo.has(es[i], f4) and evo.get(es[i], f4) == 'another')
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||
local es, ec = evo.multi_clone(4, p, { [f4] = 'another' })
|
||||
assert(#es == 4 and ec == 4)
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f2, f4))
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 200 * 2)
|
||||
assert(evo.has(es[i], f4) and evo.get(es[i], f4) == 'another')
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||
local es, ec = evo.multi_clone(5, p, { [f1] = 'hello', [f2] = 10 })
|
||||
assert(#es == 5 and ec == 5)
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2, f3))
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == nil)
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 10 * 2)
|
||||
assert(evo.has(es[i], f3) and evo.get(es[i], f3) == true)
|
||||
end
|
||||
end
|
||||
|
||||
local f1_set_count, f1_inserted_count = 0, 0
|
||||
local f2_set_sum, f3_inserted_count = 0, 0
|
||||
|
||||
evo.set(f1, evo.ON_SET, function(e, f, c)
|
||||
assert(evo.get(e, f) == c)
|
||||
f1_set_count = f1_set_count + 1
|
||||
end)
|
||||
|
||||
evo.set(f1, evo.ON_INSERT, function(e, f, c)
|
||||
assert(evo.get(e, f) == c)
|
||||
f1_inserted_count = f1_inserted_count + 1
|
||||
end)
|
||||
|
||||
evo.set(f2, evo.ON_SET, function(e, f, c)
|
||||
assert(evo.get(e, f) == c)
|
||||
f2_set_sum = f2_set_sum + c
|
||||
end)
|
||||
|
||||
evo.set(f3, evo.ON_INSERT, function(e, f, c)
|
||||
assert(evo.get(e, f) == c)
|
||||
f3_inserted_count = f3_inserted_count + 1
|
||||
end)
|
||||
|
||||
do
|
||||
f1_set_count, f1_inserted_count = 0, 0
|
||||
f2_set_sum, f3_inserted_count = 0, 0
|
||||
|
||||
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||
local es, ec = evo.multi_clone(1, p, { [f1] = 'hello', [f2] = 10 })
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2, f3))
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == nil)
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 10 * 2)
|
||||
assert(evo.has(es[i], f3) and evo.get(es[i], f3) == true)
|
||||
|
||||
assert(f1_set_count == 1)
|
||||
assert(f1_inserted_count == 1)
|
||||
assert(f2_set_sum == 100 * 2 + 10 * 2)
|
||||
assert(f3_inserted_count == 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
48
develop/testing/locate_tests.lua
Normal file
48
develop/testing/locate_tests.lua
Normal file
@@ -0,0 +1,48 @@
|
||||
local evo = require 'evolved'
|
||||
|
||||
do
|
||||
local e1, e2, f1, f2 = evo.id(4)
|
||||
|
||||
do
|
||||
local chunk, place = evo.locate(e1)
|
||||
assert(chunk == nil and place == 0)
|
||||
end
|
||||
|
||||
evo.set(e1, f1, 42)
|
||||
|
||||
do
|
||||
local chunk, place = evo.locate(e1)
|
||||
assert(chunk and chunk == evo.chunk(f1) and place == 1)
|
||||
assert(chunk:components(f1)[place] == 42)
|
||||
|
||||
chunk, place = evo.locate(e2)
|
||||
assert(chunk == nil and place == 0)
|
||||
end
|
||||
|
||||
evo.set(e1, f2, 'hello')
|
||||
|
||||
do
|
||||
local chunk, place = evo.locate(e1)
|
||||
assert(chunk and chunk == evo.chunk(f1, f2) and place == 1)
|
||||
assert(chunk:components(f1)[place] == 42)
|
||||
assert(chunk:components(f2)[place] == 'hello')
|
||||
|
||||
chunk, place = evo.locate(e2)
|
||||
assert(chunk == nil and place == 0)
|
||||
end
|
||||
|
||||
evo.set(e2, f1, 84)
|
||||
evo.set(e2, f2, 'world')
|
||||
|
||||
do
|
||||
local chunk, place = evo.locate(e1)
|
||||
assert(chunk and chunk == evo.chunk(f1, f2) and place == 1)
|
||||
assert(chunk:components(f1)[place] == 42)
|
||||
assert(chunk:components(f2)[place] == 'hello')
|
||||
|
||||
chunk, place = evo.locate(e2)
|
||||
assert(chunk and chunk == evo.chunk(f1, f2) and place == 2)
|
||||
assert(chunk:components(f1)[place] == 84)
|
||||
assert(chunk:components(f2)[place] == 'world')
|
||||
end
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
607
develop/testing/multi_spawn_tests.lua
Normal file
607
develop/testing/multi_spawn_tests.lua
Normal file
@@ -0,0 +1,607 @@
|
||||
local evo = require 'evolved'
|
||||
|
||||
do
|
||||
local entity_list
|
||||
|
||||
do
|
||||
entity_list = evo.multi_spawn(0)
|
||||
assert(entity_list and #entity_list == 0)
|
||||
|
||||
entity_list = evo.multi_spawn(0, {})
|
||||
assert(entity_list and #entity_list == 0)
|
||||
end
|
||||
|
||||
do
|
||||
entity_list = evo.multi_spawn(-1)
|
||||
assert(entity_list and #entity_list == 0)
|
||||
|
||||
entity_list = evo.multi_spawn(-1, {})
|
||||
assert(entity_list and #entity_list == 0)
|
||||
end
|
||||
|
||||
do
|
||||
entity_list = evo.builder():multi_spawn(0)
|
||||
assert(entity_list and #entity_list == 0)
|
||||
end
|
||||
|
||||
do
|
||||
entity_list = evo.builder():multi_spawn(-1)
|
||||
assert(entity_list and #entity_list == 0)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local entity_list
|
||||
|
||||
do
|
||||
entity_list = evo.multi_spawn(1)
|
||||
assert(entity_list and #entity_list == 1)
|
||||
assert(entity_list[1] and evo.empty(entity_list[1]))
|
||||
assert(not entity_list[2])
|
||||
|
||||
entity_list = evo.multi_spawn(1, {})
|
||||
assert(entity_list and #entity_list == 1)
|
||||
assert(entity_list[1] and evo.empty(entity_list[1]))
|
||||
assert(not entity_list[2])
|
||||
end
|
||||
|
||||
do
|
||||
entity_list = evo.multi_spawn(2)
|
||||
assert(entity_list and #entity_list == 2)
|
||||
assert(entity_list[1] and evo.empty(entity_list[1]))
|
||||
assert(entity_list[2] and evo.empty(entity_list[2]))
|
||||
assert(not entity_list[3])
|
||||
|
||||
entity_list = evo.multi_spawn(2, {})
|
||||
assert(entity_list and #entity_list == 2)
|
||||
assert(entity_list[1] and evo.empty(entity_list[1]))
|
||||
assert(entity_list[2] and evo.empty(entity_list[2]))
|
||||
assert(not entity_list[3])
|
||||
end
|
||||
|
||||
do
|
||||
entity_list = evo.builder():multi_spawn(1)
|
||||
assert(entity_list and #entity_list == 1)
|
||||
assert(entity_list[1] and evo.empty(entity_list[1]))
|
||||
assert(not entity_list[2])
|
||||
end
|
||||
|
||||
do
|
||||
entity_list = evo.builder():multi_spawn(2)
|
||||
assert(entity_list and #entity_list == 2)
|
||||
assert(entity_list[1] and evo.empty(entity_list[1]))
|
||||
assert(entity_list[2] and evo.empty(entity_list[2]))
|
||||
assert(not entity_list[3])
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local entity_list
|
||||
|
||||
local prefab = evo.id()
|
||||
|
||||
do
|
||||
entity_list = evo.multi_clone(0, prefab)
|
||||
assert(entity_list and #entity_list == 0)
|
||||
|
||||
entity_list = evo.multi_clone(0, prefab, {})
|
||||
assert(entity_list and #entity_list == 0)
|
||||
end
|
||||
|
||||
do
|
||||
entity_list = evo.multi_clone(-1, prefab)
|
||||
assert(entity_list and #entity_list == 0)
|
||||
|
||||
entity_list = evo.multi_clone(-1, prefab, {})
|
||||
assert(entity_list and #entity_list == 0)
|
||||
end
|
||||
|
||||
do
|
||||
entity_list = evo.builder():multi_clone(0, prefab)
|
||||
assert(entity_list and #entity_list == 0)
|
||||
end
|
||||
|
||||
do
|
||||
entity_list = evo.builder():multi_clone(-1, prefab)
|
||||
assert(entity_list and #entity_list == 0)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local entity_list
|
||||
|
||||
local prefab = evo.id()
|
||||
|
||||
do
|
||||
entity_list = evo.multi_clone(1, prefab)
|
||||
assert(entity_list and #entity_list == 1)
|
||||
assert(entity_list[1] and evo.empty(entity_list[1]))
|
||||
assert(not entity_list[2])
|
||||
|
||||
entity_list = evo.multi_clone(1, prefab, {})
|
||||
assert(entity_list and #entity_list == 1)
|
||||
assert(entity_list[1] and evo.empty(entity_list[1]))
|
||||
assert(not entity_list[2])
|
||||
end
|
||||
|
||||
do
|
||||
entity_list = evo.multi_clone(2, prefab)
|
||||
assert(entity_list and #entity_list == 2)
|
||||
assert(entity_list[1] and evo.empty(entity_list[1]))
|
||||
assert(entity_list[2] and evo.empty(entity_list[2]))
|
||||
assert(not entity_list[3])
|
||||
|
||||
entity_list = evo.multi_clone(2, prefab, {})
|
||||
assert(entity_list and #entity_list == 2)
|
||||
assert(entity_list[1] and evo.empty(entity_list[1]))
|
||||
assert(entity_list[2] and evo.empty(entity_list[2]))
|
||||
assert(not entity_list[3])
|
||||
end
|
||||
|
||||
do
|
||||
entity_list = evo.builder():multi_clone(1, prefab)
|
||||
assert(entity_list and #entity_list == 1)
|
||||
assert(entity_list[1] and evo.empty(entity_list[1]))
|
||||
assert(not entity_list[2])
|
||||
end
|
||||
|
||||
do
|
||||
entity_list = evo.builder():multi_clone(2, prefab)
|
||||
assert(entity_list and #entity_list == 2)
|
||||
assert(entity_list[1] and evo.empty(entity_list[1]))
|
||||
assert(entity_list[2] and evo.empty(entity_list[2]))
|
||||
assert(not entity_list[3])
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2 = evo.id(2)
|
||||
|
||||
do
|
||||
local entity_list
|
||||
|
||||
entity_list = evo.multi_spawn(2, { [f1] = true, [f2] = 123 })
|
||||
assert(entity_list and #entity_list == 2)
|
||||
assert(entity_list[1] and evo.get(entity_list[1], f1) == true and evo.get(entity_list[1], f2) == 123)
|
||||
assert(entity_list[2] and evo.get(entity_list[2], f1) == true and evo.get(entity_list[2], f2) == 123)
|
||||
|
||||
entity_list = evo.multi_spawn(2, { [f1] = false, [f2] = 456 })
|
||||
assert(entity_list and #entity_list == 2)
|
||||
assert(entity_list[1] and evo.get(entity_list[1], f1) == false and evo.get(entity_list[1], f2) == 456)
|
||||
assert(entity_list[2] and evo.get(entity_list[2], f1) == false and evo.get(entity_list[2], f2) == 456)
|
||||
end
|
||||
|
||||
do
|
||||
local prefab = evo.builder():set(f1, true):set(f2, 123):spawn()
|
||||
|
||||
local entity_list
|
||||
|
||||
entity_list = evo.multi_clone(2, prefab)
|
||||
assert(entity_list and #entity_list == 2)
|
||||
assert(entity_list[1] and evo.get(entity_list[1], f1) == true and evo.get(entity_list[1], f2) == 123)
|
||||
assert(entity_list[2] and evo.get(entity_list[2], f1) == true and evo.get(entity_list[2], f2) == 123)
|
||||
|
||||
entity_list = evo.multi_clone(2, prefab, {})
|
||||
assert(entity_list and #entity_list == 2)
|
||||
assert(entity_list[1] and evo.get(entity_list[1], f1) == true and evo.get(entity_list[1], f2) == 123)
|
||||
assert(entity_list[2] and evo.get(entity_list[2], f1) == true and evo.get(entity_list[2], f2) == 123)
|
||||
|
||||
entity_list = evo.multi_clone(2, prefab, { [f1] = false, [f2] = 456 })
|
||||
assert(entity_list and #entity_list == 2)
|
||||
assert(entity_list[1] and evo.get(entity_list[1], f1) == false and evo.get(entity_list[1], f2) == 456)
|
||||
assert(entity_list[2] and evo.get(entity_list[2], f1) == false and evo.get(entity_list[2], f2) == 456)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
|
||||
do
|
||||
local entity_list1, entity_list2
|
||||
|
||||
evo.defer()
|
||||
do
|
||||
entity_list1 = evo.multi_spawn(2, { [f1] = 42, [f2] = "hello", [f3] = false })
|
||||
assert(entity_list1 and #entity_list1 == 2)
|
||||
assert(entity_list1[1] and evo.empty(entity_list1[1]))
|
||||
assert(entity_list1[2] and evo.empty(entity_list1[2]))
|
||||
assert(not entity_list1[3])
|
||||
|
||||
entity_list2 = evo.multi_spawn(3, { [f2] = "world", [f3] = true })
|
||||
assert(entity_list2 and #entity_list2 == 3)
|
||||
assert(entity_list2[1] and evo.empty(entity_list2[1]))
|
||||
assert(entity_list2[2] and evo.empty(entity_list2[2]))
|
||||
assert(entity_list2[3] and evo.empty(entity_list2[3]))
|
||||
end
|
||||
evo.commit()
|
||||
do
|
||||
assert(entity_list1 and #entity_list1 == 2)
|
||||
assert(entity_list1[1] and not evo.empty(entity_list1[1]))
|
||||
assert(entity_list1[2] and not evo.empty(entity_list1[2]))
|
||||
assert(not entity_list1[3])
|
||||
assert(
|
||||
evo.get(entity_list1[1], f1) == 42 and
|
||||
evo.get(entity_list1[1], f2) == "hello" and
|
||||
evo.get(entity_list1[1], f3) == false)
|
||||
assert(
|
||||
evo.get(entity_list1[2], f1) == 42 and
|
||||
evo.get(entity_list1[2], f2) == "hello" and
|
||||
evo.get(entity_list1[2], f3) == false)
|
||||
|
||||
assert(entity_list2 and #entity_list2 == 3)
|
||||
assert(entity_list2[1] and not evo.empty(entity_list2[1]))
|
||||
assert(entity_list2[2] and not evo.empty(entity_list2[2]))
|
||||
assert(entity_list2[3] and not evo.empty(entity_list2[3]))
|
||||
assert(not entity_list2[4])
|
||||
assert(
|
||||
evo.get(entity_list2[1], f1) == nil and
|
||||
evo.get(entity_list2[1], f2) == "world" and
|
||||
evo.get(entity_list2[1], f3) == true)
|
||||
assert(
|
||||
evo.get(entity_list2[2], f1) == nil and
|
||||
evo.get(entity_list2[2], f2) == "world" and
|
||||
evo.get(entity_list2[2], f3) == true)
|
||||
assert(
|
||||
evo.get(entity_list2[3], f1) == nil and
|
||||
evo.get(entity_list2[3], f2) == "world" and
|
||||
evo.get(entity_list2[3], f3) == true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
|
||||
do
|
||||
local prefab = evo.builder():set(f1, false):set(f2, 123):spawn()
|
||||
|
||||
local entity_list1, entity_list2
|
||||
|
||||
evo.defer()
|
||||
do
|
||||
entity_list1 = evo.multi_clone(2, prefab)
|
||||
assert(entity_list1 and #entity_list1 == 2)
|
||||
assert(entity_list1[1] and evo.empty(entity_list1[1]))
|
||||
assert(entity_list1[2] and evo.empty(entity_list1[2]))
|
||||
assert(not entity_list1[3])
|
||||
|
||||
entity_list2 = evo.multi_clone(3, prefab, { [f2] = 456, [f3] = "world" })
|
||||
assert(entity_list2 and #entity_list2 == 3)
|
||||
assert(entity_list2[1] and evo.empty(entity_list2[1]))
|
||||
assert(entity_list2[2] and evo.empty(entity_list2[2]))
|
||||
assert(entity_list2[3] and evo.empty(entity_list2[3]))
|
||||
end
|
||||
evo.commit()
|
||||
do
|
||||
assert(entity_list1 and #entity_list1 == 2)
|
||||
assert(entity_list1[1] and not evo.empty(entity_list1[1]))
|
||||
assert(entity_list1[2] and not evo.empty(entity_list1[2]))
|
||||
assert(not entity_list1[3])
|
||||
assert(
|
||||
evo.get(entity_list1[1], f1) == false and
|
||||
evo.get(entity_list1[1], f2) == 123 and
|
||||
evo.get(entity_list1[1], f3) == nil)
|
||||
assert(
|
||||
evo.get(entity_list1[2], f1) == false and
|
||||
evo.get(entity_list1[2], f2) == 123 and
|
||||
evo.get(entity_list1[2], f3) == nil)
|
||||
|
||||
assert(entity_list2 and #entity_list2 == 3)
|
||||
assert(entity_list2[1] and not evo.empty(entity_list2[1]))
|
||||
assert(entity_list2[2] and not evo.empty(entity_list2[2]))
|
||||
assert(entity_list2[3] and not evo.empty(entity_list2[3]))
|
||||
assert(not entity_list2[4])
|
||||
assert(
|
||||
evo.get(entity_list2[1], f1) == false and
|
||||
evo.get(entity_list2[1], f2) == 456 and
|
||||
evo.get(entity_list2[1], f3) == "world")
|
||||
assert(
|
||||
evo.get(entity_list2[2], f1) == false and
|
||||
evo.get(entity_list2[2], f2) == 456 and
|
||||
evo.get(entity_list2[2], f3) == "world")
|
||||
assert(
|
||||
evo.get(entity_list2[3], f1) == false and
|
||||
evo.get(entity_list2[3], f2) == 456 and
|
||||
evo.get(entity_list2[3], f3) == "world")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
|
||||
evo.set(f1, evo.REQUIRES, { f2, f3 })
|
||||
evo.set(f3, evo.TAG)
|
||||
|
||||
do
|
||||
local entity_list, entity_count = evo.multi_spawn(2, { [f1] = 42 })
|
||||
|
||||
assert(entity_list and #entity_list == 2)
|
||||
assert(entity_count == 2)
|
||||
|
||||
for i = 1, entity_count do
|
||||
local e = entity_list[i]
|
||||
assert(e and not evo.empty(e))
|
||||
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == true)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == nil)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local entity_prefab = evo.builder():set(f1, 42):spawn()
|
||||
|
||||
local clone_list, clone_count = evo.multi_clone(2, entity_prefab)
|
||||
|
||||
assert(clone_list and #clone_list == 2)
|
||||
assert(clone_count == 2)
|
||||
|
||||
for i = 1, clone_count do
|
||||
local e = clone_list[i]
|
||||
assert(e and not evo.empty(e))
|
||||
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == true)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == nil)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local entity_prefab = evo.builder():set(f1, 42):spawn()
|
||||
evo.remove(entity_prefab, f2, f3)
|
||||
|
||||
local clone_list, clone_count = evo.multi_clone(2, entity_prefab, { [f1] = 21 })
|
||||
|
||||
assert(clone_list and #clone_list == 2)
|
||||
assert(clone_count == 2)
|
||||
|
||||
for i = 1, clone_count do
|
||||
local e = clone_list[i]
|
||||
assert(e and not evo.empty(e))
|
||||
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 21)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == true)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == nil)
|
||||
end
|
||||
end
|
||||
|
||||
evo.set(f2, evo.DEFAULT, false)
|
||||
|
||||
do
|
||||
local entity_list, entity_count = evo.multi_spawn(2, { [f1] = 42 })
|
||||
|
||||
assert(entity_list and #entity_list == 2)
|
||||
assert(entity_count == 2)
|
||||
|
||||
for i = 1, entity_count do
|
||||
local e = entity_list[i]
|
||||
assert(e and not evo.empty(e))
|
||||
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == false)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == nil)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local entity_prefab = evo.builder():set(f1, 42):spawn()
|
||||
|
||||
local clone_list, clone_count = evo.multi_clone(2, entity_prefab)
|
||||
|
||||
assert(clone_list and #clone_list == 2)
|
||||
assert(clone_count == 2)
|
||||
|
||||
for i = 1, clone_count do
|
||||
local e = clone_list[i]
|
||||
assert(e and not evo.empty(e))
|
||||
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == false)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == nil)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local entity_prefab = evo.builder():set(f1, 42):spawn()
|
||||
evo.remove(entity_prefab, f2, f3)
|
||||
|
||||
local clone_list, clone_count = evo.multi_clone(2, entity_prefab, { [f1] = 21 })
|
||||
|
||||
assert(clone_list and #clone_list == 2)
|
||||
assert(clone_count == 2)
|
||||
|
||||
for i = 1, clone_count do
|
||||
local e = clone_list[i]
|
||||
assert(e and not evo.empty(e))
|
||||
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 21)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == false)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == nil)
|
||||
end
|
||||
end
|
||||
|
||||
local v_set_sum = 0
|
||||
local v_insert_sum = 0
|
||||
|
||||
local f3_set_times = 0
|
||||
local f3_insert_times = 0
|
||||
|
||||
evo.set(f1, evo.ON_SET, function(e, f, v)
|
||||
assert(f == f1)
|
||||
v_set_sum = v_set_sum + v
|
||||
assert(evo.get(e, f) == v)
|
||||
end)
|
||||
|
||||
evo.set(f1, evo.ON_INSERT, function(e, f, v)
|
||||
assert(f == f1)
|
||||
v_insert_sum = v_insert_sum + v
|
||||
assert(evo.get(e, f) == v)
|
||||
end)
|
||||
|
||||
evo.set(f3, evo.ON_SET, function(e, f, v)
|
||||
assert(f == f3)
|
||||
f3_set_times = f3_set_times + 1
|
||||
assert(v == nil)
|
||||
assert(evo.has(e, f))
|
||||
end)
|
||||
|
||||
evo.set(f3, evo.ON_INSERT, function(e, f, v)
|
||||
assert(f == f3)
|
||||
f3_insert_times = f3_insert_times + 1
|
||||
assert(v == nil)
|
||||
assert(evo.has(e, f))
|
||||
end)
|
||||
|
||||
do
|
||||
local entity_list, entity_count = evo.multi_spawn(2, { [f1] = 42 })
|
||||
|
||||
assert(entity_list and #entity_list == 2)
|
||||
assert(entity_count == 2)
|
||||
|
||||
for i = 1, entity_count do
|
||||
local e = entity_list[i]
|
||||
assert(e and not evo.empty(e))
|
||||
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == false)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local entity_prefab = evo.builder():set(f1, 42):spawn()
|
||||
|
||||
local clone_list, clone_count = evo.multi_clone(2, entity_prefab)
|
||||
|
||||
assert(clone_list and #clone_list == 2)
|
||||
assert(clone_count == 2)
|
||||
|
||||
for i = 1, clone_count do
|
||||
local e = clone_list[i]
|
||||
assert(e and not evo.empty(e))
|
||||
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == false)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local entity_prefab = evo.builder():set(f1, 42):spawn()
|
||||
evo.remove(entity_prefab, f2, f3)
|
||||
|
||||
local clone_list, clone_count = evo.multi_clone(2, entity_prefab, { [f1] = 21 })
|
||||
|
||||
assert(clone_list and #clone_list == 2)
|
||||
assert(clone_count == 2)
|
||||
|
||||
for i = 1, clone_count do
|
||||
local e = clone_list[i]
|
||||
assert(e and not evo.empty(e))
|
||||
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 21)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == false)
|
||||
end
|
||||
end
|
||||
|
||||
assert(v_set_sum == 42 * 6 + 21 * 2)
|
||||
assert(v_insert_sum == 42 * 6 + 21 * 2)
|
||||
|
||||
assert(f3_set_times == 8)
|
||||
assert(f3_insert_times == 8)
|
||||
end
|
||||
|
||||
do
|
||||
local function v2(x, y) return { x = x or 0, y = y or 0 } end
|
||||
local function v2_clone(v) return { x = v.x, y = v.y } end
|
||||
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
evo.set(f1, evo.REQUIRES, { f2, f3, f4 })
|
||||
|
||||
local f1_default = v2(1, 2)
|
||||
local f2_default = v2(3, 4)
|
||||
local f3_default = v2(10, 11)
|
||||
local f4_default = v2(12, 13)
|
||||
|
||||
evo.set(f1, evo.DEFAULT, f1_default)
|
||||
evo.set(f2, evo.DEFAULT, f2_default)
|
||||
evo.set(f3, evo.DEFAULT, f3_default)
|
||||
evo.set(f4, evo.DEFAULT, f4_default)
|
||||
|
||||
evo.set(f1, evo.DUPLICATE, v2_clone)
|
||||
evo.set(f2, evo.DUPLICATE, v2_clone)
|
||||
evo.set(f3, evo.DUPLICATE, v2_clone)
|
||||
|
||||
do
|
||||
local entity_list, entity_count = evo.multi_spawn(2, { [f1] = v2(5, 6), [f2] = v2(7, 8) })
|
||||
|
||||
assert(entity_list and #entity_list == 2)
|
||||
assert(entity_count == 2)
|
||||
|
||||
for i = 1, entity_count do
|
||||
local e = entity_list[i]
|
||||
assert(e and not evo.empty(e))
|
||||
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) ~= f1_default)
|
||||
assert(evo.get(e, f1).x == 5 and evo.get(e, f1).y == 6)
|
||||
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) ~= f2_default)
|
||||
assert(evo.get(e, f2).x == 7 and evo.get(e, f2).y == 8)
|
||||
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) ~= f3_default)
|
||||
assert(evo.get(e, f3).x == 10 and evo.get(e, f3).y == 11)
|
||||
|
||||
assert(evo.has(e, f4) and evo.get(e, f4) == f4_default)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local entity_prefab = evo.builder():set(f1, v2(5, 6)):set(f2, v2(7, 8)):spawn()
|
||||
|
||||
local clone_list, clone_count = evo.multi_clone(2, entity_prefab, { [f2] = f2_default })
|
||||
|
||||
assert(clone_list and #clone_list == 2)
|
||||
assert(clone_count == 2)
|
||||
|
||||
for i = 1, clone_count do
|
||||
local e = clone_list[i]
|
||||
assert(e and not evo.empty(e))
|
||||
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) ~= f1_default and evo.get(e, f1) ~= evo.get(entity_prefab, f1))
|
||||
assert(evo.get(e, f1).x == 5 and evo.get(e, f1).y == 6)
|
||||
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) ~= f2_default and evo.get(e, f2) ~= evo.get(entity_prefab, f2))
|
||||
assert(evo.get(e, f2).x == 3 and evo.get(e, f2).y == 4)
|
||||
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) ~= f3_default)
|
||||
assert(evo.get(e, f3).x == 10 and evo.get(e, f3).y == 11)
|
||||
|
||||
assert(evo.has(e, f4) and evo.get(e, f4) == f4_default)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local entity_prefab = evo.builder():set(f1, v2(5, 6)):set(f2, v2(7, 8)):spawn()
|
||||
evo.remove(entity_prefab, f2, f3, f4)
|
||||
|
||||
local clone_list, clone_count = evo.multi_clone(2, entity_prefab, { [f2] = f2_default })
|
||||
|
||||
assert(clone_list and #clone_list == 2)
|
||||
assert(clone_count == 2)
|
||||
|
||||
for i = 1, clone_count do
|
||||
local e = clone_list[i]
|
||||
assert(e and not evo.empty(e))
|
||||
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) ~= f1_default and evo.get(e, f1) ~= evo.get(entity_prefab, f1))
|
||||
assert(evo.get(e, f1).x == 5 and evo.get(e, f1).y == 6)
|
||||
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) ~= f2_default and evo.get(e, f2) ~= evo.get(entity_prefab, f2))
|
||||
assert(evo.get(e, f2).x == 3 and evo.get(e, f2).y == 4)
|
||||
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) ~= f3_default)
|
||||
assert(evo.get(e, f3).x == 10 and evo.get(e, f3).y == 11)
|
||||
|
||||
assert(evo.has(e, f4) and evo.get(e, f4) == f4_default)
|
||||
end
|
||||
end
|
||||
end
|
||||
43
develop/testing/name_tests.lua
Normal file
43
develop/testing/name_tests.lua
Normal file
@@ -0,0 +1,43 @@
|
||||
local evo = require 'evolved'
|
||||
|
||||
do
|
||||
local id = evo.id()
|
||||
|
||||
local index, version = evo.unpack(id)
|
||||
assert(evo.name(id) == string.format('$%d#%d:%d', id, index, version))
|
||||
|
||||
evo.set(id, evo.NAME, 'hello')
|
||||
assert(evo.name(id) == 'hello')
|
||||
|
||||
evo.set(id, evo.NAME, 'world')
|
||||
assert(evo.name(id) == 'world')
|
||||
|
||||
evo.destroy(id)
|
||||
assert(evo.name(id) == string.format('$%d#%d:%d', id, index, version))
|
||||
end
|
||||
|
||||
do
|
||||
local id1, id2, id3, id4, id5 = evo.id(5)
|
||||
|
||||
evo.set(id1, evo.NAME, 'id1')
|
||||
evo.set(id2, evo.NAME, 'id2')
|
||||
evo.set(id3, evo.NAME, 'id3')
|
||||
evo.set(id4, evo.NAME, 'id4')
|
||||
evo.set(id5, evo.NAME, 'id5')
|
||||
|
||||
do
|
||||
local id1_n, id3_n, id5_n = evo.name(id1, id3, id5)
|
||||
assert(id1_n == 'id1')
|
||||
assert(id3_n == 'id3')
|
||||
assert(id5_n == 'id5')
|
||||
end
|
||||
|
||||
do
|
||||
local id1_n, id2_n, id3_n, id4_n, id5_n = evo.name(id1, id2, id3, id4, id5)
|
||||
assert(id1_n == 'id1')
|
||||
assert(id2_n == 'id2')
|
||||
assert(id3_n == 'id3')
|
||||
assert(id4_n == 'id4')
|
||||
assert(id5_n == 'id5')
|
||||
end
|
||||
end
|
||||
245
develop/testing/requires_fragment_tests.lua
Normal file
245
develop/testing/requires_fragment_tests.lua
Normal file
@@ -0,0 +1,245 @@
|
||||
local evo = require 'evolved'
|
||||
|
||||
do
|
||||
local f1, f2 = evo.id(2)
|
||||
evo.set(f1, evo.REQUIRES)
|
||||
evo.set(f2, evo.REQUIRES, evo.get(f1, evo.REQUIRES))
|
||||
local f1_rs = evo.get(f1, evo.REQUIRES)
|
||||
local f2_rs = evo.get(f2, evo.REQUIRES)
|
||||
assert(f1_rs and f2_rs and #f1_rs == 0 and #f2_rs == 0 and f1_rs ~= f2_rs)
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2 = evo.id(2)
|
||||
local f3 = evo.builder():require(f1):require(f2):spawn()
|
||||
local f3_rs = evo.get(f3, evo.REQUIRES)
|
||||
assert(f3_rs and #f3_rs == 2 and f3_rs[1] == f1 and f3_rs[2] == f2)
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2 = evo.id(2)
|
||||
local f3 = evo.builder():require(f1, f2):spawn()
|
||||
local f3_rs = evo.get(f3, evo.REQUIRES)
|
||||
assert(f3_rs and #f3_rs == 2 and f3_rs[1] == f1 and f3_rs[2] == f2)
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
evo.set(f1, evo.REQUIRES, { f2 })
|
||||
evo.set(f3, evo.REQUIRES, { f1, f2 })
|
||||
|
||||
do
|
||||
local e = evo.id()
|
||||
evo.set(e, f1)
|
||||
assert(evo.has(e, f2))
|
||||
assert(evo.get(e, f2) == true)
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.builder():set(f1):spawn()
|
||||
assert(evo.has(e, f2))
|
||||
assert(evo.get(e, f2) == true)
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.spawn { [f1] = true }
|
||||
assert(evo.has(e, f2))
|
||||
assert(evo.get(e, f2) == true)
|
||||
|
||||
evo.remove(e, f2)
|
||||
assert(not evo.has(e, f2))
|
||||
|
||||
local e2 = evo.clone(e)
|
||||
assert(evo.has(e2, f2))
|
||||
assert(evo.get(e2, f2) == true)
|
||||
|
||||
local e3 = evo.clone(e, { [f3] = true })
|
||||
assert(evo.has(e3, f2))
|
||||
assert(evo.get(e3, f2) == true)
|
||||
end
|
||||
|
||||
do
|
||||
local f0 = evo.id()
|
||||
local q0 = evo.builder():include(f0):spawn()
|
||||
|
||||
local e1 = evo.builder():set(f0):spawn()
|
||||
local e2 = evo.builder():set(f0):spawn()
|
||||
local e3 = evo.builder():set(f0):set(f2, false):spawn()
|
||||
|
||||
evo.batch_set(q0, f1)
|
||||
|
||||
assert(evo.has(e1, f2) and evo.get(e1, f2) == true)
|
||||
assert(evo.has(e2, f2) and evo.get(e2, f2) == true)
|
||||
assert(evo.has(e3, f2) and evo.get(e3, f2) == false)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
evo.set(f1, evo.REQUIRES, { f2 })
|
||||
evo.set(f2, evo.DEFAULT, 42)
|
||||
evo.set(f3, evo.REQUIRES, { f1, f2 })
|
||||
|
||||
do
|
||||
local e = evo.id()
|
||||
evo.set(e, f1)
|
||||
assert(evo.has(e, f2))
|
||||
assert(evo.get(e, f2) == 42)
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.builder():set(f1):spawn()
|
||||
assert(evo.has(e, f2))
|
||||
assert(evo.get(e, f2) == 42)
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.spawn { [f1] = true, }
|
||||
assert(evo.has(e, f2))
|
||||
assert(evo.get(e, f2) == 42)
|
||||
|
||||
evo.remove(e, f2)
|
||||
assert(not evo.has(e, f2))
|
||||
|
||||
local e2 = evo.clone(e)
|
||||
assert(evo.has(e2, f2))
|
||||
assert(evo.get(e2, f2) == 42)
|
||||
|
||||
local e3 = evo.clone(e, { [f3] = true })
|
||||
assert(evo.has(e3, f2))
|
||||
assert(evo.get(e3, f2) == 42)
|
||||
end
|
||||
|
||||
do
|
||||
local f0 = evo.id()
|
||||
local q0 = evo.builder():include(f0):spawn()
|
||||
|
||||
local e1 = evo.builder():set(f0):spawn()
|
||||
local e2 = evo.builder():set(f0):spawn()
|
||||
local e3 = evo.builder():set(f0):set(f2, 21):spawn()
|
||||
|
||||
evo.batch_set(q0, f1)
|
||||
|
||||
assert(evo.has(e1, f2) and evo.get(e1, f2) == 42)
|
||||
assert(evo.has(e2, f2) and evo.get(e2, f2) == 42)
|
||||
assert(evo.has(e3, f2) and evo.get(e3, f2) == 21)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
evo.set(f1, evo.REQUIRES, { f2 })
|
||||
evo.set(f2, evo.REQUIRES, { f3 })
|
||||
evo.set(f3, evo.DEFAULT, 42)
|
||||
evo.set(f3, evo.REQUIRES, { f1, f2 })
|
||||
|
||||
do
|
||||
local e = evo.id()
|
||||
evo.set(e, f1)
|
||||
assert(evo.has(e, f2))
|
||||
assert(evo.get(e, f2) == true)
|
||||
assert(evo.has(e, f3))
|
||||
assert(evo.get(e, f3) == 42)
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.builder():set(f1):spawn()
|
||||
assert(evo.has(e, f2))
|
||||
assert(evo.get(e, f2) == true)
|
||||
assert(evo.has(e, f3))
|
||||
assert(evo.get(e, f3) == 42)
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.spawn { [f1] = true }
|
||||
assert(evo.has(e, f2))
|
||||
assert(evo.get(e, f2) == true)
|
||||
assert(evo.has(e, f3))
|
||||
assert(evo.get(e, f3) == 42)
|
||||
|
||||
evo.remove(e, f2, f3)
|
||||
assert(not evo.has(e, f2))
|
||||
assert(not evo.has(e, f3))
|
||||
|
||||
local e2 = evo.clone(e, { [f1] = 21 })
|
||||
assert(evo.has(e2, f1) and evo.get(e2, f1) == 21)
|
||||
assert(evo.has(e2, f2) and evo.get(e2, f2) == true)
|
||||
assert(evo.has(e2, f3) and evo.get(e2, f3) == 42)
|
||||
|
||||
local e3 = evo.clone(e, { [f3] = 21 })
|
||||
assert(evo.has(e3, f1) and evo.get(e3, f1) == true)
|
||||
assert(evo.has(e3, f2) and evo.get(e3, f2) == true)
|
||||
assert(evo.has(e3, f3) and evo.get(e3, f3) == 21)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
evo.set(f1, evo.REQUIRES, { f2 })
|
||||
evo.set(f2, evo.REQUIRES, { f3 })
|
||||
evo.set(f3, evo.REQUIRES, { f1, f2, f3 })
|
||||
|
||||
do
|
||||
local e = evo.id()
|
||||
evo.set(e, f1, 42)
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == true)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == true)
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.builder():set(f1, 42):spawn()
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == true)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == true)
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.spawn { [f1] = 42 }
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == true)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == true)
|
||||
|
||||
evo.remove(e, f2, f3)
|
||||
assert(not evo.has(e, f2))
|
||||
assert(not evo.has(e, f3))
|
||||
|
||||
local e2 = evo.clone(e, { [f1] = 21 })
|
||||
assert(evo.has(e2, f1) and evo.get(e2, f1) == 21)
|
||||
assert(evo.has(e2, f2) and evo.get(e2, f2) == true)
|
||||
assert(evo.has(e2, f3) and evo.get(e2, f3) == true)
|
||||
|
||||
local e3 = evo.clone(e, { [f3] = 21 })
|
||||
assert(evo.has(e3, f1) and evo.get(e3, f1) == 42)
|
||||
assert(evo.has(e3, f2) and evo.get(e3, f2) == true)
|
||||
assert(evo.has(e3, f3) and evo.get(e3, f3) == 21)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
|
||||
do
|
||||
evo.set(f1, evo.REQUIRES, { f2 })
|
||||
do
|
||||
local e = evo.id()
|
||||
evo.set(e, f1)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == true)
|
||||
end
|
||||
evo.set(f1, evo.REQUIRES, { f2, f3 })
|
||||
do
|
||||
local e = evo.id()
|
||||
evo.set(e, f1)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == true)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == true)
|
||||
end
|
||||
evo.set(f3, evo.REQUIRES, { f4 })
|
||||
do
|
||||
local e = evo.id()
|
||||
evo.set(e, f1)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == true)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == true)
|
||||
assert(evo.has(e, f4) and evo.get(e, f4) == true)
|
||||
end
|
||||
end
|
||||
end
|
||||
329
develop/testing/spawn_tests.lua
Normal file
329
develop/testing/spawn_tests.lua
Normal file
@@ -0,0 +1,329 @@
|
||||
local evo = require 'evolved'
|
||||
|
||||
do
|
||||
do
|
||||
local e = evo.spawn()
|
||||
assert(evo.alive(e) and evo.empty(e))
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.spawn({})
|
||||
assert(evo.alive(e) and evo.empty(e))
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
evo.set(f2, evo.REQUIRES, { f1, f3 })
|
||||
|
||||
do
|
||||
local e = evo.spawn({ [f1] = 42 })
|
||||
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.spawn({ [f1] = 42, [f2] = 'hello' })
|
||||
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2, f3))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 'hello')
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == true)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
evo.set(f2, evo.REQUIRES, { f1, f3 })
|
||||
evo.set(f3, evo.DEFAULT, 21)
|
||||
evo.set(f3, evo.REQUIRES, { f2 })
|
||||
|
||||
do
|
||||
local e = evo.spawn({ [f1] = 42 })
|
||||
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.spawn({ [f1] = 42, [f2] = 'hello' })
|
||||
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2, f3))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 'hello')
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == 21)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
evo.set(f2, evo.DUPLICATE, function() return nil end)
|
||||
evo.set(f2, evo.REQUIRES, { f1, f3, f4 })
|
||||
evo.set(f3, evo.DEFAULT, 21)
|
||||
evo.set(f3, evo.DUPLICATE, function(v) return v * 3 end)
|
||||
evo.set(f3, evo.REQUIRES, { f2 })
|
||||
|
||||
do
|
||||
local e = evo.spawn({ [f1] = 42 })
|
||||
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.spawn({ [f1] = 42, [f2] = true })
|
||||
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2, f3, f4))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == true)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == 21 * 3)
|
||||
assert(evo.has(e, f4) and evo.get(e, f4) == true)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
evo.set(f2, evo.REQUIRES, { f3 })
|
||||
evo.set(f3, evo.TAG)
|
||||
|
||||
local f2_set_sum, f2_inserted_sum = 0, 0
|
||||
local f3_set_count, f3_inserted_count = 0, 0
|
||||
|
||||
evo.set(f2, evo.ON_SET, function(e, f, c)
|
||||
assert(c == 42)
|
||||
assert(evo.get(e, f) == c)
|
||||
assert(f == f2)
|
||||
f2_set_sum = f2_set_sum + c
|
||||
end)
|
||||
|
||||
evo.set(f2, evo.ON_INSERT, function(e, f, c)
|
||||
assert(c == 42)
|
||||
assert(evo.get(e, f) == c)
|
||||
assert(f == f2)
|
||||
f2_inserted_sum = f2_inserted_sum + c
|
||||
end)
|
||||
|
||||
evo.set(f3, evo.ON_SET, function(e, f, c)
|
||||
assert(c == nil)
|
||||
assert(evo.get(e, f) == c)
|
||||
assert(f == f3)
|
||||
f3_set_count = f3_set_count + 1
|
||||
end)
|
||||
|
||||
evo.set(f3, evo.ON_INSERT, function(e, f, c)
|
||||
assert(c == nil)
|
||||
assert(evo.get(e, f) == c)
|
||||
assert(f == f3)
|
||||
f3_inserted_count = f3_inserted_count + 1
|
||||
end)
|
||||
|
||||
do
|
||||
f3_set_count, f3_inserted_count = 0, 0
|
||||
local e = evo.spawn({ [f1] = 'hello', [f2] = 42 })
|
||||
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2, f3))
|
||||
assert(f2_set_sum == 42 and f2_inserted_sum == 42)
|
||||
assert(f3_set_count == 1 and f3_inserted_count == 1)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
do
|
||||
local es, ec = evo.multi_spawn(2)
|
||||
assert(#es == 2 and ec == 2)
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and evo.empty(es[i]))
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local es, ec = evo.multi_spawn(2, {})
|
||||
assert(#es == 2 and ec == 2)
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and evo.empty(es[i]))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2 = evo.id(2)
|
||||
|
||||
do
|
||||
local es, ec = evo.multi_spawn(3, { [f1] = 42 })
|
||||
assert(#es == 3 and ec == 3)
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1))
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 42)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local es, ec = evo.multi_spawn(3, { [f1] = 42, [f2] = 'hello' })
|
||||
assert(#es == 3 and ec == 3)
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2))
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 42)
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 'hello')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2 = evo.id(2)
|
||||
evo.set(f1, evo.REQUIRES, { f2 })
|
||||
|
||||
do
|
||||
local es, ec = evo.multi_spawn(3, { [f1] = 42 })
|
||||
assert(#es == 3 and ec == 3)
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2))
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 42)
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2 = evo.id(2)
|
||||
evo.set(f1, evo.REQUIRES, { f2 })
|
||||
|
||||
do
|
||||
local es, ec = evo.multi_spawn(1, { [f1] = 42 })
|
||||
assert(#es == 1 and ec == 1)
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2))
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 42)
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
evo.set(f1, evo.REQUIRES, { f2, f3 })
|
||||
evo.set(f2, evo.DEFAULT, 'hello')
|
||||
|
||||
do
|
||||
local es, ec = evo.multi_spawn(4, { [f1] = 42 })
|
||||
assert(#es == 4 and ec == 4)
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2, f3))
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 42)
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 'hello')
|
||||
assert(evo.has(es[i], f3) and evo.get(es[i], f3) == true)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local es, ec = evo.multi_spawn(4, { [f1] = 42, [f2] = 'world' })
|
||||
assert(#es == 4 and ec == 4)
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2, f3))
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 42)
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 'world')
|
||||
assert(evo.has(es[i], f3) and evo.get(es[i], f3) == true)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local es, ec = evo.multi_spawn(4, { [f1] = 42, [f2] = 'world', [f3] = false })
|
||||
assert(#es == 4 and ec == 4)
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2, f3))
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 42)
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 'world')
|
||||
assert(evo.has(es[i], f3) and evo.get(es[i], f3) == false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2 = evo.id(2)
|
||||
evo.set(f1, evo.REQUIRES, { f2 })
|
||||
evo.set(f1, evo.DUPLICATE, function() return nil end)
|
||||
evo.set(f2, evo.DEFAULT, 'hello')
|
||||
evo.set(f2, evo.DUPLICATE, function(v) return v .. '!' end)
|
||||
|
||||
do
|
||||
local es, ec = evo.multi_spawn(4, { [f1] = 42 })
|
||||
assert(#es == 4 and ec == 4)
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2))
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == true)
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 'hello!')
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local es, ec = evo.multi_spawn(4, { [f1] = 42, [f2] = 'world' })
|
||||
assert(#es == 4 and ec == 4)
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2))
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == true)
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 'world!')
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local es, ec = evo.multi_spawn(4, { [f2] = 'hello world' })
|
||||
assert(#es == 4 and ec == 4)
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f2))
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 'hello world!')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
evo.set(f2, evo.REQUIRES, { f3 })
|
||||
evo.set(f3, evo.TAG)
|
||||
|
||||
local f2_set_sum, f2_inserted_sum = 0, 0
|
||||
local f3_set_count, f3_inserted_count = 0, 0
|
||||
|
||||
evo.set(f2, evo.ON_SET, function(e, f, c)
|
||||
assert(c == 42)
|
||||
assert(evo.get(e, f) == c)
|
||||
assert(f == f2)
|
||||
f2_set_sum = f2_set_sum + c
|
||||
end)
|
||||
|
||||
evo.set(f2, evo.ON_INSERT, function(e, f, c)
|
||||
assert(c == 42)
|
||||
assert(evo.get(e, f) == c)
|
||||
assert(f == f2)
|
||||
f2_inserted_sum = f2_inserted_sum + c
|
||||
end)
|
||||
|
||||
evo.set(f3, evo.ON_SET, function(e, f, c)
|
||||
assert(c == nil)
|
||||
assert(evo.get(e, f) == c)
|
||||
assert(f == f3)
|
||||
f3_set_count = f3_set_count + 1
|
||||
end)
|
||||
|
||||
evo.set(f3, evo.ON_INSERT, function(e, f, c)
|
||||
assert(c == nil)
|
||||
assert(evo.get(e, f) == c)
|
||||
assert(f == f3)
|
||||
f3_inserted_count = f3_inserted_count + 1
|
||||
end)
|
||||
|
||||
do
|
||||
local es, ec = evo.multi_spawn(3, { [f1] = 'hello', [f2] = 42 })
|
||||
assert(#es == 3 and ec == 3)
|
||||
|
||||
for i = 1, ec do
|
||||
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2, f3))
|
||||
assert(f2_set_sum == 42 * 3 and f2_inserted_sum == 42 * 3)
|
||||
assert(f3_set_count == 3 and f3_inserted_count == 3)
|
||||
end
|
||||
end
|
||||
end
|
||||
128
develop/testing/system_as_query_tests.lua
Normal file
128
develop/testing/system_as_query_tests.lua
Normal file
@@ -0,0 +1,128 @@
|
||||
local evo = require 'evolved'
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
|
||||
local q1e3 = evo.builder():include(f1):exclude(f3):spawn()
|
||||
local q2e3 = evo.builder():include(f2):exclude(f3):spawn()
|
||||
|
||||
local e1 = evo.builder():set(f1, 1):spawn()
|
||||
local e12 = evo.builder():set(f1, 11):set(f2, 12):spawn()
|
||||
local e2 = evo.builder():set(f2, 2):spawn()
|
||||
local e23 = evo.builder():set(f2, 23):set(f3, 3):spawn()
|
||||
|
||||
local c1 = evo.chunk(f1)
|
||||
local c12 = evo.chunk(f1, f2)
|
||||
local c2 = evo.chunk(f2)
|
||||
|
||||
do
|
||||
local _, entity_list, entity_count = evo.chunk(f2, f3)
|
||||
assert(entity_count == 1 and entity_list[1] == e23)
|
||||
end
|
||||
|
||||
do
|
||||
local entity_sum = 0
|
||||
|
||||
local s = evo.builder()
|
||||
:query(q1e3)
|
||||
:execute(function(chunk, entity_list, entity_count)
|
||||
for i = 1, entity_count do
|
||||
entity_sum = entity_sum + entity_list[i]
|
||||
end
|
||||
|
||||
if chunk == c1 then
|
||||
assert(entity_count == 1)
|
||||
assert(entity_list[1] == e1)
|
||||
elseif chunk == c12 then
|
||||
assert(entity_count == 1)
|
||||
assert(entity_list[1] == e12)
|
||||
else
|
||||
assert(false, "Unexpected chunk: " .. tostring(chunk))
|
||||
end
|
||||
end):spawn()
|
||||
|
||||
evo.process(s)
|
||||
|
||||
assert(entity_sum == e1 + e12)
|
||||
end
|
||||
|
||||
do
|
||||
local entity_sum = 0
|
||||
|
||||
local s = evo.builder()
|
||||
:query(q2e3)
|
||||
:execute(function(chunk, entity_list, entity_count)
|
||||
for i = 1, entity_count do
|
||||
entity_sum = entity_sum + entity_list[i]
|
||||
end
|
||||
|
||||
if chunk == c12 then
|
||||
assert(entity_count == 1)
|
||||
assert(entity_list[1] == e12)
|
||||
elseif chunk == c2 then
|
||||
assert(entity_count == 1)
|
||||
assert(entity_list[1] == e2)
|
||||
else
|
||||
assert(false, "Unexpected chunk: " .. tostring(chunk))
|
||||
end
|
||||
end):spawn()
|
||||
|
||||
evo.process(s)
|
||||
|
||||
assert(entity_sum == e12 + e2)
|
||||
end
|
||||
|
||||
do
|
||||
local entity_sum = 0
|
||||
|
||||
local s = evo.builder()
|
||||
:include(f1)
|
||||
:exclude(f3)
|
||||
:execute(function(chunk, entity_list, entity_count)
|
||||
for i = 1, entity_count do
|
||||
entity_sum = entity_sum + entity_list[i]
|
||||
end
|
||||
|
||||
if chunk == c1 then
|
||||
assert(entity_count == 1)
|
||||
assert(entity_list[1] == e1)
|
||||
elseif chunk == c12 then
|
||||
assert(entity_count == 1)
|
||||
assert(entity_list[1] == e12)
|
||||
else
|
||||
assert(false, "Unexpected chunk: " .. tostring(chunk))
|
||||
end
|
||||
end):spawn()
|
||||
|
||||
evo.process(s)
|
||||
|
||||
assert(entity_sum == e1 + e12)
|
||||
end
|
||||
|
||||
do
|
||||
local entity_sum = 0
|
||||
|
||||
local s = evo.builder()
|
||||
:include(f2)
|
||||
:exclude(f3)
|
||||
:execute(function(chunk, entity_list, entity_count)
|
||||
for i = 1, entity_count do
|
||||
entity_sum = entity_sum + entity_list[i]
|
||||
end
|
||||
|
||||
if chunk == c12 then
|
||||
assert(entity_count == 1)
|
||||
assert(entity_list[1] == e12)
|
||||
elseif chunk == c2 then
|
||||
assert(entity_count == 1)
|
||||
assert(entity_list[1] == e2)
|
||||
else
|
||||
assert(false, "Unexpected chunk: " .. tostring(chunk))
|
||||
end
|
||||
end):spawn()
|
||||
|
||||
evo.process(s)
|
||||
|
||||
assert(entity_sum == e12 + e2)
|
||||
end
|
||||
end
|
||||
@@ -1,692 +0,0 @@
|
||||
local basics = require 'develop.basics'
|
||||
basics.unload 'evolved'
|
||||
|
||||
local evo = require 'evolved'
|
||||
|
||||
local N = 1000
|
||||
local B = evo.builder()
|
||||
local F1, F2, F3, F4, F5 = evo.id(5)
|
||||
local Q1 = evo.builder():include(F1):spawn()
|
||||
|
||||
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 = #entities, 1, -1 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 set = evo.set
|
||||
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
set(e, F1)
|
||||
entities[i] = e
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 set = evo.set
|
||||
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
set(e, F1)
|
||||
set(e, F2)
|
||||
entities[i] = e
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 set = evo.set
|
||||
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
set(e, F1)
|
||||
set(e, F2)
|
||||
set(e, F3)
|
||||
entities[i] = e
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 set = evo.set
|
||||
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
set(e, F1)
|
||||
set(e, F2)
|
||||
set(e, F3)
|
||||
set(e, F4)
|
||||
entities[i] = e
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 set = evo.set
|
||||
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
set(e, F1)
|
||||
set(e, F2)
|
||||
set(e, F3)
|
||||
set(e, F4)
|
||||
set(e, F5)
|
||||
entities[i] = e
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 set = evo.set
|
||||
|
||||
evo.defer()
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
set(e, F1)
|
||||
entities[i] = e
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 set = evo.set
|
||||
|
||||
evo.defer()
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
set(e, F1)
|
||||
set(e, F2)
|
||||
entities[i] = e
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 set = evo.set
|
||||
|
||||
evo.defer()
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
set(e, F1)
|
||||
set(e, F2)
|
||||
set(e, F3)
|
||||
entities[i] = e
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 set = evo.set
|
||||
|
||||
evo.defer()
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
set(e, F1)
|
||||
set(e, F2)
|
||||
set(e, F3)
|
||||
set(e, F4)
|
||||
entities[i] = e
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 set = evo.set
|
||||
|
||||
evo.defer()
|
||||
for i = 1, N do
|
||||
local e = id()
|
||||
set(e, F1)
|
||||
set(e, F2)
|
||||
set(e, F3)
|
||||
set(e, F4)
|
||||
set(e, F5)
|
||||
entities[i] = e
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 spawn = B.spawn
|
||||
|
||||
for i = 1, N do
|
||||
set(B, F1)
|
||||
entities[i] = spawn(B)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 spawn = B.spawn
|
||||
|
||||
for i = 1, N do
|
||||
set(B, F1)
|
||||
set(B, F2)
|
||||
entities[i] = spawn(B)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 spawn = B.spawn
|
||||
|
||||
for i = 1, N do
|
||||
set(B, F1)
|
||||
set(B, F2)
|
||||
set(B, F3)
|
||||
entities[i] = spawn(B)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 spawn = B.spawn
|
||||
|
||||
for i = 1, N do
|
||||
set(B, F1)
|
||||
set(B, F2)
|
||||
set(B, F3)
|
||||
set(B, F4)
|
||||
entities[i] = spawn(B)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 spawn = B.spawn
|
||||
|
||||
for i = 1, N do
|
||||
set(B, F1)
|
||||
set(B, F2)
|
||||
set(B, F3)
|
||||
set(B, F4)
|
||||
set(B, F5)
|
||||
entities[i] = spawn(B)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 1 components / spawn', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [F1] = true }
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 2 components / spawn', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [F1] = true, [F2] = true }
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 3 components / spawn', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [F1] = true, [F2] = true, [F3] = true }
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 4 components / spawn', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [F1] = true, [F2] = true, [F3] = true, [F4] = true }
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 5 components / spawn', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true }
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 1 components / clone', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn({ [F1] = true })
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 2 components / clone', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn({ [F1] = true, [F2] = true })
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 3 components / clone', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn({ [F1] = true, [F2] = true, [F3] = true })
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 4 components / clone', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn({ [F1] = true, [F2] = true, [F3] = true, [F4] = true })
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 5 components / clone', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn({ [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true })
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
@@ -1,374 +0,0 @@
|
||||
local basics = require 'develop.basics'
|
||||
basics.unload 'evolved'
|
||||
|
||||
local evo = require 'evolved'
|
||||
local tiny = require 'develop.3rdparty.tiny'
|
||||
|
||||
local N = 1000
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Tiny Entity Cycle: %d entities', N),
|
||||
function(world)
|
||||
world:update(0.016)
|
||||
end, function()
|
||||
local world = tiny.world()
|
||||
|
||||
for i = 1, N do
|
||||
world:addEntity({ a = i })
|
||||
end
|
||||
|
||||
local A = tiny.processingSystem()
|
||||
A.filter = tiny.requireAll('a')
|
||||
A.process = function(_, e) world:addEntity({ b = e.a }) end
|
||||
A.postProcess = function(_) world:refresh() end
|
||||
|
||||
local B = tiny.processingSystem()
|
||||
B.filter = tiny.requireAll('b')
|
||||
B.process = function(_, e) world:removeEntity(e) end
|
||||
B.postProcess = function(_) world:refresh() end
|
||||
|
||||
world:addSystem(A)
|
||||
world:addSystem(B)
|
||||
|
||||
world:refresh()
|
||||
|
||||
return world
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Evolved Entity Cycle (Defer): %d entities', N),
|
||||
function(a, b, A, B)
|
||||
evo.defer()
|
||||
do
|
||||
for chunk, _, entity_count in evo.execute(A) do
|
||||
local as = chunk:components(a)
|
||||
for i = 1, entity_count do
|
||||
evo.set(evo.id(), b, as[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
evo.commit()
|
||||
|
||||
evo.batch_destroy(B)
|
||||
end, function()
|
||||
local a, b = evo.id(2)
|
||||
|
||||
for i = 1, N do
|
||||
evo.builder():set(a, i):spawn()
|
||||
end
|
||||
|
||||
local A = evo.builder():include(a):spawn()
|
||||
local B = evo.builder():include(b):spawn()
|
||||
|
||||
return a, b, A, B
|
||||
end, function(_, _, A, _)
|
||||
evo.batch_destroy(A)
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Evolved Entity Cycle (Manual): %d entities', N),
|
||||
function(a, b, A, B)
|
||||
local to_create = {}
|
||||
local to_create_count = 0
|
||||
|
||||
for chunk, _, entity_count in evo.execute(A) do
|
||||
local as = chunk:components(a)
|
||||
for i = 1, entity_count do
|
||||
to_create_count = to_create_count + 1
|
||||
to_create[to_create_count] = as[i]
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, to_create_count do
|
||||
local e = evo.id()
|
||||
evo.set(e, b, to_create[i])
|
||||
end
|
||||
|
||||
evo.batch_destroy(B)
|
||||
end, function()
|
||||
local a, b = evo.id(2)
|
||||
|
||||
for i = 1, N do
|
||||
evo.builder():set(a, i):spawn()
|
||||
end
|
||||
|
||||
local A = evo.builder():include(a):spawn()
|
||||
local B = evo.builder():include(b):spawn()
|
||||
|
||||
return a, b, A, B
|
||||
end, function(_, _, A, _)
|
||||
evo.batch_destroy(A)
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Tiny Simple Iteration: %d entities', N),
|
||||
function(world)
|
||||
world:update(0.016)
|
||||
end, function()
|
||||
local world = tiny.world()
|
||||
|
||||
for i = 1, N do
|
||||
world:addEntity({ a = i, b = i })
|
||||
world:addEntity({ a = i, b = i, c = i })
|
||||
world:addEntity({ a = i, b = i, c = i, d = i })
|
||||
world:addEntity({ a = i, b = i, c = i, e = i })
|
||||
end
|
||||
|
||||
local AB = tiny.processingSystem()
|
||||
AB.filter = tiny.requireAll('a', 'b')
|
||||
AB.process = function(_, e) e.a, e.b = e.b, e.a end
|
||||
|
||||
local CD = tiny.processingSystem()
|
||||
CD.filter = tiny.requireAll('c', 'd')
|
||||
CD.process = function(_, e) e.c, e.d = e.d, e.c end
|
||||
|
||||
local CE = tiny.processingSystem()
|
||||
CE.filter = tiny.requireAll('c', 'e')
|
||||
CE.process = function(_, e) e.c, e.e = e.e, e.c end
|
||||
|
||||
world:addSystem(AB)
|
||||
world:addSystem(CD)
|
||||
world:addSystem(CE)
|
||||
|
||||
world:refresh()
|
||||
|
||||
return world
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Evolved Simple Iteration: %d entities', N),
|
||||
---@param a evolved.entity
|
||||
---@param b evolved.entity
|
||||
---@param c evolved.entity
|
||||
---@param d evolved.entity
|
||||
---@param e evolved.entity
|
||||
---@param AB evolved.query
|
||||
---@param CD evolved.query
|
||||
---@param CE evolved.query
|
||||
function(a, b, c, d, e, AB, CD, CE)
|
||||
for chunk, _, entity_count in evo.execute(AB) do
|
||||
local as, bs = chunk:components(a, b)
|
||||
for i = 1, entity_count do
|
||||
as[i], bs[i] = bs[i], as[i]
|
||||
end
|
||||
end
|
||||
|
||||
for chunk, _, entity_count in evo.execute(CD) do
|
||||
local cs, ds = chunk:components(c, d)
|
||||
for i = 1, entity_count do
|
||||
cs[i], ds[i] = ds[i], cs[i]
|
||||
end
|
||||
end
|
||||
|
||||
for chunk, _, entity_count in evo.execute(CE) do
|
||||
local cs, es = chunk:components(c, e)
|
||||
for i = 1, entity_count do
|
||||
cs[i], es[i] = es[i], cs[i]
|
||||
end
|
||||
end
|
||||
end, function()
|
||||
local a, b, c, d, e = evo.id(5)
|
||||
|
||||
for i = 1, N do
|
||||
evo.builder():set(a, i):set(b, i):spawn()
|
||||
evo.builder():set(a, i):set(b, i):set(c, i):spawn()
|
||||
evo.builder():set(a, i):set(b, i):set(c, i):set(d, i):spawn()
|
||||
evo.builder():set(a, i):set(b, i):set(c, i):set(e, i):spawn()
|
||||
end
|
||||
|
||||
local AB = evo.builder():include(a, b):spawn()
|
||||
local CD = evo.builder():include(c, d):spawn()
|
||||
local CE = evo.builder():include(c, e):spawn()
|
||||
|
||||
return a, b, c, d, e, AB, CD, CE
|
||||
end, function(_, _, _, _, _, AB, CD, CE)
|
||||
evo.batch_destroy(AB)
|
||||
evo.batch_destroy(CD)
|
||||
evo.batch_destroy(CE)
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Tiny Packed Iteration: %d entities', N),
|
||||
function(world)
|
||||
world:update(0.016)
|
||||
end, function()
|
||||
local world = tiny.world()
|
||||
|
||||
for i = 1, N do
|
||||
world:addEntity({ a = i, b = i, c = i, d = i, e = i })
|
||||
end
|
||||
|
||||
local A = tiny.processingSystem()
|
||||
A.filter = tiny.requireAll('a')
|
||||
A.process = function(_, e) e.a = e.a * 2 end
|
||||
|
||||
local B = tiny.processingSystem()
|
||||
B.filter = tiny.requireAll('b')
|
||||
B.process = function(_, e) e.b = e.b * 2 end
|
||||
|
||||
local C = tiny.processingSystem()
|
||||
C.filter = tiny.requireAll('c')
|
||||
C.process = function(_, e) e.c = e.c * 2 end
|
||||
|
||||
local D = tiny.processingSystem()
|
||||
D.filter = tiny.requireAll('d')
|
||||
D.process = function(_, e) e.d = e.d * 2 end
|
||||
|
||||
local E = tiny.processingSystem()
|
||||
E.filter = tiny.requireAll('e')
|
||||
E.process = function(_, e) e.e = e.e * 2 end
|
||||
|
||||
world:addSystem(A)
|
||||
world:addSystem(B)
|
||||
world:addSystem(C)
|
||||
world:addSystem(D)
|
||||
world:addSystem(E)
|
||||
|
||||
world:refresh()
|
||||
|
||||
return world
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Evolved Packed Iteration: %d entities', N),
|
||||
---@param a evolved.entity
|
||||
---@param b evolved.entity
|
||||
---@param c evolved.entity
|
||||
---@param d evolved.entity
|
||||
---@param e evolved.entity
|
||||
---@param A evolved.query
|
||||
---@param B evolved.query
|
||||
---@param C evolved.query
|
||||
---@param D evolved.query
|
||||
---@param E evolved.query
|
||||
function(a, b, c, d, e, A, B, C, D, E)
|
||||
for chunk, _, entity_count in evo.execute(A) do
|
||||
local as = chunk:components(a)
|
||||
for i = 1, entity_count do
|
||||
as[i] = as[i] * 2
|
||||
end
|
||||
end
|
||||
|
||||
for chunk, _, entity_count in evo.execute(B) do
|
||||
local bs = chunk:components(b)
|
||||
for i = 1, entity_count do
|
||||
bs[i] = bs[i] * 2
|
||||
end
|
||||
end
|
||||
|
||||
for chunk, _, entity_count in evo.execute(C) do
|
||||
local cs = chunk:components(c)
|
||||
for i = 1, entity_count do
|
||||
cs[i] = cs[i] * 2
|
||||
end
|
||||
end
|
||||
|
||||
for chunk, _, entity_count in evo.execute(D) do
|
||||
local ds = chunk:components(d)
|
||||
for i = 1, entity_count do
|
||||
ds[i] = ds[i] * 2
|
||||
end
|
||||
end
|
||||
|
||||
for chunk, _, entity_count in evo.execute(E) do
|
||||
local es = chunk:components(e)
|
||||
for i = 1, entity_count do
|
||||
es[i] = es[i] * 2
|
||||
end
|
||||
end
|
||||
end, function()
|
||||
local a, b, c, d, e = evo.id(5)
|
||||
|
||||
for i = 1, N do
|
||||
evo.builder():set(a, i):set(b, i):set(c, i):set(d, i):set(e, i):spawn()
|
||||
end
|
||||
|
||||
local A = evo.builder():include(a):spawn()
|
||||
local B = evo.builder():include(b):spawn()
|
||||
local C = evo.builder():include(c):spawn()
|
||||
local D = evo.builder():include(d):spawn()
|
||||
local E = evo.builder():include(e):spawn()
|
||||
|
||||
return a, b, c, d, e, A, B, C, D, E
|
||||
end, function(_, _, _, _, _, A, _, _, _, _)
|
||||
evo.batch_destroy(A)
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Tiny Fragmented Iteration: %d entities', N),
|
||||
function(world)
|
||||
world:update(0.016)
|
||||
end, function()
|
||||
local world = tiny.world()
|
||||
|
||||
---@type string[]
|
||||
local chars = {}
|
||||
|
||||
for i = 1, 26 do
|
||||
chars[i] = string.char(string.byte('a') + i - 1)
|
||||
end
|
||||
|
||||
for _, char in ipairs(chars) do
|
||||
for i = 1, N do
|
||||
world:addEntity({ [char] = i, data = i })
|
||||
end
|
||||
end
|
||||
|
||||
local Data = tiny.processingSystem()
|
||||
Data.filter = tiny.requireAll('data')
|
||||
Data.process = function(_, e) e.data = e.data * 2 end
|
||||
|
||||
local Last = tiny.processingSystem()
|
||||
Last.filter = tiny.requireAll('z')
|
||||
Last.process = function(_, e) e.z = e.z * 2 end
|
||||
|
||||
world:addSystem(Data)
|
||||
world:addSystem(Last)
|
||||
|
||||
world:refresh()
|
||||
|
||||
return world
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Evolved Fragmented Iteration: %d entities', N),
|
||||
---@param data evolved.entity
|
||||
---@param last evolved.entity
|
||||
---@param Data evolved.query
|
||||
---@param Last evolved.query
|
||||
function(data, last, Data, Last)
|
||||
for chunk, _, entity_count in evo.execute(Data) do
|
||||
local ds = chunk:components(data)
|
||||
for i = 1, entity_count do
|
||||
ds[i] = ds[i] * 2
|
||||
end
|
||||
end
|
||||
|
||||
for chunk, _, entity_count in evo.execute(Last) do
|
||||
local ls = chunk:components(last)
|
||||
for i = 1, entity_count do
|
||||
ls[i] = ls[i] * 2
|
||||
end
|
||||
end
|
||||
end, function()
|
||||
local data = evo.id()
|
||||
|
||||
---@type evolved.fragment[]
|
||||
local chars = {}
|
||||
|
||||
for i = 1, 26 do
|
||||
chars[i] = evo.id()
|
||||
end
|
||||
|
||||
for _, char in ipairs(chars) do
|
||||
for i = 1, N do
|
||||
evo.builder():set(char, i):set(data, i):spawn()
|
||||
end
|
||||
end
|
||||
|
||||
local Data = evo.builder():include(data):spawn()
|
||||
local Last = evo.builder():include(chars[#chars]):spawn()
|
||||
|
||||
return data, chars[#chars], Data, Last
|
||||
end, function(_, _, Data, _)
|
||||
evo.batch_destroy(Data)
|
||||
end)
|
||||
181
evolved.d.tl
Normal file
181
evolved.d.tl
Normal file
@@ -0,0 +1,181 @@
|
||||
local record Evolved
|
||||
interface Id end
|
||||
|
||||
type Entity = Id
|
||||
type Fragment = Id
|
||||
type Query = Id
|
||||
type System = Id
|
||||
|
||||
interface EachState end
|
||||
interface ExecuteState end
|
||||
|
||||
type EachIterator = function(state?: EachState): Fragment, any
|
||||
type ExecuteIterator = function(state?: ExecuteState): Chunk, { Entity }, integer
|
||||
|
||||
interface Chunk
|
||||
alive: function(self: Chunk): boolean
|
||||
empty: function(self: Chunk): boolean
|
||||
|
||||
has: function(self: Chunk, fragment: Fragment): boolean
|
||||
has_all: function(self: Chunk, ...: Fragment): boolean
|
||||
has_any: function(self: Chunk, ...: Fragment): boolean
|
||||
|
||||
entities: function(self: Chunk): { Entity }, integer
|
||||
fragments: function(self: Chunk): { Fragment }, integer
|
||||
|
||||
components: function(self: Chunk)
|
||||
components: function<C1>(self: Chunk, f1: Fragment): { C1 }
|
||||
components: function<C1, C2>(self: Chunk, f1: Fragment, f2: Fragment): { C1 }, { C2 }
|
||||
components: function<C1, C2, C3>(self: Chunk, f1: Fragment, f2: Fragment, f3: Fragment): { C1 }, { C2 }, { C3 }
|
||||
components: function<C1, C2, C3, C4>(self: Chunk, f1: Fragment, f2: Fragment, f3: Fragment, f4: Fragment): { C1 }, { C2 }, { C3 }, { C4 }
|
||||
end
|
||||
|
||||
interface Builder
|
||||
build: function(self: Builder, prefab?: Entity): Entity
|
||||
multi_build: function(self: Builder, entity_count: integer, prefab?: Entity): { Entity }, integer
|
||||
|
||||
spawn: function(self: Builder): Entity
|
||||
multi_spawn: function(self: Builder, entity_count: integer): { Entity }, integer
|
||||
|
||||
clone: function(self: Builder, prefab: Entity): Entity
|
||||
multi_clone: function(self: Builder, entity_count: integer, prefab: Entity): { Entity }, integer
|
||||
|
||||
has: function(self: Builder, fragment: Fragment): boolean
|
||||
has_all: function(self: Builder, ...: Fragment): boolean
|
||||
has_any: function(self: Builder, ...: Fragment): boolean
|
||||
|
||||
get: function(self: Builder)
|
||||
get: function<C1>(self: Builder, f1: Fragment): C1 | nil
|
||||
get: function<C1, C2>(self: Builder, f1: Fragment, f2: Fragment): C1 | nil, C2 | nil
|
||||
get: function<C1, C2, C3>(self: Builder, f1: Fragment, f2: Fragment, f3: Fragment): C1 | nil, C2 | nil, C3 | nil
|
||||
get: function<C1, C2, C3, C4>(self: Builder, f1: Fragment, f2: Fragment, f3: Fragment, f4: Fragment): C1 | nil, C2 | nil, C3 | nil, C4 | nil
|
||||
|
||||
set: function<Component>(self: Builder, fragment: Fragment, component?: Component): Builder
|
||||
remove: function(self: Builder, ...: Fragment): Builder
|
||||
clear: function(self: Builder): Builder
|
||||
|
||||
tag: function(self: Builder): Builder
|
||||
name: function(self: Builder, name: string): Builder
|
||||
|
||||
unique: function(self: Builder): Builder
|
||||
explicit: function(self: Builder): Builder
|
||||
internal: function(self: Builder): Builder
|
||||
|
||||
default: function<Component>(self: Builder, default: Component): Builder
|
||||
duplicate: function<Component>(self: Builder, duplicate: function(Component): Component): Builder
|
||||
|
||||
prefab: function(self: Builder): Builder
|
||||
disabled: function(self: Builder): Builder
|
||||
|
||||
include: function(self: Builder, ...: Fragment): Builder
|
||||
exclude: function(self: Builder, ...: Fragment): Builder
|
||||
require: function(self: Builder, ...: Fragment): Builder
|
||||
|
||||
on_set: function<Component>(self: Builder, on_set: function(Entity, Fragment, ? Component, ? Component)): Builder
|
||||
on_assign: function<Component>(self: Builder, on_assign: function(Entity, Fragment, ? Component, ? Component)): Builder
|
||||
on_insert: function<Component>(self: Builder, on_insert: function(Entity, Fragment, ? Component)): Builder
|
||||
on_remove: function<Component>(self: Builder, on_remove: function(Entity, Fragment, ? Component)): Builder
|
||||
|
||||
group: function(self: Builder, group: System): Builder
|
||||
|
||||
query: function(self: Builder, query: Query): Builder
|
||||
execute: function(self: Builder, execute: function(Chunk, {Entity}, integer)): Builder
|
||||
|
||||
prologue: function(self: Builder, prologue: function()): Builder
|
||||
epilogue: function(self: Builder, epilogue: function()): Builder
|
||||
|
||||
destruction_policy: function(self: Builder, destruction_policy: Id): Builder
|
||||
end
|
||||
|
||||
TAG: Fragment
|
||||
NAME: Fragment
|
||||
|
||||
UNIQUE: Fragment
|
||||
EXPLICIT: Fragment
|
||||
INTERNAL: Fragment
|
||||
|
||||
DEFAULT: Fragment
|
||||
DUPLICATE: Fragment
|
||||
|
||||
PREFAB: Fragment
|
||||
DISABLED: Fragment
|
||||
|
||||
INCLUDES: Fragment
|
||||
EXCLUDES: Fragment
|
||||
REQUIRES: Fragment
|
||||
|
||||
ON_SET: Fragment
|
||||
ON_ASSIGN: Fragment
|
||||
ON_INSERT: Fragment
|
||||
ON_REMOVE: Fragment
|
||||
|
||||
GROUP: Fragment
|
||||
|
||||
QUERY: Fragment
|
||||
EXECUTE: Fragment
|
||||
PROLOGUE: Fragment
|
||||
EPILOGUE: Fragment
|
||||
|
||||
DESTRUCTION_POLICY: Fragment
|
||||
DESTRUCTION_POLICY_DESTROY_ENTITY: Id
|
||||
DESTRUCTION_POLICY_REMOVE_FRAGMENT: Id
|
||||
|
||||
id: function(count?: integer): Id...
|
||||
name: function(...: Id): string...
|
||||
|
||||
pack: function(primary: integer, secondary: integer): Id
|
||||
unpack: function(id: Id): integer, integer
|
||||
|
||||
defer: function(): boolean
|
||||
commit: function(): boolean
|
||||
cancel: function(): boolean
|
||||
|
||||
spawn: function(components?: { Fragment: any }): Entity
|
||||
multi_spawn: function(entity_count: integer, components?: { Fragment: any }): { Entity }, integer
|
||||
|
||||
clone: function(prefab: Entity, components?: { Fragment: any }): Entity
|
||||
multi_clone: function(entity_count: integer, prefab: Entity, components?: { Fragment: any }): { Entity }, integer
|
||||
|
||||
alive: function(entity: Entity): boolean
|
||||
alive_all: function(...: Entity): boolean
|
||||
alive_any: function(...: Entity): boolean
|
||||
|
||||
empty: function(entity: Entity): boolean
|
||||
empty_all: function(...: Entity): boolean
|
||||
empty_any: function(...: Entity): boolean
|
||||
|
||||
has: function(entity: Entity, fragment: Fragment): boolean
|
||||
has_all: function(entity: Entity, ...: Fragment): boolean
|
||||
has_any: function(entity: Entity, ...: Fragment): boolean
|
||||
|
||||
get: function(entity: Entity)
|
||||
get: function<C1>(entity: Entity, f1: Fragment): C1 | nil
|
||||
get: function<C1, C2>(entity: Entity, f1: Fragment, f2: Fragment): C1 | nil, C2 | nil
|
||||
get: function<C1, C2, C3>(entity: Entity, f1: Fragment, f2: Fragment, f3: Fragment): C1 | nil, C2 | nil, C3 | nil
|
||||
get: function<C1, C2, C3, C4>(entity: Entity, f1: Fragment, f2: Fragment, f3: Fragment, f4: Fragment): C1 | nil, C2 | nil, C3 | nil, C4 | nil
|
||||
|
||||
set: function<Component>(entity: Entity, fragment: Fragment, component?: Component)
|
||||
remove: function(entity: Entity, ...: Fragment)
|
||||
clear: function(...: Entity)
|
||||
destroy: function(...: Entity)
|
||||
|
||||
batch_set: function<Component>(query: Query, fragment: Fragment, component?: Component)
|
||||
batch_remove: function(query: Query, ...: Fragment)
|
||||
batch_clear: function(...: Query)
|
||||
batch_destroy: function(...: Query)
|
||||
|
||||
each: function(entity: Entity): EachIterator, EachState | nil
|
||||
execute: function(query: Query): ExecuteIterator, ExecuteState | nil
|
||||
|
||||
locate: function(entity: Entity): Chunk | nil, integer
|
||||
|
||||
process: function(...: System)
|
||||
|
||||
debug_mode: function(yesno: boolean)
|
||||
collect_garbage: function()
|
||||
|
||||
chunk: function(fragment: Fragment, ...: Fragment): Chunk, { Entity }, integer
|
||||
builder: function(): Builder
|
||||
end
|
||||
|
||||
return Evolved
|
||||
4691
evolved.lua
4691
evolved.lua
File diff suppressed because it is too large
Load Diff
10
example/conf.lua
Normal file
10
example/conf.lua
Normal file
@@ -0,0 +1,10 @@
|
||||
if os.getenv('LOCAL_LUA_DEBUGGER_VSCODE') == '1' then
|
||||
require('lldebugger').start()
|
||||
end
|
||||
|
||||
---@type love.conf
|
||||
function love.conf(t)
|
||||
t.window.title = 'Evolved Example'
|
||||
t.window.width = 640
|
||||
t.window.height = 480
|
||||
end
|
||||
173
example/main.lua
Normal file
173
example/main.lua
Normal file
@@ -0,0 +1,173 @@
|
||||
local evolved = require 'evolved'
|
||||
|
||||
local STAGES = {
|
||||
ON_SETUP = evolved.builder()
|
||||
:name('STAGES.ON_SETUP')
|
||||
:build(),
|
||||
ON_UPDATE = evolved.builder()
|
||||
:name('STAGES.ON_UPDATE')
|
||||
:build(),
|
||||
ON_RENDER = evolved.builder()
|
||||
:name('STAGES.ON_RENDER')
|
||||
:build(),
|
||||
}
|
||||
|
||||
local UNIFORMS = {
|
||||
DELTA_TIME = 1.0 / 60.0,
|
||||
}
|
||||
|
||||
local FRAGMENTS = {
|
||||
POSITION_X = evolved.builder()
|
||||
:name('FRAGMENTS.POSITION_X')
|
||||
:default(0)
|
||||
:build(),
|
||||
POSITION_Y = evolved.builder()
|
||||
:name('FRAGMENTS.POSITION_Y')
|
||||
:default(0)
|
||||
:build(),
|
||||
VELOCITY_X = evolved.builder()
|
||||
:name('FRAGMENTS.VELOCITY_X')
|
||||
:default(0)
|
||||
:build(),
|
||||
VELOCITY_Y = evolved.builder()
|
||||
:name('FRAGMENTS.VELOCITY_Y')
|
||||
:default(0)
|
||||
:build(),
|
||||
}
|
||||
|
||||
local PREFABS = {
|
||||
CIRCLE = evolved.builder()
|
||||
:name('PREFABS.CIRCLE')
|
||||
:prefab()
|
||||
:set(FRAGMENTS.POSITION_X)
|
||||
:set(FRAGMENTS.POSITION_Y)
|
||||
:set(FRAGMENTS.VELOCITY_X)
|
||||
:set(FRAGMENTS.VELOCITY_Y)
|
||||
:build(),
|
||||
}
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
evolved.builder()
|
||||
:name('SYSTEMS.STARTUP')
|
||||
:group(STAGES.ON_SETUP)
|
||||
:prologue(function()
|
||||
local screen_width, screen_height = love.graphics.getDimensions()
|
||||
|
||||
local circle_list, circle_count = evolved.multi_clone(100, PREFABS.CIRCLE)
|
||||
|
||||
for i = 1, circle_count do
|
||||
local circle = circle_list[i]
|
||||
|
||||
local px = math.random() * screen_width
|
||||
local py = math.random() * screen_height
|
||||
|
||||
local vx = math.random(-100, 100)
|
||||
local vy = math.random(-100, 100)
|
||||
|
||||
evolved.set(circle, FRAGMENTS.POSITION_X, px)
|
||||
evolved.set(circle, FRAGMENTS.POSITION_Y, py)
|
||||
|
||||
evolved.set(circle, FRAGMENTS.VELOCITY_X, vx)
|
||||
evolved.set(circle, FRAGMENTS.VELOCITY_Y, vy)
|
||||
end
|
||||
end):build()
|
||||
|
||||
evolved.builder()
|
||||
:name('SYSTEMS.MOVEMENT')
|
||||
:group(STAGES.ON_UPDATE)
|
||||
:include(FRAGMENTS.POSITION_X, FRAGMENTS.POSITION_Y)
|
||||
:include(FRAGMENTS.VELOCITY_X, FRAGMENTS.VELOCITY_Y)
|
||||
:execute(function(chunk, _, entity_count)
|
||||
local delta_time = UNIFORMS.DELTA_TIME
|
||||
local screen_width, screen_height = love.graphics.getDimensions()
|
||||
|
||||
---@type number[], number[]
|
||||
local position_xs, position_ys = chunk:components(
|
||||
FRAGMENTS.POSITION_X, FRAGMENTS.POSITION_Y)
|
||||
|
||||
---@type number[], number[]
|
||||
local velocity_xs, velocity_ys = chunk:components(
|
||||
FRAGMENTS.VELOCITY_X, FRAGMENTS.VELOCITY_Y)
|
||||
|
||||
for i = 1, entity_count do
|
||||
local px, py = position_xs[i], position_ys[i]
|
||||
local vx, vy = velocity_xs[i], velocity_ys[i]
|
||||
|
||||
px = px + vx * delta_time
|
||||
py = py + vy * delta_time
|
||||
|
||||
if px < 0 and vx < 0 then
|
||||
vx = -vx
|
||||
elseif px > screen_width and vx > 0 then
|
||||
vx = -vx
|
||||
end
|
||||
|
||||
if py < 0 and vy < 0 then
|
||||
vy = -vy
|
||||
elseif py > screen_height and vy > 0 then
|
||||
vy = -vy
|
||||
end
|
||||
|
||||
position_xs[i], position_ys[i] = px, py
|
||||
velocity_xs[i], velocity_ys[i] = vx, vy
|
||||
end
|
||||
end):build()
|
||||
|
||||
evolved.builder()
|
||||
:name('SYSTEMS.RENDERING')
|
||||
:group(STAGES.ON_RENDER)
|
||||
:include(FRAGMENTS.POSITION_X, FRAGMENTS.POSITION_Y)
|
||||
:execute(function(chunk, _, entity_count)
|
||||
---@type number[], number[]
|
||||
local position_xs, position_ys = chunk:components(
|
||||
FRAGMENTS.POSITION_X, FRAGMENTS.POSITION_Y)
|
||||
|
||||
for i = 1, entity_count do
|
||||
local x, y = position_xs[i], position_ys[i]
|
||||
love.graphics.circle('fill', x, y, 10)
|
||||
end
|
||||
end):build()
|
||||
|
||||
evolved.builder()
|
||||
:name('SYSTEMS.DEBUGGING')
|
||||
:group(STAGES.ON_RENDER)
|
||||
:epilogue(function()
|
||||
local fps = love.timer.getFPS()
|
||||
local mem = collectgarbage('count')
|
||||
love.graphics.print(string.format('FPS: %d', fps), 10, 10)
|
||||
love.graphics.print(string.format('MEM: %d KB', mem), 10, 30)
|
||||
end):build()
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
---@type love.load
|
||||
function love.load()
|
||||
evolved.process(STAGES.ON_SETUP)
|
||||
end
|
||||
|
||||
---@type love.update
|
||||
function love.update(dt)
|
||||
UNIFORMS.DELTA_TIME = dt
|
||||
evolved.process(STAGES.ON_UPDATE)
|
||||
end
|
||||
|
||||
---@type love.draw
|
||||
function love.draw()
|
||||
evolved.process(STAGES.ON_RENDER)
|
||||
end
|
||||
|
||||
---@type love.keypressed
|
||||
function love.keypressed(key)
|
||||
if key == 'escape' then
|
||||
love.event.quit()
|
||||
end
|
||||
end
|
||||
34
rockspecs/evolved.lua-1.1.0-0.rockspec
Normal file
34
rockspecs/evolved.lua-1.1.0-0.rockspec
Normal file
@@ -0,0 +1,34 @@
|
||||
rockspec_format = "3.0"
|
||||
package = "evolved.lua"
|
||||
version = "1.1.0-0"
|
||||
source = {
|
||||
url = "git://github.com/BlackMATov/evolved.lua",
|
||||
tag = "v1.1.0",
|
||||
}
|
||||
description = {
|
||||
homepage = "https://github.com/BlackMATov/evolved.lua",
|
||||
summary = "Evolved ECS (Entity-Component-System) for Lua",
|
||||
detailed = [[
|
||||
`evolved.lua` is a fast and flexible ECS (Entity-Component-System) library for Lua.
|
||||
It is designed to be simple and easy to use, while providing all the features needed to create complex systems with blazing performance.
|
||||
]],
|
||||
license = "MIT",
|
||||
labels = {
|
||||
"ecs",
|
||||
"entity",
|
||||
"entities",
|
||||
"component",
|
||||
"components",
|
||||
"entity-component",
|
||||
"entity-component-system",
|
||||
},
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
evolved = "evolved.lua",
|
||||
}
|
||||
}
|
||||
34
rockspecs/evolved.lua-1.2.0-0.rockspec
Normal file
34
rockspecs/evolved.lua-1.2.0-0.rockspec
Normal file
@@ -0,0 +1,34 @@
|
||||
rockspec_format = "3.0"
|
||||
package = "evolved.lua"
|
||||
version = "1.2.0-0"
|
||||
source = {
|
||||
url = "git://github.com/BlackMATov/evolved.lua",
|
||||
tag = "v1.2.0",
|
||||
}
|
||||
description = {
|
||||
homepage = "https://github.com/BlackMATov/evolved.lua",
|
||||
summary = "Evolved ECS (Entity-Component-System) for Lua",
|
||||
detailed = [[
|
||||
`evolved.lua` is a fast and flexible ECS (Entity-Component-System) library for Lua.
|
||||
It is designed to be simple and easy to use, while providing all the features needed to create complex systems with blazing performance.
|
||||
]],
|
||||
license = "MIT",
|
||||
labels = {
|
||||
"ecs",
|
||||
"entity",
|
||||
"entities",
|
||||
"component",
|
||||
"components",
|
||||
"entity-component",
|
||||
"entity-component-system",
|
||||
},
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
evolved = "evolved.lua",
|
||||
}
|
||||
}
|
||||
34
rockspecs/evolved.lua-1.3.0-0.rockspec
Normal file
34
rockspecs/evolved.lua-1.3.0-0.rockspec
Normal file
@@ -0,0 +1,34 @@
|
||||
rockspec_format = "3.0"
|
||||
package = "evolved.lua"
|
||||
version = "1.3.0-0"
|
||||
source = {
|
||||
url = "git://github.com/BlackMATov/evolved.lua",
|
||||
tag = "v1.3.0",
|
||||
}
|
||||
description = {
|
||||
homepage = "https://github.com/BlackMATov/evolved.lua",
|
||||
summary = "Evolved ECS (Entity-Component-System) for Lua",
|
||||
detailed = [[
|
||||
`evolved.lua` is a fast and flexible ECS (Entity-Component-System) library for Lua.
|
||||
It is designed to be simple and easy to use, while providing all the features needed to create complex systems with blazing performance.
|
||||
]],
|
||||
license = "MIT",
|
||||
labels = {
|
||||
"ecs",
|
||||
"entity",
|
||||
"entities",
|
||||
"component",
|
||||
"components",
|
||||
"entity-component",
|
||||
"entity-component-system",
|
||||
},
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
evolved = "evolved.lua",
|
||||
}
|
||||
}
|
||||
34
rockspecs/evolved.lua-1.4.0-0.rockspec
Normal file
34
rockspecs/evolved.lua-1.4.0-0.rockspec
Normal file
@@ -0,0 +1,34 @@
|
||||
rockspec_format = "3.0"
|
||||
package = "evolved.lua"
|
||||
version = "1.4.0-0"
|
||||
source = {
|
||||
url = "git://github.com/BlackMATov/evolved.lua",
|
||||
tag = "v1.4.0",
|
||||
}
|
||||
description = {
|
||||
homepage = "https://github.com/BlackMATov/evolved.lua",
|
||||
summary = "Evolved ECS (Entity-Component-System) for Lua",
|
||||
detailed = [[
|
||||
`evolved.lua` is a fast and flexible ECS (Entity-Component-System) library for Lua.
|
||||
It is designed to be simple and easy to use, while providing all the features needed to create complex systems with blazing performance.
|
||||
]],
|
||||
license = "MIT",
|
||||
labels = {
|
||||
"ecs",
|
||||
"entity",
|
||||
"entities",
|
||||
"component",
|
||||
"components",
|
||||
"entity-component",
|
||||
"entity-component-system",
|
||||
},
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
evolved = "evolved.lua",
|
||||
}
|
||||
}
|
||||
34
rockspecs/evolved.lua-1.5.0-0.rockspec
Normal file
34
rockspecs/evolved.lua-1.5.0-0.rockspec
Normal file
@@ -0,0 +1,34 @@
|
||||
rockspec_format = "3.0"
|
||||
package = "evolved.lua"
|
||||
version = "1.5.0-0"
|
||||
source = {
|
||||
url = "git://github.com/BlackMATov/evolved.lua",
|
||||
tag = "v1.5.0",
|
||||
}
|
||||
description = {
|
||||
homepage = "https://github.com/BlackMATov/evolved.lua",
|
||||
summary = "Evolved ECS (Entity-Component-System) for Lua",
|
||||
detailed = [[
|
||||
`evolved.lua` is a fast and flexible ECS (Entity-Component-System) library for Lua.
|
||||
It is designed to be simple and easy to use, while providing all the features needed to create complex systems with blazing performance.
|
||||
]],
|
||||
license = "MIT",
|
||||
labels = {
|
||||
"ecs",
|
||||
"entity",
|
||||
"entities",
|
||||
"component",
|
||||
"components",
|
||||
"entity-component",
|
||||
"entity-component-system",
|
||||
},
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
evolved = "evolved.lua",
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user