Merge branch 'dev'

This commit is contained in:
BlackMATov
2025-03-16 02:06:17 +07:00
5 changed files with 1427 additions and 564 deletions

View File

@@ -72,8 +72,8 @@ set :: entity, fragment, any... -> boolean, boolean
assign :: entity, fragment, any... -> boolean, boolean
insert :: entity, fragment, any... -> boolean, boolean
remove :: entity, fragment... -> boolean, boolean
clear :: entity -> boolean, boolean
destroy :: entity -> boolean, boolean
clear :: entity... -> boolean, boolean
destroy :: entity... -> boolean, boolean
multi_set :: entity, fragment[], component[]? -> boolean, boolean
multi_assign :: entity, fragment[], component[]? -> boolean, boolean
@@ -84,8 +84,8 @@ batch_set :: query, fragment, any... -> integer, boolean
batch_assign :: query, fragment, any... -> integer, boolean
batch_insert :: query, fragment, any... -> integer, boolean
batch_remove :: query, fragment... -> integer, boolean
batch_clear :: query -> integer, boolean
batch_destroy :: query -> integer, boolean
batch_clear :: query... -> integer, boolean
batch_destroy :: query... -> integer, boolean
batch_multi_set :: query, fragment[], component[]? -> integer, boolean
batch_multi_assign :: query, fragment[], component[]? -> integer, boolean
@@ -102,17 +102,16 @@ each :: entity -> {each_state? -> fragment?, component?}, each_state?
execute :: query -> {execute_state? -> chunk?, entity[]?, integer?}, execute_state?
process :: phase... -> ()
```
```
debug :: boolean -> ()
```
```
spawn_at :: chunk?, fragment[]?, component[]? -> entity, boolean
spawn_with :: fragment[]?, component[]? -> entity, boolean
debug_mode :: boolean -> ()
collect_garbage :: boolean, boolean
```
## Builders
```
entity :: entity_builder
entity_builder:set :: fragment, any... -> entity_builder

View File

@@ -2,15 +2,12 @@
## Backlog
- collect unreachable chunks
## After first release
- add system groups
- auto chunk count reducing
- add INDEX fragment trait
- add REQUIRES fragment trait
- use compact prefix-tree for chunks
- set/assign/insert/remove/clear/destroy for lists
- optional ffi component storages
- keep entity_chunks/places tables as arrays
- batch deferred set/assign/insert/remove operations

View File

@@ -1,4 +1,4 @@
require 'develop.example'
require 'develop.unbench'
-- require 'develop.unbench'
require 'develop.untests'
require 'develop.usbench'
-- require 'develop.usbench'

View File

@@ -2,17 +2,12 @@ require 'develop.unload' 'evolved'
local evo = require 'evolved'
evo.debug(true)
do
local e1, e2 = evo.id(), evo.id()
assert(e1 ~= e2)
end
evo.debug_mode(true)
do
local i = evo.id()
for _ = 1, 0xFFE do
for _ = 1, 0xFFFFE do
local _, v0 = evo.unpack(i)
evo.destroy(i)
i = evo.id()
@@ -22,7 +17,7 @@ do
do
local _, v = evo.unpack(i)
assert(v == 0xFFF)
assert(v == 0xFFFFF)
end
evo.destroy(i)
@@ -34,6 +29,31 @@ do
end
end
do
local e1, e2 = evo.id(), evo.id()
assert(e1 ~= e2)
assert(evo.is_alive(e1))
assert(evo.is_alive(e2))
assert(evo.destroy(e1))
assert(not evo.is_alive(e1))
assert(evo.is_alive(e2))
assert(evo.destroy(e1))
assert(evo.destroy(e2))
assert(not evo.is_alive(e1))
assert(not evo.is_alive(e2))
assert(evo.destroy(e1))
assert(evo.destroy(e2))
assert(not evo.is_alive(e1))
assert(not evo.is_alive(e2))
end
do
do
local i0 = evo.id(0)
@@ -2294,18 +2314,12 @@ do
do
local iter, state = evo.execute(q)
local chunk, entities = iter(state)
local chunk, entities = iter(state)
assert(chunk == evo.chunk(f2))
assert(entities and entities[1] == e2)
end
evo.set(q, evo.INCLUDES)
do
local iter, state = evo.execute(q)
local chunk, entities = iter(state)
chunk, entities = iter(state)
assert(not chunk)
assert(not entities)
end
@@ -2398,16 +2412,16 @@ do
do
local iter, state = evo.execute(q)
local chunk, entities = iter(state)
assert(not chunk and not entities)
local chunk = iter(state)
assert(chunk and chunk ~= evo.chunk(f1))
end
evo.set(q, evo.EXCLUDES, f2)
do
local iter, state = evo.execute(q)
local chunk, entities = iter(state)
assert(not chunk and not entities)
local chunk = iter(state)
assert(chunk and chunk ~= evo.chunk(f1))
end
evo.set(q, evo.INCLUDES, f1)
@@ -5082,9 +5096,15 @@ do
end
do
local id = evo.pack(0xFFFFF, 0xFFF)
local id = evo.pack(0xBCDEF, 0xFEDCB)
local index, version = evo.unpack(id)
assert(index == 0xFFFFF and version == 0xFFF)
assert(index == 0xBCDEF and version == 0xFEDCB)
end
do
local id = evo.pack(0xFFFFF, 0xFFFFF)
local index, version = evo.unpack(id)
assert(index == 0xFFFFF and version == 0xFFFFF)
end
do
@@ -7211,3 +7231,415 @@ do
assert(not chunk and not entity_list)
end
end
do
local f1, f2 = evo.id(2)
local q12 = evo.query():include(f1, f2):build()
do
local iter, state = evo.execute(q12)
local chunk, entity_list, entity_count = iter(state)
assert(not chunk and not entity_list and not entity_count)
end
end
do
local f1, f2 = evo.id(2)
local qe12 = evo.query():exclude(f1, f2):build()
evo.entity():set(f1, 1):build()
evo.entity():set(f2, 2):build()
local e12 = evo.entity():set(f1, 3):set(f2, 4):build()
local c1 = evo.chunk(f1)
local c2 = evo.chunk(f2)
local c12 = evo.chunk(f1, f2)
do
local matched_chunk_count = 0
local matched_entity_count = 0
for c, es, ec in evo.execute(qe12) do
assert(ec > 0)
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
end
assert(matched_chunk_count > 0)
assert(matched_entity_count > 0)
end
assert(evo.assign(qe12, evo.EXCLUDES))
do
local matched_chunk_count = 0
local matched_entity_count = 0
for _, es, ec in evo.execute(qe12) do
assert(ec > 0)
assert(#es == ec)
matched_chunk_count = matched_chunk_count + 1
matched_entity_count = matched_entity_count + ec
end
assert(matched_chunk_count > 0)
assert(matched_entity_count > 0)
end
assert(evo.insert(qe12, evo.INCLUDES, f1, f2))
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_count and entity_count == 1)
assert(entity_list[1] == e12)
end
end
do
local f1, f2 = evo.id(2)
assert(evo.insert(f1, evo.NAME, 'f1'))
assert(evo.insert(f2, evo.NAME, 'f2'))
local old_c1 = assert(evo.chunk(f1))
local old_c12 = assert(evo.chunk(f1, f2))
local e1 = evo.entity():set(f1, 1):build()
evo.collect_garbage()
local e12 = evo.entity():set(f1, 2):set(f2, 3):build()
do
assert(old_c1 == evo.chunk(f1))
local old_c1_es, old_c1_ec = evo.entities(old_c1)
assert(old_c1_es and old_c1_ec)
assert(#old_c1_es == 1 and old_c1_ec == 1)
assert(old_c1_es[1] == e1)
end
do
local new_c12 = assert(evo.chunk(f1, f2))
assert(old_c12 ~= new_c12)
local new_c12_es, new_c12_ec = evo.entities(new_c12)
assert(new_c12_es and new_c12_ec)
assert(#new_c12_es == 1 and new_c12_ec == 1)
assert(new_c12_es[1] == e12)
end
assert(evo.destroy(e1))
assert(evo.destroy(e12))
evo.collect_garbage()
do
local new_c1 = assert(evo.chunk(f1))
assert(old_c1 ~= new_c1)
local new_c12 = assert(evo.chunk(f1, f2))
assert(old_c12 ~= new_c12)
end
end
do
local f1 = evo.id()
local old_c1 = evo.chunk(f1)
assert(evo.defer())
assert(not evo.collect_garbage())
assert(old_c1 == evo.chunk(f1))
assert(evo.commit())
assert(old_c1 ~= evo.chunk(f1))
end
do
do
local f1 = evo.id()
local e1, e2 = evo.id(2)
assert(evo.insert(e1, f1, f1))
assert(evo.insert(e2, f1, f1))
assert(evo.clear(e1, e2))
assert(evo.is_alive(e1) and evo.is_empty(e1))
assert(evo.is_alive(e2) and evo.is_empty(e2))
end
do
local f1 = evo.id()
local e1, e2, e3, e4, e5 = evo.id(5)
assert(evo.insert(e1, f1, f1))
assert(evo.insert(e2, f1, f1))
assert(evo.insert(e3, f1, f1))
assert(evo.insert(e4, f1, f1))
assert(evo.insert(e5, f1, f1))
assert(evo.clear(e1, e2, e3, e4, e5))
assert(evo.is_alive(e1) and evo.is_empty(e1))
assert(evo.is_alive(e2) and evo.is_empty(e2))
assert(evo.is_alive(e3) and evo.is_empty(e3))
assert(evo.is_alive(e4) and evo.is_empty(e4))
assert(evo.is_alive(e5) and evo.is_empty(e5))
end
end
do
do
local f1 = evo.id()
local e1, e2, e3 = evo.id(3)
assert(evo.insert(e1, f1, f1))
assert(evo.insert(e2, f1, f1))
assert(evo.insert(e3, f1, f1))
assert(evo.defer())
do
assert(not evo.clear(e1, e2, e3))
assert(evo.is_alive(e1) and not evo.is_empty(e1))
assert(evo.is_alive(e2) and not evo.is_empty(e2))
assert(evo.is_alive(e3) and not evo.is_empty(e3))
end
assert(evo.commit())
assert(evo.is_alive(e1) and evo.is_empty(e1))
assert(evo.is_alive(e2) and evo.is_empty(e2))
assert(evo.is_alive(e3) and evo.is_empty(e3))
end
do
local f1 = evo.id()
local e1, e2, e3, e4, e5 = evo.id(5)
assert(evo.insert(e1, f1, f1))
assert(evo.insert(e2, f1, f1))
assert(evo.insert(e3, f1, f1))
assert(evo.insert(e4, f1, f1))
assert(evo.insert(e5, f1, f1))
assert(evo.defer())
do
assert(not evo.clear(e1, e2, e3, e4, e5))
assert(evo.is_alive(e1) and not evo.is_empty(e1))
assert(evo.is_alive(e2) and not evo.is_empty(e2))
assert(evo.is_alive(e3) and not evo.is_empty(e3))
assert(evo.is_alive(e4) and not evo.is_empty(e4))
assert(evo.is_alive(e5) and not evo.is_empty(e5))
end
assert(evo.commit())
assert(evo.is_alive(e1) and evo.is_empty(e1))
assert(evo.is_alive(e2) and evo.is_empty(e2))
assert(evo.is_alive(e3) and evo.is_empty(e3))
assert(evo.is_alive(e4) and evo.is_empty(e4))
assert(evo.is_alive(e5) and evo.is_empty(e5))
end
end
do
do
local f1 = evo.id()
local e1, e2 = evo.id(2)
assert(evo.insert(e1, f1, f1))
assert(evo.insert(e2, f1, f1))
assert(evo.destroy(e1, e2))
assert(not evo.is_alive(e1) and evo.is_empty(e1))
assert(not evo.is_alive(e2) and evo.is_empty(e2))
end
do
local f1 = evo.id()
local e1, e2, e3, e4, e5 = evo.id(5)
assert(evo.insert(e1, f1, f1))
assert(evo.insert(e2, f1, f1))
assert(evo.insert(e3, f1, f1))
assert(evo.insert(e4, f1, f1))
assert(evo.insert(e5, f1, f1))
assert(evo.destroy(e1, e2, e3, e4, e5))
assert(not evo.is_alive(e1) and evo.is_empty(e1))
assert(not evo.is_alive(e2) and evo.is_empty(e2))
assert(not evo.is_alive(e3) and evo.is_empty(e3))
assert(not evo.is_alive(e4) and evo.is_empty(e4))
assert(not evo.is_alive(e5) and evo.is_empty(e5))
end
end
do
do
local f1 = evo.id()
local e1, e2, e3 = evo.id(3)
assert(evo.insert(e1, f1, f1))
assert(evo.insert(e2, f1, f1))
assert(evo.insert(e3, f1, f1))
assert(evo.defer())
do
assert(not evo.destroy(e1, e2, e3))
assert(evo.is_alive(e1) and not evo.is_empty(e1))
assert(evo.is_alive(e2) and not evo.is_empty(e2))
assert(evo.is_alive(e3) and not evo.is_empty(e3))
end
assert(evo.commit())
assert(not evo.is_alive(e1) and evo.is_empty(e1))
assert(not evo.is_alive(e2) and evo.is_empty(e2))
assert(not evo.is_alive(e3) and evo.is_empty(e3))
end
do
local f1 = evo.id()
local e1, e2, e3, e4, e5 = evo.id(5)
assert(evo.insert(e1, f1, f1))
assert(evo.insert(e2, f1, f1))
assert(evo.insert(e3, f1, f1))
assert(evo.insert(e4, f1, f1))
assert(evo.insert(e5, f1, f1))
assert(evo.defer())
do
assert(not evo.destroy(e1, e2, e3, e4, e5))
assert(evo.is_alive(e1) and not evo.is_empty(e1))
assert(evo.is_alive(e2) and not evo.is_empty(e2))
assert(evo.is_alive(e3) and not evo.is_empty(e3))
assert(evo.is_alive(e4) and not evo.is_empty(e4))
assert(evo.is_alive(e5) and not evo.is_empty(e5))
end
assert(evo.commit())
assert(not evo.is_alive(e1) and evo.is_empty(e1))
assert(not evo.is_alive(e2) and evo.is_empty(e2))
assert(not evo.is_alive(e3) and evo.is_empty(e3))
assert(not evo.is_alive(e4) and evo.is_empty(e4))
assert(not evo.is_alive(e5) and evo.is_empty(e5))
end
end
do
local f1 = evo.id()
local e1, e2 = evo.id(2)
assert(evo.insert(e1, f1, f1))
assert(evo.insert(e2, f1, f1))
assert(evo.clear(e1, e2, e1, e1))
assert(evo.is_alive(e1) and evo.is_empty(e1))
assert(evo.is_alive(e2) and evo.is_empty(e2))
end
do
local f1 = evo.id()
local e1, e2 = evo.id(2)
assert(evo.insert(e1, f1, f1))
assert(evo.insert(e2, f1, f1))
assert(evo.destroy(e1, e2, e1, e1))
assert(not evo.is_alive(e1) and evo.is_empty(e1))
assert(not evo.is_alive(e2) and evo.is_empty(e2))
end
do
local f1, f2 = evo.id(2)
local q1, q2 = evo.id(2)
assert(evo.insert(q1, evo.INCLUDES, f1))
assert(evo.insert(q2, evo.INCLUDES, f2))
local e1, e2 = evo.id(2)
assert(evo.insert(e1, f1, f1))
assert(evo.insert(e2, f2, f2))
assert(evo.batch_clear() == 0)
assert(evo.is_alive(e1) and not evo.is_empty(e1))
assert(evo.is_alive(e2) and not evo.is_empty(e2))
assert(evo.batch_clear(q1, q2, q1, q1) == 2)
assert(evo.is_alive(e1) and evo.is_empty(e1))
assert(evo.is_alive(e2) and evo.is_empty(e2))
end
do
local f1, f2 = evo.id(2)
local q1, q2 = evo.id(2)
assert(evo.insert(q1, evo.INCLUDES, f1))
assert(evo.insert(q2, evo.INCLUDES, f2))
local e1, e2 = evo.id(2)
assert(evo.insert(e1, f1, f1))
assert(evo.insert(e2, f2, f2))
assert(evo.defer())
do
assert(evo.batch_clear(q2, q1, q2, q2) == 0)
assert(evo.is_alive(e1) and not evo.is_empty(e1))
assert(evo.is_alive(e2) and not evo.is_empty(e2))
end
assert(evo.commit())
assert(evo.is_alive(e1) and evo.is_empty(e1))
assert(evo.is_alive(e2) and evo.is_empty(e2))
end
do
local f1, f2 = evo.id(2)
local q1, q2 = evo.id(2)
assert(evo.insert(q1, evo.INCLUDES, f1))
assert(evo.insert(q2, evo.INCLUDES, f2))
local e1, e2 = evo.id(2)
assert(evo.insert(e1, f1, f1))
assert(evo.insert(e2, f2, f2))
assert(evo.batch_destroy() == 0)
assert(evo.is_alive(e1) and not evo.is_empty(e1))
assert(evo.is_alive(e2) and not evo.is_empty(e2))
assert(evo.batch_destroy(q1, q2, q1, q1) == 2)
assert(not evo.is_alive(e1) and evo.is_empty(e1))
assert(not evo.is_alive(e2) and evo.is_empty(e2))
end
do
local f1, f2 = evo.id(2)
local q1, q2 = evo.id(2)
assert(evo.insert(q1, evo.INCLUDES, f1))
assert(evo.insert(q2, evo.INCLUDES, f2))
local e1, e2 = evo.id(2)
assert(evo.insert(e1, f1, f1))
assert(evo.insert(e2, f2, f2))
assert(evo.defer())
do
assert(evo.batch_destroy(q2, q1, q2, q2) == 0)
assert(evo.is_alive(e1) and not evo.is_empty(e1))
assert(evo.is_alive(e2) and not evo.is_empty(e2))
end
assert(evo.commit())
assert(not evo.is_alive(e1) and evo.is_empty(e1))
assert(not evo.is_alive(e2) and evo.is_empty(e2))
end

File diff suppressed because it is too large Load Diff