6 Commits

Author SHA1 Message Date
12a720bd9e Merge pull request #31 from BlackMATov/dev
Dev
2025-11-24 13:49:59 +07:00
BlackMATov
5895c6ee8f v1.5.0 2025-11-24 13:45:55 +07:00
BlackMATov
1c02ba5468 little love2d example 2025-11-24 13:35:34 +07:00
BlackMATov
760b477564 update changelog 2025-11-21 06:31:42 +07:00
BlackMATov
fc910881bd cache defaults/duplicates per chunk, use it for spawn/clone ops 2025-11-21 05:37:14 +07:00
BlackMATov
71a7c84a67 add spawn/clone with defaults bmarks 2025-11-20 16:19:13 +07:00
12 changed files with 1027 additions and 525 deletions

View File

@@ -28,6 +28,9 @@
"ignoreDir": [
".vscode",
"develop/3rdparty"
],
"library": [
"${3rd}/love2d/library"
]
}
}

11
.vscode/launch.json vendored
View File

@@ -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"
]
}
]
}

View File

@@ -60,7 +60,7 @@
- [Chunk](#chunk)
- [Builder](#builder)
- [Changelog](#changelog)
- [vX.X.X](#vxxx)
- [v1.5.0](#v150)
- [v1.4.0](#v140)
- [v1.3.0](#v130)
- [v1.2.0](#v120)
@@ -104,7 +104,7 @@ luarocks install evolved.lua
## Quick Start
To get started with `evolved.lua`, read the [Overview](#overview) section to understand the basic concepts and how to use the library. After that, check the [Samples](develop/samples), which demonstrate complex usage of the library. Finally, refer to the [Cheat Sheet](#cheat-sheet) for a quick reference of all the functions and classes provided by the library.
To get started with `evolved.lua`, read the [Overview](#overview) section to understand the basic concepts and how to use the library. After that, check the [Example](example), which demonstrate complex usage of the library. Finally, refer to the [Cheat Sheet](#cheat-sheet) for a quick reference of all the functions and classes provided by the library.
## Overview
@@ -1306,9 +1306,11 @@ builder_mt:destruction_policy :: id -> builder
## Changelog
### vX.X.X
### v1.5.0
- Added basic [Teal](https://github.com/teal-language) type definitions, thanks to [@p0sel0k](https://github.com/p0sel0k)
- Added a little [LÖVE](https://love2d.org) example;
- The spawn and clone operations with defaults have been significantly optimized;
- Added basic [Teal](https://github.com/teal-language) type definitions, thanks to [@p0sel0k](https://github.com/p0sel0k).
### v1.4.0

View File

@@ -11,7 +11,6 @@
- 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.
- We can cache default/duplicate per chunk to speed up entity creation with setup hooks.
## Known Issues

View File

@@ -1,5 +1,3 @@
require 'develop.samples.systems'
require 'develop.testing.build_tests'
require 'develop.testing.cancel_tests'
require 'develop.testing.clone_tests'

View File

@@ -6,16 +6,35 @@ 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)
local Q1 = evo.builder():include(F1):spawn()
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)
local R1 = evo.builder():require(F1):spawn()
local R3 = evo.builder():require(F1, F2, F3):spawn()
local R5 = evo.builder():require(F1, F2, F3, F4, F5):spawn()
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),
basics.describe_bench(
string.format('Clone Benchmarks: Simple Clone | %d entities with 1 component', N),
function()
local clone = evo.clone
@@ -25,10 +44,11 @@ basics.describe_bench(string.format('Clone Benchmarks: Simple Clone | %d entitie
clone(prefab)
end
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 1 component', N),
basics.describe_bench(
string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 1 component', N),
function()
local clone = evo.clone
@@ -40,10 +60,25 @@ basics.describe_bench(string.format('Clone Benchmarks: Simple Defer Clone | %d e
end
evo.commit()
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Simple Clone | %d entities with 3 components', N),
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
@@ -53,10 +88,11 @@ basics.describe_bench(string.format('Clone Benchmarks: Simple Clone | %d entitie
clone(prefab)
end
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 3 components', N),
basics.describe_bench(
string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 3 components', N),
function()
local clone = evo.clone
@@ -68,10 +104,25 @@ basics.describe_bench(string.format('Clone Benchmarks: Simple Defer Clone | %d e
end
evo.commit()
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Simple Clone | %d entities with 5 components', N),
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
@@ -81,10 +132,11 @@ basics.describe_bench(string.format('Clone Benchmarks: Simple Clone | %d entitie
clone(prefab)
end
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 5 components', N),
basics.describe_bench(
string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 5 components', N),
function()
local clone = evo.clone
@@ -96,29 +148,45 @@ basics.describe_bench(string.format('Clone Benchmarks: Simple Defer Clone | %d e
end
evo.commit()
evo.batch_destroy(Q1)
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),
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 { [R1] = true }
local prefab = evo.spawn { [RF1] = true }
for _ = 1, N do
clone(prefab)
end
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 1 required component', N),
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 { [R1] = true }
local prefab = evo.spawn { [RF1] = true }
evo.defer()
for _ = 1, N do
@@ -126,27 +194,43 @@ basics.describe_bench(string.format('Clone Benchmarks: Simple Defer Clone | %d e
end
evo.commit()
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Simple Clone | %d entities with 3 required components', N),
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 { [R3] = true }
local prefab = evo.spawn { [RD1] = true }
for _ = 1, N do
clone(prefab)
end
evo.batch_destroy(Q1)
evo.batch_destroy(QD1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 3 required components', N),
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 { [R3] = true }
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
@@ -154,27 +238,43 @@ basics.describe_bench(string.format('Clone Benchmarks: Simple Defer Clone | %d e
end
evo.commit()
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Simple Clone | %d entities with 5 required components', N),
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 { [R5] = true }
local prefab = evo.spawn { [RD123] = true }
for _ = 1, N do
clone(prefab)
end
evo.batch_destroy(Q1)
evo.batch_destroy(QD1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 5 required components', N),
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 { [R5] = true }
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
@@ -182,12 +282,27 @@ basics.describe_bench(string.format('Clone Benchmarks: Simple Defer Clone | %d e
end
evo.commit()
evo.batch_destroy(Q1)
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),
basics.describe_bench(
string.format('Clone Benchmarks: Multi Clone | %d entities with 1 component', N),
function()
local multi_clone = evo.multi_clone
@@ -195,10 +310,11 @@ basics.describe_bench(string.format('Clone Benchmarks: Multi Clone | %d entities
multi_clone(N, prefab)
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 1 component', N),
basics.describe_bench(
string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 1 component', N),
function()
local multi_clone = evo.multi_clone
@@ -208,10 +324,23 @@ basics.describe_bench(string.format('Clone Benchmarks: Multi Defer Clone | %d en
multi_clone(N, prefab)
evo.commit()
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Multi Clone | %d entities with 3 components', N),
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
@@ -219,10 +348,11 @@ basics.describe_bench(string.format('Clone Benchmarks: Multi Clone | %d entities
multi_clone(N, prefab)
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 3 components', N),
basics.describe_bench(
string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 3 components', N),
function()
local multi_clone = evo.multi_clone
@@ -232,10 +362,23 @@ basics.describe_bench(string.format('Clone Benchmarks: Multi Defer Clone | %d en
multi_clone(N, prefab)
evo.commit()
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Multi Clone | %d entities with 5 components', N),
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
@@ -243,10 +386,11 @@ basics.describe_bench(string.format('Clone Benchmarks: Multi Clone | %d entities
multi_clone(N, prefab)
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 5 components', N),
basics.describe_bench(
string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 5 components', N),
function()
local multi_clone = evo.multi_clone
@@ -256,79 +400,133 @@ basics.describe_bench(string.format('Clone Benchmarks: Multi Defer Clone | %d en
multi_clone(N, prefab)
evo.commit()
evo.batch_destroy(Q1)
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),
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 { [R1] = true }
local prefab = evo.spawn { [RF1] = true }
multi_clone(N, prefab)
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 1 required component', N),
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 { [R1] = true }
local prefab = evo.spawn { [RF1] = true }
evo.defer()
multi_clone(N, prefab)
evo.commit()
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Multi Clone | %d entities with 3 required components', N),
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 { [R3] = true }
local prefab = evo.spawn { [RD1] = true }
multi_clone(N, prefab)
evo.batch_destroy(Q1)
evo.batch_destroy(QD1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 3 required components', N),
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 { [R3] = true }
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(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Multi Clone | %d entities with 5 required components', N),
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 { [R5] = true }
local prefab = evo.spawn { [RD123] = true }
multi_clone(N, prefab)
evo.batch_destroy(Q1)
evo.batch_destroy(QD1)
end)
basics.describe_bench(string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 5 required components', N),
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 { [R5] = true }
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(Q1)
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)

View File

@@ -6,16 +6,35 @@ 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)
local Q1 = evo.builder():include(F1):spawn()
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)
local R1 = evo.builder():require(F1):spawn()
local R3 = evo.builder():require(F1, F2, F3):spawn()
local R5 = evo.builder():require(F1, F2, F3, F4, F5):spawn()
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),
basics.describe_bench(
string.format('Spawn Benchmarks: Simple Spawn | %d entities with 1 component', N),
function()
local spawn = evo.spawn
@@ -25,10 +44,11 @@ basics.describe_bench(string.format('Spawn Benchmarks: Simple Spawn | %d entitie
spawn(components)
end
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 1 component', N),
basics.describe_bench(
string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 1 component', N),
function()
local spawn = evo.spawn
@@ -40,10 +60,25 @@ basics.describe_bench(string.format('Spawn Benchmarks: Simple Defer Spawn | %d e
end
evo.commit()
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Simple Spawn | %d entities with 3 components', N),
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
@@ -53,10 +88,11 @@ basics.describe_bench(string.format('Spawn Benchmarks: Simple Spawn | %d entitie
spawn(components)
end
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 3 components', N),
basics.describe_bench(
string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 3 components', N),
function()
local spawn = evo.spawn
@@ -68,10 +104,25 @@ basics.describe_bench(string.format('Spawn Benchmarks: Simple Defer Spawn | %d e
end
evo.commit()
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Simple Spawn | %d entities with 5 components', N),
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
@@ -81,10 +132,11 @@ basics.describe_bench(string.format('Spawn Benchmarks: Simple Spawn | %d entitie
spawn(components)
end
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 5 components', N),
basics.describe_bench(
string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 5 components', N),
function()
local spawn = evo.spawn
@@ -96,29 +148,45 @@ basics.describe_bench(string.format('Spawn Benchmarks: Simple Defer Spawn | %d e
end
evo.commit()
evo.batch_destroy(Q1)
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),
basics.describe_bench(
string.format('Spawn Benchmarks: Simple Spawn | %d entities with 1 required component', N),
function()
local spawn = evo.spawn
local components = { [R1] = true }
local components = { [RF1] = true }
for _ = 1, N do
spawn(components)
end
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 1 required component', N),
basics.describe_bench(
string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 1 required component', N),
function()
local spawn = evo.spawn
local components = { [R1] = true }
local components = { [RF1] = true }
evo.defer()
for _ = 1, N do
@@ -126,27 +194,43 @@ basics.describe_bench(string.format('Spawn Benchmarks: Simple Defer Spawn | %d e
end
evo.commit()
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Simple Spawn | %d entities with 3 required components', N),
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 = { [R3] = true }
local components = { [RD1] = true }
for _ = 1, N do
spawn(components)
end
evo.batch_destroy(Q1)
evo.batch_destroy(QD1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 3 required components', N),
basics.describe_bench(
string.format('Spawn Benchmarks: Simple Spawn | %d entities with 3 required components', N),
function()
local spawn = evo.spawn
local components = { [R3] = true }
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
@@ -154,27 +238,43 @@ basics.describe_bench(string.format('Spawn Benchmarks: Simple Defer Spawn | %d e
end
evo.commit()
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Simple Spawn | %d entities with 5 required components', N),
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 = { [R5] = true }
local components = { [RD123] = true }
for _ = 1, N do
spawn(components)
end
evo.batch_destroy(Q1)
evo.batch_destroy(QD1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 5 required components', N),
basics.describe_bench(
string.format('Spawn Benchmarks: Simple Spawn | %d entities with 5 required components', N),
function()
local spawn = evo.spawn
local components = { [R5] = true }
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
@@ -182,12 +282,27 @@ basics.describe_bench(string.format('Spawn Benchmarks: Simple Defer Spawn | %d e
end
evo.commit()
evo.batch_destroy(Q1)
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),
basics.describe_bench(
string.format('Spawn Benchmarks: Builder Spawn | %d entities with 1 component', N),
function()
local builder = evo.builder():set(F1)
@@ -195,10 +310,11 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entiti
builder:spawn()
end
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 1 component', N),
basics.describe_bench(
string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 1 component', N),
function()
local builder = evo.builder():set(F1)
@@ -208,10 +324,23 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Defer Spawn | %d
end
evo.commit()
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 3 components', N),
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)
@@ -219,10 +348,11 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entiti
builder:spawn()
end
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 3 components', N),
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)
@@ -232,10 +362,23 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Defer Spawn | %d
end
evo.commit()
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 5 components', N),
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)
@@ -243,10 +386,11 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entiti
builder:spawn()
end
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 5 components', N),
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)
@@ -256,25 +400,39 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Defer Spawn | %d
end
evo.commit()
evo.batch_destroy(Q1)
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),
basics.describe_bench(
string.format('Spawn Benchmarks: Builder Spawn | %d entities with 1 required component', N),
function()
local builder = evo.builder():set(R1)
local builder = evo.builder():set(RF1)
for _ = 1, N do
builder:spawn()
end
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 1 required component', N),
basics.describe_bench(
string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 1 required component', N),
function()
local builder = evo.builder():set(R1)
local builder = evo.builder():set(RF1)
evo.defer()
for _ = 1, N do
@@ -282,23 +440,37 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Defer Spawn | %d
end
evo.commit()
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 3 required components', N),
basics.describe_bench(
string.format('Spawn Benchmarks: Builder Spawn With Defaults | %d entities with 1 required component', N),
function()
local builder = evo.builder():set(R3)
local builder = evo.builder():set(RD1)
for _ = 1, N do
builder:spawn()
end
evo.batch_destroy(Q1)
evo.batch_destroy(QD1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 3 required components', N),
basics.describe_bench(
string.format('Spawn Benchmarks: Builder Spawn | %d entities with 3 required components', N),
function()
local builder = evo.builder():set(R3)
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
@@ -306,23 +478,37 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Defer Spawn | %d
end
evo.commit()
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 5 required components', N),
basics.describe_bench(
string.format('Spawn Benchmarks: Builder Spawn With Defaults | %d entities with 3 required components', N),
function()
local builder = evo.builder():set(R5)
local builder = evo.builder():set(RD123)
for _ = 1, N do
builder:spawn()
end
evo.batch_destroy(Q1)
evo.batch_destroy(QD1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 5 required components', N),
basics.describe_bench(
string.format('Spawn Benchmarks: Builder Spawn | %d entities with 5 required components', N),
function()
local builder = evo.builder():set(R5)
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
@@ -330,12 +516,25 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Defer Spawn | %d
end
evo.commit()
evo.batch_destroy(Q1)
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),
basics.describe_bench(
string.format('Spawn Benchmarks: Multi Spawn | %d entities with 1 component', N),
function()
local multi_spawn = evo.multi_spawn
@@ -343,10 +542,11 @@ basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities
multi_spawn(N, components)
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 1 component', N),
basics.describe_bench(
string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 1 component', N),
function()
local multi_spawn = evo.multi_spawn
@@ -356,10 +556,23 @@ basics.describe_bench(string.format('Spawn Benchmarks: Multi Defer Spawn | %d en
multi_spawn(N, components)
evo.commit()
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities with 3 components', N),
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
@@ -367,10 +580,11 @@ basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities
multi_spawn(N, components)
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 3 components', N),
basics.describe_bench(
string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 3 components', N),
function()
local multi_spawn = evo.multi_spawn
@@ -380,10 +594,23 @@ basics.describe_bench(string.format('Spawn Benchmarks: Multi Defer Spawn | %d en
multi_spawn(N, components)
evo.commit()
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities with 5 components', N),
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
@@ -391,10 +618,11 @@ basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities
multi_spawn(N, components)
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 5 components', N),
basics.describe_bench(
string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 5 components', N),
function()
local multi_spawn = evo.multi_spawn
@@ -404,12 +632,25 @@ basics.describe_bench(string.format('Spawn Benchmarks: Multi Defer Spawn | %d en
multi_spawn(N, components)
evo.commit()
evo.batch_destroy(Q1)
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),
basics.describe_bench(
string.format('Spawn Benchmarks: Multi Spawn | %d entities with 1 required component', N),
function()
local multi_spawn = evo.multi_spawn
@@ -417,10 +658,11 @@ basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities
multi_spawn(N, components)
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 1 required component', N),
basics.describe_bench(
string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 1 required component', N),
function()
local multi_spawn = evo.multi_spawn
@@ -430,53 +672,93 @@ basics.describe_bench(string.format('Spawn Benchmarks: Multi Defer Spawn | %d en
multi_spawn(N, components)
evo.commit()
evo.batch_destroy(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities with 3 required components', N),
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 = { [R3] = true }
local components = { [D1] = true }
multi_spawn(N, components)
evo.batch_destroy(Q1)
evo.batch_destroy(QD1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 3 required components', N),
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 = { [R3] = true }
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(Q1)
evo.batch_destroy(QF1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities with 5 required components', N),
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 = { [R5] = true }
local components = { [RD123] = true }
multi_spawn(N, components)
evo.batch_destroy(Q1)
evo.batch_destroy(QD1)
end)
basics.describe_bench(string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 5 required components', N),
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 = { [R5] = true }
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(Q1)
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)

View File

@@ -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

View File

@@ -1,7 +1,7 @@
local evolved = {
__HOMEPAGE = 'https://github.com/BlackMATov/evolved.lua',
__DESCRIPTION = 'Evolved ECS (Entity-Component-System) for Lua',
__VERSION = '1.4.0',
__VERSION = '1.5.0',
__LICENSE = [[
MIT License
@@ -162,6 +162,8 @@ local __group_subsystems = {} ---@type table<evolved.system, evolved.assoc_list<
---@field package __component_indices table<evolved.fragment, integer>
---@field package __component_storages evolved.storage[]
---@field package __component_fragments evolved.fragment[]
---@field package __component_defaults evolved.default[]
---@field package __component_duplicates evolved.duplicate[]
---@field package __with_fragment_edges table<evolved.fragment, evolved.chunk>
---@field package __without_fragment_edges table<evolved.fragment, evolved.chunk>
---@field package __without_unique_fragments? evolved.chunk
@@ -997,6 +999,8 @@ function __new_chunk(chunk_parent, chunk_fragment)
__component_indices = {},
__component_storages = {},
__component_fragments = {},
__component_defaults = {},
__component_duplicates = {},
__with_fragment_edges = {},
__without_fragment_edges = {},
__without_unique_fragments = nil,
@@ -1158,26 +1162,38 @@ function __update_chunk_storages(chunk)
local component_indices = chunk.__component_indices
local component_storages = chunk.__component_storages
local component_fragments = chunk.__component_fragments
local component_defaults = chunk.__component_defaults
local component_duplicates = chunk.__component_duplicates
for fragment_index = 1, fragment_count do
local fragment = fragment_list[fragment_index]
local component_index = component_indices[fragment]
---@type evolved.default?, evolved.duplicate?
local fragment_default, fragment_duplicate =
__evolved_get(fragment, __DEFAULT, __DUPLICATE)
local is_fragment_tag = __evolved_has(fragment, __TAG)
if component_index and is_fragment_tag then
if component_index ~= component_count then
local last_component_storage = component_storages[component_count]
local last_component_fragment = component_fragments[component_count]
local last_component_default = component_defaults[component_count]
local last_component_duplicate = component_duplicates[component_count]
component_indices[last_component_fragment] = component_index
component_storages[component_index] = last_component_storage
component_fragments[component_index] = last_component_fragment
component_defaults[component_index] = last_component_default
component_duplicates[component_index] = last_component_duplicate
end
component_indices[fragment] = nil
component_storages[component_count] = nil
component_fragments[component_count] = nil
component_defaults[component_count] = nil
component_duplicates[component_count] = nil
component_count = component_count - 1
chunk.__component_count = component_count
@@ -1191,10 +1207,8 @@ function __update_chunk_storages(chunk)
component_indices[fragment] = component_storage_index
component_storages[component_storage_index] = component_storage
component_fragments[component_storage_index] = fragment
---@type evolved.default?, evolved.duplicate?
local fragment_default, fragment_duplicate =
__evolved_get(fragment, __DEFAULT, __DUPLICATE)
component_defaults[component_storage_index] = fragment_default
component_duplicates[component_storage_index] = fragment_duplicate
if fragment_duplicate then
for place = 1, entity_count do
@@ -1210,6 +1224,9 @@ function __update_chunk_storages(chunk)
component_storage[place] = new_component
end
end
elseif component_index then
component_defaults[component_index] = fragment_default
component_duplicates[component_index] = fragment_duplicate
end
end
end
@@ -2032,6 +2049,8 @@ function __spawn_entity(chunk, entity, components)
local chunk_component_indices = chunk.__component_indices
local chunk_component_storages = chunk.__component_storages
local chunk_component_fragments = chunk.__component_fragments
local chunk_component_defaults = chunk.__component_defaults
local chunk_component_duplicates = chunk.__component_duplicates
local place = chunk_entity_count + 1
@@ -2046,44 +2065,26 @@ function __spawn_entity(chunk, entity, components)
__entity_places[entity_primary] = place
end
if chunk.__has_setup_hooks then
for component_index = 1, chunk_component_count do
local component_storage = chunk_component_storages[component_index]
local component_fragment = chunk_component_fragments[component_index]
for component_index = 1, chunk_component_count do
local component_storage = chunk_component_storages[component_index]
local component_fragment = chunk_component_fragments[component_index]
local component_duplicate = chunk_component_duplicates[component_index]
---@type evolved.default?, evolved.duplicate?
local fragment_default, fragment_duplicate =
__evolved_get(component_fragment, __DEFAULT, __DUPLICATE)
local ini_component = components[component_fragment]
local ini_component = components[component_fragment]
if ini_component == nil then
ini_component = fragment_default
end
if ini_component ~= nil and fragment_duplicate then
local new_component = fragment_duplicate(ini_component)
if new_component == nil then
new_component = true
end
component_storage[place] = new_component
else
if ini_component == nil then
ini_component = true
end
component_storage[place] = ini_component
end
if ini_component == nil then
ini_component = chunk_component_defaults[component_index]
end
else
for component_index = 1, chunk_component_count do
local component_storage = chunk_component_storages[component_index]
local component_fragment = chunk_component_fragments[component_index]
local ini_component = components[component_fragment]
if ini_component ~= nil and component_duplicate then
local new_component = component_duplicate(ini_component)
if new_component == nil then
new_component = true
end
component_storage[place] = new_component
else
if ini_component == nil then
ini_component = true
end
@@ -2103,27 +2104,29 @@ function __spawn_entity(chunk, entity, components)
local fragment_on_set, fragment_on_insert =
__evolved_get(fragment, __ON_SET, __ON_INSERT)
local component_index = chunk_component_indices[fragment]
if fragment_on_set or fragment_on_insert then
local component_index = chunk_component_indices[fragment]
if component_index then
local component_storage = chunk_component_storages[component_index]
if component_index then
local component_storage = chunk_component_storages[component_index]
local new_component = component_storage[place]
local new_component = component_storage[place]
if fragment_on_set then
fragment_on_set(entity, fragment, new_component)
end
if fragment_on_set then
fragment_on_set(entity, fragment, new_component)
end
if fragment_on_insert then
fragment_on_insert(entity, fragment, new_component)
end
else
if fragment_on_set then
fragment_on_set(entity, fragment)
end
if fragment_on_insert then
fragment_on_insert(entity, fragment, new_component)
end
else
if fragment_on_set then
fragment_on_set(entity, fragment)
end
if fragment_on_insert then
fragment_on_insert(entity, fragment)
if fragment_on_insert then
fragment_on_insert(entity, fragment)
end
end
end
end
@@ -2182,6 +2185,8 @@ function __multi_spawn_entity(chunk, entity_list, entity_count, components)
local chunk_component_indices = chunk.__component_indices
local chunk_component_storages = chunk.__component_storages
local chunk_component_fragments = chunk.__component_fragments
local chunk_component_defaults = chunk.__component_defaults
local chunk_component_duplicates = chunk.__component_duplicates
local b_place = chunk_entity_count + 1
local e_place = chunk_entity_count + entity_count
@@ -2203,48 +2208,28 @@ function __multi_spawn_entity(chunk, entity_list, entity_count, components)
end
end
if chunk.__has_setup_hooks then
for component_index = 1, chunk_component_count do
local component_storage = chunk_component_storages[component_index]
local component_fragment = chunk_component_fragments[component_index]
for component_index = 1, chunk_component_count do
local component_storage = chunk_component_storages[component_index]
local component_fragment = chunk_component_fragments[component_index]
local component_duplicate = chunk_component_duplicates[component_index]
---@type evolved.default?, evolved.duplicate?
local fragment_default, fragment_duplicate =
__evolved_get(component_fragment, __DEFAULT, __DUPLICATE)
local ini_component = components[component_fragment]
local ini_component = components[component_fragment]
if ini_component == nil then
ini_component = fragment_default
end
if ini_component ~= nil and fragment_duplicate then
for place = b_place, e_place do
local new_component = fragment_duplicate(ini_component)
if new_component == nil then
new_component = true
end
component_storage[place] = new_component
end
else
if ini_component == nil then
ini_component = true
end
for place = b_place, e_place do
component_storage[place] = ini_component
end
end
if ini_component == nil then
ini_component = chunk_component_defaults[component_index]
end
else
for component_index = 1, chunk_component_count do
local component_storage = chunk_component_storages[component_index]
local component_fragment = chunk_component_fragments[component_index]
local ini_component = components[component_fragment]
if ini_component ~= nil and component_duplicate then
for place = b_place, e_place do
local new_component = component_duplicate(ini_component)
if new_component == nil then
new_component = true
end
component_storage[place] = new_component
end
else
if ini_component == nil then
ini_component = true
end
@@ -2266,12 +2251,12 @@ function __multi_spawn_entity(chunk, entity_list, entity_count, components)
local fragment_on_set, fragment_on_insert =
__evolved_get(fragment, __ON_SET, __ON_INSERT)
local component_index = chunk_component_indices[fragment]
if fragment_on_set or fragment_on_insert then
local component_index = chunk_component_indices[fragment]
if component_index then
local component_storage = chunk_component_storages[component_index]
if component_index then
local component_storage = chunk_component_storages[component_index]
if fragment_on_set or fragment_on_insert then
for place = b_place, e_place do
local entity = chunk_entity_list[place]
@@ -2286,10 +2271,6 @@ function __multi_spawn_entity(chunk, entity_list, entity_count, components)
end
end
else
-- nothing
end
else
if fragment_on_set or fragment_on_insert then
for place = b_place, e_place do
local entity = chunk_entity_list[place]
@@ -2301,8 +2282,6 @@ function __multi_spawn_entity(chunk, entity_list, entity_count, components)
fragment_on_insert(entity, fragment)
end
end
else
-- nothing
end
end
end
@@ -2370,6 +2349,8 @@ function __clone_entity(prefab, entity, components)
local chunk_component_indices = chunk.__component_indices
local chunk_component_storages = chunk.__component_storages
local chunk_component_fragments = chunk.__component_fragments
local chunk_component_defaults = chunk.__component_defaults
local chunk_component_duplicates = chunk.__component_duplicates
local prefab_component_indices = prefab_chunk.__component_indices
local prefab_component_storages = prefab_chunk.__component_storages
@@ -2387,66 +2368,38 @@ function __clone_entity(prefab, entity, components)
__entity_places[entity_primary] = place
end
if chunk.__has_setup_hooks then
for component_index = 1, chunk_component_count do
local component_storage = chunk_component_storages[component_index]
local component_fragment = chunk_component_fragments[component_index]
for component_index = 1, chunk_component_count do
local component_storage = chunk_component_storages[component_index]
local component_fragment = chunk_component_fragments[component_index]
local component_duplicate = chunk_component_duplicates[component_index]
---@type evolved.default?, evolved.duplicate?
local fragment_default, fragment_duplicate =
__evolved_get(component_fragment, __DEFAULT, __DUPLICATE)
local ini_component = components[component_fragment]
local ini_component = components[component_fragment]
if ini_component == nil then
if chunk == prefab_chunk then
ini_component = component_storage[prefab_place]
else
local prefab_component_index = prefab_component_indices[component_fragment]
if prefab_component_index then
local prefab_component_storage = prefab_component_storages[prefab_component_index]
ini_component = prefab_component_storage[prefab_place]
else
ini_component = fragment_default
end
end
end
if ini_component ~= nil and fragment_duplicate then
local new_component = fragment_duplicate(ini_component)
if new_component == nil then
new_component = true
end
component_storage[place] = new_component
if ini_component == nil then
if chunk == prefab_chunk then
ini_component = component_storage[prefab_place]
else
if ini_component == nil then
ini_component = true
local prefab_component_index = prefab_component_indices[component_fragment]
if prefab_component_index then
local prefab_component_storage = prefab_component_storages[prefab_component_index]
ini_component = prefab_component_storage[prefab_place]
else
ini_component = chunk_component_defaults[component_index]
end
component_storage[place] = ini_component
end
end
else
for component_index = 1, chunk_component_count do
local component_storage = chunk_component_storages[component_index]
local component_fragment = chunk_component_fragments[component_index]
local ini_component = components[component_fragment]
if ini_component ~= nil and component_duplicate then
local new_component = component_duplicate(ini_component)
if new_component == nil then
new_component = true
end
component_storage[place] = new_component
else
if ini_component == nil then
if chunk == prefab_chunk then
ini_component = component_storage[prefab_place]
else
local prefab_component_index = prefab_component_indices[component_fragment]
if prefab_component_index then
local prefab_component_storage = prefab_component_storages[prefab_component_index]
ini_component = prefab_component_storage[prefab_place]
else
ini_component = true
end
end
ini_component = true
end
component_storage[place] = ini_component
@@ -2464,27 +2417,29 @@ function __clone_entity(prefab, entity, components)
local fragment_on_set, fragment_on_insert =
__evolved_get(fragment, __ON_SET, __ON_INSERT)
local component_index = chunk_component_indices[fragment]
if fragment_on_set or fragment_on_insert then
local component_index = chunk_component_indices[fragment]
if component_index then
local component_storage = chunk_component_storages[component_index]
if component_index then
local component_storage = chunk_component_storages[component_index]
local new_component = component_storage[place]
local new_component = component_storage[place]
if fragment_on_set then
fragment_on_set(entity, fragment, new_component)
end
if fragment_on_set then
fragment_on_set(entity, fragment, new_component)
end
if fragment_on_insert then
fragment_on_insert(entity, fragment, new_component)
end
else
if fragment_on_set then
fragment_on_set(entity, fragment)
end
if fragment_on_insert then
fragment_on_insert(entity, fragment, new_component)
end
else
if fragment_on_set then
fragment_on_set(entity, fragment)
end
if fragment_on_insert then
fragment_on_insert(entity, fragment)
if fragment_on_insert then
fragment_on_insert(entity, fragment)
end
end
end
end
@@ -2553,6 +2508,8 @@ function __multi_clone_entity(prefab, entity_list, entity_count, components)
local chunk_component_indices = chunk.__component_indices
local chunk_component_storages = chunk.__component_storages
local chunk_component_fragments = chunk.__component_fragments
local chunk_component_defaults = chunk.__component_defaults
local chunk_component_duplicates = chunk.__component_duplicates
local prefab_component_indices = prefab_chunk.__component_indices
local prefab_component_storages = prefab_chunk.__component_storages
@@ -2577,70 +2534,40 @@ function __multi_clone_entity(prefab, entity_list, entity_count, components)
end
end
if chunk.__has_setup_hooks then
for component_index = 1, chunk_component_count do
local component_storage = chunk_component_storages[component_index]
local component_fragment = chunk_component_fragments[component_index]
for component_index = 1, chunk_component_count do
local component_storage = chunk_component_storages[component_index]
local component_fragment = chunk_component_fragments[component_index]
local component_duplicate = chunk_component_duplicates[component_index]
---@type evolved.default?, evolved.duplicate?
local fragment_default, fragment_duplicate =
__evolved_get(component_fragment, __DEFAULT, __DUPLICATE)
local ini_component = components[component_fragment]
local ini_component = components[component_fragment]
if ini_component == nil then
if chunk == prefab_chunk then
ini_component = component_storage[prefab_place]
else
local prefab_component_index = prefab_component_indices[component_fragment]
if prefab_component_index then
local prefab_component_storage = prefab_component_storages[prefab_component_index]
ini_component = prefab_component_storage[prefab_place]
else
ini_component = fragment_default
end
end
end
if ini_component ~= nil and fragment_duplicate then
for place = b_place, e_place do
local new_component = fragment_duplicate(ini_component)
if new_component == nil then
new_component = true
end
component_storage[place] = new_component
end
if ini_component == nil then
if chunk == prefab_chunk then
ini_component = component_storage[prefab_place]
else
if ini_component == nil then
ini_component = true
end
for place = b_place, e_place do
component_storage[place] = ini_component
local prefab_component_index = prefab_component_indices[component_fragment]
if prefab_component_index then
local prefab_component_storage = prefab_component_storages[prefab_component_index]
ini_component = prefab_component_storage[prefab_place]
else
ini_component = chunk_component_defaults[component_index]
end
end
end
else
for component_index = 1, chunk_component_count do
local component_storage = chunk_component_storages[component_index]
local component_fragment = chunk_component_fragments[component_index]
local ini_component = components[component_fragment]
if ini_component ~= nil and component_duplicate then
for place = b_place, e_place do
local new_component = component_duplicate(ini_component)
if ini_component == nil then
if chunk == prefab_chunk then
ini_component = component_storage[prefab_place]
else
local prefab_component_index = prefab_component_indices[component_fragment]
if prefab_component_index then
local prefab_component_storage = prefab_component_storages[prefab_component_index]
ini_component = prefab_component_storage[prefab_place]
else
ini_component = true
end
if new_component == nil then
new_component = true
end
component_storage[place] = new_component
end
else
if ini_component == nil then
ini_component = true
end
for place = b_place, e_place do
@@ -2660,12 +2587,12 @@ function __multi_clone_entity(prefab, entity_list, entity_count, components)
local fragment_on_set, fragment_on_insert =
__evolved_get(fragment, __ON_SET, __ON_INSERT)
local component_index = chunk_component_indices[fragment]
if fragment_on_set or fragment_on_insert then
local component_index = chunk_component_indices[fragment]
if component_index then
local component_storage = chunk_component_storages[component_index]
if component_index then
local component_storage = chunk_component_storages[component_index]
if fragment_on_set or fragment_on_insert then
for place = b_place, e_place do
local entity = chunk_entity_list[place]
@@ -2680,10 +2607,6 @@ function __multi_clone_entity(prefab, entity_list, entity_count, components)
end
end
else
-- nothing
end
else
if fragment_on_set or fragment_on_insert then
for place = b_place, e_place do
local entity = chunk_entity_list[place]
@@ -2695,8 +2618,6 @@ function __multi_clone_entity(prefab, entity_list, entity_count, components)
fragment_on_insert(entity, fragment)
end
end
else
-- nothing
end
end
end

10
example/conf.lua Normal file
View 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
View 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

View 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",
}
}