mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-13 11:38:15 +07:00
Compare commits
51 Commits
feature/sc
...
v1.3.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 2903b077fe | |||
|
|
d3b14a6741 | ||
|
|
fdf5a03a02 | ||
|
|
9221da6ea7 | ||
|
|
0aa57f6b5b | ||
|
|
7e38e43d7c | ||
|
|
b1b627b677 | ||
|
|
281866cf6e | ||
|
|
4ad7fec26d | ||
|
|
f15118be05 | ||
|
|
964ea45f48 | ||
|
|
b2c08e1127 | ||
|
|
2250bd64ce | ||
|
|
e564be46fb | ||
|
|
521ad94278 | ||
|
|
7f6909e48c | ||
|
|
ec745f6ad7 | ||
| 7b6ac89c8a | |||
| 6bf13890ef | |||
| db191b805f | |||
| 5ab963022c | |||
| 7de95207d6 | |||
| 4d3b909efb | |||
| 52b3cbeb20 | |||
| fec193f4f0 | |||
| e672b0291a | |||
| 4624f2e603 | |||
| c25769f64f | |||
| d7274765cb | |||
| ef033e7a0c | |||
| 3638dedca5 | |||
| d025ea039b | |||
|
|
6c0df71f17 | ||
|
|
730bffc3ad | ||
|
|
4bbd7ee60a | ||
|
|
79aecc8db3 | ||
|
|
b803faea63 | ||
|
|
722eda0b9b | ||
|
|
c6def51830 | ||
|
|
65312f79dd | ||
|
|
9877e41705 | ||
|
|
3b8367d5c4 | ||
|
|
419a6b6c45 | ||
|
|
368b50770c | ||
|
|
0d49802235 | ||
|
|
f096d747f3 | ||
|
|
4d88063c10 | ||
|
|
bf135534c0 | ||
|
|
177ea7f180 | ||
|
|
b98b5f9c42 | ||
|
|
c7120e8608 |
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@@ -8,7 +8,6 @@
|
||||
"markdown.extension.toc.levels": "2..6",
|
||||
"markdown.extension.toc.omittedFromToc": {
|
||||
"README.md": [
|
||||
"# Changelog",
|
||||
"# API Reference"
|
||||
]
|
||||
}
|
||||
|
||||
127
README.md
127
README.md
@@ -31,6 +31,7 @@
|
||||
- [Traits](#traits)
|
||||
- [Singletons](#singletons)
|
||||
- [Chunks](#chunks)
|
||||
- [Entity Location](#entity-location)
|
||||
- [Structural Changes](#structural-changes)
|
||||
- [Spawning Entities](#spawning-entities)
|
||||
- [Entity Builders](#entity-builders)
|
||||
@@ -57,6 +58,11 @@
|
||||
- [Classes](#classes)
|
||||
- [Chunk](#chunk)
|
||||
- [Builder](#builder)
|
||||
- [Changelog](#changelog)
|
||||
- [v1.3.0](#v130)
|
||||
- [v1.2.0](#v120)
|
||||
- [v1.1.0](#v110)
|
||||
- [v1.0.0](#v100)
|
||||
- [License](#license)
|
||||
|
||||
## Introduction
|
||||
@@ -360,6 +366,43 @@ end
|
||||
-- Entity: 1048603, Health: 75, Stamina: 40
|
||||
```
|
||||
|
||||
#### Entity Location
|
||||
|
||||
Sometimes it is useful to know which chunk a specific entity is in and its position within that chunk. The [`evolved.locate`](#evolvedlocate) function provides this information.
|
||||
|
||||
```lua
|
||||
---@param entity evolved.entity
|
||||
---@return evolved.chunk? chunk
|
||||
---@return integer place
|
||||
function evolved.locate(entity) end
|
||||
```
|
||||
|
||||
This function takes an entity and returns the chunk that contains it and the entity’s position (index) within that chunk. If the entity is not alive or is empty, the function returns `nil` for the chunk and `0` for the place.
|
||||
|
||||
This is low-level functionality that you will rarely need. However, it can be useful in specific cases. For example, when you need to modify an entity’s component directly to avoid unnecessary [Deferred Operations](#deferred-operations) or [Fragment Hooks](#fragment-hooks), instead of using a higher-level function like [`evolved.set`](#evolvedset).
|
||||
|
||||
```lua
|
||||
local evolved = require 'evolved'
|
||||
|
||||
local health, stamina = evolved.id(2)
|
||||
|
||||
local player = evolved.id()
|
||||
|
||||
evolved.set(player, health, 100)
|
||||
evolved.set(player, stamina, 50)
|
||||
|
||||
local player_chunk, player_place = evolved.locate(player)
|
||||
|
||||
local health_components = player_chunk:components(health)
|
||||
local stamina_components = player_chunk:components(stamina)
|
||||
|
||||
health_components[player_place] = 75
|
||||
stamina_components[player_place] = 42
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Do not use [`evolved.locate`](#evolvedlocate) to manipulate components directly unless you fully understand what you are doing. Because it is low-level functionality, incorrect use can lead to inconsistencies, as it bypasses the library’s safety checks and hook mechanisms. Use it only when you are certain it is safe and necessary.
|
||||
|
||||
### Structural Changes
|
||||
|
||||
Every time we insert or remove a fragment from an entity, the entity will be migrated to a new chunk. This is done automatically by the library, of course. However, you should be aware of this because it can affect performance, especially if you have many fragments on the entity. This is called a `structural change`.
|
||||
@@ -599,6 +642,9 @@ function evolved.defer() end
|
||||
|
||||
---@return boolean committed
|
||||
function evolved.commit() end
|
||||
|
||||
---@return boolean cancelled
|
||||
function evolved.cancel() end
|
||||
```
|
||||
|
||||
The [`evolved.defer`](#evolveddefer) function starts a deferred scope. This means that all changes made inside the scope will be queued and applied after leaving the scope. The [`evolved.commit`](#evolvedcommit) function closes the last deferred scope and applies all queued changes. These functions can be nested, so you can start a new deferred scope inside an existing one. The [`evolved.commit`](#evolvedcommit) function will apply all queued changes only when the last deferred scope is closed.
|
||||
@@ -629,6 +675,34 @@ evolved.commit()
|
||||
assert(not evolved.has(player, poisoned))
|
||||
```
|
||||
|
||||
The [`evolved.cancel`](#evolvedcancel) function can be used to cancel all queued changes in the current deferred scope. This is useful if you want to discard all changes made inside the scope and revert to the previous state on an error or some other condition.
|
||||
|
||||
```lua
|
||||
local evolved = require 'evolved'
|
||||
|
||||
local health, poisoned = evolved.id(2)
|
||||
|
||||
local player = evolved.builder()
|
||||
:set(health, 100)
|
||||
:set(poisoned, true)
|
||||
:spawn()
|
||||
|
||||
-- start a deferred scope
|
||||
evolved.defer()
|
||||
|
||||
-- this removal will be queued, not applied immediately
|
||||
evolved.remove(player, poisoned)
|
||||
|
||||
-- the player still has the poisoned fragment inside the deferred scope
|
||||
assert(evolved.has(player, poisoned))
|
||||
|
||||
-- cancel the deferred operations
|
||||
evolved.cancel()
|
||||
|
||||
-- the poisoned fragment is still there
|
||||
assert(evolved.has(player, poisoned))
|
||||
```
|
||||
|
||||
#### Batch Operations
|
||||
|
||||
The library provides a set of functions for batch operations. These functions are used to perform modifying operations on multiple chunks at once. This is very useful for performance reasons.
|
||||
@@ -839,6 +913,9 @@ evolved.set(player, health, 200) -- prints "health set to 200"
|
||||
|
||||
Use [`evolved.ON_SET`](#evolvedon_set) for callbacks on fragment insert or override, [`evolved.ON_ASSIGN`](#evolvedon_assign) for overrides, and [`evolved.ON_INSERT`](#evolvedon_insert)/[`evolved.ON_REMOVE`](#evolvedon_remove) for insertions or removals.
|
||||
|
||||
> [!NOTE]
|
||||
> Because fragments marked with [`evolved.TAG`](#evolvedtag) (also called [Fragment Tags](#fragment-tags)) have no components, their [`evolved.ON_SET`](#evolvedon_set) hooks are invoked only when the tag is inserted, not when it is overridden, as there is nothing to override. Their [`evolved.ON_ASSIGN`](#evolvedon_assign) hooks are never invoked for such tags for the same reason.
|
||||
|
||||
#### Unique Fragments
|
||||
|
||||
Some fragments should not be cloned when cloning entities. For example, `evolved.lua` has a special fragment called `evolved.PREFAB`, which marks entities used as sources for cloning. This fragment should not be present on the cloned entities. To prevent a fragment from being cloned, mark it as unique using the [`evolved.UNIQUE`](#evolvedunique) fragment trait. This ensures the fragment will not be copied when cloning entities.
|
||||
@@ -1040,7 +1117,7 @@ execute :: {chunk, entity[], integer}
|
||||
prologue :: {}
|
||||
epilogue :: {}
|
||||
|
||||
set_hook :: {entity, fragment, component, component?}
|
||||
set_hook :: {entity, fragment, component, component}
|
||||
assign_hook :: {entity, fragment, component, component}
|
||||
insert_hook :: {entity, fragment, component}
|
||||
remove_hook :: {entity, fragment, component}
|
||||
@@ -1101,6 +1178,7 @@ unpack :: id -> integer, integer
|
||||
|
||||
defer :: boolean
|
||||
commit :: boolean
|
||||
cancel :: boolean
|
||||
|
||||
spawn :: <fragment, component>? -> entity
|
||||
multi_spawn :: integer, <fragment, component>? -> entity[]
|
||||
@@ -1135,6 +1213,8 @@ batch_destroy :: query... -> ()
|
||||
each :: entity -> {each_state? -> fragment?, component?}, each_state?
|
||||
execute :: query -> {execute_state? -> chunk?, entity[]?, integer?}, execute_state?
|
||||
|
||||
locate :: entity -> chunk?, integer
|
||||
|
||||
process :: system... -> ()
|
||||
|
||||
debug_mode :: boolean -> ()
|
||||
@@ -1198,7 +1278,7 @@ builder_mt:include :: fragment... -> builder
|
||||
builder_mt:exclude :: fragment... -> builder
|
||||
builder_mt:require :: fragment... -> builder
|
||||
|
||||
builder_mt:on_set :: {entity, fragment, component, component?} -> builder
|
||||
builder_mt:on_set :: {entity, fragment, component, component} -> builder
|
||||
builder_mt:on_assign :: {entity, fragment, component, component} -> builder
|
||||
builder_mt:on_insert :: {entity, fragment, component} -> builder
|
||||
builder_mt:on_remove :: {entity, fragment} -> builder
|
||||
@@ -1214,31 +1294,37 @@ builder_mt:epilogue :: {} -> builder
|
||||
builder_mt:destruction_policy :: id -> builder
|
||||
```
|
||||
|
||||
## License
|
||||
## Changelog
|
||||
|
||||
`evolved.lua` is licensed under the [MIT License][license]. For more details, see the [LICENSE.md](./LICENSE.md) file in the repository.
|
||||
### v1.3.0
|
||||
|
||||
# Changelog
|
||||
- Added the new [`evolved.cancel`](#evolvedcancel) function
|
||||
- Added the new [`evolved.locate`](#evolvedlocate) function
|
||||
- The internal garbage collector now collects more garbage
|
||||
- Improved system processing debugging experience with stack traces on errors
|
||||
- [`SET/ASSIGN hooks`](#fragment-hooks) are not invoked for tags on override operations anymore
|
||||
- Improved performance of cloning prefabs with many [`Unique Fragments`](#unique-fragments)
|
||||
- Improved performance of builders that are used for spawning multiple times
|
||||
|
||||
## vX.X.X
|
||||
|
||||
- Nothing yet, stay tuned!
|
||||
|
||||
## v1.2.0
|
||||
### v1.2.0
|
||||
|
||||
- Added the new [`evolved.name`](#evolvedname-1) function
|
||||
- Added the new [`evolved.multi_spawn`](#evolvedmulti_spawn) and [`evolved.multi_clone`](#evolvedmulti_clone) functions
|
||||
- Added the new [`evolved.INTERNAL`](#evolvedinternal) fragment trait
|
||||
|
||||
## v1.1.0
|
||||
### v1.1.0
|
||||
|
||||
- [`Systems`](#systems) can be queries themselves now
|
||||
- Added the new [`evolved.REQUIRES`](#evolvedrequires) fragment trait
|
||||
|
||||
## v1.0.0
|
||||
### v1.0.0
|
||||
|
||||
- Initial release
|
||||
|
||||
## License
|
||||
|
||||
`evolved.lua` is licensed under the [MIT License][license]. For more details, see the [LICENSE.md](./LICENSE.md) file in the repository.
|
||||
|
||||
# API Reference
|
||||
|
||||
## Predefs
|
||||
@@ -1345,6 +1431,13 @@ function evolved.defer() end
|
||||
function evolved.commit() end
|
||||
```
|
||||
|
||||
### `evolved.cancel`
|
||||
|
||||
```lua
|
||||
---@return boolean cancelled
|
||||
function evolved.cancel() end
|
||||
```
|
||||
|
||||
### `evolved.spawn`
|
||||
|
||||
```lua
|
||||
@@ -1557,6 +1650,16 @@ function evolved.each(entity) end
|
||||
function evolved.execute(query) end
|
||||
```
|
||||
|
||||
### `evolved.locate`
|
||||
|
||||
```lua
|
||||
---@param entity evolved.entity
|
||||
---@return evolved.chunk? chunk
|
||||
---@return integer place
|
||||
---@nodiscard
|
||||
function evolved.locate(entity) end
|
||||
```
|
||||
|
||||
### `evolved.process`
|
||||
|
||||
```lua
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
|
||||
## Backlog
|
||||
|
||||
- Improve the performance of required fragments by caching first-level required chunks.
|
||||
- Improve the performance of builders that are used multiple times by caching hint chunks.
|
||||
- Queries can cache major chunks to avoid finding them every time.
|
||||
- Add a function to shrink storages to free unused memory.
|
||||
- observers and events
|
||||
- add INDEX fragment trait
|
||||
- use compact prefix-tree for chunks
|
||||
@@ -15,4 +12,7 @@
|
||||
|
||||
- We can return deferred status from modifying operations and spawn/clone methods.
|
||||
- Should we make one builder:build method instead of :spawn and :clone?
|
||||
- Should we cache the result of without_unique_fragments to clone faster?
|
||||
|
||||
## Known Issues
|
||||
|
||||
- Required fragments are slower than they should be
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
require 'develop.samples.systems'
|
||||
|
||||
require 'develop.testing.cancel_tests'
|
||||
require 'develop.testing.locate_tests'
|
||||
require 'develop.testing.multi_spawn_tests'
|
||||
require 'develop.testing.name_tests'
|
||||
require 'develop.testing.requires_fragment_tests'
|
||||
require 'develop.testing.system_as_query_tests'
|
||||
|
||||
require 'develop.benchmarks.multi_clone_bmarks'
|
||||
require 'develop.benchmarks.multi_spawn_bmarks'
|
||||
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'
|
||||
|
||||
require 'develop.untests'
|
||||
|
||||
require 'develop.unbench'
|
||||
require 'develop.usbench'
|
||||
|
||||
local basics = require 'develop.basics'
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
166
develop/benchmarks/clone_bmarks.lua
Normal file
166
develop/benchmarks/clone_bmarks.lua
Normal file
@@ -0,0 +1,166 @@
|
||||
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()
|
||||
|
||||
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()
|
||||
|
||||
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(Q1)
|
||||
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(Q1)
|
||||
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(Q1)
|
||||
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 { [R1] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 { [R3] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 { [R5] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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(Q1)
|
||||
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(Q1)
|
||||
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(Q1)
|
||||
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 { [R1] = true }
|
||||
|
||||
multi_clone(N, prefab)
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 { [R3] = true }
|
||||
|
||||
multi_clone(N, prefab)
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 { [R5] = true }
|
||||
|
||||
multi_clone(N, prefab)
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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)
|
||||
@@ -1,59 +0,0 @@
|
||||
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('Multi 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(Q1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Multi 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(Q1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Multi 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(Q1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Multi 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(Q1)
|
||||
end)
|
||||
@@ -1,59 +0,0 @@
|
||||
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('Multi 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(Q1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Multi 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(Q1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Multi 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(Q1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Multi 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(Q1)
|
||||
end)
|
||||
236
develop/benchmarks/spawn_bmarks.lua
Normal file
236
develop/benchmarks/spawn_bmarks.lua
Normal file
@@ -0,0 +1,236 @@
|
||||
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()
|
||||
|
||||
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()
|
||||
|
||||
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(Q1)
|
||||
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(Q1)
|
||||
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(Q1)
|
||||
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 = { [R1] = true }
|
||||
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end)
|
||||
|
||||
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 }
|
||||
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end)
|
||||
|
||||
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 }
|
||||
|
||||
for _ = 1, N do
|
||||
spawn(components)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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(Q1)
|
||||
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(Q1)
|
||||
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(Q1)
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 1 required component', N),
|
||||
function()
|
||||
local builder = evo.builder():set(R1)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 3 required components', N),
|
||||
function()
|
||||
local builder = evo.builder():set(R3)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end)
|
||||
|
||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 5 required components', N),
|
||||
function()
|
||||
local builder = evo.builder():set(R5)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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(Q1)
|
||||
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(Q1)
|
||||
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(Q1)
|
||||
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(Q1)
|
||||
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 = { [R3] = true }
|
||||
|
||||
multi_spawn(N, components)
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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 = { [R5] = true }
|
||||
|
||||
multi_spawn(N, components)
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
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)
|
||||
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
|
||||
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
|
||||
@@ -1,860 +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()
|
||||
local R1 = evo.builder():require(F1):spawn()
|
||||
local R2 = evo.builder():require(F1, F2):spawn()
|
||||
local R3 = evo.builder():require(F1, F2, F3):spawn()
|
||||
local R4 = evo.builder():require(F1, F2, F3, F4):spawn()
|
||||
local R5 = evo.builder():require(F1, F2, F3, F4, F5):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)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('create and destroy %d entities with 1 requires / spawn', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [R1] = 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 requires / spawn', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [R2] = 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 requires / spawn', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [R3] = 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 requires / spawn', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [R4] = 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 requires / spawn', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local spawn = evo.spawn
|
||||
|
||||
local components = { [R5] = 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 requires / clone', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn({ [R1] = 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 requires / clone', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn({ [R2] = 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 requires / clone', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn({ [R3] = 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 requires / clone', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn({ [R4] = 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 requires / clone', N),
|
||||
---@param entities evolved.id[]
|
||||
function(entities)
|
||||
local clone = evo.clone
|
||||
|
||||
local prefab = evo.spawn({ [R5] = true })
|
||||
|
||||
for i = 1, N do
|
||||
entities[i] = clone(prefab)
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end, function()
|
||||
return {}
|
||||
end)
|
||||
@@ -1525,7 +1525,7 @@ do
|
||||
do
|
||||
last_set_entity = 0
|
||||
evo.set(e, f1, 41)
|
||||
assert(last_set_entity == e)
|
||||
assert(last_set_entity == 0)
|
||||
assert(evo.has(e, f1) and not evo.has(e, f2))
|
||||
assert(evo.get(e, f1) == nil and evo.get(e, f2) == nil)
|
||||
end
|
||||
@@ -1539,13 +1539,13 @@ do
|
||||
do
|
||||
last_set_entity = 0
|
||||
evo.set(e, f1, 42)
|
||||
assert(last_set_entity == e)
|
||||
assert(last_set_entity == 0)
|
||||
assert(evo.has(e, f1) and evo.has(e, f2))
|
||||
assert(evo.get(e, f1) == nil and evo.get(e, f2) == nil)
|
||||
|
||||
last_set_entity = 0
|
||||
evo.set(e, f2, 42)
|
||||
assert(last_set_entity == e)
|
||||
assert(last_set_entity == 0)
|
||||
assert(evo.has(e, f1) and evo.has(e, f2))
|
||||
assert(evo.get(e, f1) == nil and evo.get(e, f2) == nil)
|
||||
end
|
||||
@@ -1559,13 +1559,13 @@ do
|
||||
do
|
||||
last_set_entity = 0
|
||||
evo.set(e, f1, 42)
|
||||
assert(last_set_entity == e)
|
||||
assert(last_set_entity == 0)
|
||||
assert(evo.has(e, f1) and evo.has(e, f2) and evo.has(e, f3))
|
||||
assert(evo.get(e, f1) == nil and evo.get(e, f2) == nil and evo.get(e, f3) == 43)
|
||||
|
||||
last_set_entity = 0
|
||||
evo.set(e, f2, 42)
|
||||
assert(last_set_entity == e)
|
||||
assert(last_set_entity == 0)
|
||||
assert(evo.has(e, f1) and evo.has(e, f2) and evo.has(e, f3))
|
||||
assert(evo.get(e, f1) == nil and evo.get(e, f2) == nil and evo.get(e, f3) == 43)
|
||||
|
||||
@@ -1610,7 +1610,7 @@ do
|
||||
|
||||
last_assign_entity = 0
|
||||
evo.set(e, f1)
|
||||
assert(last_assign_entity == e)
|
||||
assert(last_assign_entity == 0)
|
||||
assert(evo.has(e, f1) and not evo.has(e, f2))
|
||||
assert(evo.get(e, f1) == nil and evo.get(e, f2) == nil)
|
||||
end
|
||||
@@ -1623,7 +1623,7 @@ do
|
||||
|
||||
last_assign_entity = 0
|
||||
evo.set(e, f2, 44)
|
||||
assert(last_assign_entity == e)
|
||||
assert(last_assign_entity == 0)
|
||||
assert(evo.has(e, f1) and evo.has(e, f2))
|
||||
assert(evo.get(e, f1) == nil and evo.get(e, f2) == nil)
|
||||
end
|
||||
@@ -6373,3 +6373,79 @@ do
|
||||
assert(evo.get(e, f) ~= v2_default)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2 = evo.id(2)
|
||||
|
||||
local prefab = evo.builder():prefab():set(f1, 11):set(f2, 22):spawn()
|
||||
|
||||
do
|
||||
local entity = evo.clone(prefab)
|
||||
assert(evo.has(entity, f1) and evo.get(entity, f1) == 11)
|
||||
assert(evo.has(entity, f2) and evo.get(entity, f2) == 22)
|
||||
end
|
||||
|
||||
evo.set(f2, evo.UNIQUE)
|
||||
|
||||
do
|
||||
local entity = evo.clone(prefab)
|
||||
assert(evo.has(entity, f1) and evo.get(entity, f1) == 11)
|
||||
assert(not evo.has(entity, f2) and evo.get(entity, f2) == nil)
|
||||
end
|
||||
|
||||
evo.remove(f2, evo.UNIQUE)
|
||||
|
||||
do
|
||||
local entity = evo.clone(prefab)
|
||||
assert(evo.has(entity, f1) and evo.get(entity, f1) == 11)
|
||||
assert(evo.has(entity, f2) and evo.get(entity, f2) == 22)
|
||||
end
|
||||
|
||||
evo.set(f1, evo.UNIQUE)
|
||||
evo.set(f2, evo.UNIQUE)
|
||||
|
||||
do
|
||||
local entity = evo.clone(prefab)
|
||||
assert(evo.empty(entity))
|
||||
end
|
||||
|
||||
evo.remove(f1, evo.UNIQUE)
|
||||
evo.remove(f2, evo.UNIQUE)
|
||||
|
||||
do
|
||||
local entity = evo.clone(prefab)
|
||||
assert(evo.has(entity, f1) and evo.get(entity, f1) == 11)
|
||||
assert(evo.has(entity, f2) and evo.get(entity, f2) == 22)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
do
|
||||
local f = evo.id()
|
||||
local c = evo.chunk(f)
|
||||
local b = evo.builder():set(f, 42)
|
||||
evo.collect_garbage()
|
||||
local e = b:spawn()
|
||||
assert(evo.locate(e) ~= c)
|
||||
assert(evo.locate(e) == evo.chunk(f))
|
||||
end
|
||||
|
||||
do
|
||||
local f = evo.id()
|
||||
local c = evo.chunk(f)
|
||||
local b = evo.builder():set(f, 42)
|
||||
evo.collect_garbage()
|
||||
local es = b:multi_spawn(5)
|
||||
for i = 1, 5 do
|
||||
assert(evo.locate(es[i]) ~= c)
|
||||
assert(evo.locate(es[i]) == evo.chunk(f))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local ff, ft = evo.id(2)
|
||||
local b = evo.builder():set(ff, false):set(ft, true)
|
||||
assert(b:has_all() and not b:has_any())
|
||||
assert(b:has(ff) and b:has(ft) and b:has_all(ff, ft) and b:has_any(ff, ft))
|
||||
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)
|
||||
644
evolved.lua
644
evolved.lua
File diff suppressed because it is too large
Load Diff
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",
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user