mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-13 11:38:15 +07:00
Compare commits
39 Commits
v1.3.0
...
760b477564
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
760b477564 | ||
|
|
fc910881bd | ||
|
|
71a7c84a67 | ||
|
|
582a09a6db | ||
|
|
de73881f63 | ||
|
|
55e444ca63 | ||
|
|
e499c701ef | ||
|
|
789f167bf4 | ||
|
|
00367ce07e | ||
|
|
07902eb184 | ||
| ecdbfe660f | |||
|
|
cfd68767cf | ||
|
|
f1ba9ab909 | ||
|
|
77ff3e77db | ||
|
|
825eba5328 | ||
|
|
67002503ed | ||
|
|
1bb0089e9f | ||
|
|
dc642f5294 | ||
|
|
a81a8646e9 | ||
|
|
aa6d2c1c48 | ||
|
|
5fe48de890 | ||
| 0d7adcb5fd | |||
|
|
f48f1bb290 | ||
|
|
6f1a85165f | ||
|
|
bd87e593e9 | ||
|
|
0eac310fd5 | ||
|
|
22cedd26bb | ||
|
|
d298be4188 | ||
|
|
24933e6a04 | ||
|
|
6841bb42fe | ||
|
|
dc912eb6da | ||
|
|
8d3c4633fb | ||
|
|
8704fb0c39 | ||
|
|
86c9ef7cf2 | ||
|
|
bd5f9bb61f | ||
|
|
cfa5dc7a9f | ||
|
|
243adc1a93 | ||
|
|
cf19fba9e4 | ||
|
|
784b9c6a15 |
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"[json][jsonc][lua][markdown][yaml]": {
|
"[json][jsonc][lua][markdown][teal][yaml]": {
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"files.insertFinalNewline": true,
|
"files.insertFinalNewline": true,
|
||||||
"files.trimFinalNewlines": true,
|
"files.trimFinalNewlines": true,
|
||||||
|
|||||||
131
README.md
131
README.md
@@ -48,6 +48,7 @@
|
|||||||
- [Fragment Hooks](#fragment-hooks)
|
- [Fragment Hooks](#fragment-hooks)
|
||||||
- [Unique Fragments](#unique-fragments)
|
- [Unique Fragments](#unique-fragments)
|
||||||
- [Explicit Fragments](#explicit-fragments)
|
- [Explicit Fragments](#explicit-fragments)
|
||||||
|
- [Internal Fragments](#internal-fragments)
|
||||||
- [Shared Components](#shared-components)
|
- [Shared Components](#shared-components)
|
||||||
- [Fragment Requirements](#fragment-requirements)
|
- [Fragment Requirements](#fragment-requirements)
|
||||||
- [Destruction Policies](#destruction-policies)
|
- [Destruction Policies](#destruction-policies)
|
||||||
@@ -59,6 +60,8 @@
|
|||||||
- [Chunk](#chunk)
|
- [Chunk](#chunk)
|
||||||
- [Builder](#builder)
|
- [Builder](#builder)
|
||||||
- [Changelog](#changelog)
|
- [Changelog](#changelog)
|
||||||
|
- [vX.X.X](#vxxx)
|
||||||
|
- [v1.4.0](#v140)
|
||||||
- [v1.3.0](#v130)
|
- [v1.3.0](#v130)
|
||||||
- [v1.2.0](#v120)
|
- [v1.2.0](#v120)
|
||||||
- [v1.1.0](#v110)
|
- [v1.1.0](#v110)
|
||||||
@@ -153,11 +156,11 @@ function evolved.alive_any(...) end
|
|||||||
Sometimes (for debugging purposes, for example), it is necessary to extract the index and version from an identifier or to pack them back into an identifier. The [`evolved.pack`](#evolvedpack) and [`evolved.unpack`](#evolvedunpack) functions can be used for this purpose.
|
Sometimes (for debugging purposes, for example), it is necessary to extract the index and version from an identifier or to pack them back into an identifier. The [`evolved.pack`](#evolvedpack) and [`evolved.unpack`](#evolvedunpack) functions can be used for this purpose.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
---@param index integer
|
---@param primary integer
|
||||||
---@param version integer
|
---@param secondary integer
|
||||||
---@return evolved.id id
|
---@return evolved.id id
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function evolved.pack(index, version) end
|
function evolved.pack(primary, secondary) end
|
||||||
|
|
||||||
---@param id evolved.id
|
---@param id evolved.id
|
||||||
---@return integer primary
|
---@return integer primary
|
||||||
@@ -461,7 +464,7 @@ local health, stamina = evolved.id(2)
|
|||||||
local enemy = evolved.builder()
|
local enemy = evolved.builder()
|
||||||
:set(health, 100)
|
:set(health, 100)
|
||||||
:set(stamina, 50)
|
:set(stamina, 50)
|
||||||
:spawn()
|
:build()
|
||||||
```
|
```
|
||||||
|
|
||||||
Builders can be reused, so you can create a builder with a specific set of fragments and components and then use it to spawn multiple entities with the same fragments and components.
|
Builders can be reused, so you can create a builder with a specific set of fragments and components and then use it to spawn multiple entities with the same fragments and components.
|
||||||
@@ -502,16 +505,16 @@ local evolved = require 'evolved'
|
|||||||
|
|
||||||
local health = evolved.builder()
|
local health = evolved.builder()
|
||||||
:name('health')
|
:name('health')
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
local stamina = evolved.builder()
|
local stamina = evolved.builder()
|
||||||
:name('stamina')
|
:name('stamina')
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
local player = evolved.builder()
|
local player = evolved.builder()
|
||||||
:set(health, 100)
|
:set(health, 100)
|
||||||
:set(stamina, 50)
|
:set(stamina, 50)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
for fragment, component in evolved.each(player) do
|
for fragment, component in evolved.each(player) do
|
||||||
print(string.format('Fragment (%s) has value %d',
|
print(string.format('Fragment (%s) has value %d',
|
||||||
@@ -600,7 +603,7 @@ The builder interface can be used to create queries too. It is more convenient t
|
|||||||
local query = evolved.builder()
|
local query = evolved.builder()
|
||||||
:include(health, poisoned)
|
:include(health, poisoned)
|
||||||
:exclude(resistant)
|
:exclude(resistant)
|
||||||
:spawn()
|
:build()
|
||||||
```
|
```
|
||||||
|
|
||||||
We don't have to set both [`evolved.INCLUDES`](#evolvedincludes) and [`evolved.EXCLUDES`](#evolvedexcludes) fragments, we can even do it without filters at all, then the query will match all chunks in the world.
|
We don't have to set both [`evolved.INCLUDES`](#evolvedincludes) and [`evolved.EXCLUDES`](#evolvedexcludes) fragments, we can even do it without filters at all, then the query will match all chunks in the world.
|
||||||
@@ -657,7 +660,7 @@ local health, poisoned = evolved.id(2)
|
|||||||
local player = evolved.builder()
|
local player = evolved.builder()
|
||||||
:set(health, 100)
|
:set(health, 100)
|
||||||
:set(poisoned, true)
|
:set(poisoned, true)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
-- start a deferred scope
|
-- start a deferred scope
|
||||||
evolved.defer()
|
evolved.defer()
|
||||||
@@ -685,7 +688,7 @@ local health, poisoned = evolved.id(2)
|
|||||||
local player = evolved.builder()
|
local player = evolved.builder()
|
||||||
:set(health, 100)
|
:set(health, 100)
|
||||||
:set(poisoned, true)
|
:set(poisoned, true)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
-- start a deferred scope
|
-- start a deferred scope
|
||||||
evolved.defer()
|
evolved.defer()
|
||||||
@@ -733,7 +736,7 @@ local destroying_mark = evolved.id()
|
|||||||
|
|
||||||
local destroying_mark_query = evolved.builder()
|
local destroying_mark_query = evolved.builder()
|
||||||
:include(destroying_mark)
|
:include(destroying_mark)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
-- destroy all entities with the destroying_mark fragment
|
-- destroy all entities with the destroying_mark fragment
|
||||||
evolved.batch_destroy(destroying_mark_query)
|
evolved.batch_destroy(destroying_mark_query)
|
||||||
@@ -755,7 +758,7 @@ local health, max_health = evolved.id(2)
|
|||||||
|
|
||||||
local query = evolved.builder()
|
local query = evolved.builder()
|
||||||
:include(health, max_health)
|
:include(health, max_health)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
local system = evolved.builder()
|
local system = evolved.builder()
|
||||||
:query(query)
|
:query(query)
|
||||||
@@ -768,7 +771,7 @@ local system = evolved.builder()
|
|||||||
health_components[i] + 1,
|
health_components[i] + 1,
|
||||||
max_health_components[i])
|
max_health_components[i])
|
||||||
end
|
end
|
||||||
end):spawn()
|
end):build()
|
||||||
```
|
```
|
||||||
|
|
||||||
The [`evolved.process`](#evolvedprocess) function is used to process systems. It takes systems as arguments and executes them in the order they were passed.
|
The [`evolved.process`](#evolvedprocess) function is used to process systems. It takes systems as arguments and executes them in the order they were passed.
|
||||||
@@ -795,7 +798,7 @@ local system = evolved.builder()
|
|||||||
health_components[i] - 1,
|
health_components[i] - 1,
|
||||||
0)
|
0)
|
||||||
end
|
end
|
||||||
end):spawn()
|
end):build()
|
||||||
|
|
||||||
evolved.process(system)
|
evolved.process(system)
|
||||||
```
|
```
|
||||||
@@ -814,7 +817,7 @@ local velocity_x, velocity_y = evolved.id(2)
|
|||||||
local physical_body_query = evolved.builder()
|
local physical_body_query = evolved.builder()
|
||||||
:include(position_x, position_y)
|
:include(position_x, position_y)
|
||||||
:include(velocity_x, velocity_y)
|
:include(velocity_x, velocity_y)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
local physics_group = evolved.id()
|
local physics_group = evolved.id()
|
||||||
|
|
||||||
@@ -829,7 +832,7 @@ evolved.builder()
|
|||||||
vx[i] = vx[i] + gravity_x
|
vx[i] = vx[i] + gravity_x
|
||||||
vy[i] = vy[i] + gravity_y
|
vy[i] = vy[i] + gravity_y
|
||||||
end
|
end
|
||||||
end):spawn()
|
end):build()
|
||||||
|
|
||||||
evolved.builder()
|
evolved.builder()
|
||||||
:group(physics_group)
|
:group(physics_group)
|
||||||
@@ -845,7 +848,7 @@ evolved.builder()
|
|||||||
px[i] = px[i] + vx[i]
|
px[i] = px[i] + vx[i]
|
||||||
py[i] = py[i] + vy[i]
|
py[i] = py[i] + vy[i]
|
||||||
end
|
end
|
||||||
end):spawn()
|
end):build()
|
||||||
|
|
||||||
evolved.process(physics_group)
|
evolved.process(physics_group)
|
||||||
```
|
```
|
||||||
@@ -862,7 +865,7 @@ local system = evolved.builder()
|
|||||||
:epilogue(function()
|
:epilogue(function()
|
||||||
print('Epilogue')
|
print('Epilogue')
|
||||||
end)
|
end)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
evolved.process(system)
|
evolved.process(system)
|
||||||
```
|
```
|
||||||
@@ -904,7 +907,7 @@ local evolved = require 'evolved'
|
|||||||
local health = evolved.builder()
|
local health = evolved.builder()
|
||||||
:on_set(function(entity, fragment, component)
|
:on_set(function(entity, fragment, component)
|
||||||
print('health set to ' .. component)
|
print('health set to ' .. component)
|
||||||
end):spawn()
|
end):build()
|
||||||
|
|
||||||
local player = evolved.id()
|
local player = evolved.id()
|
||||||
evolved.set(player, health, 100) -- prints "health set to 100"
|
evolved.set(player, health, 100) -- prints "health set to 100"
|
||||||
@@ -929,7 +932,7 @@ local enemy_prefab = evolved.builder()
|
|||||||
:prefab()
|
:prefab()
|
||||||
:set(health, 100)
|
:set(health, 100)
|
||||||
:set(stamina, 50)
|
:set(stamina, 50)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
local enemy_clone = evolved.clone(enemy_prefab)
|
local enemy_clone = evolved.clone(enemy_prefab)
|
||||||
|
|
||||||
@@ -951,18 +954,22 @@ local evolved = require 'evolved'
|
|||||||
|
|
||||||
local enemy_tag = evolved.builder()
|
local enemy_tag = evolved.builder()
|
||||||
:tag()
|
:tag()
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
local only_enabled_enemies = evolved.builder()
|
local only_enabled_enemies = evolved.builder()
|
||||||
:include(enemy_tag)
|
:include(enemy_tag)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
local all_enemies_including_disabled = evolved.builder()
|
local all_enemies_including_disabled = evolved.builder()
|
||||||
:include(enemy_tag)
|
:include(enemy_tag)
|
||||||
:include(evolved.DISABLED)
|
:include(evolved.DISABLED)
|
||||||
:spawn()
|
:build()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Internal Fragments
|
||||||
|
|
||||||
|
All predefined fragments provided by the library are marked as internal with the [`evolved.INTERNAL`](#evolvedinternal) trait. Because [`evolved.INTERNAL`](#evolvedinternal) is itself marked as [`evolved.EXPLICIT`](#evolvedexplicit), these fragments are hidden from queries by default. This prevents accidental use of internal fragments in user code and helps distinguish them from user-defined fragments.
|
||||||
|
|
||||||
#### Shared Components
|
#### Shared Components
|
||||||
|
|
||||||
Often, we want to store components as tables, and by default, these tables will be shared between entities. This means that if you modify the table in one entity, it will be modified in all entities that share this table. Sometimes this is what we want. For example, when we want to share a configuration or some resource between entities. But in other cases, we want each entity to have its own copy of the table. For example, if we want to store the position of an entity as a table, we don't want to share this table with other entities. Yes, we can copy the table manually, but the library provides a little bit of syntactic sugar for this.
|
Often, we want to store components as tables, and by default, these tables will be shared between entities. This means that if you modify the table in one entity, it will be modified in all entities that share this table. Sometimes this is what we want. For example, when we want to share a configuration or some resource between entities. But in other cases, we want each entity to have its own copy of the table. For example, if we want to store the position of an entity as a table, we don't want to share this table with other entities. Yes, we can copy the table manually, but the library provides a little bit of syntactic sugar for this.
|
||||||
@@ -976,11 +983,11 @@ local position = evolved.id()
|
|||||||
|
|
||||||
local enemy1 = evolved.builder()
|
local enemy1 = evolved.builder()
|
||||||
:set(position, initial_position)
|
:set(position, initial_position)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
local enemy2 = evolved.builder()
|
local enemy2 = evolved.builder()
|
||||||
:set(position, initial_position)
|
:set(position, initial_position)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
-- the enemy1 and enemy2 share the same table,
|
-- the enemy1 and enemy2 share the same table,
|
||||||
-- and that's definitely not what we want in this case
|
-- and that's definitely not what we want in this case
|
||||||
@@ -1005,15 +1012,15 @@ end
|
|||||||
local position = evolved.builder()
|
local position = evolved.builder()
|
||||||
:default(vector2(0, 0))
|
:default(vector2(0, 0))
|
||||||
:duplicate(vector2_duplicate)
|
:duplicate(vector2_duplicate)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
local enemy1 = evolved.builder()
|
local enemy1 = evolved.builder()
|
||||||
:set(position)
|
:set(position)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
local enemy2 = evolved.builder()
|
local enemy2 = evolved.builder()
|
||||||
:set(position)
|
:set(position)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
-- the enemy1 and enemy2 have different tables now
|
-- the enemy1 and enemy2 have different tables now
|
||||||
assert(evolved.get(enemy1, position) ~= evolved.get(enemy2, position))
|
assert(evolved.get(enemy1, position) ~= evolved.get(enemy2, position))
|
||||||
@@ -1029,21 +1036,21 @@ local evolved = require 'evolved'
|
|||||||
local position = evolved.builder()
|
local position = evolved.builder()
|
||||||
:default(vector2(0, 0))
|
:default(vector2(0, 0))
|
||||||
:duplicate(vector2_duplicate)
|
:duplicate(vector2_duplicate)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
local velocity = evolved.builder()
|
local velocity = evolved.builder()
|
||||||
:default(vector2(0, 0))
|
:default(vector2(0, 0))
|
||||||
:duplicate(vector2_duplicate)
|
:duplicate(vector2_duplicate)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
local physical = evolved.builder()
|
local physical = evolved.builder()
|
||||||
:tag()
|
:tag()
|
||||||
:require(position, velocity)
|
:require(position, velocity)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
local enemy = evolved.builder()
|
local enemy = evolved.builder()
|
||||||
:set(physical)
|
:set(physical)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
assert(evolved.has_all(enemy, position, velocity))
|
assert(evolved.has_all(enemy, position, velocity))
|
||||||
```
|
```
|
||||||
@@ -1057,11 +1064,11 @@ local evolved = require 'evolved'
|
|||||||
|
|
||||||
local world = evolved.builder()
|
local world = evolved.builder()
|
||||||
:tag()
|
:tag()
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
local entity = evolved.builder()
|
local entity = evolved.builder()
|
||||||
:set(world)
|
:set(world)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
-- destroy the world fragment that is attached to the entity
|
-- destroy the world fragment that is attached to the entity
|
||||||
evolved.destroy(world)
|
evolved.destroy(world)
|
||||||
@@ -1082,11 +1089,11 @@ local evolved = require 'evolved'
|
|||||||
local world = evolved.builder()
|
local world = evolved.builder()
|
||||||
:tag()
|
:tag()
|
||||||
:destruction_policy(evolved.DESTRUCTION_POLICY_DESTROY_ENTITY)
|
:destruction_policy(evolved.DESTRUCTION_POLICY_DESTROY_ENTITY)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
local entity = evolved.builder()
|
local entity = evolved.builder()
|
||||||
:set(world)
|
:set(world)
|
||||||
:spawn()
|
:build()
|
||||||
|
|
||||||
-- destroy the world fragment that is attached to the entity
|
-- destroy the world fragment that is attached to the entity
|
||||||
evolved.destroy(world)
|
evolved.destroy(world)
|
||||||
@@ -1181,10 +1188,10 @@ commit :: boolean
|
|||||||
cancel :: boolean
|
cancel :: boolean
|
||||||
|
|
||||||
spawn :: <fragment, component>? -> entity
|
spawn :: <fragment, component>? -> entity
|
||||||
multi_spawn :: integer, <fragment, component>? -> entity[]
|
multi_spawn :: integer, <fragment, component>? -> entity[], integer
|
||||||
|
|
||||||
clone :: entity, <fragment, component>? -> entity
|
clone :: entity, <fragment, component>? -> entity
|
||||||
multi_clone :: integer, entity, <fragment, component>? -> entity[]
|
multi_clone :: integer, entity, <fragment, component>? -> entity[], integer
|
||||||
|
|
||||||
alive :: entity -> boolean
|
alive :: entity -> boolean
|
||||||
alive_all :: entity... -> boolean
|
alive_all :: entity... -> boolean
|
||||||
@@ -1245,11 +1252,14 @@ chunk_mt:components :: fragment... -> storage...
|
|||||||
```
|
```
|
||||||
builder :: builder
|
builder :: builder
|
||||||
|
|
||||||
|
builder_mt:build :: entity? -> entity
|
||||||
|
builder_mt:multi_build :: integer, entity? -> entity[], integer
|
||||||
|
|
||||||
builder_mt:spawn :: entity
|
builder_mt:spawn :: entity
|
||||||
builder_mt:multi_spawn :: integer -> entity[]
|
builder_mt:multi_spawn :: integer -> entity[], integer
|
||||||
|
|
||||||
builder_mt:clone :: entity -> entity
|
builder_mt:clone :: entity -> entity
|
||||||
builder_mt:multi_clone :: integer, entity -> entity[]
|
builder_mt:multi_clone :: integer, entity -> entity[], integer
|
||||||
|
|
||||||
builder_mt:has :: fragment -> boolean
|
builder_mt:has :: fragment -> boolean
|
||||||
builder_mt:has_all :: fragment... -> boolean
|
builder_mt:has_all :: fragment... -> boolean
|
||||||
@@ -1296,6 +1306,17 @@ builder_mt:destruction_policy :: id -> builder
|
|||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
### vX.X.X
|
||||||
|
|
||||||
|
- The spawn and clone operations with defaults have been significantly optimized
|
||||||
|
- Added basic [Teal](https://github.com/teal-language) type definitions, thanks to [@p0sel0k](https://github.com/p0sel0k)
|
||||||
|
|
||||||
|
### v1.4.0
|
||||||
|
|
||||||
|
- Improved query execution performance by caching some internal calculations
|
||||||
|
- Added the universal [`builder.build`](#evolvedbuilder_mtbuild) and [`builder.multi_build`](#evolvedbuilder_mtmulti_build) methods that can be used to spawn or clone entities depending on the method arguments
|
||||||
|
- [`evolved.ON_REMOVE`](#evolvedon_remove) hooks are now invoked before the fragment is actually removed from the entity
|
||||||
|
|
||||||
### v1.3.0
|
### v1.3.0
|
||||||
|
|
||||||
- Added the new [`evolved.cancel`](#evolvedcancel) function
|
- Added the new [`evolved.cancel`](#evolvedcancel) function
|
||||||
@@ -1400,11 +1421,11 @@ function evolved.name(...) end
|
|||||||
### `evolved.pack`
|
### `evolved.pack`
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
---@param index integer
|
---@param primary integer
|
||||||
---@param version integer
|
---@param secondary integer
|
||||||
---@return evolved.id id
|
---@return evolved.id id
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function evolved.pack(index, version) end
|
function evolved.pack(primary, secondary) end
|
||||||
```
|
```
|
||||||
|
|
||||||
### `evolved.unpack`
|
### `evolved.unpack`
|
||||||
@@ -1452,6 +1473,7 @@ function evolved.spawn(components) end
|
|||||||
---@param entity_count integer
|
---@param entity_count integer
|
||||||
---@param components? table<evolved.fragment, evolved.component>
|
---@param components? table<evolved.fragment, evolved.component>
|
||||||
---@return evolved.entity[] entity_list
|
---@return evolved.entity[] entity_list
|
||||||
|
---@return integer entity_count
|
||||||
function evolved.multi_spawn(entity_count, components) end
|
function evolved.multi_spawn(entity_count, components) end
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1471,6 +1493,7 @@ function evolved.clone(prefab, components) end
|
|||||||
---@param prefab evolved.entity
|
---@param prefab evolved.entity
|
||||||
---@param components? table<evolved.fragment, evolved.component>
|
---@param components? table<evolved.fragment, evolved.component>
|
||||||
---@return evolved.entity[] entity_list
|
---@return evolved.entity[] entity_list
|
||||||
|
---@return integer entity_count
|
||||||
function evolved.multi_clone(entity_count, prefab, components) end
|
function evolved.multi_clone(entity_count, prefab, components) end
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1776,6 +1799,24 @@ function evolved.chunk_mt:components(...) end
|
|||||||
function evolved.builder() end
|
function evolved.builder() end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### `evolved.builder_mt:build`
|
||||||
|
|
||||||
|
```lua
|
||||||
|
---@param prefab? evolved.entity
|
||||||
|
---@return evolved.entity entity
|
||||||
|
function evolved.builder_mt:build(prefab) end
|
||||||
|
```
|
||||||
|
|
||||||
|
### `evolved.builder_mt:multi_build`
|
||||||
|
|
||||||
|
```lua
|
||||||
|
---@param entity_count integer
|
||||||
|
---@param prefab? evolved.entity
|
||||||
|
---@return evolved.entity[] entity_list
|
||||||
|
---@return integer entity_count
|
||||||
|
function evolved.builder_mt:multi_build(entity_count, prefab) end
|
||||||
|
```
|
||||||
|
|
||||||
#### `evolved.builder_mt:spawn`
|
#### `evolved.builder_mt:spawn`
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
@@ -1788,6 +1829,7 @@ function evolved.builder_mt:spawn() end
|
|||||||
```lua
|
```lua
|
||||||
---@param entity_count integer
|
---@param entity_count integer
|
||||||
---@return evolved.entity[] entity_list
|
---@return evolved.entity[] entity_list
|
||||||
|
---@return integer entity_count
|
||||||
function evolved.builder_mt:multi_spawn(entity_count) end
|
function evolved.builder_mt:multi_spawn(entity_count) end
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1805,6 +1847,7 @@ function evolved.builder_mt:clone(prefab) end
|
|||||||
---@param entity_count integer
|
---@param entity_count integer
|
||||||
---@param prefab evolved.entity
|
---@param prefab evolved.entity
|
||||||
---@return evolved.entity[] entity_list
|
---@return evolved.entity[] entity_list
|
||||||
|
---@return integer entity_count
|
||||||
function evolved.builder_mt:multi_clone(entity_count, prefab) end
|
function evolved.builder_mt:multi_clone(entity_count, prefab) end
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1907,7 +1950,7 @@ function evolved.builder_mt:internal() end
|
|||||||
#### `evolved.builder_mt:default`
|
#### `evolved.builder_mt:default`
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
---@param default evolved.component
|
---@param default evolved.default
|
||||||
---@return evolved.builder builder
|
---@return evolved.builder builder
|
||||||
function evolved.builder_mt:default(default) end
|
function evolved.builder_mt:default(default) end
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
## Backlog
|
## Backlog
|
||||||
|
|
||||||
- Queries can cache major chunks to avoid finding them every time.
|
|
||||||
- observers and events
|
- observers and events
|
||||||
- add INDEX fragment trait
|
- add INDEX fragment trait
|
||||||
- use compact prefix-tree for chunks
|
- use compact prefix-tree for chunks
|
||||||
@@ -11,8 +10,9 @@
|
|||||||
## Thoughts
|
## Thoughts
|
||||||
|
|
||||||
- We can return deferred status from modifying operations and spawn/clone methods.
|
- We can return deferred status from modifying operations and spawn/clone methods.
|
||||||
- Should we make one builder:build method instead of :spawn and :clone?
|
- We should have a way to not copy components on deferred spawn/clone.
|
||||||
|
|
||||||
## Known Issues
|
## Known Issues
|
||||||
|
|
||||||
- Required fragments are slower than they should be
|
- Required fragments are slower than they should be
|
||||||
|
- Errors in hooks are cannot be handled properly right now
|
||||||
@@ -1,10 +1,14 @@
|
|||||||
require 'develop.samples.systems'
|
require 'develop.samples.systems'
|
||||||
|
|
||||||
|
require 'develop.testing.build_tests'
|
||||||
require 'develop.testing.cancel_tests'
|
require 'develop.testing.cancel_tests'
|
||||||
|
require 'develop.testing.clone_tests'
|
||||||
require 'develop.testing.locate_tests'
|
require 'develop.testing.locate_tests'
|
||||||
|
require 'develop.testing.main_tests'
|
||||||
require 'develop.testing.multi_spawn_tests'
|
require 'develop.testing.multi_spawn_tests'
|
||||||
require 'develop.testing.name_tests'
|
require 'develop.testing.name_tests'
|
||||||
require 'develop.testing.requires_fragment_tests'
|
require 'develop.testing.requires_fragment_tests'
|
||||||
|
require 'develop.testing.spawn_tests'
|
||||||
require 'develop.testing.system_as_query_tests'
|
require 'develop.testing.system_as_query_tests'
|
||||||
|
|
||||||
require 'develop.benchmarks.clone_bmarks'
|
require 'develop.benchmarks.clone_bmarks'
|
||||||
@@ -14,13 +18,13 @@ require 'develop.benchmarks.process_bmarks'
|
|||||||
require 'develop.benchmarks.spawn_bmarks'
|
require 'develop.benchmarks.spawn_bmarks'
|
||||||
require 'develop.benchmarks.table_bmarks'
|
require 'develop.benchmarks.table_bmarks'
|
||||||
|
|
||||||
require 'develop.untests'
|
|
||||||
|
|
||||||
local basics = require 'develop.basics'
|
local basics = require 'develop.basics'
|
||||||
|
|
||||||
print '----------------------------------------'
|
print '----------------------------------------'
|
||||||
basics.describe_fuzz 'develop.fuzzing.destroy_fuzz'
|
basics.describe_fuzz 'develop.fuzzing.destroy_fuzz'
|
||||||
print '----------------------------------------'
|
print '----------------------------------------'
|
||||||
|
basics.describe_fuzz 'develop.fuzzing.execute_fuzz'
|
||||||
|
print '----------------------------------------'
|
||||||
basics.describe_fuzz 'develop.fuzzing.batch_destroy_fuzz'
|
basics.describe_fuzz 'develop.fuzzing.batch_destroy_fuzz'
|
||||||
print '----------------------------------------'
|
print '----------------------------------------'
|
||||||
basics.describe_fuzz 'develop.fuzzing.explicit_fuzz'
|
basics.describe_fuzz 'develop.fuzzing.explicit_fuzz'
|
||||||
|
|||||||
@@ -6,16 +6,35 @@ evo.debug_mode(false)
|
|||||||
local N = 1000
|
local N = 1000
|
||||||
|
|
||||||
local F1, F2, F3, F4, F5 = evo.id(5)
|
local F1, F2, F3, F4, F5 = evo.id(5)
|
||||||
|
local D1, D2, D3, D4, D5 = evo.id(5)
|
||||||
|
|
||||||
local Q1 = evo.builder():include(F1):spawn()
|
evo.set(D1, evo.DEFAULT, true)
|
||||||
|
evo.set(D2, evo.DEFAULT, true)
|
||||||
|
evo.set(D3, evo.DEFAULT, true)
|
||||||
|
evo.set(D4, evo.DEFAULT, true)
|
||||||
|
evo.set(D5, evo.DEFAULT, true)
|
||||||
|
|
||||||
local R1 = evo.builder():require(F1):spawn()
|
evo.set(D1, evo.DUPLICATE, function(v) return not v end)
|
||||||
local R3 = evo.builder():require(F1, F2, F3):spawn()
|
evo.set(D2, evo.DUPLICATE, function(v) return not v end)
|
||||||
local R5 = evo.builder():require(F1, F2, F3, F4, F5):spawn()
|
evo.set(D3, evo.DUPLICATE, function(v) return not v end)
|
||||||
|
evo.set(D4, evo.DUPLICATE, function(v) return not v end)
|
||||||
|
evo.set(D5, evo.DUPLICATE, function(v) return not v end)
|
||||||
|
|
||||||
|
local QF1 = evo.builder():include(F1):spawn()
|
||||||
|
local QD1 = evo.builder():include(D1):spawn()
|
||||||
|
|
||||||
|
local RF1 = evo.builder():require(F1):spawn()
|
||||||
|
local RF123 = evo.builder():require(F1, F2, F3):spawn()
|
||||||
|
local RF12345 = evo.builder():require(F1, F2, F3, F4, F5):spawn()
|
||||||
|
|
||||||
|
local RD1 = evo.builder():require(D1):spawn()
|
||||||
|
local RD123 = evo.builder():require(D1, D2, D3):spawn()
|
||||||
|
local RD12345 = evo.builder():require(D1, D2, D3, D4, D5):spawn()
|
||||||
|
|
||||||
print '----------------------------------------'
|
print '----------------------------------------'
|
||||||
|
|
||||||
basics.describe_bench(string.format('Clone Benchmarks: Simple Clone | %d entities with 1 component', N),
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Simple Clone | %d entities with 1 component', N),
|
||||||
function()
|
function()
|
||||||
local clone = evo.clone
|
local clone = evo.clone
|
||||||
|
|
||||||
@@ -25,10 +44,41 @@ basics.describe_bench(string.format('Clone Benchmarks: Simple Clone | %d entitie
|
|||||||
clone(prefab)
|
clone(prefab)
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Clone Benchmarks: Simple Clone | %d entities with 3 components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 1 component', N),
|
||||||
|
function()
|
||||||
|
local clone = evo.clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [F1] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
for _ = 1, N do
|
||||||
|
clone(prefab)
|
||||||
|
end
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Simple Clone With Defaults | %d entities with 1 component', N),
|
||||||
|
function()
|
||||||
|
local clone = evo.clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [D1] = true }
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
clone(prefab)
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Simple Clone | %d entities with 3 components', N),
|
||||||
function()
|
function()
|
||||||
local clone = evo.clone
|
local clone = evo.clone
|
||||||
|
|
||||||
@@ -38,10 +88,41 @@ basics.describe_bench(string.format('Clone Benchmarks: Simple Clone | %d entitie
|
|||||||
clone(prefab)
|
clone(prefab)
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Clone Benchmarks: Simple Clone | %d entities with 5 components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 3 components', N),
|
||||||
|
function()
|
||||||
|
local clone = evo.clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [F1] = true, [F2] = true, [F3] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
for _ = 1, N do
|
||||||
|
clone(prefab)
|
||||||
|
end
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Simple Clone With Defaults | %d entities with 3 components', N),
|
||||||
|
function()
|
||||||
|
local clone = evo.clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [D1] = true, [D2] = true, [D3] = true }
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
clone(prefab)
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Simple Clone | %d entities with 5 components', N),
|
||||||
function()
|
function()
|
||||||
local clone = evo.clone
|
local clone = evo.clone
|
||||||
|
|
||||||
@@ -51,53 +132,177 @@ basics.describe_bench(string.format('Clone Benchmarks: Simple Clone | %d entitie
|
|||||||
clone(prefab)
|
clone(prefab)
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 5 components', N),
|
||||||
|
function()
|
||||||
|
local clone = evo.clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
for _ = 1, N do
|
||||||
|
clone(prefab)
|
||||||
|
end
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Simple Clone With Defaults | %d entities with 5 components', N),
|
||||||
|
function()
|
||||||
|
local clone = evo.clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [D1] = true, [D2] = true, [D3] = true, [D4] = true, [D5] = true }
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
clone(prefab)
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
print '----------------------------------------'
|
print '----------------------------------------'
|
||||||
|
|
||||||
basics.describe_bench(string.format('Clone Benchmarks: Simple Clone | %d entities with 1 required component', N),
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Simple Clone | %d entities with 1 required component', N),
|
||||||
function()
|
function()
|
||||||
local clone = evo.clone
|
local clone = evo.clone
|
||||||
|
|
||||||
local prefab = evo.spawn { [R1] = true }
|
local prefab = evo.spawn { [RF1] = true }
|
||||||
|
|
||||||
for _ = 1, N do
|
for _ = 1, N do
|
||||||
clone(prefab)
|
clone(prefab)
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Clone Benchmarks: Simple Clone | %d entities with 3 required components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 1 required component', N),
|
||||||
function()
|
function()
|
||||||
local clone = evo.clone
|
local clone = evo.clone
|
||||||
|
|
||||||
local prefab = evo.spawn { [R3] = true }
|
local prefab = evo.spawn { [RF1] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
for _ = 1, N do
|
for _ = 1, N do
|
||||||
clone(prefab)
|
clone(prefab)
|
||||||
end
|
end
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Clone Benchmarks: Simple Clone | %d entities with 5 required components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Simple Clone With Defaults | %d entities with 1 required component', N),
|
||||||
function()
|
function()
|
||||||
local clone = evo.clone
|
local clone = evo.clone
|
||||||
|
|
||||||
local prefab = evo.spawn { [R5] = true }
|
local prefab = evo.spawn { [RD1] = true }
|
||||||
|
|
||||||
for _ = 1, N do
|
for _ = 1, N do
|
||||||
clone(prefab)
|
clone(prefab)
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Simple Clone | %d entities with 3 required components', N),
|
||||||
|
function()
|
||||||
|
local clone = evo.clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [RF123] = true }
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
clone(prefab)
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 3 required components', N),
|
||||||
|
function()
|
||||||
|
local clone = evo.clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [RF123] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
for _ = 1, N do
|
||||||
|
clone(prefab)
|
||||||
|
end
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Simple Clone With Defaults | %d entities with 3 required components', N),
|
||||||
|
function()
|
||||||
|
local clone = evo.clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [RD123] = true }
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
clone(prefab)
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Simple Clone | %d entities with 5 required components', N),
|
||||||
|
function()
|
||||||
|
local clone = evo.clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [RF12345] = true }
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
clone(prefab)
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Simple Defer Clone | %d entities with 5 required components', N),
|
||||||
|
function()
|
||||||
|
local clone = evo.clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [RF12345] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
for _ = 1, N do
|
||||||
|
clone(prefab)
|
||||||
|
end
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Simple Clone With Defaults | %d entities with 5 required components', N),
|
||||||
|
function()
|
||||||
|
local clone = evo.clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [RD12345] = true }
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
clone(prefab)
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
print '----------------------------------------'
|
print '----------------------------------------'
|
||||||
|
|
||||||
basics.describe_bench(string.format('Clone Benchmarks: Multi Clone | %d entities with 1 component', N),
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Multi Clone | %d entities with 1 component', N),
|
||||||
function()
|
function()
|
||||||
local multi_clone = evo.multi_clone
|
local multi_clone = evo.multi_clone
|
||||||
|
|
||||||
@@ -105,10 +310,37 @@ basics.describe_bench(string.format('Clone Benchmarks: Multi Clone | %d entities
|
|||||||
|
|
||||||
multi_clone(N, prefab)
|
multi_clone(N, prefab)
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Clone Benchmarks: Multi Clone | %d entities with 3 components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 1 component', N),
|
||||||
|
function()
|
||||||
|
local multi_clone = evo.multi_clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [F1] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
multi_clone(N, prefab)
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Multi Clone With Defaults | %d entities with 1 component', N),
|
||||||
|
function()
|
||||||
|
local multi_clone = evo.multi_clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [D1] = true }
|
||||||
|
|
||||||
|
multi_clone(N, prefab)
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Multi Clone | %d entities with 3 components', N),
|
||||||
function()
|
function()
|
||||||
local multi_clone = evo.multi_clone
|
local multi_clone = evo.multi_clone
|
||||||
|
|
||||||
@@ -116,10 +348,37 @@ basics.describe_bench(string.format('Clone Benchmarks: Multi Clone | %d entities
|
|||||||
|
|
||||||
multi_clone(N, prefab)
|
multi_clone(N, prefab)
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Clone Benchmarks: Multi Clone | %d entities with 5 components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 3 components', N),
|
||||||
|
function()
|
||||||
|
local multi_clone = evo.multi_clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [F1] = true, [F2] = true, [F3] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
multi_clone(N, prefab)
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Multi Clone With Defaults | %d entities with 3 components', N),
|
||||||
|
function()
|
||||||
|
local multi_clone = evo.multi_clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [D1] = true, [D2] = true, [D3] = true }
|
||||||
|
|
||||||
|
multi_clone(N, prefab)
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Multi Clone | %d entities with 5 components', N),
|
||||||
function()
|
function()
|
||||||
local multi_clone = evo.multi_clone
|
local multi_clone = evo.multi_clone
|
||||||
|
|
||||||
@@ -127,40 +386,147 @@ basics.describe_bench(string.format('Clone Benchmarks: Multi Clone | %d entities
|
|||||||
|
|
||||||
multi_clone(N, prefab)
|
multi_clone(N, prefab)
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 5 components', N),
|
||||||
|
function()
|
||||||
|
local multi_clone = evo.multi_clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
multi_clone(N, prefab)
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Multi Clone With Defaults | %d entities with 5 components', N),
|
||||||
|
function()
|
||||||
|
local multi_clone = evo.multi_clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [D1] = true, [D2] = true, [D3] = true, [D4] = true, [D5] = true }
|
||||||
|
|
||||||
|
multi_clone(N, prefab)
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
print '----------------------------------------'
|
print '----------------------------------------'
|
||||||
|
|
||||||
basics.describe_bench(string.format('Clone Benchmarks: Multi Clone | %d entities with 1 required component', N),
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Multi Clone | %d entities with 1 required component', N),
|
||||||
function()
|
function()
|
||||||
local multi_clone = evo.multi_clone
|
local multi_clone = evo.multi_clone
|
||||||
|
|
||||||
local prefab = evo.spawn { [R1] = true }
|
local prefab = evo.spawn { [RF1] = true }
|
||||||
|
|
||||||
multi_clone(N, prefab)
|
multi_clone(N, prefab)
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Clone Benchmarks: Multi Clone | %d entities with 3 required components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 1 required component', N),
|
||||||
function()
|
function()
|
||||||
local multi_clone = evo.multi_clone
|
local multi_clone = evo.multi_clone
|
||||||
|
|
||||||
local prefab = evo.spawn { [R3] = true }
|
local prefab = evo.spawn { [RF1] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
multi_clone(N, prefab)
|
multi_clone(N, prefab)
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Clone Benchmarks: Multi Clone | %d entities with 5 required components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Multi Clone With Defaults | %d entities with 1 required component', N),
|
||||||
function()
|
function()
|
||||||
local multi_clone = evo.multi_clone
|
local multi_clone = evo.multi_clone
|
||||||
|
|
||||||
local prefab = evo.spawn { [R5] = true }
|
local prefab = evo.spawn { [RD1] = true }
|
||||||
|
|
||||||
multi_clone(N, prefab)
|
multi_clone(N, prefab)
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Multi Clone | %d entities with 3 required components', N),
|
||||||
|
function()
|
||||||
|
local multi_clone = evo.multi_clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [RF123] = true }
|
||||||
|
|
||||||
|
multi_clone(N, prefab)
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 3 required components', N),
|
||||||
|
function()
|
||||||
|
local multi_clone = evo.multi_clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [RF123] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
multi_clone(N, prefab)
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Multi Clone With Defaults | %d entities with 3 required components', N),
|
||||||
|
function()
|
||||||
|
local multi_clone = evo.multi_clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [RD123] = true }
|
||||||
|
|
||||||
|
multi_clone(N, prefab)
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Multi Clone | %d entities with 5 required components', N),
|
||||||
|
function()
|
||||||
|
local multi_clone = evo.multi_clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [RF12345] = true }
|
||||||
|
|
||||||
|
multi_clone(N, prefab)
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Multi Defer Clone | %d entities with 5 required components', N),
|
||||||
|
function()
|
||||||
|
local multi_clone = evo.multi_clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [RF12345] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
multi_clone(N, prefab)
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Clone Benchmarks: Multi Clone With Defaults | %d entities with 5 required components', N),
|
||||||
|
function()
|
||||||
|
local multi_clone = evo.multi_clone
|
||||||
|
|
||||||
|
local prefab = evo.spawn { [RD12345] = true }
|
||||||
|
|
||||||
|
multi_clone(N, prefab)
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -6,16 +6,35 @@ evo.debug_mode(false)
|
|||||||
local N = 1000
|
local N = 1000
|
||||||
|
|
||||||
local F1, F2, F3, F4, F5 = evo.id(5)
|
local F1, F2, F3, F4, F5 = evo.id(5)
|
||||||
|
local D1, D2, D3, D4, D5 = evo.id(5)
|
||||||
|
|
||||||
local Q1 = evo.builder():include(F1):spawn()
|
evo.set(D1, evo.DEFAULT, true)
|
||||||
|
evo.set(D2, evo.DEFAULT, true)
|
||||||
|
evo.set(D3, evo.DEFAULT, true)
|
||||||
|
evo.set(D4, evo.DEFAULT, true)
|
||||||
|
evo.set(D5, evo.DEFAULT, true)
|
||||||
|
|
||||||
local R1 = evo.builder():require(F1):spawn()
|
evo.set(D1, evo.DUPLICATE, function(v) return not v end)
|
||||||
local R3 = evo.builder():require(F1, F2, F3):spawn()
|
evo.set(D2, evo.DUPLICATE, function(v) return not v end)
|
||||||
local R5 = evo.builder():require(F1, F2, F3, F4, F5):spawn()
|
evo.set(D3, evo.DUPLICATE, function(v) return not v end)
|
||||||
|
evo.set(D4, evo.DUPLICATE, function(v) return not v end)
|
||||||
|
evo.set(D5, evo.DUPLICATE, function(v) return not v end)
|
||||||
|
|
||||||
|
local QF1 = evo.builder():include(F1):spawn()
|
||||||
|
local QD1 = evo.builder():include(D1):spawn()
|
||||||
|
|
||||||
|
local RF1 = evo.builder():require(F1):spawn()
|
||||||
|
local RF123 = evo.builder():require(F1, F2, F3):spawn()
|
||||||
|
local RF12345 = evo.builder():require(F1, F2, F3, F4, F5):spawn()
|
||||||
|
|
||||||
|
local RD1 = evo.builder():require(D1):spawn()
|
||||||
|
local RD123 = evo.builder():require(D1, D2, D3):spawn()
|
||||||
|
local RD12345 = evo.builder():require(D1, D2, D3, D4, D5):spawn()
|
||||||
|
|
||||||
print '----------------------------------------'
|
print '----------------------------------------'
|
||||||
|
|
||||||
basics.describe_bench(string.format('Spawn Benchmarks: Simple Spawn | %d entities with 1 component', N),
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Simple Spawn | %d entities with 1 component', N),
|
||||||
function()
|
function()
|
||||||
local spawn = evo.spawn
|
local spawn = evo.spawn
|
||||||
|
|
||||||
@@ -25,10 +44,41 @@ basics.describe_bench(string.format('Spawn Benchmarks: Simple Spawn | %d entitie
|
|||||||
spawn(components)
|
spawn(components)
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Spawn Benchmarks: Simple Spawn | %d entities with 3 components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 1 component', N),
|
||||||
|
function()
|
||||||
|
local spawn = evo.spawn
|
||||||
|
|
||||||
|
local components = { [F1] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
for _ = 1, N do
|
||||||
|
spawn(components)
|
||||||
|
end
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Simple Spawn With Defaults | %d entities with 1 component', N),
|
||||||
|
function()
|
||||||
|
local spawn = evo.spawn
|
||||||
|
|
||||||
|
local components = { [D1] = true }
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
spawn(components)
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Simple Spawn | %d entities with 3 components', N),
|
||||||
function()
|
function()
|
||||||
local spawn = evo.spawn
|
local spawn = evo.spawn
|
||||||
|
|
||||||
@@ -38,10 +88,41 @@ basics.describe_bench(string.format('Spawn Benchmarks: Simple Spawn | %d entitie
|
|||||||
spawn(components)
|
spawn(components)
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Spawn Benchmarks: Simple Spawn | %d entities with 5 components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 3 components', N),
|
||||||
|
function()
|
||||||
|
local spawn = evo.spawn
|
||||||
|
|
||||||
|
local components = { [F1] = true, [F2] = true, [F3] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
for _ = 1, N do
|
||||||
|
spawn(components)
|
||||||
|
end
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Simple Spawn With Defaults | %d entities with 3 components', N),
|
||||||
|
function()
|
||||||
|
local spawn = evo.spawn
|
||||||
|
|
||||||
|
local components = { [D1] = true, [D2] = true, [D3] = true }
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
spawn(components)
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Simple Spawn | %d entities with 5 components', N),
|
||||||
function()
|
function()
|
||||||
local spawn = evo.spawn
|
local spawn = evo.spawn
|
||||||
|
|
||||||
@@ -51,53 +132,177 @@ basics.describe_bench(string.format('Spawn Benchmarks: Simple Spawn | %d entitie
|
|||||||
spawn(components)
|
spawn(components)
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 5 components', N),
|
||||||
|
function()
|
||||||
|
local spawn = evo.spawn
|
||||||
|
|
||||||
|
local components = { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
for _ = 1, N do
|
||||||
|
spawn(components)
|
||||||
|
end
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Simple Spawn With Defaults | %d entities with 5 components', N),
|
||||||
|
function()
|
||||||
|
local spawn = evo.spawn
|
||||||
|
|
||||||
|
local components = { [D1] = true, [D2] = true, [D3] = true, [D4] = true, [D5] = true }
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
spawn(components)
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
print '----------------------------------------'
|
print '----------------------------------------'
|
||||||
|
|
||||||
basics.describe_bench(string.format('Spawn Benchmarks: Simple Spawn | %d entities with 1 required component', N),
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Simple Spawn | %d entities with 1 required component', N),
|
||||||
function()
|
function()
|
||||||
local spawn = evo.spawn
|
local spawn = evo.spawn
|
||||||
|
|
||||||
local components = { [R1] = true }
|
local components = { [RF1] = true }
|
||||||
|
|
||||||
for _ = 1, N do
|
for _ = 1, N do
|
||||||
spawn(components)
|
spawn(components)
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Spawn Benchmarks: Simple Spawn | %d entities with 3 required components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 1 required component', N),
|
||||||
function()
|
function()
|
||||||
local spawn = evo.spawn
|
local spawn = evo.spawn
|
||||||
|
|
||||||
local components = { [R3] = true }
|
local components = { [RF1] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
for _ = 1, N do
|
for _ = 1, N do
|
||||||
spawn(components)
|
spawn(components)
|
||||||
end
|
end
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Spawn Benchmarks: Simple Spawn | %d entities with 5 required components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Simple Spawn With Defaults | %d entities with 1 required component', N),
|
||||||
function()
|
function()
|
||||||
local spawn = evo.spawn
|
local spawn = evo.spawn
|
||||||
|
|
||||||
local components = { [R5] = true }
|
local components = { [RD1] = true }
|
||||||
|
|
||||||
for _ = 1, N do
|
for _ = 1, N do
|
||||||
spawn(components)
|
spawn(components)
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Simple Spawn | %d entities with 3 required components', N),
|
||||||
|
function()
|
||||||
|
local spawn = evo.spawn
|
||||||
|
|
||||||
|
local components = { [RF123] = true }
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
spawn(components)
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 3 required components', N),
|
||||||
|
function()
|
||||||
|
local spawn = evo.spawn
|
||||||
|
|
||||||
|
local components = { [RF123] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
for _ = 1, N do
|
||||||
|
spawn(components)
|
||||||
|
end
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Simple Spawn With Defaults | %d entities with 3 required components', N),
|
||||||
|
function()
|
||||||
|
local spawn = evo.spawn
|
||||||
|
|
||||||
|
local components = { [RD123] = true }
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
spawn(components)
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Simple Spawn | %d entities with 5 required components', N),
|
||||||
|
function()
|
||||||
|
local spawn = evo.spawn
|
||||||
|
|
||||||
|
local components = { [RF12345] = true }
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
spawn(components)
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Simple Defer Spawn | %d entities with 5 required components', N),
|
||||||
|
function()
|
||||||
|
local spawn = evo.spawn
|
||||||
|
|
||||||
|
local components = { [RF12345] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
for _ = 1, N do
|
||||||
|
spawn(components)
|
||||||
|
end
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Simple Spawn With Defaults | %d entities with 5 required components', N),
|
||||||
|
function()
|
||||||
|
local spawn = evo.spawn
|
||||||
|
|
||||||
|
local components = { [RD12345] = true }
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
spawn(components)
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
print '----------------------------------------'
|
print '----------------------------------------'
|
||||||
|
|
||||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 1 component', N),
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Builder Spawn | %d entities with 1 component', N),
|
||||||
function()
|
function()
|
||||||
local builder = evo.builder():set(F1)
|
local builder = evo.builder():set(F1)
|
||||||
|
|
||||||
@@ -105,10 +310,37 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entiti
|
|||||||
builder:spawn()
|
builder:spawn()
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 3 components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 1 component', N),
|
||||||
|
function()
|
||||||
|
local builder = evo.builder():set(F1)
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
for _ = 1, N do
|
||||||
|
builder:spawn()
|
||||||
|
end
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Builder Spawn With Defaults | %d entities with 1 component', N),
|
||||||
|
function()
|
||||||
|
local builder = evo.builder():set(D1)
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
builder:spawn()
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Builder Spawn | %d entities with 3 components', N),
|
||||||
function()
|
function()
|
||||||
local builder = evo.builder():set(F1):set(F2):set(F3)
|
local builder = evo.builder():set(F1):set(F2):set(F3)
|
||||||
|
|
||||||
@@ -116,10 +348,37 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entiti
|
|||||||
builder:spawn()
|
builder:spawn()
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 5 components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 3 components', N),
|
||||||
|
function()
|
||||||
|
local builder = evo.builder():set(F1):set(F2):set(F3)
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
for _ = 1, N do
|
||||||
|
builder:spawn()
|
||||||
|
end
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Builder Spawn With Defaults | %d entities with 3 components', N),
|
||||||
|
function()
|
||||||
|
local builder = evo.builder():set(D1):set(D2):set(D3)
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
builder:spawn()
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Builder Spawn | %d entities with 5 components', N),
|
||||||
function()
|
function()
|
||||||
local builder = evo.builder():set(F1):set(F2):set(F3):set(F4):set(F5)
|
local builder = evo.builder():set(F1):set(F2):set(F3):set(F4):set(F5)
|
||||||
|
|
||||||
@@ -127,47 +386,155 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entiti
|
|||||||
builder:spawn()
|
builder:spawn()
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 5 components', N),
|
||||||
|
function()
|
||||||
|
local builder = evo.builder():set(F1):set(F2):set(F3):set(F4):set(F5)
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
for _ = 1, N do
|
||||||
|
builder:spawn()
|
||||||
|
end
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Builder Spawn With Defaults | %d entities with 5 components', N),
|
||||||
|
function()
|
||||||
|
local builder = evo.builder():set(D1):set(D2):set(D3):set(D4):set(D5)
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
builder:spawn()
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
print '----------------------------------------'
|
print '----------------------------------------'
|
||||||
|
|
||||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 1 required component', N),
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Builder Spawn | %d entities with 1 required component', N),
|
||||||
function()
|
function()
|
||||||
local builder = evo.builder():set(R1)
|
local builder = evo.builder():set(RF1)
|
||||||
|
|
||||||
for _ = 1, N do
|
for _ = 1, N do
|
||||||
builder:spawn()
|
builder:spawn()
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 3 required components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 1 required component', N),
|
||||||
function()
|
function()
|
||||||
local builder = evo.builder():set(R3)
|
local builder = evo.builder():set(RF1)
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
for _ = 1, N do
|
for _ = 1, N do
|
||||||
builder:spawn()
|
builder:spawn()
|
||||||
end
|
end
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 5 required components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Builder Spawn With Defaults | %d entities with 1 required component', N),
|
||||||
function()
|
function()
|
||||||
local builder = evo.builder():set(R5)
|
local builder = evo.builder():set(RD1)
|
||||||
|
|
||||||
for _ = 1, N do
|
for _ = 1, N do
|
||||||
builder:spawn()
|
builder:spawn()
|
||||||
end
|
end
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Builder Spawn | %d entities with 3 required components', N),
|
||||||
|
function()
|
||||||
|
local builder = evo.builder():set(RF123)
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
builder:spawn()
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 3 required components', N),
|
||||||
|
function()
|
||||||
|
local builder = evo.builder():set(RF123)
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
for _ = 1, N do
|
||||||
|
builder:spawn()
|
||||||
|
end
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Builder Spawn With Defaults | %d entities with 3 required components', N),
|
||||||
|
function()
|
||||||
|
local builder = evo.builder():set(RD123)
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
builder:spawn()
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Builder Spawn | %d entities with 5 required components', N),
|
||||||
|
function()
|
||||||
|
local builder = evo.builder():set(RF12345)
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
builder:spawn()
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Builder Defer Spawn | %d entities with 5 required components', N),
|
||||||
|
function()
|
||||||
|
local builder = evo.builder():set(RF12345)
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
for _ = 1, N do
|
||||||
|
builder:spawn()
|
||||||
|
end
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Builder Spawn With Defaults | %d entities with 5 required components', N),
|
||||||
|
function()
|
||||||
|
local builder = evo.builder():set(RD12345)
|
||||||
|
|
||||||
|
for _ = 1, N do
|
||||||
|
builder:spawn()
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
print '----------------------------------------'
|
print '----------------------------------------'
|
||||||
|
|
||||||
basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities with 1 component', N),
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Multi Spawn | %d entities with 1 component', N),
|
||||||
function()
|
function()
|
||||||
local multi_spawn = evo.multi_spawn
|
local multi_spawn = evo.multi_spawn
|
||||||
|
|
||||||
@@ -175,10 +542,37 @@ basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities
|
|||||||
|
|
||||||
multi_spawn(N, components)
|
multi_spawn(N, components)
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities with 3 components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 1 component', N),
|
||||||
|
function()
|
||||||
|
local multi_spawn = evo.multi_spawn
|
||||||
|
|
||||||
|
local components = { [F1] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
multi_spawn(N, components)
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Multi Spawn With Defaults | %d entities with 1 component', N),
|
||||||
|
function()
|
||||||
|
local multi_spawn = evo.multi_spawn
|
||||||
|
|
||||||
|
local components = { [D1] = true }
|
||||||
|
|
||||||
|
multi_spawn(N, components)
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Multi Spawn | %d entities with 3 components', N),
|
||||||
function()
|
function()
|
||||||
local multi_spawn = evo.multi_spawn
|
local multi_spawn = evo.multi_spawn
|
||||||
|
|
||||||
@@ -186,10 +580,37 @@ basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities
|
|||||||
|
|
||||||
multi_spawn(N, components)
|
multi_spawn(N, components)
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities with 5 components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 3 components', N),
|
||||||
|
function()
|
||||||
|
local multi_spawn = evo.multi_spawn
|
||||||
|
|
||||||
|
local components = { [F1] = true, [F2] = true, [F3] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
multi_spawn(N, components)
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Multi Spawn With Defaults | %d entities with 3 components', N),
|
||||||
|
function()
|
||||||
|
local multi_spawn = evo.multi_spawn
|
||||||
|
|
||||||
|
local components = { [D1] = true, [D2] = true, [D3] = true }
|
||||||
|
|
||||||
|
multi_spawn(N, components)
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Multi Spawn | %d entities with 5 components', N),
|
||||||
function()
|
function()
|
||||||
local multi_spawn = evo.multi_spawn
|
local multi_spawn = evo.multi_spawn
|
||||||
|
|
||||||
@@ -197,12 +618,39 @@ basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities
|
|||||||
|
|
||||||
multi_spawn(N, components)
|
multi_spawn(N, components)
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 5 components', N),
|
||||||
|
function()
|
||||||
|
local multi_spawn = evo.multi_spawn
|
||||||
|
|
||||||
|
local components = { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
multi_spawn(N, components)
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Multi Spawn With Defaults | %d entities with 5 components', N),
|
||||||
|
function()
|
||||||
|
local multi_spawn = evo.multi_spawn
|
||||||
|
|
||||||
|
local components = { [D1] = true, [D2] = true, [D3] = true, [D4] = true, [D5] = true }
|
||||||
|
|
||||||
|
multi_spawn(N, components)
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
print '----------------------------------------'
|
print '----------------------------------------'
|
||||||
|
|
||||||
basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities with 1 required component', N),
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Multi Spawn | %d entities with 1 required component', N),
|
||||||
function()
|
function()
|
||||||
local multi_spawn = evo.multi_spawn
|
local multi_spawn = evo.multi_spawn
|
||||||
|
|
||||||
@@ -210,27 +658,107 @@ basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities
|
|||||||
|
|
||||||
multi_spawn(N, components)
|
multi_spawn(N, components)
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities with 3 required components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 1 required component', N),
|
||||||
function()
|
function()
|
||||||
local multi_spawn = evo.multi_spawn
|
local multi_spawn = evo.multi_spawn
|
||||||
|
|
||||||
local components = { [R3] = true }
|
local components = { [F1] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
multi_spawn(N, components)
|
multi_spawn(N, components)
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QF1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities with 5 required components', N),
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Multi Spawn With Defaults | %d entities with 1 required component', N),
|
||||||
function()
|
function()
|
||||||
local multi_spawn = evo.multi_spawn
|
local multi_spawn = evo.multi_spawn
|
||||||
|
|
||||||
local components = { [R5] = true }
|
local components = { [D1] = true }
|
||||||
|
|
||||||
multi_spawn(N, components)
|
multi_spawn(N, components)
|
||||||
|
|
||||||
evo.batch_destroy(Q1)
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Multi Spawn | %d entities with 3 required components', N),
|
||||||
|
function()
|
||||||
|
local multi_spawn = evo.multi_spawn
|
||||||
|
|
||||||
|
local components = { [RF123] = true }
|
||||||
|
|
||||||
|
multi_spawn(N, components)
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 3 required components', N),
|
||||||
|
function()
|
||||||
|
local multi_spawn = evo.multi_spawn
|
||||||
|
|
||||||
|
local components = { [RF123] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
multi_spawn(N, components)
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Multi Spawn With Defaults | %d entities with 3 required components', N),
|
||||||
|
function()
|
||||||
|
local multi_spawn = evo.multi_spawn
|
||||||
|
|
||||||
|
local components = { [RD123] = true }
|
||||||
|
|
||||||
|
multi_spawn(N, components)
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Multi Spawn | %d entities with 5 required components', N),
|
||||||
|
function()
|
||||||
|
local multi_spawn = evo.multi_spawn
|
||||||
|
|
||||||
|
local components = { [RF12345] = true }
|
||||||
|
|
||||||
|
multi_spawn(N, components)
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Multi Defer Spawn | %d entities with 5 required components', N),
|
||||||
|
function()
|
||||||
|
local multi_spawn = evo.multi_spawn
|
||||||
|
|
||||||
|
local components = { [RF12345] = true }
|
||||||
|
|
||||||
|
evo.defer()
|
||||||
|
multi_spawn(N, components)
|
||||||
|
evo.commit()
|
||||||
|
|
||||||
|
evo.batch_destroy(QF1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
basics.describe_bench(
|
||||||
|
string.format('Spawn Benchmarks: Multi Spawn With Defaults | %d entities with 5 required components', N),
|
||||||
|
function()
|
||||||
|
local multi_spawn = evo.multi_spawn
|
||||||
|
|
||||||
|
local components = { [RD12345] = true }
|
||||||
|
|
||||||
|
multi_spawn(N, components)
|
||||||
|
|
||||||
|
evo.batch_destroy(QD1)
|
||||||
end)
|
end)
|
||||||
|
|||||||
267
develop/fuzzing/execute_fuzz.lua
Normal file
267
develop/fuzzing/execute_fuzz.lua
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
local evo = require 'evolved'
|
||||||
|
|
||||||
|
evo.debug_mode(true)
|
||||||
|
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---
|
||||||
|
|
||||||
|
local __table_unpack = (function()
|
||||||
|
---@diagnostic disable-next-line: deprecated
|
||||||
|
return table.unpack or unpack
|
||||||
|
end)()
|
||||||
|
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---
|
||||||
|
|
||||||
|
local all_fragment_list = {} ---@type evolved.fragment[]
|
||||||
|
|
||||||
|
for i = 1, math.random(1, 10) do
|
||||||
|
local fragment = evo.id()
|
||||||
|
all_fragment_list[i] = fragment
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param query evolved.query
|
||||||
|
local function generate_query(query)
|
||||||
|
local include_set = {}
|
||||||
|
local include_list = {}
|
||||||
|
local include_count = 0
|
||||||
|
|
||||||
|
for _ = 1, math.random(0, #all_fragment_list) do
|
||||||
|
local include = all_fragment_list[math.random(1, #all_fragment_list)]
|
||||||
|
|
||||||
|
if not include_set[include] then
|
||||||
|
include_count = include_count + 1
|
||||||
|
include_set[include] = include_count
|
||||||
|
include_list[include_count] = include
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local exclude_set = {}
|
||||||
|
local exclude_list = {}
|
||||||
|
local exclude_count = 0
|
||||||
|
|
||||||
|
for _ = 1, math.random(0, #all_fragment_list) do
|
||||||
|
local exclude = all_fragment_list[math.random(1, #all_fragment_list)]
|
||||||
|
|
||||||
|
if not exclude_set[exclude] then
|
||||||
|
exclude_count = exclude_count + 1
|
||||||
|
exclude_set[exclude] = exclude_count
|
||||||
|
exclude_list[exclude_count] = exclude
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if include_count > 0 then
|
||||||
|
evo.set(query, evo.INCLUDES, include_list)
|
||||||
|
end
|
||||||
|
|
||||||
|
if exclude_count > 0 then
|
||||||
|
evo.set(query, evo.EXCLUDES, exclude_list)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param query_count integer
|
||||||
|
---@return evolved.query[] query_list
|
||||||
|
---@return integer query_count
|
||||||
|
---@nodiscard
|
||||||
|
local function generate_queries(query_count)
|
||||||
|
local query_list = {} ---@type evolved.query[]
|
||||||
|
|
||||||
|
for i = 1, query_count do
|
||||||
|
local query = evo.id()
|
||||||
|
query_list[i] = query
|
||||||
|
generate_query(query)
|
||||||
|
end
|
||||||
|
|
||||||
|
return query_list, query_count
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param entity evolved.entity
|
||||||
|
local function generate_entity(entity)
|
||||||
|
for _ = 0, math.random(0, #all_fragment_list) do
|
||||||
|
local fragment = all_fragment_list[math.random(1, #all_fragment_list)]
|
||||||
|
evo.set(entity, fragment)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param entity_count integer
|
||||||
|
---@return evolved.entity[] entity_list
|
||||||
|
---@return integer entity_count
|
||||||
|
local function generate_entities(entity_count)
|
||||||
|
local entity_list = {} ---@type evolved.entity[]
|
||||||
|
|
||||||
|
for i = 1, entity_count do
|
||||||
|
local entity = evo.id()
|
||||||
|
entity_list[i] = entity
|
||||||
|
generate_entity(entity)
|
||||||
|
end
|
||||||
|
|
||||||
|
return entity_list, entity_count
|
||||||
|
end
|
||||||
|
|
||||||
|
local pre_query_list, pre_query_count = generate_queries(math.random(1, 10))
|
||||||
|
local pre_entity_list, pre_entity_count = generate_entities(math.random(1, 10))
|
||||||
|
|
||||||
|
for _ = 1, math.random(1, 5) do
|
||||||
|
local fragment = all_fragment_list[math.random(1, #all_fragment_list)]
|
||||||
|
|
||||||
|
evo.set(fragment, evo.EXPLICIT)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _ = 1, math.random(1, 5) do
|
||||||
|
local query = pre_query_list[math.random(1, pre_query_count)]
|
||||||
|
|
||||||
|
if math.random(1, 2) == 1 then
|
||||||
|
generate_query(query)
|
||||||
|
else
|
||||||
|
if math.random(1, 2) == 1 then
|
||||||
|
evo.remove(query, evo.INCLUDES)
|
||||||
|
else
|
||||||
|
evo.remove(query, evo.EXCLUDES)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local post_query_list, post_query_count = generate_queries(math.random(1, 10))
|
||||||
|
local post_entity_list, post_entity_count = generate_entities(math.random(1, 10))
|
||||||
|
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---
|
||||||
|
|
||||||
|
local all_query_list = {}
|
||||||
|
local all_query_count = 0
|
||||||
|
local all_entity_list = {}
|
||||||
|
local all_entity_count = 0
|
||||||
|
|
||||||
|
for i = 1, pre_query_count do
|
||||||
|
all_query_count = all_query_count + 1
|
||||||
|
all_query_list[all_query_count] = pre_query_list[i]
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, post_query_count do
|
||||||
|
all_query_count = all_query_count + 1
|
||||||
|
all_query_list[all_query_count] = post_query_list[i]
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, pre_entity_count do
|
||||||
|
all_entity_count = all_entity_count + 1
|
||||||
|
all_entity_list[all_entity_count] = pre_entity_list[i]
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, post_entity_count do
|
||||||
|
all_entity_count = all_entity_count + 1
|
||||||
|
all_entity_list[all_entity_count] = post_entity_list[i]
|
||||||
|
end
|
||||||
|
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---
|
||||||
|
|
||||||
|
local function execute_query(query)
|
||||||
|
local query_chunk_set = {}
|
||||||
|
local query_entity_set = {}
|
||||||
|
|
||||||
|
local query_include_list = evo.get(query, evo.INCLUDES) or {}
|
||||||
|
local query_exclude_list = evo.get(query, evo.EXCLUDES) or {}
|
||||||
|
|
||||||
|
local query_include_set = {}
|
||||||
|
for _, include in ipairs(query_include_list) do
|
||||||
|
query_include_set[include] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
for chunk, entity_list, entity_count in evo.execute(query) do
|
||||||
|
assert(not query_chunk_set[chunk])
|
||||||
|
query_chunk_set[chunk] = true
|
||||||
|
|
||||||
|
for i = 1, entity_count do
|
||||||
|
local entity = entity_list[i]
|
||||||
|
assert(not query_entity_set[entity])
|
||||||
|
query_entity_set[entity] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(chunk:has_all(__table_unpack(query_include_list)))
|
||||||
|
assert(not chunk:has_any(__table_unpack(query_exclude_list)))
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, all_entity_count do
|
||||||
|
local entity = all_entity_list[i]
|
||||||
|
|
||||||
|
local is_entity_matched =
|
||||||
|
evo.has_all(entity, __table_unpack(query_include_list))
|
||||||
|
and not evo.has_any(entity, __table_unpack(query_exclude_list))
|
||||||
|
|
||||||
|
for fragment in evo.each(entity) do
|
||||||
|
if evo.has(fragment, evo.EXPLICIT) and not query_include_set[fragment] then
|
||||||
|
is_entity_matched = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if is_entity_matched then
|
||||||
|
assert(query_entity_set[entity])
|
||||||
|
else
|
||||||
|
assert(not query_entity_set[entity])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, all_query_count do
|
||||||
|
execute_query(all_query_list[i])
|
||||||
|
end
|
||||||
|
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---
|
||||||
|
|
||||||
|
for _ = 1, math.random(1, 5) do
|
||||||
|
local fragment = all_fragment_list[math.random(1, #all_fragment_list)]
|
||||||
|
|
||||||
|
evo.set(fragment, evo.EXPLICIT)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _ = 1, math.random(1, 5) do
|
||||||
|
local query = pre_query_list[math.random(1, pre_query_count)]
|
||||||
|
|
||||||
|
if math.random(1, 2) == 1 then
|
||||||
|
generate_query(query)
|
||||||
|
else
|
||||||
|
if math.random(1, 2) == 1 then
|
||||||
|
evo.remove(query, evo.INCLUDES)
|
||||||
|
else
|
||||||
|
evo.remove(query, evo.EXCLUDES)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, all_query_count do
|
||||||
|
execute_query(all_query_list[i])
|
||||||
|
end
|
||||||
|
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---
|
||||||
|
|
||||||
|
if math.random(1, 2) == 1 then
|
||||||
|
evo.collect_garbage()
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.destroy(__table_unpack(all_query_list))
|
||||||
|
evo.destroy(__table_unpack(all_entity_list))
|
||||||
|
evo.destroy(__table_unpack(all_fragment_list))
|
||||||
|
|
||||||
|
if math.random(1, 2) == 1 then
|
||||||
|
evo.collect_garbage()
|
||||||
|
end
|
||||||
41
develop/testing/build_tests.lua
Normal file
41
develop/testing/build_tests.lua
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
local evo = require 'evolved'
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2 = evo.id(2)
|
||||||
|
|
||||||
|
do
|
||||||
|
local e = evo.builder():set(f1, 42):set(f2, 'hello'):build()
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == 'hello')
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.builder():set(f1, 42):build()
|
||||||
|
local e = evo.builder():set(f2, 'hello'):build(p)
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == 'hello')
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local entity_list, entity_count = evo.builder():set(f1, 42):set(f2, 'hello'):multi_build(5)
|
||||||
|
assert(entity_count == 5)
|
||||||
|
|
||||||
|
for i = 1, entity_count do
|
||||||
|
local e = entity_list[i]
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == 'hello')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.builder():set(f1, 42):build()
|
||||||
|
local entity_list, entity_count = evo.builder():set(f2, 'hello'):multi_build(5, p)
|
||||||
|
assert(entity_count == 5)
|
||||||
|
|
||||||
|
for i = 1, entity_count do
|
||||||
|
local e = entity_list[i]
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == 'hello')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
397
develop/testing/clone_tests.lua
Normal file
397
develop/testing/clone_tests.lua
Normal file
@@ -0,0 +1,397 @@
|
|||||||
|
local evo = require 'evolved'
|
||||||
|
|
||||||
|
do
|
||||||
|
do
|
||||||
|
local p = evo.spawn()
|
||||||
|
local e = evo.clone(p)
|
||||||
|
assert(evo.alive(e) and evo.empty(e))
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn()
|
||||||
|
local e = evo.clone(p, {})
|
||||||
|
assert(evo.alive(e) and evo.empty(e))
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2 = evo.id(2)
|
||||||
|
evo.set(f1, evo.REQUIRES, { f2 })
|
||||||
|
evo.set(f2, evo.DEFAULT, 42)
|
||||||
|
|
||||||
|
local p = evo.spawn()
|
||||||
|
local e = evo.clone(p, { [f1] = 'hello' })
|
||||||
|
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2))
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 'hello')
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == 42)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2, f3, f4 = evo.id(4)
|
||||||
|
evo.set(f1, evo.TAG)
|
||||||
|
evo.set(f1, evo.REQUIRES, { f2, f3 })
|
||||||
|
evo.set(f4, evo.UNIQUE)
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f4] = 'unique' }
|
||||||
|
local e = evo.clone(p)
|
||||||
|
assert(evo.alive(e) and evo.empty(e))
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f4] = 'unique' }
|
||||||
|
local e = evo.clone(p, {})
|
||||||
|
assert(evo.alive(e) and evo.empty(e))
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f4] = 'unique' }
|
||||||
|
local e = evo.clone(p, { [f4] = 'another' })
|
||||||
|
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f4))
|
||||||
|
assert(evo.has(e, f4) and evo.get(e, f4) == 'another')
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||||
|
local e = evo.clone(p, { [f4] = 'another' })
|
||||||
|
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f2, f4))
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == 100)
|
||||||
|
assert(evo.has(e, f4) and evo.get(e, f4) == 'another')
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||||
|
local e = evo.clone(p, { [f1] = 'hello', [f3] = 10 })
|
||||||
|
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2, f3))
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == nil)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == 100)
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3) == 10)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
do
|
||||||
|
local f1, f2, f3, f4 = evo.id(4)
|
||||||
|
evo.set(f4, evo.TAG)
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f2] = 21, [f3] = 'hello', [f4] = true }
|
||||||
|
local e = evo.clone(p, { [f1] = 'world', [f2] = 10 })
|
||||||
|
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2, f3, f4))
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 'world')
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == 10)
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3) == 'hello')
|
||||||
|
assert(evo.has(e, f4) and evo.get(e, f4) == nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2, f3, f4 = evo.id(4)
|
||||||
|
evo.set(f2, evo.DEFAULT, 42)
|
||||||
|
evo.set(f3, evo.DUPLICATE, function() return nil end)
|
||||||
|
evo.set(f4, evo.TAG)
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f2] = 21, [f3] = 'hello', [f4] = true }
|
||||||
|
local e = evo.clone(p, { [f1] = 'world', [f2] = 10 })
|
||||||
|
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2, f3, f4))
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 'world')
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == 10)
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3) == true)
|
||||||
|
assert(evo.has(e, f4) and evo.get(e, f4) == nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2, f3, f4 = evo.id(4)
|
||||||
|
evo.set(f1, evo.TAG)
|
||||||
|
evo.set(f1, evo.REQUIRES, { f2, f3 })
|
||||||
|
evo.set(f2, evo.DEFAULT, 42)
|
||||||
|
evo.set(f2, evo.DUPLICATE, function(v) return v * 2 end)
|
||||||
|
evo.set(f3, evo.DUPLICATE, function() return nil end)
|
||||||
|
evo.set(f4, evo.UNIQUE)
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f4] = 'unique' }
|
||||||
|
local e = evo.clone(p)
|
||||||
|
assert(evo.alive(e) and evo.empty(e))
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f4] = 'unique' }
|
||||||
|
local e = evo.clone(p, {})
|
||||||
|
assert(evo.alive(e) and evo.empty(e))
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f4] = 'unique' }
|
||||||
|
local e = evo.clone(p, { [f4] = 'another' })
|
||||||
|
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f4))
|
||||||
|
assert(evo.has(e, f4) and evo.get(e, f4) == 'another')
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||||
|
local e = evo.clone(p, { [f4] = 'another' })
|
||||||
|
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f2, f4))
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == 200 * 2)
|
||||||
|
assert(evo.has(e, f4) and evo.get(e, f4) == 'another')
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||||
|
local e = evo.clone(p, { [f1] = 'hello', [f2] = 10 })
|
||||||
|
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2, f3))
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == nil)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == 10 * 2)
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3) == true)
|
||||||
|
end
|
||||||
|
|
||||||
|
local f1_set_count, f1_inserted_count = 0, 0
|
||||||
|
local f2_set_sum, f3_inserted_count = 0, 0
|
||||||
|
|
||||||
|
evo.set(f1, evo.ON_SET, function(e, f, c)
|
||||||
|
assert(evo.get(e, f) == c)
|
||||||
|
f1_set_count = f1_set_count + 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f1, evo.ON_INSERT, function(e, f, c)
|
||||||
|
assert(evo.get(e, f) == c)
|
||||||
|
f1_inserted_count = f1_inserted_count + 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f2, evo.ON_SET, function(e, f, c)
|
||||||
|
assert(evo.get(e, f) == c)
|
||||||
|
f2_set_sum = f2_set_sum + c
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f3, evo.ON_INSERT, function(e, f, c)
|
||||||
|
assert(evo.get(e, f) == c)
|
||||||
|
f3_inserted_count = f3_inserted_count + 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
do
|
||||||
|
f1_set_count, f1_inserted_count = 0, 0
|
||||||
|
f2_set_sum, f3_inserted_count = 0, 0
|
||||||
|
|
||||||
|
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||||
|
local e = evo.clone(p, { [f1] = 'hello', [f2] = 10 })
|
||||||
|
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2, f3))
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == nil)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == 10 * 2)
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3) == true)
|
||||||
|
|
||||||
|
assert(f1_set_count == 1)
|
||||||
|
assert(f1_inserted_count == 1)
|
||||||
|
assert(f2_set_sum == 100 * 2 + 10 * 2)
|
||||||
|
assert(f3_inserted_count == 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2, f3, f4 = evo.id(4)
|
||||||
|
evo.set(f1, evo.TAG)
|
||||||
|
evo.set(f1, evo.REQUIRES, { f2, f3 })
|
||||||
|
evo.set(f4, evo.UNIQUE)
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f4] = 'unique' }
|
||||||
|
local es, ec = evo.multi_clone(1, p)
|
||||||
|
assert(#es == 1 and ec == 1)
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and evo.empty(es[i]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f4] = 'unique' }
|
||||||
|
local es, ec = evo.multi_clone(2, p, {})
|
||||||
|
assert(#es == 2 and ec == 2)
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and evo.empty(es[i]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f4] = 'unique' }
|
||||||
|
local es, ec = evo.multi_clone(3, p, { [f4] = 'another' })
|
||||||
|
assert(#es == 3 and ec == 3)
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f4))
|
||||||
|
assert(evo.has(es[i], f4) and evo.get(es[i], f4) == 'another')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||||
|
local es, ec = evo.multi_clone(4, p, { [f4] = 'another' })
|
||||||
|
assert(#es == 4 and ec == 4)
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f2, f4))
|
||||||
|
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 100)
|
||||||
|
assert(evo.has(es[i], f4) and evo.get(es[i], f4) == 'another')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||||
|
local es, ec = evo.multi_clone(5, p, { [f1] = 'hello', [f3] = 10 })
|
||||||
|
assert(#es == 5 and ec == 5)
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2, f3))
|
||||||
|
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == nil)
|
||||||
|
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 100)
|
||||||
|
assert(evo.has(es[i], f3) and evo.get(es[i], f3) == 10)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
do
|
||||||
|
local f1, f2, f3, f4 = evo.id(4)
|
||||||
|
evo.set(f4, evo.TAG)
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f2] = 21, [f3] = 'hello', [f4] = true }
|
||||||
|
local es, ec = evo.multi_clone(2, p, { [f1] = 'world', [f2] = 10 })
|
||||||
|
assert(#es == 2 and ec == 2)
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2, f3, f4))
|
||||||
|
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 'world')
|
||||||
|
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 10)
|
||||||
|
assert(evo.has(es[i], f3) and evo.get(es[i], f3) == 'hello')
|
||||||
|
assert(evo.has(es[i], f4) and evo.get(es[i], f4) == nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2, f3, f4 = evo.id(4)
|
||||||
|
evo.set(f2, evo.DEFAULT, 42)
|
||||||
|
evo.set(f3, evo.DUPLICATE, function() return nil end)
|
||||||
|
evo.set(f4, evo.TAG)
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f2] = 21, [f3] = 'hello', [f4] = true }
|
||||||
|
local es, ec = evo.multi_clone(2, p, { [f1] = 'world', [f2] = 10 })
|
||||||
|
assert(#es == 2 and ec == 2)
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2, f3, f4))
|
||||||
|
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 'world')
|
||||||
|
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 10)
|
||||||
|
assert(evo.has(es[i], f3) and evo.get(es[i], f3) == true)
|
||||||
|
assert(evo.has(es[i], f4) and evo.get(es[i], f4) == nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2, f3, f4 = evo.id(4)
|
||||||
|
evo.set(f1, evo.TAG)
|
||||||
|
evo.set(f1, evo.REQUIRES, { f2, f3 })
|
||||||
|
evo.set(f2, evo.DEFAULT, 42)
|
||||||
|
evo.set(f2, evo.DUPLICATE, function(v) return v * 2 end)
|
||||||
|
evo.set(f3, evo.DUPLICATE, function() return nil end)
|
||||||
|
evo.set(f4, evo.UNIQUE)
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f4] = 'unique' }
|
||||||
|
local es, ec = evo.multi_clone(3, p)
|
||||||
|
assert(#es == 3 and ec == 3)
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and evo.empty(es[i]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f4] = 'unique' }
|
||||||
|
local es, ec = evo.multi_clone(3, p, {})
|
||||||
|
assert(#es == 3 and ec == 3)
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and evo.empty(es[i]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f4] = 'unique' }
|
||||||
|
local es, ec = evo.multi_clone(2, p, { [f4] = 'another' })
|
||||||
|
assert(#es == 2 and ec == 2)
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f4))
|
||||||
|
assert(evo.has(es[i], f4) and evo.get(es[i], f4) == 'another')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||||
|
local es, ec = evo.multi_clone(4, p, { [f4] = 'another' })
|
||||||
|
assert(#es == 4 and ec == 4)
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f2, f4))
|
||||||
|
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 200 * 2)
|
||||||
|
assert(evo.has(es[i], f4) and evo.get(es[i], f4) == 'another')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||||
|
local es, ec = evo.multi_clone(5, p, { [f1] = 'hello', [f2] = 10 })
|
||||||
|
assert(#es == 5 and ec == 5)
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2, f3))
|
||||||
|
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == nil)
|
||||||
|
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 10 * 2)
|
||||||
|
assert(evo.has(es[i], f3) and evo.get(es[i], f3) == true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local f1_set_count, f1_inserted_count = 0, 0
|
||||||
|
local f2_set_sum, f3_inserted_count = 0, 0
|
||||||
|
|
||||||
|
evo.set(f1, evo.ON_SET, function(e, f, c)
|
||||||
|
assert(evo.get(e, f) == c)
|
||||||
|
f1_set_count = f1_set_count + 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f1, evo.ON_INSERT, function(e, f, c)
|
||||||
|
assert(evo.get(e, f) == c)
|
||||||
|
f1_inserted_count = f1_inserted_count + 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f2, evo.ON_SET, function(e, f, c)
|
||||||
|
assert(evo.get(e, f) == c)
|
||||||
|
f2_set_sum = f2_set_sum + c
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f3, evo.ON_INSERT, function(e, f, c)
|
||||||
|
assert(evo.get(e, f) == c)
|
||||||
|
f3_inserted_count = f3_inserted_count + 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
do
|
||||||
|
f1_set_count, f1_inserted_count = 0, 0
|
||||||
|
f2_set_sum, f3_inserted_count = 0, 0
|
||||||
|
|
||||||
|
local p = evo.spawn { [f2] = 100, [f4] = 'unique' }
|
||||||
|
local es, ec = evo.multi_clone(1, p, { [f1] = 'hello', [f2] = 10 })
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2, f3))
|
||||||
|
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == nil)
|
||||||
|
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 10 * 2)
|
||||||
|
assert(evo.has(es[i], f3) and evo.get(es[i], f3) == true)
|
||||||
|
|
||||||
|
assert(f1_set_count == 1)
|
||||||
|
assert(f1_inserted_count == 1)
|
||||||
|
assert(f2_set_sum == 100 * 2 + 10 * 2)
|
||||||
|
assert(f3_inserted_count == 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -2530,7 +2530,7 @@ do
|
|||||||
end)
|
end)
|
||||||
:on_remove(function(e, f, c)
|
:on_remove(function(e, f, c)
|
||||||
f2_remove_count = f2_remove_count + 1
|
f2_remove_count = f2_remove_count + 1
|
||||||
assert(evo.get(e, f) == nil)
|
assert(evo.get(e, f) == c)
|
||||||
assert(evo.alive(f))
|
assert(evo.alive(f))
|
||||||
assert(c == 82)
|
assert(c == 82)
|
||||||
end)
|
end)
|
||||||
@@ -3321,7 +3321,7 @@ do
|
|||||||
remove_count = remove_count + 1
|
remove_count = remove_count + 1
|
||||||
assert(f == f1)
|
assert(f == f1)
|
||||||
assert(c == 51)
|
assert(c == 51)
|
||||||
assert(evo.get(e, f1) == nil)
|
assert(evo.get(e, f1) == c)
|
||||||
|
|
||||||
do
|
do
|
||||||
evo.remove(e, f2)
|
evo.remove(e, f2)
|
||||||
@@ -3348,7 +3348,7 @@ do
|
|||||||
remove_count = remove_count + 1
|
remove_count = remove_count + 1
|
||||||
assert(f == f2)
|
assert(f == f2)
|
||||||
assert(c == 51)
|
assert(c == 51)
|
||||||
assert(evo.get(e, f2) == nil)
|
assert(evo.get(e, f2) == c)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -3518,8 +3518,7 @@ do
|
|||||||
assert(e == e1 or e == e2)
|
assert(e == e1 or e == e2)
|
||||||
assert(f == f1)
|
assert(f == f1)
|
||||||
assert(c == 51)
|
assert(c == 51)
|
||||||
assert(evo.get(e1, f1) == nil)
|
assert(evo.get(e, f) == c)
|
||||||
assert(evo.get(e2, f1) == nil)
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
do
|
do
|
||||||
@@ -6449,3 +6448,650 @@ do
|
|||||||
assert(b:has_all() and not b:has_any())
|
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))
|
assert(b:has(ff) and b:has(ft) and b:has_all(ff, ft) and b:has_any(ff, ft))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
do
|
||||||
|
local f = evo.id()
|
||||||
|
local q = evo.builder():include(f):spawn()
|
||||||
|
local e = evo.builder():set(f, 42):spawn()
|
||||||
|
|
||||||
|
local iter, state = evo.execute(q)
|
||||||
|
local chunk, entity_list, entity_count = iter(state)
|
||||||
|
assert(chunk and entity_list and entity_count)
|
||||||
|
assert(chunk == evo.chunk(f) and entity_count == 1 and entity_list[1] == e)
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f = evo.id()
|
||||||
|
local e = evo.builder():set(f, 42):spawn()
|
||||||
|
local q = evo.builder():include(f):spawn()
|
||||||
|
|
||||||
|
local iter, state = evo.execute(q)
|
||||||
|
local chunk, entity_list, entity_count = iter(state)
|
||||||
|
assert(chunk and entity_list and entity_count)
|
||||||
|
assert(chunk == evo.chunk(f) and entity_count == 1 and entity_list[1] == e)
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2 = evo.id(2)
|
||||||
|
local q = evo.builder():exclude(f2):spawn()
|
||||||
|
local e = evo.builder():set(f1, 42):spawn()
|
||||||
|
|
||||||
|
local e_count = 0
|
||||||
|
|
||||||
|
for chunk, entity_list, entity_count in evo.execute(q) do
|
||||||
|
for i = 1, entity_count do
|
||||||
|
if entity_list[i] == e then
|
||||||
|
e_count = e_count + 1
|
||||||
|
assert(chunk == evo.chunk(f1))
|
||||||
|
assert(chunk:components(f1)[1] == 42)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(e_count == 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2, f3 = evo.id(3)
|
||||||
|
local q = evo.builder():exclude(f2):spawn()
|
||||||
|
local e1 = evo.builder():set(f1, 42):spawn()
|
||||||
|
local e2 = evo.builder():set(f1, 42):set(f3, 21):spawn()
|
||||||
|
|
||||||
|
local e1_count, e2_count = 0, 0
|
||||||
|
|
||||||
|
for chunk, entity_list, entity_count in evo.execute(q) do
|
||||||
|
for i = 1, entity_count do
|
||||||
|
if entity_list[i] == e1 then
|
||||||
|
e1_count = e1_count + 1
|
||||||
|
assert(chunk == evo.chunk(f1))
|
||||||
|
assert(chunk:components(f1)[1] == 42)
|
||||||
|
end
|
||||||
|
|
||||||
|
if entity_list[i] == e2 then
|
||||||
|
e2_count = e2_count + 1
|
||||||
|
assert(chunk == evo.chunk(f1, f3))
|
||||||
|
assert(chunk:components(f1)[1] == 42)
|
||||||
|
assert(chunk:components(f3)[1] == 21)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(e1_count == 1)
|
||||||
|
assert(e2_count == 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2 = evo.id(2)
|
||||||
|
local e = evo.builder():set(f1, 42):spawn()
|
||||||
|
local q = evo.builder():exclude(f2):spawn()
|
||||||
|
|
||||||
|
local e_count = 0
|
||||||
|
|
||||||
|
for chunk, entity_list, entity_count in evo.execute(q) do
|
||||||
|
for i = 1, entity_count do
|
||||||
|
if entity_list[i] == e then
|
||||||
|
e_count = e_count + 1
|
||||||
|
assert(chunk == evo.chunk(f1))
|
||||||
|
assert(chunk:components(f1)[1] == 42)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(e_count == 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2, f3 = evo.id(3)
|
||||||
|
local e1 = evo.builder():set(f1, 42):spawn()
|
||||||
|
local e2 = evo.builder():set(f1, 42):set(f3, 21):spawn()
|
||||||
|
local q = evo.builder():exclude(f2):spawn()
|
||||||
|
|
||||||
|
local e1_count, e2_count = 0, 0
|
||||||
|
|
||||||
|
for chunk, entity_list, entity_count in evo.execute(q) do
|
||||||
|
for i = 1, entity_count do
|
||||||
|
if entity_list[i] == e1 then
|
||||||
|
e1_count = e1_count + 1
|
||||||
|
assert(chunk == evo.chunk(f1))
|
||||||
|
assert(chunk:components(f1)[1] == 42)
|
||||||
|
end
|
||||||
|
|
||||||
|
if entity_list[i] == e2 then
|
||||||
|
e2_count = e2_count + 1
|
||||||
|
assert(chunk == evo.chunk(f1, f3))
|
||||||
|
assert(chunk:components(f1)[1] == 42)
|
||||||
|
assert(chunk:components(f3)[1] == 21)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(e1_count == 1)
|
||||||
|
assert(e2_count == 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2 = evo.id(2)
|
||||||
|
local q1 = evo.builder():include(f1):spawn()
|
||||||
|
local q2 = evo.builder():include(f2):spawn()
|
||||||
|
local e12 = evo.builder():set(f1, 42):set(f2, 21):spawn()
|
||||||
|
|
||||||
|
do
|
||||||
|
local iter, state = evo.execute(q1)
|
||||||
|
local chunk, entity_list, entity_count = iter(state)
|
||||||
|
assert(chunk and entity_list and entity_count)
|
||||||
|
assert(chunk == evo.chunk(f1, f2) and entity_count == 1 and entity_list[1] == e12)
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local iter, state = evo.execute(q2)
|
||||||
|
local chunk, entity_list, entity_count = iter(state)
|
||||||
|
assert(chunk and entity_list and entity_count)
|
||||||
|
assert(chunk == evo.chunk(f1, f2) and entity_count == 1 and entity_list[1] == e12)
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.set(f1, evo.EXPLICIT)
|
||||||
|
|
||||||
|
do
|
||||||
|
local iter, state = evo.execute(q1)
|
||||||
|
local chunk, entity_list, entity_count = iter(state)
|
||||||
|
assert(chunk and entity_list and entity_count)
|
||||||
|
assert(chunk == evo.chunk(f1, f2) and entity_count == 1 and entity_list[1] == e12)
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local iter, state = evo.execute(q2)
|
||||||
|
local chunk, entity_list, entity_count = iter(state)
|
||||||
|
assert(not chunk and not entity_list and not entity_count)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local function v2(x, y) return { x = x or 0, y = y or 0 } end
|
||||||
|
local function v2_clone(v) return { x = v.x, y = v.y } end
|
||||||
|
|
||||||
|
local f1, f2 = evo.id(2)
|
||||||
|
|
||||||
|
local f1_default = v2(1, 2)
|
||||||
|
local f2_default = v2(3, 4)
|
||||||
|
|
||||||
|
evo.set(f1, evo.DEFAULT, f1_default)
|
||||||
|
evo.set(f2, evo.DEFAULT, f2_default)
|
||||||
|
|
||||||
|
evo.set(f1, evo.DUPLICATE, v2_clone)
|
||||||
|
evo.set(f2, evo.DUPLICATE, v2_clone)
|
||||||
|
|
||||||
|
local e1 = evo.builder():set(f1, v2(10, 11)):spawn()
|
||||||
|
local e2 = evo.builder():set(f1, v2(12, 13)):set(f2, v2(14, 15)):spawn()
|
||||||
|
|
||||||
|
do
|
||||||
|
assert(evo.has(e1, f1) and evo.get(e1, f1).x == 10 and evo.get(e1, f1).y == 11)
|
||||||
|
assert(evo.get(e1, f1) ~= f1_default)
|
||||||
|
|
||||||
|
assert(evo.has(e2, f1) and evo.get(e2, f1).x == 12 and evo.get(e2, f1).y == 13)
|
||||||
|
assert(evo.get(e2, f1) ~= f1_default)
|
||||||
|
assert(evo.has(e2, f2) and evo.get(e2, f2).x == 14 and evo.get(e2, f2).y == 15)
|
||||||
|
assert(evo.get(e2, f2) ~= f2_default)
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.set(f1, evo.TAG)
|
||||||
|
|
||||||
|
do
|
||||||
|
assert(evo.has(e1, f1) and evo.get(e1, f1) == nil)
|
||||||
|
|
||||||
|
assert(evo.has(e2, f1) and evo.get(e2, f1) == nil)
|
||||||
|
assert(evo.has(e2, f2) and evo.get(e2, f2).x == 14 and evo.get(e2, f2).y == 15)
|
||||||
|
assert(evo.get(e2, f2) ~= f2_default)
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.remove(f1, evo.TAG)
|
||||||
|
|
||||||
|
do
|
||||||
|
assert(evo.has(e1, f1) and evo.get(e1, f1).x == 1 and evo.get(e1, f1).y == 2)
|
||||||
|
assert(evo.get(e1, f1) ~= f1_default)
|
||||||
|
|
||||||
|
assert(evo.has(e2, f1) and evo.get(e2, f1).x == 1 and evo.get(e2, f1).y == 2)
|
||||||
|
assert(evo.get(e2, f1) ~= f1_default)
|
||||||
|
assert(evo.has(e2, f2) and evo.get(e2, f2).x == 14 and evo.get(e2, f2).y == 15)
|
||||||
|
assert(evo.get(e2, f2) ~= f2_default)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2, f3 = evo.id(3)
|
||||||
|
|
||||||
|
evo.set(f1, evo.REQUIRES, { f2, f3 })
|
||||||
|
evo.set(f2, evo.DEFAULT, false)
|
||||||
|
evo.set(f3, evo.TAG)
|
||||||
|
|
||||||
|
local v_set_sum = 0
|
||||||
|
local v_insert_sum = 0
|
||||||
|
|
||||||
|
local f3_set_times = 0
|
||||||
|
local f3_insert_times = 0
|
||||||
|
|
||||||
|
evo.set(f1, evo.ON_SET, function(e, f, v)
|
||||||
|
assert(f == f1)
|
||||||
|
v_set_sum = v_set_sum + v
|
||||||
|
assert(evo.get(e, f) == v)
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f1, evo.ON_INSERT, function(e, f, v)
|
||||||
|
assert(f == f1)
|
||||||
|
v_insert_sum = v_insert_sum + v
|
||||||
|
assert(evo.get(e, f) == v)
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f3, evo.ON_SET, function(e, f, v)
|
||||||
|
assert(f == f3)
|
||||||
|
f3_set_times = f3_set_times + 1
|
||||||
|
assert(v == nil)
|
||||||
|
assert(evo.has(e, f))
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f3, evo.ON_INSERT, function(e, f, v)
|
||||||
|
assert(f == f3)
|
||||||
|
f3_insert_times = f3_insert_times + 1
|
||||||
|
assert(v == nil)
|
||||||
|
assert(evo.has(e, f))
|
||||||
|
end)
|
||||||
|
|
||||||
|
do
|
||||||
|
local e = evo.spawn({ [f1] = 42 })
|
||||||
|
assert(e and not evo.empty(e))
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == false)
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local entity_prefab = evo.builder():set(f1, 42):spawn()
|
||||||
|
|
||||||
|
local e = evo.clone(entity_prefab)
|
||||||
|
assert(e and not evo.empty(e))
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == false)
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local entity_prefab = evo.builder():set(f1, 42):spawn()
|
||||||
|
evo.remove(entity_prefab, f2, f3)
|
||||||
|
|
||||||
|
local e = evo.clone(entity_prefab, { [f1] = 21 })
|
||||||
|
assert(e and not evo.empty(e))
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 21)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == false)
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(v_set_sum == 42 * 4 + 21 * 1)
|
||||||
|
assert(v_insert_sum == 42 * 4 + 21 * 1)
|
||||||
|
|
||||||
|
assert(f3_set_times == 5)
|
||||||
|
assert(f3_insert_times == 5)
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local function v2(x, y) return { x = x or 0, y = y or 0 } end
|
||||||
|
local function v2_clone(v) return { x = v.x, y = v.y } end
|
||||||
|
|
||||||
|
local f1, f2, f3, f4, f5, f6, f7 = evo.id(7)
|
||||||
|
evo.set(f1, evo.REQUIRES, { f2, f3, f4 })
|
||||||
|
evo.set(f5, evo.REQUIRES, { f6, f7 })
|
||||||
|
|
||||||
|
local f1_default = v2(1, 2)
|
||||||
|
local f2_default = v2(3, 4)
|
||||||
|
local f3_default = v2(10, 11)
|
||||||
|
local f4_default = v2(12, 13)
|
||||||
|
local f6_default = v2(14, 15)
|
||||||
|
local f7_default = v2(16, 17)
|
||||||
|
|
||||||
|
evo.set(f1, evo.DEFAULT, f1_default)
|
||||||
|
evo.set(f2, evo.DEFAULT, f2_default)
|
||||||
|
evo.set(f3, evo.DEFAULT, f3_default)
|
||||||
|
evo.set(f4, evo.DEFAULT, f4_default)
|
||||||
|
evo.set(f6, evo.DEFAULT, f6_default)
|
||||||
|
evo.set(f7, evo.DEFAULT, f7_default)
|
||||||
|
|
||||||
|
evo.set(f1, evo.DUPLICATE, v2_clone)
|
||||||
|
evo.set(f2, evo.DUPLICATE, v2_clone)
|
||||||
|
evo.set(f3, evo.DUPLICATE, v2_clone)
|
||||||
|
evo.set(f5, evo.DUPLICATE, v2_clone)
|
||||||
|
evo.set(f6, evo.DUPLICATE, v2_clone)
|
||||||
|
|
||||||
|
do
|
||||||
|
local entity_list, entity_count = evo.multi_spawn(2, { [f1] = v2(5, 6), [f2] = v2(7, 8) })
|
||||||
|
|
||||||
|
assert(entity_list and #entity_list == 2)
|
||||||
|
assert(entity_count == 2)
|
||||||
|
|
||||||
|
local q_f1 = evo.builder():include(f1):spawn()
|
||||||
|
|
||||||
|
local f2_v = v2(20, 21)
|
||||||
|
evo.batch_set(q_f1, f2, f2_v)
|
||||||
|
|
||||||
|
for i = 1, entity_count do
|
||||||
|
local e = entity_list[i]
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1).x == 5 and evo.get(e, f1).y == 6)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2).x == 20 and evo.get(e, f2).y == 21)
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3).x == 10 and evo.get(e, f3).y == 11)
|
||||||
|
assert(evo.has(e, f4) and evo.get(e, f4).x == 12 and evo.get(e, f4).y == 13)
|
||||||
|
|
||||||
|
assert(evo.get(e, f1) ~= f1_default)
|
||||||
|
assert(evo.get(e, f2) ~= f2_v and evo.get(e, f2) ~= f2_default)
|
||||||
|
assert(evo.get(e, f3) ~= f3_default)
|
||||||
|
assert(evo.get(e, f4) == f4_default)
|
||||||
|
end
|
||||||
|
|
||||||
|
local f5_v = v2(30, 31)
|
||||||
|
evo.batch_set(q_f1, f5, f5_v)
|
||||||
|
|
||||||
|
for i = 1, entity_count do
|
||||||
|
local e = entity_list[i]
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1).x == 5 and evo.get(e, f1).y == 6)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2).x == 20 and evo.get(e, f2).y == 21)
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3).x == 10 and evo.get(e, f3).y == 11)
|
||||||
|
assert(evo.has(e, f4) and evo.get(e, f4).x == 12 and evo.get(e, f4).y == 13)
|
||||||
|
assert(evo.has(e, f5) and evo.get(e, f5).x == 30 and evo.get(e, f5).y == 31)
|
||||||
|
assert(evo.has(e, f6) and evo.get(e, f6).x == 14 and evo.get(e, f6).y == 15)
|
||||||
|
assert(evo.has(e, f7) and evo.get(e, f7).x == 16 and evo.get(e, f7).y == 17)
|
||||||
|
|
||||||
|
assert(evo.get(e, f1) ~= f1_default)
|
||||||
|
assert(evo.get(e, f2) ~= f2_v and evo.get(e, f2) ~= f2_default)
|
||||||
|
assert(evo.get(e, f3) ~= f3_default)
|
||||||
|
assert(evo.get(e, f4) == f4_default)
|
||||||
|
assert(evo.get(e, f5) ~= f5_v)
|
||||||
|
assert(evo.get(e, f6) ~= f6_default)
|
||||||
|
assert(evo.get(e, f7) == f7_default)
|
||||||
|
end
|
||||||
|
|
||||||
|
f5_v = v2(32, 33)
|
||||||
|
evo.batch_set(q_f1, f5, f5_v)
|
||||||
|
|
||||||
|
for i = 1, entity_count do
|
||||||
|
local e = entity_list[i]
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1).x == 5 and evo.get(e, f1).y == 6)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2).x == 20 and evo.get(e, f2).y == 21)
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3).x == 10 and evo.get(e, f3).y == 11)
|
||||||
|
assert(evo.has(e, f4) and evo.get(e, f4).x == 12 and evo.get(e, f4).y == 13)
|
||||||
|
assert(evo.has(e, f5) and evo.get(e, f5).x == 32 and evo.get(e, f5).y == 33)
|
||||||
|
assert(evo.has(e, f6) and evo.get(e, f6).x == 14 and evo.get(e, f6).y == 15)
|
||||||
|
assert(evo.has(e, f7) and evo.get(e, f7).x == 16 and evo.get(e, f7).y == 17)
|
||||||
|
|
||||||
|
assert(evo.get(e, f1) ~= f1_default)
|
||||||
|
assert(evo.get(e, f2) ~= f2_v and evo.get(e, f2) ~= f2_default)
|
||||||
|
assert(evo.get(e, f3) ~= f3_default)
|
||||||
|
assert(evo.get(e, f4) == f4_default)
|
||||||
|
assert(evo.get(e, f5) ~= f5_v)
|
||||||
|
assert(evo.get(e, f6) ~= f6_default)
|
||||||
|
assert(evo.get(e, f7) == f7_default)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local function v2(x, y) return { x = x or 0, y = y or 0 } end
|
||||||
|
local function v2_clone(v) return { x = v.x, y = v.y } end
|
||||||
|
|
||||||
|
local f1, f2, f3, f4, f5, f6, f7 = evo.id(7)
|
||||||
|
evo.set(f1, evo.REQUIRES, { f2, f3, f4 })
|
||||||
|
evo.set(f5, evo.REQUIRES, { f6, f7 })
|
||||||
|
|
||||||
|
local f1_default = v2(1, 2)
|
||||||
|
local f2_default = v2(3, 4)
|
||||||
|
local f3_default = v2(10, 11)
|
||||||
|
local f4_default = v2(12, 13)
|
||||||
|
local f6_default = v2(14, 15)
|
||||||
|
local f7_default = v2(16, 17)
|
||||||
|
|
||||||
|
evo.set(f1, evo.DEFAULT, f1_default)
|
||||||
|
evo.set(f2, evo.DEFAULT, f2_default)
|
||||||
|
evo.set(f3, evo.DEFAULT, f3_default)
|
||||||
|
evo.set(f4, evo.DEFAULT, f4_default)
|
||||||
|
evo.set(f6, evo.DEFAULT, f6_default)
|
||||||
|
evo.set(f7, evo.DEFAULT, f7_default)
|
||||||
|
|
||||||
|
evo.set(f1, evo.DUPLICATE, v2_clone)
|
||||||
|
evo.set(f2, evo.DUPLICATE, v2_clone)
|
||||||
|
evo.set(f3, evo.DUPLICATE, v2_clone)
|
||||||
|
evo.set(f5, evo.DUPLICATE, v2_clone)
|
||||||
|
evo.set(f6, evo.DUPLICATE, v2_clone)
|
||||||
|
|
||||||
|
local f5_set_sum = 0
|
||||||
|
local f5_insert_sum = 0
|
||||||
|
local f6_set_sum = 0
|
||||||
|
local f6_insert_sum = 0
|
||||||
|
local f7_set_sum = 0
|
||||||
|
local f7_insert_sum = 0
|
||||||
|
|
||||||
|
evo.set(f5, evo.ON_SET, function(e, f, v)
|
||||||
|
assert(evo.get(e, f) == v)
|
||||||
|
assert(f == f5)
|
||||||
|
f5_set_sum = f5_set_sum + v.x + v.y
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f5, evo.ON_INSERT, function(e, f, v)
|
||||||
|
assert(evo.get(e, f) == v)
|
||||||
|
assert(f == f5)
|
||||||
|
f5_insert_sum = f5_insert_sum + v.x + v.y
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f6, evo.ON_SET, function(e, f, v)
|
||||||
|
assert(evo.get(e, f) == v)
|
||||||
|
assert(f == f6)
|
||||||
|
f6_set_sum = f6_set_sum + v.x + v.y
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f6, evo.ON_INSERT, function(e, f, v)
|
||||||
|
assert(evo.get(e, f) == v)
|
||||||
|
assert(f == f6)
|
||||||
|
f6_insert_sum = f6_insert_sum + v.x + v.y
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f7, evo.ON_SET, function(e, f, v)
|
||||||
|
assert(evo.get(e, f) == v)
|
||||||
|
assert(f == f7)
|
||||||
|
f7_set_sum = f7_set_sum + v.x + v.y
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f7, evo.ON_INSERT, function(e, f, v)
|
||||||
|
assert(evo.get(e, f) == v)
|
||||||
|
assert(f == f7)
|
||||||
|
f7_insert_sum = f7_insert_sum + v.x + v.y
|
||||||
|
end)
|
||||||
|
|
||||||
|
do
|
||||||
|
local entity_list, entity_count = evo.multi_spawn(2, { [f1] = v2(5, 6), [f2] = v2(7, 8) })
|
||||||
|
|
||||||
|
assert(entity_list and #entity_list == 2)
|
||||||
|
assert(entity_count == 2)
|
||||||
|
|
||||||
|
local q_f1 = evo.builder():include(f1):spawn()
|
||||||
|
|
||||||
|
local f2_v = v2(20, 21)
|
||||||
|
evo.batch_set(q_f1, f2, f2_v)
|
||||||
|
|
||||||
|
for i = 1, entity_count do
|
||||||
|
local e = entity_list[i]
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1).x == 5 and evo.get(e, f1).y == 6)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2).x == 20 and evo.get(e, f2).y == 21)
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3).x == 10 and evo.get(e, f3).y == 11)
|
||||||
|
assert(evo.has(e, f4) and evo.get(e, f4).x == 12 and evo.get(e, f4).y == 13)
|
||||||
|
|
||||||
|
assert(evo.get(e, f1) ~= f1_default)
|
||||||
|
assert(evo.get(e, f2) ~= f2_v and evo.get(e, f2) ~= f2_default)
|
||||||
|
assert(evo.get(e, f3) ~= f3_default)
|
||||||
|
assert(evo.get(e, f4) == f4_default)
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(f5_set_sum == 0)
|
||||||
|
assert(f5_insert_sum == 0)
|
||||||
|
assert(f6_set_sum == 0)
|
||||||
|
assert(f6_insert_sum == 0)
|
||||||
|
assert(f7_set_sum == 0)
|
||||||
|
assert(f7_insert_sum == 0)
|
||||||
|
|
||||||
|
local f5_v = v2(30, 31)
|
||||||
|
evo.batch_set(q_f1, f5, f5_v)
|
||||||
|
|
||||||
|
assert(f5_set_sum == (30 + 31) * entity_count)
|
||||||
|
assert(f5_insert_sum == (30 + 31) * entity_count)
|
||||||
|
assert(f6_set_sum == (14 + 15) * entity_count)
|
||||||
|
assert(f6_insert_sum == (14 + 15) * entity_count)
|
||||||
|
assert(f7_set_sum == (16 + 17) * entity_count)
|
||||||
|
assert(f7_insert_sum == (16 + 17) * entity_count)
|
||||||
|
|
||||||
|
for i = 1, entity_count do
|
||||||
|
local e = entity_list[i]
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1).x == 5 and evo.get(e, f1).y == 6)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2).x == 20 and evo.get(e, f2).y == 21)
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3).x == 10 and evo.get(e, f3).y == 11)
|
||||||
|
assert(evo.has(e, f4) and evo.get(e, f4).x == 12 and evo.get(e, f4).y == 13)
|
||||||
|
assert(evo.has(e, f5) and evo.get(e, f5).x == 30 and evo.get(e, f5).y == 31)
|
||||||
|
assert(evo.has(e, f6) and evo.get(e, f6).x == 14 and evo.get(e, f6).y == 15)
|
||||||
|
assert(evo.has(e, f7) and evo.get(e, f7).x == 16 and evo.get(e, f7).y == 17)
|
||||||
|
|
||||||
|
assert(evo.get(e, f1) ~= f1_default)
|
||||||
|
assert(evo.get(e, f2) ~= f2_v and evo.get(e, f2) ~= f2_default)
|
||||||
|
assert(evo.get(e, f3) ~= f3_default)
|
||||||
|
assert(evo.get(e, f4) == f4_default)
|
||||||
|
assert(evo.get(e, f5) ~= f5_v)
|
||||||
|
assert(evo.get(e, f6) ~= f6_default)
|
||||||
|
assert(evo.get(e, f7) == f7_default)
|
||||||
|
end
|
||||||
|
|
||||||
|
f5_set_sum = 0
|
||||||
|
f5_insert_sum = 0
|
||||||
|
f6_set_sum = 0
|
||||||
|
f6_insert_sum = 0
|
||||||
|
f7_set_sum = 0
|
||||||
|
f7_insert_sum = 0
|
||||||
|
|
||||||
|
f5_v = v2(32, 33)
|
||||||
|
evo.batch_set(q_f1, f5, f5_v)
|
||||||
|
|
||||||
|
assert(f5_set_sum == (32 + 33) * entity_count)
|
||||||
|
assert(f5_insert_sum == 0)
|
||||||
|
assert(f6_set_sum == 0)
|
||||||
|
assert(f6_insert_sum == 0)
|
||||||
|
assert(f7_set_sum == 0)
|
||||||
|
assert(f7_insert_sum == 0)
|
||||||
|
|
||||||
|
for i = 1, entity_count do
|
||||||
|
local e = entity_list[i]
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1).x == 5 and evo.get(e, f1).y == 6)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2).x == 20 and evo.get(e, f2).y == 21)
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3).x == 10 and evo.get(e, f3).y == 11)
|
||||||
|
assert(evo.has(e, f4) and evo.get(e, f4).x == 12 and evo.get(e, f4).y == 13)
|
||||||
|
assert(evo.has(e, f5) and evo.get(e, f5).x == 32 and evo.get(e, f5).y == 33)
|
||||||
|
assert(evo.has(e, f6) and evo.get(e, f6).x == 14 and evo.get(e, f6).y == 15)
|
||||||
|
assert(evo.has(e, f7) and evo.get(e, f7).x == 16 and evo.get(e, f7).y == 17)
|
||||||
|
|
||||||
|
assert(evo.get(e, f1) ~= f1_default)
|
||||||
|
assert(evo.get(e, f2) ~= f2_v and evo.get(e, f2) ~= f2_default)
|
||||||
|
assert(evo.get(e, f3) ~= f3_default)
|
||||||
|
assert(evo.get(e, f4) == f4_default)
|
||||||
|
assert(evo.get(e, f5) ~= f5_v)
|
||||||
|
assert(evo.get(e, f6) ~= f6_default)
|
||||||
|
assert(evo.get(e, f7) == f7_default)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local s1, s2 = evo.id(2)
|
||||||
|
|
||||||
|
local process_order = ''
|
||||||
|
|
||||||
|
evo.set(s1, evo.PROLOGUE, function()
|
||||||
|
process_order = process_order .. '1'
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(s2, evo.PROLOGUE, function()
|
||||||
|
process_order = process_order .. '2'
|
||||||
|
end)
|
||||||
|
|
||||||
|
do
|
||||||
|
process_order = ''
|
||||||
|
evo.set(s2, evo.GROUP, s1)
|
||||||
|
evo.process(s1)
|
||||||
|
assert(process_order == '12')
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
process_order = ''
|
||||||
|
evo.remove(s2, evo.GROUP)
|
||||||
|
evo.process(s1)
|
||||||
|
assert(process_order == '1')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local s1, s2, s3 = evo.id(3)
|
||||||
|
|
||||||
|
local process_order = ''
|
||||||
|
|
||||||
|
evo.set(s1, evo.PROLOGUE, function()
|
||||||
|
process_order = process_order .. '1'
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(s2, evo.PROLOGUE, function()
|
||||||
|
process_order = process_order .. '2'
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(s3, evo.PROLOGUE, function()
|
||||||
|
process_order = process_order .. '3'
|
||||||
|
end)
|
||||||
|
|
||||||
|
do
|
||||||
|
process_order = ''
|
||||||
|
evo.set(s2, evo.GROUP, s1)
|
||||||
|
evo.process(s1)
|
||||||
|
assert(process_order == '12')
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
process_order = ''
|
||||||
|
evo.set(s2, evo.GROUP, s3)
|
||||||
|
evo.process(s1)
|
||||||
|
assert(process_order == '1')
|
||||||
|
evo.process(s3)
|
||||||
|
assert(process_order == '132')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2 = evo.id(2)
|
||||||
|
evo.set(f1, evo.NAME, 'f1')
|
||||||
|
evo.set(f2, evo.NAME, 'f2')
|
||||||
|
|
||||||
|
do
|
||||||
|
local c1 = evo.chunk(f1)
|
||||||
|
assert(tostring(c1) == '<f1>')
|
||||||
|
|
||||||
|
local c2 = evo.chunk(f2)
|
||||||
|
assert(tostring(c2) == '<f2>')
|
||||||
|
|
||||||
|
local c12 = evo.chunk(f1, f2)
|
||||||
|
assert(tostring(c12) == '<f1, f2>')
|
||||||
|
|
||||||
|
local c21 = evo.chunk(f2, f1)
|
||||||
|
assert(tostring(c21) == '<f1, f2>')
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local b = evo.builder():set(f1)
|
||||||
|
assert(tostring(b) == '<f1>')
|
||||||
|
|
||||||
|
b:set(f1, 1):set(f2, 2)
|
||||||
|
assert(tostring(b) == '<f1, f2>')
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -306,3 +306,302 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2, f3 = evo.id(3)
|
||||||
|
|
||||||
|
evo.set(f1, evo.REQUIRES, { f2, f3 })
|
||||||
|
evo.set(f3, evo.TAG)
|
||||||
|
|
||||||
|
do
|
||||||
|
local entity_list, entity_count = evo.multi_spawn(2, { [f1] = 42 })
|
||||||
|
|
||||||
|
assert(entity_list and #entity_list == 2)
|
||||||
|
assert(entity_count == 2)
|
||||||
|
|
||||||
|
for i = 1, entity_count do
|
||||||
|
local e = entity_list[i]
|
||||||
|
assert(e and not evo.empty(e))
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == true)
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3) == nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local entity_prefab = evo.builder():set(f1, 42):spawn()
|
||||||
|
|
||||||
|
local clone_list, clone_count = evo.multi_clone(2, entity_prefab)
|
||||||
|
|
||||||
|
assert(clone_list and #clone_list == 2)
|
||||||
|
assert(clone_count == 2)
|
||||||
|
|
||||||
|
for i = 1, clone_count do
|
||||||
|
local e = clone_list[i]
|
||||||
|
assert(e and not evo.empty(e))
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == true)
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3) == nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local entity_prefab = evo.builder():set(f1, 42):spawn()
|
||||||
|
evo.remove(entity_prefab, f2, f3)
|
||||||
|
|
||||||
|
local clone_list, clone_count = evo.multi_clone(2, entity_prefab, { [f1] = 21 })
|
||||||
|
|
||||||
|
assert(clone_list and #clone_list == 2)
|
||||||
|
assert(clone_count == 2)
|
||||||
|
|
||||||
|
for i = 1, clone_count do
|
||||||
|
local e = clone_list[i]
|
||||||
|
assert(e and not evo.empty(e))
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 21)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == true)
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3) == nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
evo.set(f2, evo.DEFAULT, false)
|
||||||
|
|
||||||
|
do
|
||||||
|
local entity_list, entity_count = evo.multi_spawn(2, { [f1] = 42 })
|
||||||
|
|
||||||
|
assert(entity_list and #entity_list == 2)
|
||||||
|
assert(entity_count == 2)
|
||||||
|
|
||||||
|
for i = 1, entity_count do
|
||||||
|
local e = entity_list[i]
|
||||||
|
assert(e and not evo.empty(e))
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == false)
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3) == nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local entity_prefab = evo.builder():set(f1, 42):spawn()
|
||||||
|
|
||||||
|
local clone_list, clone_count = evo.multi_clone(2, entity_prefab)
|
||||||
|
|
||||||
|
assert(clone_list and #clone_list == 2)
|
||||||
|
assert(clone_count == 2)
|
||||||
|
|
||||||
|
for i = 1, clone_count do
|
||||||
|
local e = clone_list[i]
|
||||||
|
assert(e and not evo.empty(e))
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == false)
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3) == nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local entity_prefab = evo.builder():set(f1, 42):spawn()
|
||||||
|
evo.remove(entity_prefab, f2, f3)
|
||||||
|
|
||||||
|
local clone_list, clone_count = evo.multi_clone(2, entity_prefab, { [f1] = 21 })
|
||||||
|
|
||||||
|
assert(clone_list and #clone_list == 2)
|
||||||
|
assert(clone_count == 2)
|
||||||
|
|
||||||
|
for i = 1, clone_count do
|
||||||
|
local e = clone_list[i]
|
||||||
|
assert(e and not evo.empty(e))
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 21)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == false)
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3) == nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local v_set_sum = 0
|
||||||
|
local v_insert_sum = 0
|
||||||
|
|
||||||
|
local f3_set_times = 0
|
||||||
|
local f3_insert_times = 0
|
||||||
|
|
||||||
|
evo.set(f1, evo.ON_SET, function(e, f, v)
|
||||||
|
assert(f == f1)
|
||||||
|
v_set_sum = v_set_sum + v
|
||||||
|
assert(evo.get(e, f) == v)
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f1, evo.ON_INSERT, function(e, f, v)
|
||||||
|
assert(f == f1)
|
||||||
|
v_insert_sum = v_insert_sum + v
|
||||||
|
assert(evo.get(e, f) == v)
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f3, evo.ON_SET, function(e, f, v)
|
||||||
|
assert(f == f3)
|
||||||
|
f3_set_times = f3_set_times + 1
|
||||||
|
assert(v == nil)
|
||||||
|
assert(evo.has(e, f))
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f3, evo.ON_INSERT, function(e, f, v)
|
||||||
|
assert(f == f3)
|
||||||
|
f3_insert_times = f3_insert_times + 1
|
||||||
|
assert(v == nil)
|
||||||
|
assert(evo.has(e, f))
|
||||||
|
end)
|
||||||
|
|
||||||
|
do
|
||||||
|
local entity_list, entity_count = evo.multi_spawn(2, { [f1] = 42 })
|
||||||
|
|
||||||
|
assert(entity_list and #entity_list == 2)
|
||||||
|
assert(entity_count == 2)
|
||||||
|
|
||||||
|
for i = 1, entity_count do
|
||||||
|
local e = entity_list[i]
|
||||||
|
assert(e and not evo.empty(e))
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local entity_prefab = evo.builder():set(f1, 42):spawn()
|
||||||
|
|
||||||
|
local clone_list, clone_count = evo.multi_clone(2, entity_prefab)
|
||||||
|
|
||||||
|
assert(clone_list and #clone_list == 2)
|
||||||
|
assert(clone_count == 2)
|
||||||
|
|
||||||
|
for i = 1, clone_count do
|
||||||
|
local e = clone_list[i]
|
||||||
|
assert(e and not evo.empty(e))
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local entity_prefab = evo.builder():set(f1, 42):spawn()
|
||||||
|
evo.remove(entity_prefab, f2, f3)
|
||||||
|
|
||||||
|
local clone_list, clone_count = evo.multi_clone(2, entity_prefab, { [f1] = 21 })
|
||||||
|
|
||||||
|
assert(clone_list and #clone_list == 2)
|
||||||
|
assert(clone_count == 2)
|
||||||
|
|
||||||
|
for i = 1, clone_count do
|
||||||
|
local e = clone_list[i]
|
||||||
|
assert(e and not evo.empty(e))
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 21)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(v_set_sum == 42 * 6 + 21 * 2)
|
||||||
|
assert(v_insert_sum == 42 * 6 + 21 * 2)
|
||||||
|
|
||||||
|
assert(f3_set_times == 8)
|
||||||
|
assert(f3_insert_times == 8)
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local function v2(x, y) return { x = x or 0, y = y or 0 } end
|
||||||
|
local function v2_clone(v) return { x = v.x, y = v.y } end
|
||||||
|
|
||||||
|
local f1, f2, f3, f4 = evo.id(4)
|
||||||
|
evo.set(f1, evo.REQUIRES, { f2, f3, f4 })
|
||||||
|
|
||||||
|
local f1_default = v2(1, 2)
|
||||||
|
local f2_default = v2(3, 4)
|
||||||
|
local f3_default = v2(10, 11)
|
||||||
|
local f4_default = v2(12, 13)
|
||||||
|
|
||||||
|
evo.set(f1, evo.DEFAULT, f1_default)
|
||||||
|
evo.set(f2, evo.DEFAULT, f2_default)
|
||||||
|
evo.set(f3, evo.DEFAULT, f3_default)
|
||||||
|
evo.set(f4, evo.DEFAULT, f4_default)
|
||||||
|
|
||||||
|
evo.set(f1, evo.DUPLICATE, v2_clone)
|
||||||
|
evo.set(f2, evo.DUPLICATE, v2_clone)
|
||||||
|
evo.set(f3, evo.DUPLICATE, v2_clone)
|
||||||
|
|
||||||
|
do
|
||||||
|
local entity_list, entity_count = evo.multi_spawn(2, { [f1] = v2(5, 6), [f2] = v2(7, 8) })
|
||||||
|
|
||||||
|
assert(entity_list and #entity_list == 2)
|
||||||
|
assert(entity_count == 2)
|
||||||
|
|
||||||
|
for i = 1, entity_count do
|
||||||
|
local e = entity_list[i]
|
||||||
|
assert(e and not evo.empty(e))
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) ~= f1_default)
|
||||||
|
assert(evo.get(e, f1).x == 5 and evo.get(e, f1).y == 6)
|
||||||
|
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) ~= f2_default)
|
||||||
|
assert(evo.get(e, f2).x == 7 and evo.get(e, f2).y == 8)
|
||||||
|
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3) ~= f3_default)
|
||||||
|
assert(evo.get(e, f3).x == 10 and evo.get(e, f3).y == 11)
|
||||||
|
|
||||||
|
assert(evo.has(e, f4) and evo.get(e, f4) == f4_default)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local entity_prefab = evo.builder():set(f1, v2(5, 6)):set(f2, v2(7, 8)):spawn()
|
||||||
|
|
||||||
|
local clone_list, clone_count = evo.multi_clone(2, entity_prefab, { [f2] = f2_default })
|
||||||
|
|
||||||
|
assert(clone_list and #clone_list == 2)
|
||||||
|
assert(clone_count == 2)
|
||||||
|
|
||||||
|
for i = 1, clone_count do
|
||||||
|
local e = clone_list[i]
|
||||||
|
assert(e and not evo.empty(e))
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) ~= f1_default and evo.get(e, f1) ~= evo.get(entity_prefab, f1))
|
||||||
|
assert(evo.get(e, f1).x == 5 and evo.get(e, f1).y == 6)
|
||||||
|
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) ~= f2_default and evo.get(e, f2) ~= evo.get(entity_prefab, f2))
|
||||||
|
assert(evo.get(e, f2).x == 3 and evo.get(e, f2).y == 4)
|
||||||
|
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3) ~= f3_default)
|
||||||
|
assert(evo.get(e, f3).x == 10 and evo.get(e, f3).y == 11)
|
||||||
|
|
||||||
|
assert(evo.has(e, f4) and evo.get(e, f4) == f4_default)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local entity_prefab = evo.builder():set(f1, v2(5, 6)):set(f2, v2(7, 8)):spawn()
|
||||||
|
evo.remove(entity_prefab, f2, f3, f4)
|
||||||
|
|
||||||
|
local clone_list, clone_count = evo.multi_clone(2, entity_prefab, { [f2] = f2_default })
|
||||||
|
|
||||||
|
assert(clone_list and #clone_list == 2)
|
||||||
|
assert(clone_count == 2)
|
||||||
|
|
||||||
|
for i = 1, clone_count do
|
||||||
|
local e = clone_list[i]
|
||||||
|
assert(e and not evo.empty(e))
|
||||||
|
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) ~= f1_default and evo.get(e, f1) ~= evo.get(entity_prefab, f1))
|
||||||
|
assert(evo.get(e, f1).x == 5 and evo.get(e, f1).y == 6)
|
||||||
|
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) ~= f2_default and evo.get(e, f2) ~= evo.get(entity_prefab, f2))
|
||||||
|
assert(evo.get(e, f2).x == 3 and evo.get(e, f2).y == 4)
|
||||||
|
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3) ~= f3_default)
|
||||||
|
assert(evo.get(e, f3).x == 10 and evo.get(e, f3).y == 11)
|
||||||
|
|
||||||
|
assert(evo.has(e, f4) and evo.get(e, f4) == f4_default)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
329
develop/testing/spawn_tests.lua
Normal file
329
develop/testing/spawn_tests.lua
Normal file
@@ -0,0 +1,329 @@
|
|||||||
|
local evo = require 'evolved'
|
||||||
|
|
||||||
|
do
|
||||||
|
do
|
||||||
|
local e = evo.spawn()
|
||||||
|
assert(evo.alive(e) and evo.empty(e))
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local e = evo.spawn({})
|
||||||
|
assert(evo.alive(e) and evo.empty(e))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2, f3 = evo.id(3)
|
||||||
|
evo.set(f2, evo.REQUIRES, { f1, f3 })
|
||||||
|
|
||||||
|
do
|
||||||
|
local e = evo.spawn({ [f1] = 42 })
|
||||||
|
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1))
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local e = evo.spawn({ [f1] = 42, [f2] = 'hello' })
|
||||||
|
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2, f3))
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == 'hello')
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3) == true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2, f3 = evo.id(3)
|
||||||
|
evo.set(f2, evo.REQUIRES, { f1, f3 })
|
||||||
|
evo.set(f3, evo.DEFAULT, 21)
|
||||||
|
evo.set(f3, evo.REQUIRES, { f2 })
|
||||||
|
|
||||||
|
do
|
||||||
|
local e = evo.spawn({ [f1] = 42 })
|
||||||
|
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1))
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local e = evo.spawn({ [f1] = 42, [f2] = 'hello' })
|
||||||
|
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2, f3))
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == 'hello')
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3) == 21)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2, f3, f4 = evo.id(4)
|
||||||
|
evo.set(f2, evo.DUPLICATE, function() return nil end)
|
||||||
|
evo.set(f2, evo.REQUIRES, { f1, f3, f4 })
|
||||||
|
evo.set(f3, evo.DEFAULT, 21)
|
||||||
|
evo.set(f3, evo.DUPLICATE, function(v) return v * 3 end)
|
||||||
|
evo.set(f3, evo.REQUIRES, { f2 })
|
||||||
|
|
||||||
|
do
|
||||||
|
local e = evo.spawn({ [f1] = 42 })
|
||||||
|
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1))
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local e = evo.spawn({ [f1] = 42, [f2] = true })
|
||||||
|
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2, f3, f4))
|
||||||
|
assert(evo.has(e, f1) and evo.get(e, f1) == 42)
|
||||||
|
assert(evo.has(e, f2) and evo.get(e, f2) == true)
|
||||||
|
assert(evo.has(e, f3) and evo.get(e, f3) == 21 * 3)
|
||||||
|
assert(evo.has(e, f4) and evo.get(e, f4) == true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2, f3 = evo.id(3)
|
||||||
|
evo.set(f2, evo.REQUIRES, { f3 })
|
||||||
|
evo.set(f3, evo.TAG)
|
||||||
|
|
||||||
|
local f2_set_sum, f2_inserted_sum = 0, 0
|
||||||
|
local f3_set_count, f3_inserted_count = 0, 0
|
||||||
|
|
||||||
|
evo.set(f2, evo.ON_SET, function(e, f, c)
|
||||||
|
assert(c == 42)
|
||||||
|
assert(evo.get(e, f) == c)
|
||||||
|
assert(f == f2)
|
||||||
|
f2_set_sum = f2_set_sum + c
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f2, evo.ON_INSERT, function(e, f, c)
|
||||||
|
assert(c == 42)
|
||||||
|
assert(evo.get(e, f) == c)
|
||||||
|
assert(f == f2)
|
||||||
|
f2_inserted_sum = f2_inserted_sum + c
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f3, evo.ON_SET, function(e, f, c)
|
||||||
|
assert(c == nil)
|
||||||
|
assert(evo.get(e, f) == c)
|
||||||
|
assert(f == f3)
|
||||||
|
f3_set_count = f3_set_count + 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f3, evo.ON_INSERT, function(e, f, c)
|
||||||
|
assert(c == nil)
|
||||||
|
assert(evo.get(e, f) == c)
|
||||||
|
assert(f == f3)
|
||||||
|
f3_inserted_count = f3_inserted_count + 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
do
|
||||||
|
f3_set_count, f3_inserted_count = 0, 0
|
||||||
|
local e = evo.spawn({ [f1] = 'hello', [f2] = 42 })
|
||||||
|
assert(evo.alive(e) and not evo.empty(e) and evo.locate(e) == evo.chunk(f1, f2, f3))
|
||||||
|
assert(f2_set_sum == 42 and f2_inserted_sum == 42)
|
||||||
|
assert(f3_set_count == 1 and f3_inserted_count == 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
do
|
||||||
|
local es, ec = evo.multi_spawn(2)
|
||||||
|
assert(#es == 2 and ec == 2)
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and evo.empty(es[i]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local es, ec = evo.multi_spawn(2, {})
|
||||||
|
assert(#es == 2 and ec == 2)
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and evo.empty(es[i]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2 = evo.id(2)
|
||||||
|
|
||||||
|
do
|
||||||
|
local es, ec = evo.multi_spawn(3, { [f1] = 42 })
|
||||||
|
assert(#es == 3 and ec == 3)
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1))
|
||||||
|
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 42)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local es, ec = evo.multi_spawn(3, { [f1] = 42, [f2] = 'hello' })
|
||||||
|
assert(#es == 3 and ec == 3)
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2))
|
||||||
|
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 42)
|
||||||
|
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 'hello')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2 = evo.id(2)
|
||||||
|
evo.set(f1, evo.REQUIRES, { f2 })
|
||||||
|
|
||||||
|
do
|
||||||
|
local es, ec = evo.multi_spawn(3, { [f1] = 42 })
|
||||||
|
assert(#es == 3 and ec == 3)
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2))
|
||||||
|
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 42)
|
||||||
|
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2 = evo.id(2)
|
||||||
|
evo.set(f1, evo.REQUIRES, { f2 })
|
||||||
|
|
||||||
|
do
|
||||||
|
local es, ec = evo.multi_spawn(1, { [f1] = 42 })
|
||||||
|
assert(#es == 1 and ec == 1)
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2))
|
||||||
|
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 42)
|
||||||
|
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2, f3 = evo.id(3)
|
||||||
|
evo.set(f1, evo.REQUIRES, { f2, f3 })
|
||||||
|
evo.set(f2, evo.DEFAULT, 'hello')
|
||||||
|
|
||||||
|
do
|
||||||
|
local es, ec = evo.multi_spawn(4, { [f1] = 42 })
|
||||||
|
assert(#es == 4 and ec == 4)
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2, f3))
|
||||||
|
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 42)
|
||||||
|
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 'hello')
|
||||||
|
assert(evo.has(es[i], f3) and evo.get(es[i], f3) == true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local es, ec = evo.multi_spawn(4, { [f1] = 42, [f2] = 'world' })
|
||||||
|
assert(#es == 4 and ec == 4)
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2, f3))
|
||||||
|
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 42)
|
||||||
|
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 'world')
|
||||||
|
assert(evo.has(es[i], f3) and evo.get(es[i], f3) == true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local es, ec = evo.multi_spawn(4, { [f1] = 42, [f2] = 'world', [f3] = false })
|
||||||
|
assert(#es == 4 and ec == 4)
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2, f3))
|
||||||
|
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 42)
|
||||||
|
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 'world')
|
||||||
|
assert(evo.has(es[i], f3) and evo.get(es[i], f3) == false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2 = evo.id(2)
|
||||||
|
evo.set(f1, evo.REQUIRES, { f2 })
|
||||||
|
evo.set(f1, evo.DUPLICATE, function() return nil end)
|
||||||
|
evo.set(f2, evo.DEFAULT, 'hello')
|
||||||
|
evo.set(f2, evo.DUPLICATE, function(v) return v .. '!' end)
|
||||||
|
|
||||||
|
do
|
||||||
|
local es, ec = evo.multi_spawn(4, { [f1] = 42 })
|
||||||
|
assert(#es == 4 and ec == 4)
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2))
|
||||||
|
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == true)
|
||||||
|
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 'hello!')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local es, ec = evo.multi_spawn(4, { [f1] = 42, [f2] = 'world' })
|
||||||
|
assert(#es == 4 and ec == 4)
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2))
|
||||||
|
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == true)
|
||||||
|
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 'world!')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local es, ec = evo.multi_spawn(4, { [f2] = 'hello world' })
|
||||||
|
assert(#es == 4 and ec == 4)
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f2))
|
||||||
|
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 'hello world!')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local f1, f2, f3 = evo.id(3)
|
||||||
|
evo.set(f2, evo.REQUIRES, { f3 })
|
||||||
|
evo.set(f3, evo.TAG)
|
||||||
|
|
||||||
|
local f2_set_sum, f2_inserted_sum = 0, 0
|
||||||
|
local f3_set_count, f3_inserted_count = 0, 0
|
||||||
|
|
||||||
|
evo.set(f2, evo.ON_SET, function(e, f, c)
|
||||||
|
assert(c == 42)
|
||||||
|
assert(evo.get(e, f) == c)
|
||||||
|
assert(f == f2)
|
||||||
|
f2_set_sum = f2_set_sum + c
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f2, evo.ON_INSERT, function(e, f, c)
|
||||||
|
assert(c == 42)
|
||||||
|
assert(evo.get(e, f) == c)
|
||||||
|
assert(f == f2)
|
||||||
|
f2_inserted_sum = f2_inserted_sum + c
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f3, evo.ON_SET, function(e, f, c)
|
||||||
|
assert(c == nil)
|
||||||
|
assert(evo.get(e, f) == c)
|
||||||
|
assert(f == f3)
|
||||||
|
f3_set_count = f3_set_count + 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
evo.set(f3, evo.ON_INSERT, function(e, f, c)
|
||||||
|
assert(c == nil)
|
||||||
|
assert(evo.get(e, f) == c)
|
||||||
|
assert(f == f3)
|
||||||
|
f3_inserted_count = f3_inserted_count + 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
do
|
||||||
|
local es, ec = evo.multi_spawn(3, { [f1] = 'hello', [f2] = 42 })
|
||||||
|
assert(#es == 3 and ec == 3)
|
||||||
|
|
||||||
|
for i = 1, ec do
|
||||||
|
assert(evo.alive(es[i]) and not evo.empty(es[i]) and evo.locate(es[i]) == evo.chunk(f1, f2, f3))
|
||||||
|
assert(f2_set_sum == 42 * 3 and f2_inserted_sum == 42 * 3)
|
||||||
|
assert(f3_set_count == 3 and f3_inserted_count == 3)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
181
evolved.d.tl
Normal file
181
evolved.d.tl
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
local record Evolved
|
||||||
|
interface Id end
|
||||||
|
|
||||||
|
type Entity = Id
|
||||||
|
type Fragment = Id
|
||||||
|
type Query = Id
|
||||||
|
type System = Id
|
||||||
|
|
||||||
|
interface EachState end
|
||||||
|
interface ExecuteState end
|
||||||
|
|
||||||
|
type EachIterator = function(state?: EachState): Fragment, any
|
||||||
|
type ExecuteIterator = function(state?: ExecuteState): Chunk, { Entity }, integer
|
||||||
|
|
||||||
|
interface Chunk
|
||||||
|
alive: function(self: Chunk): boolean
|
||||||
|
empty: function(self: Chunk): boolean
|
||||||
|
|
||||||
|
has: function(self: Chunk, fragment: Fragment): boolean
|
||||||
|
has_all: function(self: Chunk, ...: Fragment): boolean
|
||||||
|
has_any: function(self: Chunk, ...: Fragment): boolean
|
||||||
|
|
||||||
|
entities: function(self: Chunk): { Entity }, integer
|
||||||
|
fragments: function(self: Chunk): { Fragment }, integer
|
||||||
|
|
||||||
|
components: function(self: Chunk)
|
||||||
|
components: function<C1>(self: Chunk, f1: Fragment): { C1 }
|
||||||
|
components: function<C1, C2>(self: Chunk, f1: Fragment, f2: Fragment): { C1 }, { C2 }
|
||||||
|
components: function<C1, C2, C3>(self: Chunk, f1: Fragment, f2: Fragment, f3: Fragment): { C1 }, { C2 }, { C3 }
|
||||||
|
components: function<C1, C2, C3, C4>(self: Chunk, f1: Fragment, f2: Fragment, f3: Fragment, f4: Fragment): { C1 }, { C2 }, { C3 }, { C4 }
|
||||||
|
end
|
||||||
|
|
||||||
|
interface Builder
|
||||||
|
build: function(self: Builder, prefab?: Entity): Entity
|
||||||
|
multi_build: function(self: Builder, entity_count: integer, prefab?: Entity): { Entity }, integer
|
||||||
|
|
||||||
|
spawn: function(self: Builder): Entity
|
||||||
|
multi_spawn: function(self: Builder, entity_count: integer): { Entity }, integer
|
||||||
|
|
||||||
|
clone: function(self: Builder, prefab: Entity): Entity
|
||||||
|
multi_clone: function(self: Builder, entity_count: integer, prefab: Entity): { Entity }, integer
|
||||||
|
|
||||||
|
has: function(self: Builder, fragment: Fragment): boolean
|
||||||
|
has_all: function(self: Builder, ...: Fragment): boolean
|
||||||
|
has_any: function(self: Builder, ...: Fragment): boolean
|
||||||
|
|
||||||
|
get: function(self: Builder)
|
||||||
|
get: function<C1>(self: Builder, f1: Fragment): C1 | nil
|
||||||
|
get: function<C1, C2>(self: Builder, f1: Fragment, f2: Fragment): C1 | nil, C2 | nil
|
||||||
|
get: function<C1, C2, C3>(self: Builder, f1: Fragment, f2: Fragment, f3: Fragment): C1 | nil, C2 | nil, C3 | nil
|
||||||
|
get: function<C1, C2, C3, C4>(self: Builder, f1: Fragment, f2: Fragment, f3: Fragment, f4: Fragment): C1 | nil, C2 | nil, C3 | nil, C4 | nil
|
||||||
|
|
||||||
|
set: function<Component>(self: Builder, fragment: Fragment, component?: Component): Builder
|
||||||
|
remove: function(self: Builder, ...: Fragment): Builder
|
||||||
|
clear: function(self: Builder): Builder
|
||||||
|
|
||||||
|
tag: function(self: Builder): Builder
|
||||||
|
name: function(self: Builder, name: string): Builder
|
||||||
|
|
||||||
|
unique: function(self: Builder): Builder
|
||||||
|
explicit: function(self: Builder): Builder
|
||||||
|
internal: function(self: Builder): Builder
|
||||||
|
|
||||||
|
default: function<Component>(self: Builder, default: Component): Builder
|
||||||
|
duplicate: function<Component>(self: Builder, duplicate: function(Component): Component): Builder
|
||||||
|
|
||||||
|
prefab: function(self: Builder): Builder
|
||||||
|
disabled: function(self: Builder): Builder
|
||||||
|
|
||||||
|
include: function(self: Builder, ...: Fragment): Builder
|
||||||
|
exclude: function(self: Builder, ...: Fragment): Builder
|
||||||
|
require: function(self: Builder, ...: Fragment): Builder
|
||||||
|
|
||||||
|
on_set: function<Component>(self: Builder, on_set: function(Entity, Fragment, ? Component, ? Component)): Builder
|
||||||
|
on_assign: function<Component>(self: Builder, on_assign: function(Entity, Fragment, ? Component, ? Component)): Builder
|
||||||
|
on_insert: function<Component>(self: Builder, on_insert: function(Entity, Fragment, ? Component)): Builder
|
||||||
|
on_remove: function<Component>(self: Builder, on_remove: function(Entity, Fragment, ? Component)): Builder
|
||||||
|
|
||||||
|
group: function(self: Builder, group: System): Builder
|
||||||
|
|
||||||
|
query: function(self: Builder, query: Query): Builder
|
||||||
|
execute: function(self: Builder, execute: function(Chunk, {Entity}, integer)): Builder
|
||||||
|
|
||||||
|
prologue: function(self: Builder, prologue: function()): Builder
|
||||||
|
epilogue: function(self: Builder, epilogue: function()): Builder
|
||||||
|
|
||||||
|
destruction_policy: function(self: Builder, destruction_policy: Id): Builder
|
||||||
|
end
|
||||||
|
|
||||||
|
TAG: Fragment
|
||||||
|
NAME: Fragment
|
||||||
|
|
||||||
|
UNIQUE: Fragment
|
||||||
|
EXPLICIT: Fragment
|
||||||
|
INTERNAL: Fragment
|
||||||
|
|
||||||
|
DEFAULT: Fragment
|
||||||
|
DUPLICATE: Fragment
|
||||||
|
|
||||||
|
PREFAB: Fragment
|
||||||
|
DISABLED: Fragment
|
||||||
|
|
||||||
|
INCLUDES: Fragment
|
||||||
|
EXCLUDES: Fragment
|
||||||
|
REQUIRES: Fragment
|
||||||
|
|
||||||
|
ON_SET: Fragment
|
||||||
|
ON_ASSIGN: Fragment
|
||||||
|
ON_INSERT: Fragment
|
||||||
|
ON_REMOVE: Fragment
|
||||||
|
|
||||||
|
GROUP: Fragment
|
||||||
|
|
||||||
|
QUERY: Fragment
|
||||||
|
EXECUTE: Fragment
|
||||||
|
PROLOGUE: Fragment
|
||||||
|
EPILOGUE: Fragment
|
||||||
|
|
||||||
|
DESTRUCTION_POLICY: Fragment
|
||||||
|
DESTRUCTION_POLICY_DESTROY_ENTITY: Id
|
||||||
|
DESTRUCTION_POLICY_REMOVE_FRAGMENT: Id
|
||||||
|
|
||||||
|
id: function(count?: integer): Id...
|
||||||
|
name: function(...: Id): string...
|
||||||
|
|
||||||
|
pack: function(primary: integer, secondary: integer): Id
|
||||||
|
unpack: function(id: Id): integer, integer
|
||||||
|
|
||||||
|
defer: function(): boolean
|
||||||
|
commit: function(): boolean
|
||||||
|
cancel: function(): boolean
|
||||||
|
|
||||||
|
spawn: function(components?: { Fragment: any }): Entity
|
||||||
|
multi_spawn: function(entity_count: integer, components?: { Fragment: any }): { Entity }, integer
|
||||||
|
|
||||||
|
clone: function(prefab: Entity, components?: { Fragment: any }): Entity
|
||||||
|
multi_clone: function(entity_count: integer, prefab: Entity, components?: { Fragment: any }): { Entity }, integer
|
||||||
|
|
||||||
|
alive: function(entity: Entity): boolean
|
||||||
|
alive_all: function(...: Entity): boolean
|
||||||
|
alive_any: function(...: Entity): boolean
|
||||||
|
|
||||||
|
empty: function(entity: Entity): boolean
|
||||||
|
empty_all: function(...: Entity): boolean
|
||||||
|
empty_any: function(...: Entity): boolean
|
||||||
|
|
||||||
|
has: function(entity: Entity, fragment: Fragment): boolean
|
||||||
|
has_all: function(entity: Entity, ...: Fragment): boolean
|
||||||
|
has_any: function(entity: Entity, ...: Fragment): boolean
|
||||||
|
|
||||||
|
get: function(entity: Entity)
|
||||||
|
get: function<C1>(entity: Entity, f1: Fragment): C1 | nil
|
||||||
|
get: function<C1, C2>(entity: Entity, f1: Fragment, f2: Fragment): C1 | nil, C2 | nil
|
||||||
|
get: function<C1, C2, C3>(entity: Entity, f1: Fragment, f2: Fragment, f3: Fragment): C1 | nil, C2 | nil, C3 | nil
|
||||||
|
get: function<C1, C2, C3, C4>(entity: Entity, f1: Fragment, f2: Fragment, f3: Fragment, f4: Fragment): C1 | nil, C2 | nil, C3 | nil, C4 | nil
|
||||||
|
|
||||||
|
set: function<Component>(entity: Entity, fragment: Fragment, component?: Component)
|
||||||
|
remove: function(entity: Entity, ...: Fragment)
|
||||||
|
clear: function(...: Entity)
|
||||||
|
destroy: function(...: Entity)
|
||||||
|
|
||||||
|
batch_set: function<Component>(query: Query, fragment: Fragment, component?: Component)
|
||||||
|
batch_remove: function(query: Query, ...: Fragment)
|
||||||
|
batch_clear: function(...: Query)
|
||||||
|
batch_destroy: function(...: Query)
|
||||||
|
|
||||||
|
each: function(entity: Entity): EachIterator, EachState | nil
|
||||||
|
execute: function(query: Query): ExecuteIterator, ExecuteState | nil
|
||||||
|
|
||||||
|
locate: function(entity: Entity): Chunk | nil, integer
|
||||||
|
|
||||||
|
process: function(...: System)
|
||||||
|
|
||||||
|
debug_mode: function(yesno: boolean)
|
||||||
|
collect_garbage: function()
|
||||||
|
|
||||||
|
chunk: function(fragment: Fragment, ...: Fragment): Chunk, { Entity }, integer
|
||||||
|
builder: function(): Builder
|
||||||
|
end
|
||||||
|
|
||||||
|
return Evolved
|
||||||
1814
evolved.lua
1814
evolved.lua
File diff suppressed because it is too large
Load Diff
34
rockspecs/evolved.lua-1.4.0-0.rockspec
Normal file
34
rockspecs/evolved.lua-1.4.0-0.rockspec
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
rockspec_format = "3.0"
|
||||||
|
package = "evolved.lua"
|
||||||
|
version = "1.4.0-0"
|
||||||
|
source = {
|
||||||
|
url = "git://github.com/BlackMATov/evolved.lua",
|
||||||
|
tag = "v1.4.0",
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
homepage = "https://github.com/BlackMATov/evolved.lua",
|
||||||
|
summary = "Evolved ECS (Entity-Component-System) for Lua",
|
||||||
|
detailed = [[
|
||||||
|
`evolved.lua` is a fast and flexible ECS (Entity-Component-System) library for Lua.
|
||||||
|
It is designed to be simple and easy to use, while providing all the features needed to create complex systems with blazing performance.
|
||||||
|
]],
|
||||||
|
license = "MIT",
|
||||||
|
labels = {
|
||||||
|
"ecs",
|
||||||
|
"entity",
|
||||||
|
"entities",
|
||||||
|
"component",
|
||||||
|
"components",
|
||||||
|
"entity-component",
|
||||||
|
"entity-component-system",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
}
|
||||||
|
build = {
|
||||||
|
type = "builtin",
|
||||||
|
modules = {
|
||||||
|
evolved = "evolved.lua",
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user