71 Commits

Author SHA1 Message Date
2903b077fe Merge pull request #24 from BlackMATov/dev
Dev
2025-09-26 17:30:35 +07:00
BlackMATov
d3b14a6741 v1.3.0 2025-09-26 17:27:49 +07:00
BlackMATov
fdf5a03a02 improve performance of builders that are used for spawning multiple times 2025-09-26 17:21:50 +07:00
BlackMATov
9221da6ea7 slightly improve required fragments perf 2025-09-24 18:16:01 +07:00
BlackMATov
0aa57f6b5b benchmarks refactoring 2 2025-09-24 00:51:25 +07:00
BlackMATov
7e38e43d7c benchmarks refactoring 2025-09-23 17:37:29 +07:00
BlackMATov
b1b627b677 improve perf of cloning prefabs with many unique fragments 2025-09-23 07:53:11 +07:00
BlackMATov
281866cf6e set/assign hooks are not invoked for tags on override operations anymore 2025-09-23 07:24:26 +07:00
BlackMATov
4ad7fec26d update readme 2025-09-23 05:05:30 +07:00
BlackMATov
f15118be05 the new evolved.locate public function
ref: #23
2025-09-23 04:58:10 +07:00
BlackMATov
964ea45f48 use xpcall to process systems 2025-09-22 21:27:57 +07:00
BlackMATov
b2c08e1127 cancel deferring ops in systems on error 2025-09-22 05:51:21 +07:00
BlackMATov
2250bd64ce the new evolved.cancel public function 2025-09-22 02:34:37 +07:00
BlackMATov
e564be46fb collect garbage from old bytecode 2025-09-22 01:56:08 +07:00
BlackMATov
521ad94278 the internal garbage collector now collects more garbage 2025-09-20 03:11:12 +07:00
BlackMATov
7f6909e48c remove some unused code about pinned chunks 2025-09-20 01:53:29 +07:00
BlackMATov
ec745f6ad7 Merge branch 'feature/schemes' into dev 2025-09-19 19:51:02 +07:00
BlackMATov
b3eec59f8b update readme 2025-09-19 19:50:50 +07:00
BlackMATov
1635dd66b1 remove schemes temporary 2025-09-19 18:58:18 +07:00
BlackMATov
b420085ed5 proof of concept ffi component storages
fast batch ops storage swapping was temporary removed
2025-09-19 07:04:19 +07:00
BlackMATov
6d5f810d45 experimental scheme creation 2025-09-15 17:56:44 +07:00
BlackMATov
5447f50090 dummy SCHEME class and readme 2025-09-12 05:58:41 +07:00
BlackMATov
e6d79dc600 Merge branch 'dev' into feature/schemes 2025-09-12 05:45:33 +07:00
7b6ac89c8a Merge pull request #21 from BlackMATov/dev
Dev
2025-09-12 05:30:07 +07:00
BlackMATov
91b3910eda v1.2.0 2025-09-12 05:27:17 +07:00
BlackMATov
7f5ac62a79 Merge branch 'feature/multi_spawn' into dev 2025-09-12 05:13:55 +07:00
BlackMATov
327a6bcbce final tweaks of the multi_spawn/clone functions 2025-09-12 05:11:29 +07:00
BlackMATov
5184b39f4e proof of concept multi_clone/spawn optimizations 2025-09-12 01:52:33 +07:00
BlackMATov
de7d1a6674 dirty proof of concept multi_spawn impl (without any optimization) 2025-09-11 06:57:13 +07:00
BlackMATov
632232b9b1 dummy multi spawn api 2025-09-11 01:27:54 +07:00
BlackMATov
fbc61a8895 style fixes 2025-09-10 16:27:50 +07:00
BlackMATov
e3ed2d89a6 style fixes 2025-09-09 14:46:54 +07:00
BlackMATov
bb7f469288 inline internal ids unpacking 2025-09-09 05:02:27 +07:00
BlackMATov
8417cecbbe little test fixes 2025-09-08 17:42:31 +07:00
BlackMATov
eb31ed247b little test fixes 2025-09-08 17:41:18 +07:00
BlackMATov
9400401161 dummy SCHEME fragment trait 2025-09-03 15:07:32 +07:00
BlackMATov
59fb4d8ea4 update readme 2025-09-01 16:09:35 +07:00
BlackMATov
001e6f2956 Merge branch 'feature/pairs' into dev 2025-09-01 15:49:46 +07:00
6bf13890ef Merge pull request #14 from BlackMATov/dev
Dev
2025-06-06 21:28:17 +07:00
db191b805f Merge pull request #13 from BlackMATov/dev
Dev
2025-05-23 20:07:43 +07:00
5ab963022c Merge pull request #12 from BlackMATov/dev
Dev
2025-05-21 20:48:59 +07:00
7de95207d6 Merge pull request #11 from BlackMATov/dev
Dev
2025-05-21 17:34:13 +07:00
4d3b909efb Merge pull request #10 from BlackMATov/dev
Dev
2025-05-21 06:20:38 +07:00
52b3cbeb20 Merge pull request #9 from BlackMATov/dev
Dev
2025-05-21 03:38:16 +07:00
fec193f4f0 Merge pull request #8 from BlackMATov/dev
Dev
2025-05-21 02:11:39 +07:00
e672b0291a Merge pull request #7 from BlackMATov/dev
Dev
2025-05-02 07:28:38 +07:00
4624f2e603 Merge pull request #6 from BlackMATov/dev
Dev
2025-04-30 23:47:13 +07:00
c25769f64f Merge pull request #5 from BlackMATov/dev
Dev
2025-04-19 18:40:25 +07:00
d7274765cb Merge pull request #4 from BlackMATov/dev
Dev
2025-04-09 03:04:19 +07:00
ef033e7a0c Merge pull request #3 from BlackMATov/dev
Dev
2025-04-09 00:58:14 +07:00
3638dedca5 Merge pull request #2 from BlackMATov/dev
Dev
2025-04-06 21:27:33 +07:00
d025ea039b Merge pull request #1 from BlackMATov/dev
Dev
2025-04-05 02:12:18 +07:00
BlackMATov
6c0df71f17 Merge branch 'dev' 2025-03-27 15:36:58 +07:00
BlackMATov
730bffc3ad Merge branch 'dev' 2025-03-19 06:52:10 +07:00
BlackMATov
4bbd7ee60a Merge branch 'dev' 2025-03-18 07:08:27 +07:00
BlackMATov
79aecc8db3 Merge branch 'dev' 2025-03-17 00:23:36 +07:00
BlackMATov
b803faea63 Merge branch 'dev' 2025-03-16 07:46:26 +07:00
BlackMATov
722eda0b9b Merge branch 'dev' 2025-03-16 02:06:17 +07:00
BlackMATov
c6def51830 Merge branch 'dev' 2025-03-10 08:14:38 +07:00
BlackMATov
65312f79dd Merge branch 'dev' 2025-03-08 06:07:06 +07:00
BlackMATov
9877e41705 Merge branch 'dev' 2025-03-02 12:09:33 +07:00
BlackMATov
3b8367d5c4 Merge branch 'dev' 2025-02-24 06:06:26 +07:00
BlackMATov
419a6b6c45 Merge branch 'dev' 2025-02-23 03:54:56 +07:00
BlackMATov
368b50770c Merge branch 'dev' 2025-02-22 00:31:27 +07:00
BlackMATov
0d49802235 Merge branch 'dev' 2025-02-08 04:52:56 +07:00
BlackMATov
f096d747f3 Merge branch 'dev' 2025-01-31 22:14:13 +07:00
BlackMATov
4d88063c10 Merge branch 'dev' 2025-01-31 12:51:30 +07:00
BlackMATov
bf135534c0 Merge branch 'dev' 2025-01-25 08:37:55 +07:00
BlackMATov
177ea7f180 Merge branch 'dev' 2025-01-21 10:52:19 +07:00
BlackMATov
b98b5f9c42 Merge branch 'dev' 2025-01-18 01:39:27 +07:00
BlackMATov
c7120e8608 opt: get chunk by fragments without sorting 2025-01-16 06:42:03 +07:00
19 changed files with 3710 additions and 2174 deletions

View File

@@ -8,7 +8,6 @@
"markdown.extension.toc.levels": "2..6",
"markdown.extension.toc.omittedFromToc": {
"README.md": [
"# Changelog",
"# API Reference"
]
}

178
README.md
View File

@@ -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 entitys 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 entitys 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 librarys 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}
@@ -1097,13 +1174,17 @@ id :: integer? -> id...
name :: id... -> string...
pack :: integer, integer -> id
unpack :: id -> integer, integer, integer
unpack :: id -> integer, integer
defer :: boolean
commit :: boolean
cancel :: boolean
spawn :: <fragment, component>? -> entity
clone :: entity -> <fragment, component>? -> entity
multi_spawn :: integer, <fragment, component>? -> entity[]
clone :: entity, <fragment, component>? -> entity
multi_clone :: integer, entity, <fragment, component>? -> entity[]
alive :: entity -> boolean
alive_all :: entity... -> boolean
@@ -1132,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 -> ()
@@ -1163,7 +1246,10 @@ chunk_mt:components :: fragment... -> storage...
builder :: builder
builder_mt:spawn :: entity
builder_mt:multi_spawn :: integer -> entity[]
builder_mt:clone :: entity -> entity
builder_mt:multi_clone :: integer, entity -> entity[]
builder_mt:has :: fragment -> boolean
builder_mt:has_all :: fragment... -> boolean
@@ -1192,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
@@ -1208,26 +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
### 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
@@ -1334,23 +1431,49 @@ function evolved.defer() end
function evolved.commit() end
```
### `evolved.cancel`
```lua
---@return boolean cancelled
function evolved.cancel() end
```
### `evolved.spawn`
```lua
---@param components? table<evolved.fragment, evolved.component>
---@return evolved.entity
---@return evolved.entity entity
function evolved.spawn(components) end
```
### `evolved.multi_spawn`
```lua
---@param entity_count integer
---@param components? table<evolved.fragment, evolved.component>
---@return evolved.entity[] entity_list
function evolved.multi_spawn(entity_count, components) end
```
### `evolved.clone`
```lua
---@param prefab evolved.entity
---@param components? table<evolved.fragment, evolved.component>
---@return evolved.entity
---@return evolved.entity entity
function evolved.clone(prefab, components) end
```
### `evolved.multi_clone`
```lua
---@param entity_count integer
---@param prefab evolved.entity
---@param components? table<evolved.fragment, evolved.component>
---@return evolved.entity[] entity_list
function evolved.multi_clone(entity_count, prefab, components) end
```
### `evolved.alive`
```lua
@@ -1527,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
@@ -1646,18 +1779,35 @@ function evolved.builder() end
#### `evolved.builder_mt:spawn`
```lua
---@return evolved.entity
---@return evolved.entity entity
function evolved.builder_mt:spawn() end
```
#### `evolved.builder_mt:multi_spawn`
```lua
---@param entity_count integer
---@return evolved.entity[] entity_list
function evolved.builder_mt:multi_spawn(entity_count) end
```
#### `evolved.builder_mt:clone`
```lua
---@param prefab evolved.entity
---@return evolved.entity
---@return evolved.entity entity
function evolved.builder_mt:clone(prefab) end
```
#### `evolved.builder_mt:multi_clone`
```lua
---@param entity_count integer
---@param prefab evolved.entity
---@return evolved.entity[] entity_list
function evolved.builder_mt:multi_clone(entity_count, prefab) end
```
#### `evolved.builder_mt:has`
```lua

View File

@@ -2,19 +2,17 @@
## 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 multi-spawn to the builder to spawn multiple entities at once.
- Add a function to shrink storages to free unused memory.
- observers and events
- add INDEX fragment trait
- use compact prefix-tree for chunks
- optional ffi component storages
- add EXCLUSIVE fragment trait
## Thoughts
- 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

View File

@@ -1,13 +1,20 @@
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.untests'
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.unbench'
require 'develop.usbench'
require 'develop.untests'
local basics = require 'develop.basics'

View 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)

View 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)

View 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)

View File

@@ -0,0 +1,102 @@
local evo = require 'evolved'
local basics = require 'develop.basics'
evo.debug_mode(false)
local N = 10000
print '----------------------------------------'
basics.describe_bench(string.format('Process Benchmarks: Evolved AoS Processing | %d entities', N),
function(w)
evo.process(w)
end,
function()
local wf = evo.builder()
:set(evo.DESTRUCTION_POLICY, evo.DESTRUCTION_POLICY_DESTROY_ENTITY)
:spawn()
local pf = evo.builder():set(wf):spawn()
local vf = evo.builder():set(wf):spawn()
evo.multi_spawn(N, {
[wf] = true,
[pf] = { x = 0, y = 0, z = 0, w = 0 },
[vf] = { x = 0, y = 0, z = 0, w = 0 },
})
evo.builder()
:set(wf)
:set(evo.GROUP, wf)
:set(evo.QUERY, evo.builder():set(wf):include(pf, vf):spawn())
:set(evo.EXECUTE, function(chunk, _, entity_count)
local ps, vs = chunk:components(pf, vf)
for i = 1, entity_count do
local p, s = ps[i], vs[i]
p.x = p.x + s.x
p.y = p.y + s.y
end
end)
:spawn()
return wf
end,
function(w)
evo.destroy(w)
end)
basics.describe_bench(string.format('Process Benchmarks: Evolved SoA Processing | %d entities', N),
function(w)
evo.process(w)
end,
function()
local wf = evo.builder()
:set(evo.DESTRUCTION_POLICY, evo.DESTRUCTION_POLICY_DESTROY_ENTITY)
:spawn()
local pxf = evo.builder():set(wf):spawn()
local pyf = evo.builder():set(wf):spawn()
local pzf = evo.builder():set(wf):spawn()
local pwf = evo.builder():set(wf):spawn()
local vxf = evo.builder():set(wf):spawn()
local vyf = evo.builder():set(wf):spawn()
local vzf = evo.builder():set(wf):spawn()
local vwf = evo.builder():set(wf):spawn()
evo.multi_spawn(N, {
[wf] = true,
[pxf] = 0,
[pyf] = 0,
[pzf] = 0,
[pwf] = 0,
[vxf] = 0,
[vyf] = 0,
[vzf] = 0,
[vwf] = 0,
})
evo.builder()
:set(wf)
:set(evo.GROUP, wf)
:set(evo.QUERY, evo.builder():set(wf):include(pxf, pyf, vxf, vyf):spawn())
:set(evo.EXECUTE, function(chunk, _, entity_count)
local pxs, pys = chunk:components(pxf, pyf)
local vxs, vys = chunk:components(vxf, vyf)
for i = 1, entity_count do
pxs[i] = pxs[i] + vxs[i]
pys[i] = pys[i] + vys[i]
end
end)
:spawn()
return wf
end,
function(w)
evo.destroy(w)
end)

View 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)

View 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)

View 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

View 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

View File

@@ -0,0 +1,308 @@
local evo = require 'evolved'
do
local entity_list
do
entity_list = evo.multi_spawn(0)
assert(entity_list and #entity_list == 0)
entity_list = evo.multi_spawn(0, {})
assert(entity_list and #entity_list == 0)
end
do
entity_list = evo.multi_spawn(-1)
assert(entity_list and #entity_list == 0)
entity_list = evo.multi_spawn(-1, {})
assert(entity_list and #entity_list == 0)
end
do
entity_list = evo.builder():multi_spawn(0)
assert(entity_list and #entity_list == 0)
end
do
entity_list = evo.builder():multi_spawn(-1)
assert(entity_list and #entity_list == 0)
end
end
do
local entity_list
do
entity_list = evo.multi_spawn(1)
assert(entity_list and #entity_list == 1)
assert(entity_list[1] and evo.empty(entity_list[1]))
assert(not entity_list[2])
entity_list = evo.multi_spawn(1, {})
assert(entity_list and #entity_list == 1)
assert(entity_list[1] and evo.empty(entity_list[1]))
assert(not entity_list[2])
end
do
entity_list = evo.multi_spawn(2)
assert(entity_list and #entity_list == 2)
assert(entity_list[1] and evo.empty(entity_list[1]))
assert(entity_list[2] and evo.empty(entity_list[2]))
assert(not entity_list[3])
entity_list = evo.multi_spawn(2, {})
assert(entity_list and #entity_list == 2)
assert(entity_list[1] and evo.empty(entity_list[1]))
assert(entity_list[2] and evo.empty(entity_list[2]))
assert(not entity_list[3])
end
do
entity_list = evo.builder():multi_spawn(1)
assert(entity_list and #entity_list == 1)
assert(entity_list[1] and evo.empty(entity_list[1]))
assert(not entity_list[2])
end
do
entity_list = evo.builder():multi_spawn(2)
assert(entity_list and #entity_list == 2)
assert(entity_list[1] and evo.empty(entity_list[1]))
assert(entity_list[2] and evo.empty(entity_list[2]))
assert(not entity_list[3])
end
end
do
local entity_list
local prefab = evo.id()
do
entity_list = evo.multi_clone(0, prefab)
assert(entity_list and #entity_list == 0)
entity_list = evo.multi_clone(0, prefab, {})
assert(entity_list and #entity_list == 0)
end
do
entity_list = evo.multi_clone(-1, prefab)
assert(entity_list and #entity_list == 0)
entity_list = evo.multi_clone(-1, prefab, {})
assert(entity_list and #entity_list == 0)
end
do
entity_list = evo.builder():multi_clone(0, prefab)
assert(entity_list and #entity_list == 0)
end
do
entity_list = evo.builder():multi_clone(-1, prefab)
assert(entity_list and #entity_list == 0)
end
end
do
local entity_list
local prefab = evo.id()
do
entity_list = evo.multi_clone(1, prefab)
assert(entity_list and #entity_list == 1)
assert(entity_list[1] and evo.empty(entity_list[1]))
assert(not entity_list[2])
entity_list = evo.multi_clone(1, prefab, {})
assert(entity_list and #entity_list == 1)
assert(entity_list[1] and evo.empty(entity_list[1]))
assert(not entity_list[2])
end
do
entity_list = evo.multi_clone(2, prefab)
assert(entity_list and #entity_list == 2)
assert(entity_list[1] and evo.empty(entity_list[1]))
assert(entity_list[2] and evo.empty(entity_list[2]))
assert(not entity_list[3])
entity_list = evo.multi_clone(2, prefab, {})
assert(entity_list and #entity_list == 2)
assert(entity_list[1] and evo.empty(entity_list[1]))
assert(entity_list[2] and evo.empty(entity_list[2]))
assert(not entity_list[3])
end
do
entity_list = evo.builder():multi_clone(1, prefab)
assert(entity_list and #entity_list == 1)
assert(entity_list[1] and evo.empty(entity_list[1]))
assert(not entity_list[2])
end
do
entity_list = evo.builder():multi_clone(2, prefab)
assert(entity_list and #entity_list == 2)
assert(entity_list[1] and evo.empty(entity_list[1]))
assert(entity_list[2] and evo.empty(entity_list[2]))
assert(not entity_list[3])
end
end
do
local f1, f2 = evo.id(2)
do
local entity_list
entity_list = evo.multi_spawn(2, { [f1] = true, [f2] = 123 })
assert(entity_list and #entity_list == 2)
assert(entity_list[1] and evo.get(entity_list[1], f1) == true and evo.get(entity_list[1], f2) == 123)
assert(entity_list[2] and evo.get(entity_list[2], f1) == true and evo.get(entity_list[2], f2) == 123)
entity_list = evo.multi_spawn(2, { [f1] = false, [f2] = 456 })
assert(entity_list and #entity_list == 2)
assert(entity_list[1] and evo.get(entity_list[1], f1) == false and evo.get(entity_list[1], f2) == 456)
assert(entity_list[2] and evo.get(entity_list[2], f1) == false and evo.get(entity_list[2], f2) == 456)
end
do
local prefab = evo.builder():set(f1, true):set(f2, 123):spawn()
local entity_list
entity_list = evo.multi_clone(2, prefab)
assert(entity_list and #entity_list == 2)
assert(entity_list[1] and evo.get(entity_list[1], f1) == true and evo.get(entity_list[1], f2) == 123)
assert(entity_list[2] and evo.get(entity_list[2], f1) == true and evo.get(entity_list[2], f2) == 123)
entity_list = evo.multi_clone(2, prefab, {})
assert(entity_list and #entity_list == 2)
assert(entity_list[1] and evo.get(entity_list[1], f1) == true and evo.get(entity_list[1], f2) == 123)
assert(entity_list[2] and evo.get(entity_list[2], f1) == true and evo.get(entity_list[2], f2) == 123)
entity_list = evo.multi_clone(2, prefab, { [f1] = false, [f2] = 456 })
assert(entity_list and #entity_list == 2)
assert(entity_list[1] and evo.get(entity_list[1], f1) == false and evo.get(entity_list[1], f2) == 456)
assert(entity_list[2] and evo.get(entity_list[2], f1) == false and evo.get(entity_list[2], f2) == 456)
end
end
do
local f1, f2, f3 = evo.id(3)
do
local entity_list1, entity_list2
evo.defer()
do
entity_list1 = evo.multi_spawn(2, { [f1] = 42, [f2] = "hello", [f3] = false })
assert(entity_list1 and #entity_list1 == 2)
assert(entity_list1[1] and evo.empty(entity_list1[1]))
assert(entity_list1[2] and evo.empty(entity_list1[2]))
assert(not entity_list1[3])
entity_list2 = evo.multi_spawn(3, { [f2] = "world", [f3] = true })
assert(entity_list2 and #entity_list2 == 3)
assert(entity_list2[1] and evo.empty(entity_list2[1]))
assert(entity_list2[2] and evo.empty(entity_list2[2]))
assert(entity_list2[3] and evo.empty(entity_list2[3]))
end
evo.commit()
do
assert(entity_list1 and #entity_list1 == 2)
assert(entity_list1[1] and not evo.empty(entity_list1[1]))
assert(entity_list1[2] and not evo.empty(entity_list1[2]))
assert(not entity_list1[3])
assert(
evo.get(entity_list1[1], f1) == 42 and
evo.get(entity_list1[1], f2) == "hello" and
evo.get(entity_list1[1], f3) == false)
assert(
evo.get(entity_list1[2], f1) == 42 and
evo.get(entity_list1[2], f2) == "hello" and
evo.get(entity_list1[2], f3) == false)
assert(entity_list2 and #entity_list2 == 3)
assert(entity_list2[1] and not evo.empty(entity_list2[1]))
assert(entity_list2[2] and not evo.empty(entity_list2[2]))
assert(entity_list2[3] and not evo.empty(entity_list2[3]))
assert(not entity_list2[4])
assert(
evo.get(entity_list2[1], f1) == nil and
evo.get(entity_list2[1], f2) == "world" and
evo.get(entity_list2[1], f3) == true)
assert(
evo.get(entity_list2[2], f1) == nil and
evo.get(entity_list2[2], f2) == "world" and
evo.get(entity_list2[2], f3) == true)
assert(
evo.get(entity_list2[3], f1) == nil and
evo.get(entity_list2[3], f2) == "world" and
evo.get(entity_list2[3], f3) == true)
end
end
end
do
local f1, f2, f3 = evo.id(3)
do
local prefab = evo.builder():set(f1, false):set(f2, 123):spawn()
local entity_list1, entity_list2
evo.defer()
do
entity_list1 = evo.multi_clone(2, prefab)
assert(entity_list1 and #entity_list1 == 2)
assert(entity_list1[1] and evo.empty(entity_list1[1]))
assert(entity_list1[2] and evo.empty(entity_list1[2]))
assert(not entity_list1[3])
entity_list2 = evo.multi_clone(3, prefab, { [f2] = 456, [f3] = "world" })
assert(entity_list2 and #entity_list2 == 3)
assert(entity_list2[1] and evo.empty(entity_list2[1]))
assert(entity_list2[2] and evo.empty(entity_list2[2]))
assert(entity_list2[3] and evo.empty(entity_list2[3]))
end
evo.commit()
do
assert(entity_list1 and #entity_list1 == 2)
assert(entity_list1[1] and not evo.empty(entity_list1[1]))
assert(entity_list1[2] and not evo.empty(entity_list1[2]))
assert(not entity_list1[3])
assert(
evo.get(entity_list1[1], f1) == false and
evo.get(entity_list1[1], f2) == 123 and
evo.get(entity_list1[1], f3) == nil)
assert(
evo.get(entity_list1[2], f1) == false and
evo.get(entity_list1[2], f2) == 123 and
evo.get(entity_list1[2], f3) == nil)
assert(entity_list2 and #entity_list2 == 3)
assert(entity_list2[1] and not evo.empty(entity_list2[1]))
assert(entity_list2[2] and not evo.empty(entity_list2[2]))
assert(entity_list2[3] and not evo.empty(entity_list2[3]))
assert(not entity_list2[4])
assert(
evo.get(entity_list2[1], f1) == false and
evo.get(entity_list2[1], f2) == 456 and
evo.get(entity_list2[1], f3) == "world")
assert(
evo.get(entity_list2[2], f1) == false and
evo.get(entity_list2[2], f2) == 456 and
evo.get(entity_list2[2], f3) == "world")
assert(
evo.get(entity_list2[3], f1) == false and
evo.get(entity_list2[3], f2) == 456 and
evo.get(entity_list2[3], f3) == "world")
end
end
end

View File

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

View File

@@ -598,29 +598,31 @@ do
evo.set(e2b, f2, 45)
do
local chunk, entities = evo.chunk(f1)
assert(entities and entities[1] == e1)
local chunk, entity_list, entity_count = evo.chunk(f1)
assert(entity_list and entity_list[1] == e1)
assert(entity_count and entity_count == 1)
assert(chunk and chunk:components(f1)[1] == 41)
end
do
local chunk, entities = evo.chunk(f1, f2)
local chunk, entity_list, entity_count = evo.chunk(f1, f2)
assert(chunk == evo.chunk(f1, f2))
assert(chunk == evo.chunk(f1, f1, f2))
assert(chunk == evo.chunk(f1, f1, f2, f2))
assert(chunk == evo.chunk(f1, f2, f2, f1))
assert(chunk == evo.chunk(f2, f1))
assert(chunk == evo.chunk(f2, f1, f2, f1))
assert(entities and entities[1] == e2 and entities[2] == e2b)
assert(entity_list and entity_list[1] == e2 and entity_list[2] == e2b)
assert(entity_count and entity_count == 2)
assert(chunk and chunk:components(f1)[1] == 42 and chunk:components(f2)[1] == 43)
assert(chunk and chunk:components(f1)[2] == 44 and chunk:components(f2)[2] == 45)
end
do
local chunk123, entities123 = evo.chunk(f1, f2, f3)
local chunk321, entities321 = evo.chunk(f3, f2, f1)
assert(chunk123 and #entities123 == 0)
assert(chunk321 and #entities321 == 0)
local chunk123, entities123, entity123_count = evo.chunk(f1, f2, f3)
local chunk321, entities321, entity321_count = evo.chunk(f3, f2, f1)
assert(chunk123 and #entities123 >= 0 and entity123_count == 0)
assert(chunk321 and #entities321 >= 0 and entity321_count == 0)
assert(chunk123 == chunk321 and entities123 == entities321)
end
end
@@ -1523,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
@@ -1537,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
@@ -1557,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)
@@ -1608,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
@@ -1621,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
@@ -1864,13 +1866,13 @@ do
assert(evo.get(e3, f1) == nil and evo.get(e3, f2) == nil and evo.get(e3, f3) == 43)
do
local chunk, chunk_entities = evo.chunk(f1, f2, f3)
assert(chunk and chunk_entities)
local chunk, chunk_entity_list, chunk_entity_count = evo.chunk(f1, f2, f3)
assert(chunk and chunk_entity_list and chunk_entity_count == 2)
assert(chunk_entities[1] == e3 and chunk_entities[2] == e1)
assert(chunk_entity_list[1] == e3 and chunk_entity_list[2] == e1)
assert(#chunk:components(f1) == 0)
assert(#chunk:components(f2) == 0)
assert(#chunk:components(f1) >= 0)
assert(#chunk:components(f2) >= 0)
assert(chunk:components(f3)[1] == 43 and chunk:components(f3)[2] == 50)
end
end
@@ -1906,22 +1908,22 @@ do
assert(not evo.has(e3, f1) and evo.has(e3, f2) and evo.has(e3, f3))
do
local chunk, chunk_entities = evo.chunk(f2)
assert(chunk and chunk_entities)
local chunk, chunk_entity_list, chunk_entity_count = evo.chunk(f2)
assert(chunk and chunk_entity_list and chunk_entity_count == 1)
assert(chunk_entities[1] == e1)
assert(#chunk:components(f1) == 0)
assert(#chunk:components(f2) == 0)
assert(#chunk:components(f3) == 0)
assert(chunk_entity_list[1] == e1)
assert(#chunk:components(f1) >= 0)
assert(#chunk:components(f2) >= 0)
assert(#chunk:components(f3) >= 0)
end
do
local chunk, chunk_entities = evo.chunk(f2, f3)
assert(chunk and chunk_entities)
local chunk, chunk_entity_list, chunk_entity_count = evo.chunk(f2, f3)
assert(chunk and chunk_entity_list and chunk_entity_count == 1)
assert(chunk_entities[1] == e3)
assert(#chunk:components(f1) == 0)
assert(#chunk:components(f2) == 0)
assert(chunk_entity_list[1] == e3)
assert(#chunk:components(f1) >= 0)
assert(#chunk:components(f2) >= 0)
assert(chunk:components(f3)[1] == 43)
end
end
@@ -1961,13 +1963,13 @@ do
assert(not evo.has(e3, f1) and not evo.has(e3, f2) and not evo.has(e3, f3))
do
local chunk, chunk_entities = evo.chunk(f1, f2, f3)
assert(chunk and chunk_entities)
local chunk, chunk_entity_list, chunk_entity_count = evo.chunk(f1, f2, f3)
assert(chunk and chunk_entity_list and chunk_entity_count == 0)
assert(next(chunk_entities) == nil)
assert(#chunk:components(f1) == 0)
assert(#chunk:components(f2) == 0)
assert(#chunk:components(f3) == 0)
assert(#chunk_entity_list >= 0)
assert(#chunk:components(f1) >= 0)
assert(#chunk:components(f2) >= 0)
assert(#chunk:components(f3) >= 0)
end
end
end
@@ -2006,13 +2008,13 @@ do
assert(not evo.has(e3, f1) and not evo.has(e3, f2) and not evo.has(e3, f3))
do
local chunk, chunk_entities = evo.chunk(f1, f2, f3)
assert(chunk and chunk_entities)
local chunk, chunk_entity_list, chunk_entity_count = evo.chunk(f1, f2, f3)
assert(chunk and chunk_entity_list and chunk_entity_count == 0)
assert(next(chunk_entities) == nil)
assert(#chunk:components(f1) == 0)
assert(#chunk:components(f2) == 0)
assert(#chunk:components(f3) == 0)
assert(#chunk_entity_list >= 0)
assert(#chunk:components(f1) >= 0)
assert(#chunk:components(f2) >= 0)
assert(#chunk:components(f3) >= 0)
end
end
end
@@ -2197,13 +2199,15 @@ do
do
local iter, state = evo.execute(q)
local chunk, entities = iter(state)
local chunk, entity_list, entity_count = iter(state)
assert(chunk == evo.chunk(f2))
assert(entities and entities[1] == e2)
assert(entity_list and entity_list[1] == e2)
assert(entity_count == 1)
chunk, entities = iter(state)
chunk, entity_list, entity_count = iter(state)
assert(not chunk)
assert(not entities)
assert(not entity_list)
assert(not entity_count)
end
end
@@ -2224,9 +2228,9 @@ do
do
local entity_sum = 0
for _, entities in evo.execute(q) do
assert(#entities > 0)
for _, e in ipairs(entities) do
for _, entity_list, entity_count in evo.execute(q) do
assert(entity_count > 0)
for _, e in ipairs(entity_list) do
entity_sum = entity_sum + e
end
end
@@ -2253,30 +2257,35 @@ do
do
local iter, state = evo.execute(q)
local chunk, entities = iter(state)
local chunk, entity_list, entity_count = iter(state)
assert(chunk == evo.chunk(f1))
assert(entities and entities[1] == e1)
assert(entity_list and entity_list[1] == e1)
assert(entity_count == 1)
chunk, entities = iter(state)
chunk, entity_list, entity_count = iter(state)
assert(not chunk)
assert(not entities)
assert(not entity_list)
assert(not entity_count)
end
evo.set(q, evo.EXCLUDES)
do
local iter, state = evo.execute(q)
local chunk, entities = iter(state)
local chunk, entity_list, entity_count = iter(state)
assert(chunk == evo.chunk(f1))
assert(entities and entities[1] == e1)
assert(entity_list and entity_list[1] == e1)
assert(entity_count == 1)
chunk, entities = iter(state)
chunk, entity_list, entity_count = iter(state)
assert(chunk == evo.chunk(f1, f2))
assert(entities and entities[1] == e2)
assert(entity_list and entity_list[1] == e2)
assert(entity_count == 1)
chunk, entities = iter(state)
chunk, entity_list, entity_count = iter(state)
assert(not chunk)
assert(not entities)
assert(not entity_list)
assert(not entity_count)
end
end
@@ -2310,9 +2319,10 @@ do
do
local iter, state = evo.execute(q)
local chunk, entities = iter(state)
local chunk, entity_list, entity_count = iter(state)
assert(chunk == evo.chunk(f1))
assert(entities and entities[1] == e1)
assert(entity_list and entity_list[1] == e1)
assert(entity_count == 1)
end
end
@@ -2448,7 +2458,7 @@ do
local function collect_entities(q)
local entities = {}
for _, es, es_count in evo.execute(q) do
assert(#es == es_count)
assert(#es >= es_count)
for _, e in ipairs(es) do
entities[#entities + 1] = e
end
@@ -2462,7 +2472,7 @@ do
do
local entities = collect_entities(q1)
assert(#entities == 3)
assert(#entities >= 3)
assert(entities[1] == e1)
assert(entities[2] == e2)
assert(entities[3] == e3)
@@ -2470,14 +2480,14 @@ do
do
local entities = collect_entities(q2)
assert(#entities == 2)
assert(#entities >= 2)
assert(entities[1] == e2)
assert(entities[2] == e3)
end
do
local entities = collect_entities(q3)
assert(#entities == 1)
assert(#entities >= 1)
assert(entities[1] == e2)
end
end
@@ -3246,36 +3256,36 @@ do
local e = evo.spawn({ [f1] = 1, [f2] = 2, [f3] = 3, [f4] = 4, [f5] = 5 })
local c, es = evo.chunk(f1, f2, f3, f4, f5)
assert(c and es and #es == 1 and es[1] == e)
assert(c and es and #es >= 1 and es[1] == e)
do
local c1, c2 = c:components(f1, f2)
assert(c1 and #c1 == 1 and c1[1] == 1)
assert(c2 and #c2 == 1 and c2[1] == 2)
assert(c1 and #c1 >= 1 and c1[1] == 1)
assert(c2 and #c2 >= 1 and c2[1] == 2)
end
do
local c1, c2, c3 = c:components(f1, f2, f3)
assert(c1 and #c1 == 1 and c1[1] == 1)
assert(c2 and #c2 == 1 and c2[1] == 2)
assert(c3 and #c3 == 1 and c3[1] == 3)
assert(c1 and #c1 >= 1 and c1[1] == 1)
assert(c2 and #c2 >= 1 and c2[1] == 2)
assert(c3 and #c3 >= 1 and c3[1] == 3)
end
do
local c1, c2, c3, c4 = c:components(f1, f2, f3, f4)
assert(c1 and #c1 == 1 and c1[1] == 1)
assert(c2 and #c2 == 1 and c2[1] == 2)
assert(c3 and #c3 == 1 and c3[1] == 3)
assert(c4 and #c4 == 1 and c4[1] == 4)
assert(c1 and #c1 >= 1 and c1[1] == 1)
assert(c2 and #c2 >= 1 and c2[1] == 2)
assert(c3 and #c3 >= 1 and c3[1] == 3)
assert(c4 and #c4 >= 1 and c4[1] == 4)
end
do
local c1, c2, c3, c4, c5 = c:components(f1, f2, f3, f4, f5)
assert(c1 and #c1 == 1 and c1[1] == 1)
assert(c2 and #c2 == 1 and c2[1] == 2)
assert(c3 and #c3 == 1 and c3[1] == 3)
assert(c4 and #c4 == 1 and c4[1] == 4)
assert(c5 and #c5 == 1 and c5[1] == 5)
assert(c1 and #c1 >= 1 and c1[1] == 1)
assert(c2 and #c2 >= 1 and c2[1] == 2)
assert(c3 and #c3 >= 1 and c3[1] == 3)
assert(c4 and #c4 >= 1 and c4[1] == 4)
assert(c5 and #c5 >= 1 and c5[1] == 5)
end
end
@@ -3722,7 +3732,7 @@ do
do
local c1, c1_es = evo.chunk(f1)
assert(c1 and c1_es and #c1_es == 2)
assert(c1 and c1_es and #c1_es >= 2)
assert(c1_es[1] == e1a and c1_es[2] == e1b)
assert(c1:components(f1)[1] == 1 and c1:components(f1)[2] == 11)
end
@@ -3731,10 +3741,10 @@ do
do
local c1, c1_es = evo.chunk(f1)
assert(c1 and c1_es and #c1_es == 0)
assert(c1 and c1_es and #c1_es >= 0)
local c12, c12_es = evo.chunk(f1, f2)
assert(c12 and c12_es and #c12_es == 2)
assert(c12 and c12_es and #c12_es >= 2)
assert(c12_es[1] == e1a and c12_es[2] == e1b)
assert(c12:components(f1)[1] == 1 and c12:components(f1)[2] == 11)
assert(c12:components(f2)[1] == 2 and c12:components(f2)[2] == 2)
@@ -3745,7 +3755,7 @@ do
do
local c1, c1_es = evo.chunk(f1)
assert(c1 and c1_es and #c1_es == 2)
assert(c1 and c1_es and #c1_es >= 2)
assert(c1_es[1] == e1c and c1_es[2] == e1d)
assert(c1:components(f1)[1] == 111 and c1:components(f1)[2] == 1111)
end
@@ -3755,10 +3765,10 @@ do
do
local c1, c1_es = evo.chunk(f1)
assert(c1 and c1_es and #c1_es == 0)
assert(c1 and c1_es and #c1_es >= 0)
local c12, c12_es = evo.chunk(f1, f2)
assert(c12 and c12_es and #c12_es == 4)
assert(c12 and c12_es and #c12_es >= 4)
assert(c12_es[1] == e1a and c12_es[2] == e1b)
assert(c12_es[3] == e1c and c12_es[4] == e1d)
assert(c12:components(f1)[1] == 1 and c12:components(f1)[2] == 11)
@@ -3778,7 +3788,7 @@ do
do
local c123, c123_es = evo.chunk(f1, f2, f3)
assert(c123 and c123_es and #c123_es == 2)
assert(c123 and c123_es and #c123_es >= 2)
assert(c123_es[1] == e123a and c123_es[2] == e123b)
assert(c123:components(f1)[1] == 1 and c123:components(f1)[2] == 11)
assert(c123:components(f2)[1] == 2 and c123:components(f2)[2] == 22)
@@ -3789,7 +3799,7 @@ do
do
local c13, c13_es = evo.chunk(f3, f1)
assert(c13 and c13_es and #c13_es == 2)
assert(c13 and c13_es and #c13_es >= 2)
assert(c13_es[1] == e123a and c13_es[2] == e123b)
assert(c13:components(f1)[1] == 1 and c13:components(f1)[2] == 11)
assert(c13:components(f2)[1] == nil and c13:components(f2)[2] == nil)
@@ -3801,7 +3811,7 @@ do
do
local c3, c3_es = evo.chunk(f3)
assert(c3 and c3_es and #c3_es == 2)
assert(c3 and c3_es and #c3_es >= 2)
assert(c3_es[1] == e3a and c3_es[2] == e3b)
assert(c3:components(f3)[1] == 3 and c3:components(f3)[2] == 33)
end
@@ -3810,7 +3820,7 @@ do
do
local c3, c3_es = evo.chunk(f3)
assert(c3 and c3_es and #c3_es == 4)
assert(c3 and c3_es and #c3_es >= 4)
assert(c3_es[1] == e3a and c3_es[2] == e3b)
assert(c3_es[3] == e123a and c3_es[4] == e123b)
assert(c3:components(f1)[1] == nil and c3:components(f1)[2] == nil)
@@ -3833,13 +3843,13 @@ do
do
local c1, c1_es, c1_ec = evo.chunk(f1)
assert(c1 and c1_es and c1_ec)
assert(c1_ec == 2 and #c1_es == 2 and c1_es[1] == e1a and c1_es[2] == e1b)
assert(c1_ec == 2 and #c1_es >= 2 and c1_es[1] == e1a and c1_es[2] == e1b)
end
do
local c12, c12_es, c12_ec = evo.chunk(f1, f2)
assert(c12 and c12_es and c12_ec)
assert(c12_ec == 1 and #c12_es == 1 and c12_es[1] == e12)
assert(c12_ec == 1 and #c12_es >= 1 and c12_es[1] == e12)
end
end
@@ -3897,14 +3907,14 @@ do
do
local c1_es, c1_ec = c1:entities()
assert(c1_es and #c1_es == 2 and c1_ec == 2)
assert(c1_es and #c1_es >= 2 and c1_ec == 2)
assert(c1_es[1] == e1a and c1_es[2] == e1b)
local c2_es, c2_ec = c2:entities()
assert(c2_es and #c2_es == 0 and c2_ec == 0)
assert(c2_es and #c2_es >= 0 and c2_ec == 0)
local c12_es, c12_ec = c12:entities()
assert(c12_es and #c12_es == 2 and c12_ec == 2)
assert(c12_es and #c12_es >= 2 and c12_ec == 2)
assert(c12_es[1] == e12a and c12_es[2] == e12b)
end
@@ -3915,14 +3925,14 @@ do
do
local c1_es, c1_ec = c1:entities()
assert(c1_es and #c1_es == 0 and c1_ec == 0)
assert(c1_es and #c1_es >= 0 and c1_ec == 0)
local c2_es, c2_ec = c2:entities()
assert(c2_es and #c2_es == 2 and c2_ec == 2)
assert(c2_es and #c2_es >= 2 and c2_ec == 2)
assert(c2_es[1] == e12a and c2_es[2] == e12b)
local c12_es, c12_ec = c12:entities()
assert(c12_es and #c12_es == 2 and c12_ec == 2)
assert(c12_es and #c12_es >= 2 and c12_ec == 2)
assert(c12_es[1] == e1a and c12_es[2] == e1b)
end
end
@@ -3938,7 +3948,7 @@ do
assert(evo.empty(f2))
local c1_es, c1_ec = c1:entities()
assert(c1_es and #c1_es == 0 and c1_ec == 0)
assert(c1_es and #c1_es >= 0 and c1_ec == 0)
end
end
@@ -3949,7 +3959,7 @@ do
evo.destroy(f1)
do
local c1_es, c1_ec = c1:entities()
assert(c1_es and #c1_es == 0 and c1_ec == 0)
assert(c1_es and #c1_es >= 0 and c1_ec == 0)
end
end
@@ -3964,26 +3974,26 @@ do
evo.set(f2, f2)
do
local c1_es, c1_ec = c1:entities()
assert(c1_es and #c1_es == 0 and c1_ec == 0)
assert(c1_es and #c1_es >= 0 and c1_ec == 0)
local c2_es, c2_ec = c2:entities()
assert(c2_es and #c2_es == 0 and c2_ec == 0)
assert(c2_es and #c2_es >= 0 and c2_ec == 0)
local c12_es, c12_ec = c12:entities()
assert(c12_es and #c12_es == 1 and c12_ec == 1)
assert(c12_es and #c12_es >= 1 and c12_ec == 1)
assert(c12_es[1] == f2)
end
evo.destroy(f1)
do
local c1_es, c1_ec = c1:entities()
assert(c1_es and #c1_es == 0 and c1_ec == 0)
assert(c1_es and #c1_es >= 0 and c1_ec == 0)
local c2_es, c2_ec = c2:entities()
assert(c2_es and #c2_es == 1 and c2_ec == 1)
assert(c2_es and #c2_es >= 1 and c2_ec == 1)
assert(c2_es[1] == f2)
local c12_es, c12_ec = c12:entities()
assert(c12_es and #c12_es == 0 and c12_ec == 0)
assert(c12_es and #c12_es >= 0 and c12_ec == 0)
end
end
@@ -3998,25 +4008,25 @@ do
evo.set(f2, f2)
do
local c1_es, c1_ec = c1:entities()
assert(c1_es and #c1_es == 0 and c1_ec == 0)
assert(c1_es and #c1_es >= 0 and c1_ec == 0)
local c2_es, c2_ec = c2:entities()
assert(c2_es and #c2_es == 0 and c2_ec == 0)
assert(c2_es and #c2_es >= 0 and c2_ec == 0)
local c12_es, c12_ec = c12:entities()
assert(c12_es and #c12_es == 1 and c12_ec == 1)
assert(c12_es and #c12_es >= 1 and c12_ec == 1)
assert(c12_es[1] == f2)
end
evo.destroy(f1)
do
local c1_es, c1_ec = c1:entities()
assert(c1_es and #c1_es == 0 and c1_ec == 0)
assert(c1_es and #c1_es >= 0 and c1_ec == 0)
local c2_es, c2_ec = c2:entities()
assert(c2_es and #c2_es == 0 and c2_ec == 0)
assert(c2_es and #c2_es >= 0 and c2_ec == 0)
local c12_es, c12_ec = c12:entities()
assert(c12_es and #c12_es == 0 and c12_ec == 0)
assert(c12_es and #c12_es >= 0 and c12_ec == 0)
end
end
@@ -4028,20 +4038,20 @@ do
evo.set(f3, f2)
do
local c1_es, c1_ec = c1:entities()
assert(c1_es and #c1_es == 1 and c1_ec == 1)
assert(c1_es and #c1_es >= 1 and c1_ec == 1)
assert(c1_es[1] == f2)
local c2_es, c2_ec = c2:entities()
assert(c2_es and #c2_es == 1 and c2_ec == 1)
assert(c2_es and #c2_es >= 1 and c2_ec == 1)
assert(c2_es[1] == f3)
end
evo.destroy(f1)
do
local c1_es, c1_ec = c1:entities()
assert(c1_es and #c1_es == 0 and c1_ec == 0)
assert(c1_es and #c1_es >= 0 and c1_ec == 0)
local c2_es, c2_ec = c2:entities()
assert(c2_es and #c2_es == 1 and c2_ec == 1)
assert(c2_es and #c2_es >= 1 and c2_ec == 1)
assert(c2_es[1] == f3)
end
end
@@ -4055,20 +4065,20 @@ do
evo.set(f3, f2)
do
local c1_es, c1_ec = c1:entities()
assert(c1_es and #c1_es == 1 and c1_ec == 1)
assert(c1_es and #c1_es >= 1 and c1_ec == 1)
assert(c1_es[1] == f2)
local c2_es, c2_ec = c2:entities()
assert(c2_es and #c2_es == 1 and c2_ec == 1)
assert(c2_es and #c2_es >= 1 and c2_ec == 1)
assert(c2_es[1] == f3)
end
evo.destroy(f1)
do
local c1_es, c1_ec = c1:entities()
assert(c1_es and #c1_es == 0 and c1_ec == 0)
assert(c1_es and #c1_es >= 0 and c1_ec == 0)
local c2_es, c2_ec = c2:entities()
assert(c2_es and #c2_es == 1 and c2_ec == 1)
assert(c2_es and #c2_es >= 1 and c2_ec == 1)
assert(c2_es[1] == f3)
end
end
@@ -4082,20 +4092,20 @@ do
evo.set(f3, f2)
do
local c1_es, c1_ec = c1:entities()
assert(c1_es and #c1_es == 1 and c1_ec == 1)
assert(c1_es and #c1_es >= 1 and c1_ec == 1)
assert(c1_es[1] == f2)
local c2_es, c2_ec = c2:entities()
assert(c2_es and #c2_es == 1 and c2_ec == 1)
assert(c2_es and #c2_es >= 1 and c2_ec == 1)
assert(c2_es[1] == f3)
end
evo.destroy(f1)
do
local c1_es, c1_ec = c1:entities()
assert(c1_es and #c1_es == 0 and c1_ec == 0)
assert(c1_es and #c1_es >= 0 and c1_ec == 0)
local c2_es, c2_ec = c2:entities()
assert(c2_es and #c2_es == 0 and c2_ec == 0)
assert(c2_es and #c2_es >= 0 and c2_ec == 0)
end
end
@@ -4122,14 +4132,14 @@ do
do
local c4_es, c4_ec = c4:entities()
assert(c4_es and #c4_es == 3 and c4_ec == 3)
assert(c4_es and #c4_es >= 3 and c4_ec == 3)
assert(c4_es[1] == e24 and c4_es[2] == e14 and c4_es[3] == e124)
end
assert(#c14:entities() == 0)
assert(#c24:entities() == 0)
assert(#c124:entities() == 0)
assert(#c234:entities() == 0)
assert(#c14:entities() >= 0)
assert(#c24:entities() >= 0)
assert(#c124:entities() >= 0)
assert(#c234:entities() >= 0)
assert(evo.alive(e14) and not evo.empty(e14))
assert(evo.alive(e24) and not evo.empty(e24))
@@ -4159,7 +4169,7 @@ do
assert(remove_count == 1)
local c1_es, c1_ec = c1:entities()
assert(c1_es and #c1_es == 0 and c1_ec == 0)
assert(c1_es and #c1_es >= 0 and c1_ec == 0)
end
end
@@ -4185,7 +4195,7 @@ do
assert(remove_count == 1)
local c1_es, c1_ec = c1:entities()
assert(c1_es and #c1_es == 0 and c1_ec == 0)
assert(c1_es and #c1_es >= 0 and c1_ec == 0)
end
end
@@ -4219,27 +4229,27 @@ do
do
local c1_es, c1_ec = c1:entities()
assert(c1 and c1_es and c1_ec)
assert(c1_ec == 4 and #c1_es == 4)
assert(c1_ec == 4 and #c1_es >= 4)
assert(c1_es[1] == e1a and c1_es[2] == e1b and c1_es[3] == e12a and c1_es[4] == e12b)
end
do
local c12_es, c12_ec = c12:entities()
assert(c12 and c12_es and c12_ec)
assert(c12_ec == 0 and #c12_es == 0)
assert(c12_ec == 0 and #c12_es >= 0)
end
do
local c13_es, c13_ec = c13:entities()
assert(c13 and c13_es and c13_ec)
assert(c13_ec == 2 and #c13_es == 2)
assert(c13_ec == 2 and #c13_es >= 2)
assert(c13_es[1] == e123a and c13_es[2] == e123b)
end
do
local c123_es, c123_ec = c123:entities()
assert(c123 and c123_es and c123_ec)
assert(c123_ec == 0 and #c123_es == 0)
assert(c123_ec == 0 and #c123_es >= 0)
end
end
@@ -4291,7 +4301,7 @@ do
do
local c2, c2_es, c2_ec = evo.chunk(f2)
assert(c2 and c2_es and c2_ec)
assert(#c2_es == 2 and c2_ec == 2)
assert(#c2_es >= 2 and c2_ec == 2)
assert(c2_es[1] == e2a and c2_es[2] == e2b)
end
end
@@ -4324,7 +4334,7 @@ do
do
local c2, c2_es, c2_ec = evo.chunk(f2)
assert(c2 and c2_es and c2_ec)
assert(#c2_es == 4 and c2_ec == 4)
assert(#c2_es >= 4 and c2_ec == 4)
assert(c2_es[1] == e2a and c2_es[2] == e2b and c2_es[3] == e12a and c2_es[4] == e12b)
end
end
@@ -4349,10 +4359,10 @@ do
assert(c1 and c23)
assert(#c1:fragments() == 1)
assert(#c1:fragments() >= 1)
assert(c1:fragments()[1] == f1)
assert(#c23:fragments() == 2)
assert(#c23:fragments() >= 2)
assert(c23:fragments()[1] == f2)
assert(c23:fragments()[2] == f3)
end
@@ -4372,20 +4382,23 @@ do
local iter, state = evo.execute(q1)
local chunk, entity_list = iter(state)
assert(entity_list and #entity_list == 1)
local chunk, entity_list, entity_count = iter(state)
assert(entity_list and #entity_list >= 1)
assert(entity_count and entity_count == 1)
assert(chunk == evo.chunk(f0, f1) and entity_list[1] == e1)
chunk, entity_list = iter(state)
assert(entity_list and #entity_list == 1)
chunk, entity_list, entity_count = iter(state)
assert(entity_list and #entity_list >= 1)
assert(entity_count and entity_count == 1)
assert(chunk == evo.chunk(f0, f1, f2) and entity_list[1] == e12)
chunk, entity_list = iter(state)
assert(entity_list and #entity_list == 1)
chunk, entity_list, entity_count = iter(state)
assert(entity_list and #entity_list >= 1)
assert(entity_count and entity_count == 1)
assert(chunk == evo.chunk(f0, f1, f2, f3) and entity_list[1] == e123)
chunk, entity_list = iter(state)
assert(not chunk and not entity_list)
chunk, entity_list, entity_count = iter(state)
assert(not chunk and not entity_list and not entity_count)
end
do
@@ -4393,16 +4406,18 @@ do
local iter, state = evo.execute(q1)
local chunk, entity_list = iter(state)
assert(entity_list and #entity_list == 1)
local chunk, entity_list, entity_count = iter(state)
assert(entity_list and #entity_list >= 1)
assert(entity_count and entity_count == 1)
assert(chunk == evo.chunk(f0, f1) and entity_list[1] == e1)
chunk, entity_list = iter(state)
assert(entity_list and #entity_list == 1)
chunk, entity_list, entity_count = iter(state)
assert(entity_list and #entity_list >= 1)
assert(entity_count and entity_count == 1)
assert(chunk == evo.chunk(f0, f1, f2) and entity_list[1] == e12)
chunk, entity_list = iter(state)
assert(not chunk and not entity_list)
chunk, entity_list, entity_count = iter(state)
assert(not chunk and not entity_list and not entity_count)
end
end
@@ -4435,7 +4450,7 @@ do
for c, es, ec in evo.execute(qe12) do
assert(ec > 0)
assert(#es == ec)
assert(#es >= ec)
assert(c ~= c1 and c ~= c2 and c ~= c12)
matched_chunk_count = matched_chunk_count + 1
matched_entity_count = matched_entity_count + ec
@@ -4453,7 +4468,7 @@ do
for _, es, ec in evo.execute(qe12) do
assert(ec > 0)
assert(#es == ec)
assert(#es >= ec)
matched_chunk_count = matched_chunk_count + 1
matched_entity_count = matched_entity_count + ec
end
@@ -4468,7 +4483,7 @@ do
local iter, state = evo.execute(qe12)
local chunk, entity_list, entity_count = iter(state)
assert(chunk == c12)
assert(entity_list and #entity_list == 1)
assert(entity_list and #entity_list >= 1)
assert(entity_count and entity_count == 1)
assert(entity_list[1] == e12)
end
@@ -4495,7 +4510,7 @@ do
local old_c1_es, old_c1_ec = old_c1:entities()
assert(old_c1_es and old_c1_ec)
assert(#old_c1_es == 1 and old_c1_ec == 1)
assert(#old_c1_es >= 1 and old_c1_ec == 1)
assert(old_c1_es[1] == e1)
end
@@ -4507,7 +4522,7 @@ do
local new_c12_es, new_c12_ec = new_c12:entities()
assert(new_c12_es and new_c12_ec)
assert(#new_c12_es == 1 and new_c12_ec == 1)
assert(#new_c12_es >= 1 and new_c12_ec == 1)
assert(new_c12_es[1] == e12)
end
@@ -6358,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

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
rockspec_format = "3.0"
package = "evolved.lua"
version = "1.2.0-0"
source = {
url = "git://github.com/BlackMATov/evolved.lua",
tag = "v1.2.0",
}
description = {
homepage = "https://github.com/BlackMATov/evolved.lua",
summary = "Evolved ECS (Entity-Component-System) for Lua",
detailed = [[
`evolved.lua` is a fast and flexible ECS (Entity-Component-System) library for Lua.
It is designed to be simple and easy to use, while providing all the features needed to create complex systems with blazing performance.
]],
license = "MIT",
labels = {
"ecs",
"entity",
"entities",
"component",
"components",
"entity-component",
"entity-component-system",
},
}
dependencies = {
"lua >= 5.1",
}
build = {
type = "builtin",
modules = {
evolved = "evolved.lua",
}
}

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