2 Commits

Author SHA1 Message Date
BlackMATov
ffb0e37b7a update roadmap 2025-09-01 16:10:23 +07:00
BlackMATov
a63b0d4400 Revert "temp remove pairs to merge other changes to dev"
This reverts commit fb6d13ca74.
2025-09-01 15:50:48 +07:00
15 changed files with 4895 additions and 2238 deletions

202
README.md
View File

@@ -53,7 +53,8 @@
- [Cheat Sheet](#cheat-sheet)
- [Aliases](#aliases)
- [Predefs](#predefs)
- [Functions](#functions)
- [Core Functions](#core-functions)
- [Relation Functions](#relation-functions)
- [Classes](#classes)
- [Chunk](#chunk)
- [Builder](#builder)
@@ -156,6 +157,7 @@ function evolved.pack(index, version) end
---@param id evolved.id
---@return integer primary
---@return integer secondary
---@return integer options
---@nodiscard
function evolved.unpack(id) end
```
@@ -1024,6 +1026,7 @@ assert(not evolved.alive(entity))
```
id :: implementation-specific
pair :: id
entity :: id
fragment :: id
@@ -1047,14 +1050,20 @@ remove_hook :: {entity, fragment, component}
each_state :: implementation-specific
execute_state :: implementation-specific
primaries_state :: implementation-specific
secondaries_state :: implementation-specific
each_iterator :: {each_state? -> fragment?, component?}
execute_iterator :: {execute_state? -> chunk?, entity[]?, integer?}
primaries_iterator :: {primaries_state? -> fragment?, component?}
secondaries_iterator :: {secondaries_state? -> fragment?, component?}
```
### Predefs
```
ANY :: fragment
TAG :: fragment
NAME :: fragment
@@ -1090,23 +1099,20 @@ DESTRUCTION_POLICY_DESTROY_ENTITY :: id
DESTRUCTION_POLICY_REMOVE_FRAGMENT :: id
```
### Functions
### Core Functions
```
id :: integer? -> id...
name :: id... -> string...
pack :: integer, integer -> id
unpack :: id -> integer, integer
unpack :: id -> integer, integer, integer
defer :: boolean
commit :: boolean
spawn :: <fragment, component>? -> entity
multi_spawn :: integer, <fragment, component>? -> entity[]
clone :: entity, <fragment, component>? -> entity
multi_clone :: integer, entity, <fragment, component>? -> entity[]
clone :: entity -> <fragment, component>? -> entity
alive :: entity -> boolean
alive_all :: entity... -> boolean
@@ -1141,6 +1147,25 @@ debug_mode :: boolean -> ()
collect_garbage :: ()
```
### Relation Functions
```
pair :: id, id -> pair
unpair :: pair -> id, id
is_pair :: id -> boolean
is_wildcard :: id -> boolean
primary :: entity, fragment, integer? -> fragment?, component?
secondary :: entity, fragment, integer? -> fragment?, component?
primaries :: entity, fragment -> {primaries_state? -> fragment?, component?}, primaries_state?
secondaries :: entity, fragment -> {secondaries_state? -> fragment?, component?}, secondaries_state?
primary_count :: entity, fragment -> integer
secondary_count :: entity, fragment -> integer
```
### Classes
#### Chunk
@@ -1166,10 +1191,7 @@ chunk_mt:components :: fragment... -> storage...
builder :: builder
builder_mt:spawn :: entity
builder_mt:multi_spawn :: integer -> entity[]
builder_mt:clone :: entity -> entity
builder_mt:multi_clone :: integer, entity -> entity[]
builder_mt:has :: fragment -> boolean
builder_mt:has_all :: fragment... -> boolean
@@ -1222,12 +1244,7 @@ builder_mt:destruction_policy :: id -> builder
## vX.X.X
- Nothing yet, stay tuned!
## v1.2.0
- Added the new [`evolved.name`](#evolvedname-1) function
- Added the new [`evolved.multi_spawn`](#evolvedmulti_spawn) and [`evolved.multi_clone`](#evolvedmulti_clone) functions
- Added the new [`evolved.INTERNAL`](#evolvedinternal) fragment trait
## v1.1.0
@@ -1243,6 +1260,8 @@ builder_mt:destruction_policy :: id -> builder
## Predefs
### `evolved.ANY`
### `evolved.TAG`
### `evolved.NAME`
@@ -1291,7 +1310,7 @@ builder_mt:destruction_policy :: id -> builder
### `evolved.DESTRUCTION_POLICY_REMOVE_FRAGMENT`
## Functions
## Core Functions
### `evolved.id`
@@ -1327,6 +1346,7 @@ function evolved.pack(index, version) end
---@param id evolved.id
---@return integer primary
---@return integer secondary
---@return integer options
---@nodiscard
function evolved.unpack(id) end
```
@@ -1349,38 +1369,19 @@ function evolved.commit() end
```lua
---@param components? table<evolved.fragment, evolved.component>
---@return evolved.entity entity
---@return evolved.entity
function evolved.spawn(components) end
```
### `evolved.multi_spawn`
```lua
---@param entity_count integer
---@param components? table<evolved.fragment, evolved.component>
---@return evolved.entity[] entity_list
function evolved.multi_spawn(entity_count, components) end
```
### `evolved.clone`
```lua
---@param prefab evolved.entity
---@param components? table<evolved.fragment, evolved.component>
---@return evolved.entity entity
---@return evolved.entity
function evolved.clone(prefab, components) end
```
### `evolved.multi_clone`
```lua
---@param entity_count integer
---@param prefab evolved.entity
---@param components? table<evolved.fragment, evolved.component>
---@return evolved.entity[] entity_list
function evolved.multi_clone(entity_count, prefab, components) end
```
### `evolved.alive`
```lua
@@ -1577,6 +1578,112 @@ function evolved.debug_mode(yesno) end
function evolved.collect_garbage() end
```
## Relation Functions
### `evolved.pair`
```lua
---@param primary evolved.id
---@param secondary evolved.id
---@return evolved.pair pair
---@nodiscard
function evolved.pair(primary, secondary) end
```
### `evolved.unpair`
```lua
---@param pair evolved.pair
---@return evolved.id primary
---@return evolved.id secondary
---@nodiscard
function evolved.unpair(pair) end
```
### `evolved.is_pair`
```lua
---@param id evolved.id
---@return boolean
---@nodiscard
function evolved.is_pair(id) end
```
### `evolved.is_wildcard`
```lua
---@param id evolved.id
---@return boolean
---@nodiscard
function evolved.is_wildcard(id) end
```
### `evolved.primary`
```lua
---@param entity evolved.entity
---@param secondary evolved.fragment
---@param index? integer
---@return evolved.fragment? primary
---@return evolved.component? component
---@nodiscard
function evolved.primary(entity, secondary, index) end
```
### `evolved.secondary`
```lua
---@param entity evolved.entity
---@param primary evolved.fragment
---@param index? integer
---@return evolved.fragment? secondary
---@return evolved.component? component
---@nodiscard
function evolved.secondary(entity, primary, index) end
```
### `evolved.primaries`
```lua
---@param entity evolved.entity
---@param secondary evolved.fragment
---@return evolved.primaries_iterator iterator
---@return evolved.primaries_state? iterator_state
---@nodiscard
function evolved.primaries(entity, secondary) end
```
### `evolved.secondaries`
```lua
---@param entity evolved.entity
---@param primary evolved.fragment
---@return evolved.secondaries_iterator iterator
---@return evolved.secondaries_state? iterator_state
---@nodiscard
function evolved.secondaries(entity, primary) end
```
### `evolved.primary_count`
```lua
---@param entity evolved.entity
---@param secondary evolved.fragment
---@return integer
---@nodiscard
function evolved.primary_count(entity, secondary) end
```
### `evolved.secondary_count`
```lua
---@param entity evolved.entity
---@param primary evolved.fragment
---@return integer
---@nodiscard
function evolved.secondary_count(entity, primary) end
```
## Classes
### Chunk
@@ -1676,35 +1783,18 @@ function evolved.builder() end
#### `evolved.builder_mt:spawn`
```lua
---@return evolved.entity entity
---@return evolved.entity
function evolved.builder_mt:spawn() end
```
#### `evolved.builder_mt:multi_spawn`
```lua
---@param entity_count integer
---@return evolved.entity[] entity_list
function evolved.builder_mt:multi_spawn(entity_count) end
```
#### `evolved.builder_mt:clone`
```lua
---@param prefab evolved.entity
---@return evolved.entity entity
---@return evolved.entity
function evolved.builder_mt:clone(prefab) end
```
#### `evolved.builder_mt:multi_clone`
```lua
---@param entity_count integer
---@param prefab evolved.entity
---@return evolved.entity[] entity_list
function evolved.builder_mt:multi_clone(entity_count, prefab) end
```
#### `evolved.builder_mt:has`
```lua

View File

@@ -5,6 +5,7 @@
- Improve the performance of required fragments by caching first-level required chunks.
- Improve the performance of builders that are used multiple times by caching hint chunks.
- Queries can cache major chunks to avoid finding them every time.
- Add multi-spawn to the builder to spawn multiple entities at once.
- Add a function to shrink storages to free unused memory.
- observers and events
- add INDEX fragment trait

View File

@@ -1,14 +1,11 @@
require 'develop.samples.relations'
require 'develop.samples.systems'
require 'develop.testing.multi_spawn_tests'
require 'develop.testing.name_tests'
require 'develop.testing.pairs_tests'
require 'develop.testing.requires_fragment_tests'
require 'develop.testing.system_as_query_tests'
require 'develop.benchmarks.multi_clone_bmarks'
require 'develop.benchmarks.multi_spawn_bmarks'
require 'develop.benchmarks.process_bmarks'
require 'develop.untests'
require 'develop.unbench'
@@ -28,3 +25,5 @@ print '----------------------------------------'
basics.describe_fuzz 'develop.fuzzing.requires_fuzz'
print '----------------------------------------'
basics.describe_fuzz 'develop.fuzzing.unique_fuzz'
print '----------------------------------------'
basics.describe_fuzz 'develop.fuzzing.wildcard_fuzz'

View File

@@ -1,59 +0,0 @@
local evo = require 'evolved'
local basics = require 'develop.basics'
evo.debug_mode(false)
local N = 1000
local F1, F2, F3, F4, F5 = evo.id(5)
local Q1 = evo.builder():include(F1):spawn()
print '----------------------------------------'
basics.describe_bench(string.format('Multi Clone Benchmarks: Simple Clone | %d entities with 1 component', N),
function()
local clone = evo.clone
local prefab = evo.spawn { [F1] = true }
for _ = 1, N do
clone(prefab)
end
evo.batch_destroy(Q1)
end)
basics.describe_bench(string.format('Multi Clone Benchmarks: Simple Clone | %d entities with 5 components', N),
function()
local clone = evo.clone
local prefab = evo.spawn { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true }
for _ = 1, N do
clone(prefab)
end
evo.batch_destroy(Q1)
end)
basics.describe_bench(string.format('Multi Clone Benchmarks: Multi Clone | %d entities with 1 component', N),
function()
local multi_clone = evo.multi_clone
local prefab = evo.spawn { [F1] = true }
multi_clone(N, prefab)
evo.batch_destroy(Q1)
end)
basics.describe_bench(string.format('Multi Clone Benchmarks: Multi Clone | %d entities with 5 components', N),
function()
local multi_clone = evo.multi_clone
local prefab = evo.spawn { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true }
multi_clone(N, prefab)
evo.batch_destroy(Q1)
end)

View File

@@ -1,59 +0,0 @@
local evo = require 'evolved'
local basics = require 'develop.basics'
evo.debug_mode(false)
local N = 1000
local F1, F2, F3, F4, F5 = evo.id(5)
local Q1 = evo.builder():include(F1):spawn()
print '----------------------------------------'
basics.describe_bench(string.format('Multi Spawn Benchmarks: Simple Spawn | %d entities with 1 component', N),
function()
local spawn = evo.spawn
local components = { [F1] = true }
for _ = 1, N do
spawn(components)
end
evo.batch_destroy(Q1)
end)
basics.describe_bench(string.format('Multi Spawn Benchmarks: Simple Spawn | %d entities with 5 components', N),
function()
local spawn = evo.spawn
local components = { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true }
for _ = 1, N do
spawn(components)
end
evo.batch_destroy(Q1)
end)
basics.describe_bench(string.format('Multi Spawn Benchmarks: Multi Spawn | %d entities with 1 component', N),
function()
local multi_spawn = evo.multi_spawn
local components = { [F1] = true }
multi_spawn(N, components)
evo.batch_destroy(Q1)
end)
basics.describe_bench(string.format('Multi Spawn Benchmarks: Multi Spawn | %d entities with 5 components', N),
function()
local multi_spawn = evo.multi_spawn
local components = { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true }
multi_spawn(N, components)
evo.batch_destroy(Q1)
end)

View File

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

View File

@@ -13,8 +13,9 @@ for _ = 1, 1000 do
local initial_secondary = math.random(1, 2 ^ 20 - 1)
local packed_id = evo.pack(initial_primary, initial_secondary)
local unpacked_primary, unpacked_secondary = evo.unpack(packed_id)
local unpacked_primary, unpacked_secondary, unpacked_options = evo.unpack(packed_id)
assert(initial_primary == unpacked_primary)
assert(initial_secondary == unpacked_secondary)
assert(0 == unpacked_options)
end

View File

@@ -0,0 +1,275 @@
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_entity_list = {} ---@type evolved.entity[]
local all_fragment_list = {} ---@type evolved.fragment[]
for i = 1, math.random(1, 5) do
local fragment_builder = evo.builder()
if math.random(1, 3) == 1 then
fragment_builder:explicit()
end
if math.random(1, 3) == 1 then
if math.random(1, 2) == 1 then
fragment_builder:destruction_policy(evo.DESTRUCTION_POLICY_DESTROY_ENTITY)
else
fragment_builder:destruction_policy(evo.DESTRUCTION_POLICY_REMOVE_FRAGMENT)
end
end
all_fragment_list[i] = fragment_builder:spawn()
end
for i = 1, math.random(50, 100) do
local entity_builder = evo.builder()
for _ = 0, math.random(0, #all_fragment_list) do
if math.random(1, 2) == 1 then
local fragment = all_fragment_list[math.random(1, #all_fragment_list)]
entity_builder:set(fragment)
else
local primary = all_fragment_list[math.random(1, #all_fragment_list)]
local secondary = all_fragment_list[math.random(1, #all_fragment_list)]
entity_builder:set(evo.pair(primary, secondary))
end
end
all_entity_list[i] = entity_builder:spawn()
end
---
---
---
---
---
for _ = 1, math.random(1, 100) do
local query_builder = evo.builder()
local query_include_set = {} ---@type table<evolved.fragment, integer>
local query_include_list = {} ---@type evolved.entity[]
local query_include_count = 0 ---@type integer
local query_exclude_set = {} ---@type table<evolved.fragment, integer>
local query_exclude_list = {} ---@type evolved.entity[]
local query_exclude_count = 0 ---@type integer
for _ = 1, math.random(0, 2) do
if math.random(1, 2) == 1 then
local fragment = all_fragment_list[math.random(1, #all_fragment_list)]
query_builder:include(fragment)
if not query_include_set[fragment] then
query_include_count = query_include_count + 1
query_include_set[fragment] = query_include_count
query_include_list[query_include_count] = fragment
end
else
local primary = all_fragment_list[math.random(1, #all_fragment_list)]
local secondary = all_fragment_list[math.random(1, #all_fragment_list)]
if math.random(1, 3) == 1 then
primary = evo.ANY
end
if math.random(1, 3) == 1 then
secondary = evo.ANY
end
local pair = evo.pair(primary, secondary)
query_builder:include(pair)
if not query_include_set[pair] then
query_include_count = query_include_count + 1
query_include_set[pair] = query_include_count
query_include_list[query_include_count] = pair
end
end
end
for _ = 1, math.random(0, 2) do
if math.random(1, 2) == 1 then
local fragment = all_fragment_list[math.random(1, #all_fragment_list)]
query_builder:exclude(fragment)
if not query_exclude_set[fragment] then
query_exclude_count = query_exclude_count + 1
query_exclude_set[fragment] = query_exclude_count
query_exclude_list[query_exclude_count] = fragment
end
else
local primary = all_fragment_list[math.random(1, #all_fragment_list)]
local secondary = all_fragment_list[math.random(1, #all_fragment_list)]
if math.random(1, 3) == 1 then
primary = evo.ANY
end
if math.random(1, 3) == 1 then
secondary = evo.ANY
end
local pair = evo.pair(primary, secondary)
query_builder:exclude(pair)
if not query_exclude_set[pair] then
query_exclude_count = query_exclude_count + 1
query_exclude_set[pair] = query_exclude_count
query_exclude_list[query_exclude_count] = pair
end
end
end
local query_entity_set = {} ---@type table<evolved.entity, integer>
local query_entity_count = 0 ---@type integer
do
local query = query_builder:spawn()
for chunk, entity_list, entity_count in evo.execute(query) do
if not chunk:has(evo.INTERNAL) then
for i = 1, entity_count do
local entity = entity_list[i]
assert(not query_entity_set[entity])
query_entity_count = query_entity_count + 1
query_entity_set[entity] = query_entity_count
end
end
end
if query_entity_set[query] then
query_entity_set[query] = nil
query_entity_count = query_entity_count - 1
end
evo.destroy(query)
end
do
local expected_entity_count = 0
for _, entity in ipairs(all_entity_list) do
local is_entity_expected =
not evo.empty(entity) and
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
local is_fragment_explicit = false
if not is_fragment_explicit and evo.is_pair(fragment) then
is_fragment_explicit = evo.has(evo.unpair(fragment), evo.EXPLICIT)
end
if not is_fragment_explicit and not evo.is_pair(fragment) then
is_fragment_explicit = evo.has(fragment, evo.EXPLICIT)
end
if is_fragment_explicit then
local is_fragment_included = false
if not is_fragment_included then
is_fragment_included = query_include_set[fragment] ~= nil
end
if not is_fragment_included and evo.is_pair(fragment) then
local fragment_primary = evo.unpair(fragment)
is_fragment_included = query_include_set[evo.pair(fragment_primary, evo.ANY)] ~= nil
end
if not is_fragment_included and not evo.is_pair(fragment) then
is_fragment_included = query_include_set[evo.pair(fragment, evo.ANY)] ~= nil
end
if not is_fragment_included then
is_entity_expected = false
break
end
end
end
if is_entity_expected then
assert(query_entity_set[entity])
expected_entity_count = expected_entity_count + 1
else
assert(not query_entity_set[entity])
end
end
for _, entity in ipairs(all_fragment_list) do
local is_entity_expected =
not evo.empty(entity) and
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) then
is_entity_expected = is_entity_expected and
(query_include_set[fragment] ~= nil) or
(evo.is_pair(fragment) and query_include_set[evo.pair(fragment, evo.ANY)] ~= nil)
end
end
if is_entity_expected then
assert(query_entity_set[entity])
expected_entity_count = expected_entity_count + 1
else
assert(not query_entity_set[entity])
end
end
assert(query_entity_count == expected_entity_count)
end
end
---
---
---
---
---
if math.random(1, 2) == 1 then
evo.collect_garbage()
end
if math.random(1, 2) == 1 then
evo.destroy(__table_unpack(all_entity_list))
if math.random(1, 2) == 1 then
evo.collect_garbage()
end
evo.destroy(__table_unpack(all_fragment_list))
else
evo.destroy(__table_unpack(all_fragment_list))
if math.random(1, 2) == 1 then
evo.collect_garbage()
end
evo.destroy(__table_unpack(all_entity_list))
end
if math.random(1, 2) == 1 then
evo.collect_garbage()
end

View File

@@ -0,0 +1,79 @@
---@diagnostic disable: unused-local
local evo = require 'evolved'
evo.debug_mode(true)
local fragments = {
planet = evo.builder()
:name('planet')
:tag()
:spawn(),
spaceship = evo.builder()
:name('spaceship')
:tag()
:spawn(),
}
local relations = {
docked_to = evo.builder()
:name('docked_to')
:tag()
:spawn(),
}
local planets = {
mars = evo.builder()
:name('Mars')
:set(fragments.planet)
:spawn(),
venus = evo.builder()
:name('Venus')
:set(fragments.planet)
:spawn(),
}
local spaceships = {
falcon = evo.builder()
:name('Millennium Falcon')
:set(fragments.spaceship)
:set(evo.pair(relations.docked_to, planets.mars))
:spawn(),
enterprise = evo.builder()
:name('USS Enterprise')
:set(fragments.spaceship)
:set(evo.pair(relations.docked_to, planets.venus))
:spawn(),
}
local queries = {
all_docked_spaceships = evo.builder()
:include(fragments.spaceship)
:include(evo.pair(relations.docked_to, evo.ANY))
:spawn(),
docked_spaceships_to_mars = evo.builder()
:include(fragments.spaceship)
:include(evo.pair(relations.docked_to, planets.mars))
:spawn(),
}
print '-= | All Docked Spaceships | =-'
for chunk, entity_list, entity_count in evo.execute(queries.all_docked_spaceships) do
for i = 1, entity_count do
local entity = entity_list[i]
local planet = evo.secondary(entity, relations.docked_to)
print(string.format('%s is docked to %s', evo.name(entity), evo.name(planet)))
end
end
print '-= | Docked Spaceships to Mars | =-'
for chunk, entity_list, entity_count in evo.execute(queries.docked_spaceships_to_mars) do
for i = 1, entity_count do
local entity = entity_list[i]
local planet = evo.secondary(entity, relations.docked_to)
print(string.format('%s is docked to %s', evo.name(entity), evo.name(planet)))
end
end

View File

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

View File

@@ -3,8 +3,8 @@ local evo = require 'evolved'
do
local id = evo.id()
local index, version = evo.unpack(id)
assert(evo.name(id) == string.format('$%d#%d:%d', id, index, version))
local index, version, options = evo.unpack(id)
assert(evo.name(id) == string.format('$%d#%d:%d:%d', id, index, version, options))
evo.set(id, evo.NAME, 'hello')
assert(evo.name(id) == 'hello')
@@ -13,7 +13,7 @@ do
assert(evo.name(id) == 'world')
evo.destroy(id)
assert(evo.name(id) == string.format('$%d#%d:%d', id, index, version))
assert(evo.name(id) == string.format('$%d#%d:%d:%d', id, index, version, options))
end
do

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

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