diff --git a/README.md b/README.md index da2c857..d765344 100644 --- a/README.md +++ b/README.md @@ -29,9 +29,16 @@ ``` TAG :: fragment NAME :: fragment + +UNIQUE :: fragment +EXPLICIT :: fragment + DEFAULT :: fragment DUPLICATE :: fragment +PREFAB :: fragment +DISABLED :: fragment + INCLUDES :: fragment EXCLUDES :: fragment @@ -48,8 +55,6 @@ EXECUTE :: fragment PROLOGUE :: fragment EPILOGUE :: fragment -DISABLED :: fragment - DESTROY_POLICY :: fragment DESTROY_POLICY_DESTROY_ENTITY :: id DESTROY_POLICY_REMOVE_FRAGMENT :: id @@ -66,17 +71,20 @@ unpack :: id -> integer, integer defer :: boolean commit :: boolean -is_alive :: chunk | entity -> boolean -is_alive_all :: chunk | entity... -> boolean -is_alive_any :: chunk | entity... -> boolean +spawn :: ? -> entity +clone :: entity -> ? -> entity -is_empty :: chunk | entity -> boolean -is_empty_all :: chunk | entity... -> boolean -is_empty_any :: chunk | entity... -> boolean +alive :: entity -> boolean +alive_all :: entity... -> boolean +alive_any :: entity... -> boolean -has :: chunk | entity, fragment -> boolean -has_all :: chunk | entity, fragment... -> boolean -has_any :: chunk | entity, fragment... -> boolean +empty :: entity -> boolean +empty_all :: entity... -> boolean +empty_any :: entity... -> boolean + +has :: entity, fragment -> boolean +has_all :: entity, fragment... -> boolean +has_any :: entity, fragment... -> boolean get :: entity, fragment... -> component... @@ -85,67 +93,84 @@ remove :: entity, fragment... -> () clear :: entity... -> () destroy :: entity... -> () -multi_set :: entity, fragment[], component[]? -> () -multi_remove :: entity, fragment[] -> () - batch_set :: query, fragment, component -> () batch_remove :: query, fragment... -> () batch_clear :: query... -> () batch_destroy :: query... -> () -batch_multi_set :: query, fragment[], component[]? -> () -batch_multi_remove :: query, fragment[] -> () - -chunk :: fragment, fragment... -> chunk, entity[], integer - -entities :: chunk -> entity[], integer -fragments :: chunk -> fragment[], integer -components :: chunk, fragment... -> component[]... - each :: entity -> {each_state? -> fragment?, component?}, each_state? execute :: query -> {execute_state? -> chunk?, entity[]?, integer?}, execute_state? process :: system... -> () -spawn_at :: chunk?, fragment[]?, component[]? -> entity -spawn_as :: entity?, fragment[]?, component[]? -> entity -spawn_with :: fragment[]?, component[]? -> entity - debug_mode :: boolean -> () collect_garbage :: () ``` +## Chunk + +``` +chunk :: fragment, fragment... -> chunk, entity[], integer + +chunk:alive :: boolean +chunk:empty :: boolean + +chunk:has :: fragment -> boolean +chunk:has_all :: fragment... -> boolean +chunk:has_any :: fragment... -> boolean + +chunk:entities :: entity[], integer +chunk:fragments :: fragment[], integer +chunk:components :: fragment... -> component[]... +``` + ## Builder ``` builder :: builder + +builder:spawn :: entity +builder:clone :: entity -> entity + builder:has :: fragment -> boolean builder:has_all :: fragment... -> boolean builder:has_any :: fragment... -> boolean + builder:get :: fragment... -> component... + builder:set :: fragment, component -> builder builder:remove :: fragment... -> builder builder:clear :: builder + builder:tag :: builder builder:name :: string -> builder -builder:prefab :: entity -> builder -builder:single :: component -> builder + +builder:unique :: builder +builder:explicit :: builder + builder:default :: component -> builder builder:duplicate :: {component -> component} -> builder + +builder:prefab :: builder +builder:disabled :: builder + builder:include :: fragment... -> builder builder:exclude :: fragment... -> builder + builder:on_set :: {entity, fragment, component, component?} -> builder builder:on_assign :: {entity, fragment, component, component} -> builder builder:on_insert :: {entity, fragment, component} -> builder builder:on_remove :: {entity, fragment} -> builder + builder:group :: system -> builder + builder:query :: query -> builder builder:execute :: {chunk, entity[], integer} -> builder + builder:prologue :: {} -> builder builder:epilogue :: {} -> builder -builder:disabled :: builder + builder:destroy_policy :: id -> builder -builder:build :: boolean -> entity ``` ## [License (MIT)](./LICENSE.md) diff --git a/ROADMAP.md b/ROADMAP.md index 4bb3636..7092a02 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2,10 +2,6 @@ ## Backlog -- builders should be rewritten :/ -- add PREFAB entity trait -- is/has_all/any for lists? - ## After first release - cached queries diff --git a/develop/all.lua b/develop/all.lua index 721dfcf..1a518e5 100644 --- a/develop/all.lua +++ b/develop/all.lua @@ -5,5 +5,11 @@ require 'develop.usbench' local basics = require 'develop.basics' +print '----------------------------------------' basics.describe_fuzz 'develop.fuzzing.destroy_fuzz' +print '----------------------------------------' basics.describe_fuzz 'develop.fuzzing.batch_destroy_fuzz' +print '----------------------------------------' +basics.describe_fuzz 'develop.fuzzing.explicit_fuzz' +print '----------------------------------------' +basics.describe_fuzz 'develop.fuzzing.unique_fuzz' diff --git a/develop/example.lua b/develop/example.lua index 22cc32a..a2cc625 100644 --- a/develop/example.lua +++ b/develop/example.lua @@ -17,28 +17,28 @@ local function vector2(x, y) return { x = x, y = y } end -local groups = { - awake = evo.builder():build(), - physics = evo.builder():build(), - graphics = evo.builder():build(), - shutdown = evo.builder():build(), +local consts = { + delta_time = 0.016, + physics_gravity = vector2(0, 9.81), } -local singles = { - delta_time = evo.builder():single(0.016):build(), - physics_gravity = evo.builder():single(vector2(0, 9.81)):build(), +local groups = { + awake = evo.spawn(), + physics = evo.spawn(), + graphics = evo.spawn(), + shutdown = evo.spawn(), } local fragments = { - force = evo.builder():build(), - position = evo.builder():build(), - velocity = evo.builder():build(), + force = evo.spawn(), + position = evo.spawn(), + velocity = evo.spawn(), } local queries = { physics_bodies = evo.builder() :include(fragments.force, fragments.position, fragments.velocity) - :build(), + :spawn(), } local awake_system = evo.builder() @@ -49,20 +49,18 @@ local awake_system = evo.builder() :set(fragments.force, vector2(0, 0)) :set(fragments.position, vector2(0, 0)) :set(fragments.velocity, vector2(0, 0)) - :build() - end):build() + :spawn() + end):spawn() local integrate_forces_system = evo.builder() :group(groups.physics) :query(queries.physics_bodies) :execute(function(chunk, entities, entity_count) - ---@type number, evolved.vector2 local delta_time, physics_gravity = - evo.get(singles.delta_time, singles.delta_time), - evo.get(singles.physics_gravity, singles.physics_gravity) + consts.delta_time, consts.physics_gravity ---@type evolved.vector2[], evolved.vector2[] - local forces, velocities = evo.components(chunk, + local forces, velocities = chunk:components( fragments.force, fragments.velocity) for i = 1, entity_count do @@ -71,18 +69,17 @@ local integrate_forces_system = evo.builder() velocity.x = velocity.x + (physics_gravity.x + force.x) * delta_time velocity.y = velocity.y + (physics_gravity.y + force.y) * delta_time end - end):build() + end):spawn() local integrate_velocities_system = evo.builder() :group(groups.physics) :query(queries.physics_bodies) :execute(function(chunk, entities, entity_count) - ---@type number local delta_time = - evo.get(singles.delta_time, singles.delta_time) + consts.delta_time ---@type evolved.vector2[], evolved.vector2[], evolved.vector2[] - local forces, positions, velocities = evo.components(chunk, + local forces, positions, velocities = chunk:components( fragments.force, fragments.position, fragments.velocity) for i = 1, entity_count do @@ -94,14 +91,14 @@ local integrate_velocities_system = evo.builder() force.x = 0 force.y = 0 end - end):build() + end):spawn() local graphics_system = evo.builder() :group(groups.graphics) :query(queries.physics_bodies) :execute(function(chunk, entities, entity_count) ---@type evolved.vector2[] - local positions = evo.components(chunk, + local positions = chunk:components( fragments.position) for i = 1, entity_count do @@ -111,14 +108,14 @@ local graphics_system = evo.builder() '|-> {entity %d} at {%.4f, %.4f}', entity, position.x, position.y)) end - end):build() + end):spawn() local shutdown_system = evo.builder() :group(groups.shutdown) :epilogue(function() print '-= | Shutdown | =-' evo.batch_destroy(queries.physics_bodies) - end):build() + end):spawn() do evo.process(groups.awake) diff --git a/develop/fuzzing/batch_destroy_fuzz.lua b/develop/fuzzing/batch_destroy_fuzz.lua index b8b4968..ce7d0ae 100644 --- a/develop/fuzzing/batch_destroy_fuzz.lua +++ b/develop/fuzzing/batch_destroy_fuzz.lua @@ -81,7 +81,7 @@ end do local r = math.random(1, 2) - local q = evo.builder():include(__table_unpack(destroying_include_list)):build() + local q = evo.builder():include(__table_unpack(destroying_include_list)):spawn() if r == 1 then evo.batch_destroy(q) @@ -98,17 +98,17 @@ end --- --- -local all_chunk_query = evo.builder():build() +local all_chunk_query = evo.spawn() for chunk in evo.execute(all_chunk_query) do - assert(not evo.has_any(chunk, __table_unpack(should_be_destroyed_entity_list))) - for _, fragment in ipairs(evo.fragments(chunk)) do + assert(not chunk:has_any(__table_unpack(should_be_destroyed_entity_list))) + for _, fragment in ipairs(chunk:fragments()) do assert(not evo.has_all(fragment, __table_unpack(destroying_include_list))) end end for _, destroyed_entity in ipairs(should_be_destroyed_entity_list) do - assert(not evo.is_alive(destroyed_entity)) + assert(not evo.alive(destroyed_entity)) end --- diff --git a/develop/fuzzing/destroy_fuzz.lua b/develop/fuzzing/destroy_fuzz.lua index e9b4707..adb07ba 100644 --- a/develop/fuzzing/destroy_fuzz.lua +++ b/develop/fuzzing/destroy_fuzz.lua @@ -102,19 +102,19 @@ end --- --- -local all_chunk_query = evo.builder():build() +local all_chunk_query = evo.spawn() for chunk in evo.execute(all_chunk_query) do - assert(not evo.has_any(chunk, __table_unpack(destroying_entity_list))) - assert(not evo.has_any(chunk, __table_unpack(should_be_destroyed_entity_list))) + assert(not chunk:has_any(__table_unpack(destroying_entity_list))) + assert(not chunk:has_any(__table_unpack(should_be_destroyed_entity_list))) end for _, destroying_entity in ipairs(destroying_entity_list) do - assert(not evo.is_alive(destroying_entity)) + assert(not evo.alive(destroying_entity)) end for _, destroyed_entity in ipairs(should_be_destroyed_entity_list) do - assert(not evo.is_alive(destroyed_entity)) + assert(not evo.alive(destroyed_entity)) end --- diff --git a/develop/fuzzing/explicit_fuzz.lua b/develop/fuzzing/explicit_fuzz.lua new file mode 100644 index 0000000..6aeb7c6 --- /dev/null +++ b/develop/fuzzing/explicit_fuzz.lua @@ -0,0 +1,81 @@ +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[] + +for i = 1, math.random(1, 10) do + local entity = evo.id() + all_entity_list[i] = entity +end + +for _, entity in ipairs(all_entity_list) do + for _ = 0, math.random(0, #all_entity_list) do + local fragment = all_entity_list[math.random(1, #all_entity_list)] + evo.set(entity, fragment) + end + + if math.random(1, 5) == 1 then + evo.set(entity, evo.EXPLICIT) + end +end + +--- +--- +--- +--- +--- + +for _ = 1, 100 do + local include_set = {} ---@type table + local include_list = {} ---@type evolved.entity[] + local include_count = 0 + + for _ = 1, math.random(1, #all_entity_list) do + local include = all_entity_list[math.random(1, #all_entity_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 q = evo.builder():include(__table_unpack(include_list)):spawn() + + for chunk in evo.execute(q) do + local fragment_list, fragment_count = chunk:fragments() + for i = 1, fragment_count do + local fragment = fragment_list[i] + assert(include_set[fragment] or not evo.has(fragment, evo.EXPLICIT)) + end + end + + evo.destroy(q) +end + +--- +--- +--- +--- +--- + +evo.destroy(__table_unpack(all_entity_list)) +evo.collect_garbage() diff --git a/develop/fuzzing/unique_fuzz.lua b/develop/fuzzing/unique_fuzz.lua new file mode 100644 index 0000000..731ba5e --- /dev/null +++ b/develop/fuzzing/unique_fuzz.lua @@ -0,0 +1,67 @@ +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[] + +for i = 1, math.random(1, 10) do + local entity = evo.id() + all_entity_list[i] = entity +end + +for _, entity in ipairs(all_entity_list) do + for _ = 0, math.random(0, #all_entity_list) do + local fragment = all_entity_list[math.random(1, #all_entity_list)] + evo.set(entity, fragment) + end + + if math.random(1, 5) == 1 then + evo.set(entity, evo.UNIQUE) + end +end + +--- +--- +--- +--- +--- + +for _, entity in ipairs(all_entity_list) do + local entity_clone = evo.clone(entity) + + for fragment in evo.each(entity_clone) do + assert(not evo.has(fragment, evo.UNIQUE)) + end + + for fragment in evo.each(entity) do + assert(evo.has(entity_clone, fragment) or evo.has(fragment, evo.UNIQUE)) + end + + evo.destroy(entity_clone) +end + +--- +--- +--- +--- +--- + +evo.destroy(__table_unpack(all_entity_list)) +evo.collect_garbage() diff --git a/develop/unbench.lua b/develop/unbench.lua index c59e47d..dad7af8 100644 --- a/develop/unbench.lua +++ b/develop/unbench.lua @@ -6,7 +6,7 @@ local evo = require 'evolved' local N = 1000 local B = evo.builder() local F1, F2, F3, F4, F5 = evo.id(5) -local Q1 = evo.builder():include(F1):build() +local Q1 = evo.builder():include(F1):spawn() print '----------------------------------------' @@ -440,11 +440,11 @@ basics.describe_bench(string.format('create and destroy %d entities with 1 compo ---@param entities evolved.id[] function(entities) local set = B.set - local build = B.build + local spawn = B.spawn for i = 1, N do set(B, F1) - entities[i] = build(B) + entities[i] = spawn(B) end evo.batch_destroy(Q1) @@ -456,12 +456,12 @@ basics.describe_bench(string.format('create and destroy %d entities with 2 compo ---@param entities evolved.id[] function(entities) local set = B.set - local build = B.build + local spawn = B.spawn for i = 1, N do set(B, F1) set(B, F2) - entities[i] = build(B) + entities[i] = spawn(B) end evo.batch_destroy(Q1) @@ -473,13 +473,13 @@ basics.describe_bench(string.format('create and destroy %d entities with 3 compo ---@param entities evolved.id[] function(entities) local set = B.set - local build = B.build + local spawn = B.spawn for i = 1, N do set(B, F1) set(B, F2) set(B, F3) - entities[i] = build(B) + entities[i] = spawn(B) end evo.batch_destroy(Q1) @@ -491,14 +491,14 @@ basics.describe_bench(string.format('create and destroy %d entities with 4 compo ---@param entities evolved.id[] function(entities) local set = B.set - local build = B.build + local spawn = B.spawn for i = 1, N do set(B, F1) set(B, F2) set(B, F3) set(B, F4) - entities[i] = build(B) + entities[i] = spawn(B) end evo.batch_destroy(Q1) @@ -510,7 +510,7 @@ basics.describe_bench(string.format('create and destroy %d entities with 5 compo ---@param entities evolved.id[] function(entities) local set = B.set - local build = B.build + local spawn = B.spawn for i = 1, N do set(B, F1) @@ -518,7 +518,7 @@ basics.describe_bench(string.format('create and destroy %d entities with 5 compo set(B, F3) set(B, F4) set(B, F5) - entities[i] = build(B) + entities[i] = spawn(B) end evo.batch_destroy(Q1) @@ -528,15 +528,15 @@ basics.describe_bench(string.format('create and destroy %d entities with 5 compo print '----------------------------------------' -basics.describe_bench(string.format('create and destroy %d entities with 1 components / multi-set', N), +basics.describe_bench(string.format('create and destroy %d entities with 1 components / spawn', N), ---@param entities evolved.id[] function(entities) - local set = evo.multi_set + local spawn = evo.spawn + + local components = { [F1] = true } for i = 1, N do - local e = evo.id() - set(e, { F1 }) - entities[i] = e + entities[i] = spawn(components) end evo.batch_destroy(Q1) @@ -544,15 +544,15 @@ basics.describe_bench(string.format('create and destroy %d entities with 1 compo return {} end) -basics.describe_bench(string.format('create and destroy %d entities with 2 components / multi-set', N), +basics.describe_bench(string.format('create and destroy %d entities with 2 components / spawn', N), ---@param entities evolved.id[] function(entities) - local set = evo.multi_set + local spawn = evo.spawn + + local components = { [F1] = true, [F2] = true } for i = 1, N do - local e = evo.id() - set(e, { F1, F2 }) - entities[i] = e + entities[i] = spawn(components) end evo.batch_destroy(Q1) @@ -560,15 +560,15 @@ basics.describe_bench(string.format('create and destroy %d entities with 2 compo return {} end) -basics.describe_bench(string.format('create and destroy %d entities with 3 components / multi-set', N), +basics.describe_bench(string.format('create and destroy %d entities with 3 components / spawn', N), ---@param entities evolved.id[] function(entities) - local set = evo.multi_set + local spawn = evo.spawn + + local components = { [F1] = true, [F2] = true, [F3] = true } for i = 1, N do - local e = evo.id() - set(e, { F1, F2, F3 }) - entities[i] = e + entities[i] = spawn(components) end evo.batch_destroy(Q1) @@ -576,15 +576,15 @@ basics.describe_bench(string.format('create and destroy %d entities with 3 compo return {} end) -basics.describe_bench(string.format('create and destroy %d entities with 4 components / multi-set', N), +basics.describe_bench(string.format('create and destroy %d entities with 4 components / spawn', N), ---@param entities evolved.id[] function(entities) - local set = evo.multi_set + local spawn = evo.spawn + + local components = { [F1] = true, [F2] = true, [F3] = true, [F4] = true } for i = 1, N do - local e = evo.id() - set(e, { F1, F2, F3, F4 }) - entities[i] = e + entities[i] = spawn(components) end evo.batch_destroy(Q1) @@ -592,15 +592,15 @@ basics.describe_bench(string.format('create and destroy %d entities with 4 compo return {} end) -basics.describe_bench(string.format('create and destroy %d entities with 5 components / multi-set', N), +basics.describe_bench(string.format('create and destroy %d entities with 5 components / spawn', N), ---@param entities evolved.id[] function(entities) - local set = evo.multi_set + local spawn = evo.spawn + + local components = { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true } for i = 1, N do - local e = evo.id() - set(e, { F1, F2, F3, F4, F5 }) - entities[i] = e + entities[i] = spawn(components) end evo.batch_destroy(Q1) @@ -610,18 +610,16 @@ basics.describe_bench(string.format('create and destroy %d entities with 5 compo print '----------------------------------------' -basics.describe_bench(string.format('create and destroy %d entities with 1 components / spawn_at', N), + +basics.describe_bench(string.format('create and destroy %d entities with 1 components / clone', N), ---@param entities evolved.id[] function(entities) - local spawn_at = evo.spawn_at + local clone = evo.clone - local fragments = { F1 } - local components = { true } - - local chunk = evo.chunk(F1) + local prefab = evo.spawn({ [F1] = true }) for i = 1, N do - entities[i] = spawn_at(chunk, fragments, components) + entities[i] = clone(prefab) end evo.batch_destroy(Q1) @@ -629,18 +627,15 @@ basics.describe_bench(string.format('create and destroy %d entities with 1 compo return {} end) -basics.describe_bench(string.format('create and destroy %d entities with 2 components / spawn_at', N), +basics.describe_bench(string.format('create and destroy %d entities with 2 components / clone', N), ---@param entities evolved.id[] function(entities) - local spawn_at = evo.spawn_at + local clone = evo.clone - local fragments = { F1, F2 } - local components = { true, true } - - local chunk = evo.chunk(F1, F2) + local prefab = evo.spawn({ [F1] = true, [F2] = true }) for i = 1, N do - entities[i] = spawn_at(chunk, fragments, components) + entities[i] = clone(prefab) end evo.batch_destroy(Q1) @@ -648,18 +643,15 @@ basics.describe_bench(string.format('create and destroy %d entities with 2 compo return {} end) -basics.describe_bench(string.format('create and destroy %d entities with 3 components / spawn_at', N), +basics.describe_bench(string.format('create and destroy %d entities with 3 components / clone', N), ---@param entities evolved.id[] function(entities) - local spawn_at = evo.spawn_at + local clone = evo.clone - local fragments = { F1, F2, F3 } - local components = { true, true, true } - - local chunk = evo.chunk(F1, F2, F3) + local prefab = evo.spawn({ [F1] = true, [F2] = true, [F3] = true }) for i = 1, N do - entities[i] = spawn_at(chunk, fragments, components) + entities[i] = clone(prefab) end evo.batch_destroy(Q1) @@ -667,18 +659,15 @@ basics.describe_bench(string.format('create and destroy %d entities with 3 compo return {} end) -basics.describe_bench(string.format('create and destroy %d entities with 4 components / spawn_at', N), +basics.describe_bench(string.format('create and destroy %d entities with 4 components / clone', N), ---@param entities evolved.id[] function(entities) - local spawn_at = evo.spawn_at + local clone = evo.clone - local fragments = { F1, F2, F3, F4 } - local components = { true, true, true, true } - - local chunk = evo.chunk(F1, F2, F3, F4) + local prefab = evo.spawn({ [F1] = true, [F2] = true, [F3] = true, [F4] = true }) for i = 1, N do - entities[i] = spawn_at(chunk, fragments, components) + entities[i] = clone(prefab) end evo.batch_destroy(Q1) @@ -686,207 +675,18 @@ basics.describe_bench(string.format('create and destroy %d entities with 4 compo return {} end) -basics.describe_bench(string.format('create and destroy %d entities with 5 components / spawn_at', N), +basics.describe_bench(string.format('create and destroy %d entities with 5 components / clone', N), ---@param entities evolved.id[] function(entities) - local spawn_at = evo.spawn_at + local clone = evo.clone - local fragments = { F1, F2, F3, F4, F5 } - local components = { true, true, true, true, true } - - local chunk = evo.chunk(F1, F2, F3, F4, F5) + local prefab = evo.spawn({ [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true }) for i = 1, N do - entities[i] = spawn_at(chunk, fragments, components) + entities[i] = clone(prefab) end evo.batch_destroy(Q1) end, function() return {} end) - -print '----------------------------------------' - -basics.describe_bench(string.format('create and destroy %d entities with 1 components / spawn_as', N), - ---@param entities evolved.id[] - function(entities) - local spawn_as = evo.spawn_as - - local fragments = { F1 } - local components = { true } - - local prefab = evo.spawn_with(fragments, components) - - for i = 1, N do - entities[i] = spawn_as(prefab, fragments, components) - end - - evo.batch_destroy(Q1) - end, function() - return {} - end) - -basics.describe_bench(string.format('create and destroy %d entities with 2 components / spawn_as', N), - ---@param entities evolved.id[] - function(entities) - local spawn_as = evo.spawn_as - - local fragments = { F1, F2 } - local components = { true, true } - - local prefab = evo.spawn_with(fragments, components) - - for i = 1, N do - entities[i] = spawn_as(prefab, fragments, components) - end - - evo.batch_destroy(Q1) - end, function() - return {} - end) - -basics.describe_bench(string.format('create and destroy %d entities with 3 components / spawn_as', N), - ---@param entities evolved.id[] - function(entities) - local spawn_as = evo.spawn_as - - local fragments = { F1, F2, F3 } - local components = { true, true, true } - - local prefab = evo.spawn_with(fragments, components) - - for i = 1, N do - entities[i] = spawn_as(prefab, fragments, components) - end - - evo.batch_destroy(Q1) - end, function() - return {} - end) - -basics.describe_bench(string.format('create and destroy %d entities with 4 components / spawn_as', N), - ---@param entities evolved.id[] - function(entities) - local spawn_as = evo.spawn_as - - local fragments = { F1, F2, F3, F4 } - local components = { true, true, true, true } - - local prefab = evo.spawn_with(fragments, components) - - for i = 1, N do - entities[i] = spawn_as(prefab, fragments, components) - end - - evo.batch_destroy(Q1) - end, function() - return {} - end) - -basics.describe_bench(string.format('create and destroy %d entities with 5 components / spawn_as', N), - ---@param entities evolved.id[] - function(entities) - local spawn_as = evo.spawn_as - - local fragments = { F1, F2, F3, F4, F5 } - local components = { true, true, true, true, true } - - local prefab = evo.spawn_with(fragments, components) - - for i = 1, N do - entities[i] = spawn_as(prefab, fragments, components) - end - - evo.batch_destroy(Q1) - end, function() - return {} - end) - -print '----------------------------------------' - -basics.describe_bench(string.format('create and destroy %d entities with 1 components / spawn_with', N), - ---@param entities evolved.id[] - function(entities) - local spawn_with = evo.spawn_with - - local fragments = { F1 } - local components = { true } - - for i = 1, N do - entities[i] = spawn_with(fragments, components) - end - - evo.batch_destroy(Q1) - end, function() - return {} - end) - -basics.describe_bench(string.format('create and destroy %d entities with 2 components / spawn_with', N), - ---@param entities evolved.id[] - function(entities) - local spawn_with = evo.spawn_with - - local fragments = { F1, F2 } - local components = { true, true } - - for i = 1, N do - entities[i] = spawn_with(fragments, components) - end - - evo.batch_destroy(Q1) - end, function() - return {} - end) - -basics.describe_bench(string.format('create and destroy %d entities with 3 components / spawn_with', N), - ---@param entities evolved.id[] - function(entities) - local spawn_with = evo.spawn_with - - local fragments = { F1, F2, F3 } - local components = { true, true, true } - - for i = 1, N do - entities[i] = spawn_with(fragments, components) - end - - evo.batch_destroy(Q1) - end, function() - return {} - end) - -basics.describe_bench(string.format('create and destroy %d entities with 4 components / spawn_with', N), - ---@param entities evolved.id[] - function(entities) - local spawn_with = evo.spawn_with - - local fragments = { F1, F2, F3, F4 } - local components = { true, true, true, true } - - for i = 1, N do - entities[i] = spawn_with(fragments, components) - end - - evo.batch_destroy(Q1) - end, function() - return {} - end) - -basics.describe_bench(string.format('create and destroy %d entities with 5 components / spawn_with', N), - ---@param entities evolved.id[] - function(entities) - local spawn_with = evo.spawn_with - - local fragments = { F1, F2, F3, F4, F5 } - local components = { true, true, true, true, true } - - for i = 1, N do - entities[i] = spawn_with(fragments, components) - end - - evo.batch_destroy(Q1) - end, function() - return {} - end) - -print '----------------------------------------' diff --git a/develop/untests.lua b/develop/untests.lua index 6c69830..06c1c1f 100644 --- a/develop/untests.lua +++ b/develop/untests.lua @@ -5,7 +5,7 @@ local evo = require 'evolved' evo.debug_mode(true) -do +if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == nil then local i = evo.id() for _ = 1, 0xFFFFE do @@ -34,25 +34,25 @@ do local e1, e2 = evo.id(), evo.id() assert(e1 ~= e2) - assert(evo.is_alive(e1)) - assert(evo.is_alive(e2)) + assert(evo.alive(e1)) + assert(evo.alive(e2)) evo.destroy(e1) - assert(not evo.is_alive(e1)) - assert(evo.is_alive(e2)) + assert(not evo.alive(e1)) + assert(evo.alive(e2)) evo.destroy(e1) evo.destroy(e2) - assert(not evo.is_alive(e1)) - assert(not evo.is_alive(e2)) + assert(not evo.alive(e1)) + assert(not evo.alive(e2)) evo.destroy(e1) evo.destroy(e2) - assert(not evo.is_alive(e1)) - assert(not evo.is_alive(e2)) + assert(not evo.alive(e1)) + assert(not evo.alive(e2)) end do @@ -542,11 +542,11 @@ do evo.set(e, f, 42) assert(evo.has(e, f)) - assert(evo.is_alive(e)) + assert(evo.alive(e)) evo.destroy(e) assert(not evo.has(e, f)) - assert(not evo.is_alive(e)) + assert(not evo.alive(e)) end do @@ -554,24 +554,24 @@ do do local e = evo.id() - assert(evo.is_empty(e)) + assert(evo.empty(e)) evo.set(e, f, 42) - assert(not evo.is_empty(e)) + assert(not evo.empty(e)) evo.clear(e) - assert(evo.is_empty(e)) + assert(evo.empty(e)) end do local e = evo.id() - assert(evo.is_empty(e)) + assert(evo.empty(e)) evo.set(e, f, 42) - assert(not evo.is_empty(e)) + assert(not evo.empty(e)) evo.destroy(e) - assert(evo.is_empty(e)) + assert(evo.empty(e)) end end @@ -594,7 +594,7 @@ do do local chunk, entities = evo.chunk(f1) assert(entities and entities[1] == e1) - assert(chunk and evo.components(chunk, f1)[1] == 41) + assert(chunk and chunk:components(f1)[1] == 41) end do @@ -606,8 +606,8 @@ do assert(chunk == evo.chunk(f2, f1)) assert(chunk == evo.chunk(f2, f1, f2, f1)) assert(entities and entities[1] == e2 and entities[2] == e2b) - assert(chunk and evo.components(chunk, f1)[1] == 42 and evo.components(chunk, f2)[1] == 43) - assert(chunk and evo.components(chunk, f1)[2] == 44 and evo.components(chunk, f2)[2] == 45) + 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 @@ -674,7 +674,7 @@ do assert(evo.get(e3, f2) == nil) assert(evo.get(e3, f3) == nil) - assert(not evo.is_alive(e4)) + assert(not evo.alive(e4)) end do @@ -939,17 +939,17 @@ do evo.batch_clear(q) - assert(evo.is_alive(e1)) - assert(evo.is_alive(e2)) - assert(evo.is_alive(e3)) - assert(evo.is_alive(e4)) - assert(evo.is_alive(e5)) + assert(evo.alive(e1)) + assert(evo.alive(e2)) + assert(evo.alive(e3)) + assert(evo.alive(e4)) + assert(evo.alive(e5)) - assert(not evo.is_empty(e1)) - assert(evo.is_empty(e2)) - assert(evo.is_empty(e3)) - assert(evo.is_empty(e4)) - assert(not evo.is_empty(e5)) + assert(not evo.empty(e1)) + assert(evo.empty(e2)) + assert(evo.empty(e3)) + assert(evo.empty(e4)) + assert(not evo.empty(e5)) end do local f1, f2, f3, f4 = evo.id(4) @@ -1011,17 +1011,17 @@ do assert(entity_sum == e2 * 2 + e3 * 3 + e4 * 4) assert(component_sum == 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50) - assert(evo.is_alive(e1)) - assert(evo.is_alive(e2)) - assert(evo.is_alive(e3)) - assert(evo.is_alive(e4)) - assert(evo.is_alive(e5)) + assert(evo.alive(e1)) + assert(evo.alive(e2)) + assert(evo.alive(e3)) + assert(evo.alive(e4)) + assert(evo.alive(e5)) - assert(not evo.is_empty(e1)) - assert(evo.is_empty(e2)) - assert(evo.is_empty(e3)) - assert(evo.is_empty(e4)) - assert(not evo.is_empty(e5)) + assert(not evo.empty(e1)) + assert(evo.empty(e2)) + assert(evo.empty(e3)) + assert(evo.empty(e4)) + assert(not evo.empty(e5)) end end @@ -1057,17 +1057,17 @@ do evo.batch_destroy(q) - assert(evo.is_alive(e1)) - assert(not evo.is_alive(e2)) - assert(not evo.is_alive(e3)) - assert(not evo.is_alive(e4)) - assert(evo.is_alive(e5)) + assert(evo.alive(e1)) + assert(not evo.alive(e2)) + assert(not evo.alive(e3)) + assert(not evo.alive(e4)) + assert(evo.alive(e5)) - assert(not evo.is_empty(e1)) - assert(evo.is_empty(e2)) - assert(evo.is_empty(e3)) - assert(evo.is_empty(e4)) - assert(not evo.is_empty(e5)) + assert(not evo.empty(e1)) + assert(evo.empty(e2)) + assert(evo.empty(e3)) + assert(evo.empty(e4)) + assert(not evo.empty(e5)) end do local f1, f2, f3, f4 = evo.id(4) @@ -1129,17 +1129,17 @@ do assert(entity_sum == e2 * 2 + e3 * 3 + e4 * 4) assert(component_sum == 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50) - assert(evo.is_alive(e1)) - assert(not evo.is_alive(e2)) - assert(not evo.is_alive(e3)) - assert(not evo.is_alive(e4)) - assert(evo.is_alive(e5)) + assert(evo.alive(e1)) + assert(not evo.alive(e2)) + assert(not evo.alive(e3)) + assert(not evo.alive(e4)) + assert(evo.alive(e5)) - assert(not evo.is_empty(e1)) - assert(evo.is_empty(e2)) - assert(evo.is_empty(e3)) - assert(evo.is_empty(e4)) - assert(not evo.is_empty(e5)) + assert(not evo.empty(e1)) + assert(evo.empty(e2)) + assert(evo.empty(e3)) + assert(evo.empty(e4)) + assert(not evo.empty(e5)) end end @@ -1263,13 +1263,13 @@ do local f1, f2 = evo.id(2) evo.set(f2, evo.DEFAULT, 42) - local e1 = evo.builder():set(f1, 11):build() - local e2 = evo.builder():set(f1, 21):set(f2, 22):build() + local e1 = evo.builder():set(f1, 11):spawn() + local e2 = evo.builder():set(f1, 21):set(f2, 22):spawn() assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == nil) assert(evo.get(e2, f1) == 21 and evo.get(e2, f2) == 22) - local q = evo.builder():include(f1):exclude(f2):build() + local q = evo.builder():include(f1):exclude(f2):spawn() evo.batch_set(q, f2) assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == 42) @@ -1695,7 +1695,7 @@ do last_remove_entity = 0 evo.clear(e) - assert(evo.is_alive(e)) + assert(evo.alive(e)) assert(last_remove_entity == e) assert(not evo.has(e, f1)) assert(evo.get(e, f1) == nil) @@ -1708,7 +1708,7 @@ do last_remove_entity = 0 evo.clear(e) - assert(evo.is_alive(e)) + assert(evo.alive(e)) assert(last_remove_entity == e) assert(not evo.has(e, f1) and not evo.has(e, f2)) assert(evo.get(e, f1) == nil and evo.get(e, f2) == nil) @@ -1722,7 +1722,7 @@ do last_remove_entity = 0 evo.clear(e) - assert(evo.is_alive(e)) + assert(evo.alive(e)) assert(last_remove_entity == e) assert(not evo.has(e, f1) and not evo.has(e, f2) and not evo.has(e, f3)) assert(evo.get(e, f1) == nil and evo.get(e, f2) == nil and evo.get(e, f3) == nil) @@ -1736,7 +1736,7 @@ do last_remove_entity = 0 evo.destroy(e) - assert(not evo.is_alive(e)) + assert(not evo.alive(e)) assert(last_remove_entity == e) assert(not evo.has(e, f1)) assert(evo.get(e, f1) == nil) @@ -1749,7 +1749,7 @@ do last_remove_entity = 0 evo.destroy(e) - assert(not evo.is_alive(e)) + assert(not evo.alive(e)) assert(last_remove_entity == e) assert(not evo.has(e, f1) and not evo.has(e, f2)) assert(evo.get(e, f1) == nil and evo.get(e, f2) == nil) @@ -1763,7 +1763,7 @@ do last_remove_entity = 0 evo.destroy(e) - assert(not evo.is_alive(e)) + assert(not evo.alive(e)) assert(last_remove_entity == e) assert(not evo.has(e, f1) and not evo.has(e, f2) and not evo.has(e, f3)) assert(evo.get(e, f1) == nil and evo.get(e, f2) == nil and evo.get(e, f3) == nil) @@ -1863,9 +1863,9 @@ do assert(chunk_entities[1] == e3 and chunk_entities[2] == e1) - assert(#evo.components(chunk, f1) == 0) - assert(#evo.components(chunk, f2) == 0) - assert(evo.components(chunk, f3)[1] == 43 and evo.components(chunk, f3)[2] == 50) + assert(#chunk:components(f1) == 0) + assert(#chunk:components(f2) == 0) + assert(chunk:components(f3)[1] == 43 and chunk:components(f3)[2] == 50) end end end @@ -1904,9 +1904,9 @@ do assert(chunk and chunk_entities) assert(chunk_entities[1] == e1) - assert(#evo.components(chunk, f1) == 0) - assert(#evo.components(chunk, f2) == 0) - assert(#evo.components(chunk, f3) == 0) + assert(#chunk:components(f1) == 0) + assert(#chunk:components(f2) == 0) + assert(#chunk:components(f3) == 0) end do @@ -1914,9 +1914,9 @@ do assert(chunk and chunk_entities) assert(chunk_entities[1] == e3) - assert(#evo.components(chunk, f1) == 0) - assert(#evo.components(chunk, f2) == 0) - assert(evo.components(chunk, f3)[1] == 43) + assert(#chunk:components(f1) == 0) + assert(#chunk:components(f2) == 0) + assert(chunk:components(f3)[1] == 43) end end end @@ -1946,9 +1946,9 @@ do evo.batch_clear(q) - assert(evo.is_alive(e1)) - assert(evo.is_alive(e2)) - assert(evo.is_alive(e3)) + assert(evo.alive(e1)) + assert(evo.alive(e2)) + assert(evo.alive(e3)) assert(not evo.has(e1, f1) and not evo.has(e1, f2) and not evo.has(e1, f3)) assert(evo.has(e2, f1) and not evo.has(e2, f2) and not evo.has(e2, f3)) @@ -1959,9 +1959,9 @@ do assert(chunk and chunk_entities) assert(next(chunk_entities) == nil) - assert(#evo.components(chunk, f1) == 0) - assert(#evo.components(chunk, f2) == 0) - assert(#evo.components(chunk, f3) == 0) + assert(#chunk:components(f1) == 0) + assert(#chunk:components(f2) == 0) + assert(#chunk:components(f3) == 0) end end end @@ -1991,9 +1991,9 @@ do evo.batch_destroy(q) - assert(not evo.is_alive(e1)) - assert(evo.is_alive(e2)) - assert(not evo.is_alive(e3)) + assert(not evo.alive(e1)) + assert(evo.alive(e2)) + assert(not evo.alive(e3)) assert(not evo.has(e1, f1) and not evo.has(e1, f2) and not evo.has(e1, f3)) assert(evo.has(e2, f1) and not evo.has(e2, f2) and not evo.has(e2, f3)) @@ -2004,9 +2004,9 @@ do assert(chunk and chunk_entities) assert(next(chunk_entities) == nil) - assert(#evo.components(chunk, f1) == 0) - assert(#evo.components(chunk, f2) == 0) - assert(#evo.components(chunk, f3) == 0) + assert(#chunk:components(f1) == 0) + assert(#chunk:components(f2) == 0) + assert(#chunk:components(f3) == 0) end end end @@ -2144,11 +2144,11 @@ do assert(evo.defer()) assert(not evo.batch_clear(q)) - assert(evo.is_alive(e1)) + assert(evo.alive(e1)) assert(evo.get(e1, f1) == 41) assert(evo.commit()) - assert(evo.is_alive(e1)) + assert(evo.alive(e1)) assert(evo.get(e1, f1) == nil) end end @@ -2166,11 +2166,11 @@ do assert(evo.defer()) assert(not evo.batch_destroy(q)) - assert(evo.is_alive(e1)) + assert(evo.alive(e1)) assert(evo.get(e1, f1) == 41) assert(evo.commit()) - assert(not evo.is_alive(e1)) + assert(not evo.alive(e1)) assert(evo.get(e1, f1) == nil) end end @@ -2403,7 +2403,7 @@ do local e = evo.builder() :set(f1, 41) :set(f2, 42) - :build() + :spawn() assert(evo.has(e, f1) and evo.get(e, f1) == 41) assert(evo.has(e, f2) and evo.get(e, f2) == 42) end @@ -2412,28 +2412,28 @@ do local e = evo.builder() :set(f1, 11) :set(f1, 41) - :build() + :spawn() assert(evo.has(e, f1) and evo.get(e, f1) == 41) end end do - local f1 = evo.builder():default(41):build() - local f2 = evo.builder():default(42):build() - local f3 = evo.builder():tag():build() + local f1 = evo.builder():default(41):spawn() + local f2 = evo.builder():default(42):spawn() + local f3 = evo.builder():tag():spawn() - local e0 = evo.builder():build() + local e0 = evo.builder():spawn() assert(not evo.has_any(e0, f1, f2, f3)) - local e1 = evo.builder():set(f1):build() + local e1 = evo.builder():set(f1):spawn() assert(evo.has(e1, f1)) assert(evo.get(e1, f1) == 41) - local e2 = evo.builder():set(f1):set(f2):build() + local e2 = evo.builder():set(f1):set(f2):spawn() assert(evo.has(e2, f1) and evo.has(e2, f2)) assert(evo.get(e2, f1) == 41 and evo.get(e2, f2) == 42) - local e3 = evo.builder():set(f1):set(f2):set(f3):build() + local e3 = evo.builder():set(f1):set(f2):set(f3):spawn() assert(evo.has(e3, f1) and evo.has(e3, f2) and evo.has(e3, f3)) assert(evo.get(e3, f1) == 41 and evo.get(e3, f2) == 42 and evo.get(e3, f3) == nil) @@ -2450,9 +2450,9 @@ do return entities end - local q1 = evo.builder():include(f1):build() - local q2 = evo.builder():include(f1, f2):build() - local q3 = evo.builder():include(f1):include(f2):exclude(f3):build() + local q1 = evo.builder():include(f1):spawn() + local q2 = evo.builder():include(f1, f2):spawn() + local q3 = evo.builder():include(f1):include(f2):exclude(f3):spawn() do local entities = collect_entities(q1) @@ -2484,27 +2484,27 @@ do local FB = evo.builder() - local f1 = FB + local f1 = FB:clear() :on_assign(function(e, f, nc, oc) f1_assign_count = f1_assign_count + 1 - assert(evo.is_alive(e)) - assert(evo.is_alive(f)) + assert(evo.alive(e)) + assert(evo.alive(f)) assert(nc == 42) assert(oc == 41) end) :on_insert(function(e, f, nc) f1_insert_count = f1_insert_count + 1 - assert(evo.is_alive(e)) - assert(evo.is_alive(f)) + assert(evo.alive(e)) + assert(evo.alive(f)) assert(nc == 41) end) - :build() + :spawn() - local f2 = FB + local f2 = FB:clear() :on_set(function(e, f, nc, oc) f2_set_count = f2_set_count + 1 - assert(evo.is_alive(e)) - assert(evo.is_alive(f)) + assert(evo.alive(e)) + assert(evo.alive(f)) if oc then assert(oc == 81) assert(nc == 82) @@ -2515,15 +2515,15 @@ do :on_remove(function(e, f, c) f2_remove_count = f2_remove_count + 1 assert(evo.get(e, f) == nil) - assert(evo.is_alive(f)) + assert(evo.alive(f)) assert(c == 82) end) - :build() + :spawn() - local e1 = evo.builder():set(f1, 41):build() + local e1 = evo.builder():set(f1, 41):spawn() assert(f1_assign_count == 0 and f1_insert_count == 1) - local e2 = evo.builder():set(f1, 42):set(f1, 41):build() + local e2 = evo.builder():set(f1, 42):set(f1, 41):spawn() assert(f1_assign_count == 0 and f1_insert_count == 2) evo.set(e1, f1, 42) @@ -2555,516 +2555,12 @@ do assert(f2_remove_count == 2) end -do - local f1, f2, f3 = evo.id(3) - - do - local e = evo.id() - evo.multi_set(e, {}) - evo.multi_set(e, {}, {}) - evo.multi_set(e, {}, { 41 }) - assert(evo.is_alive(e) and evo.is_empty(e)) - - evo.multi_set(e, { f1 }) - assert(evo.has(e, f1) and evo.get(e, f1) == true) - - evo.multi_set(e, { f2 }, { 42, 43 }) - assert(evo.has(e, f1) and evo.get(e, f1) == true) - assert(evo.has(e, f2) and evo.get(e, f2) == 42) - end - - do - local e = evo.id() - evo.multi_set(e, { f1, f2 }, { 41 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 41) - assert(evo.has(e, f2) and evo.get(e, f2) == true) - - evo.multi_set(e, { f1, f3 }, { 20, 43 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 20) - assert(evo.has(e, f2) and evo.get(e, f2) == true) - assert(evo.has(e, f3) and evo.get(e, f3) == 43) - end -end - -do - local f1, f2, f3 = evo.id(3) - - do - local e1 = evo.id() - evo.multi_set(e1, { f1, f2 }, { 41, 42 }) - assert(evo.has(e1, f1) and evo.get(e1, f1) == 41) - assert(evo.has(e1, f2) and evo.get(e1, f2) == 42) - - local e2 = evo.id() - evo.multi_set(e2, { f1, f2 }, { 43, 44 }) - assert(evo.has(e2, f1) and evo.get(e2, f1) == 43) - assert(evo.has(e2, f2) and evo.get(e2, f2) == 44) - - evo.multi_set(e1, { f3 }) - do - local chunk, entities = evo.chunk(f1, f2) - assert(entities and #entities == 1 and entities[1] == e2) - assert(chunk and evo.components(chunk, f2)[1] == 44) - end - end - - do - local e1, e2 = evo.id(2) - evo.defer() - do - evo.multi_set(e1, { f1, f2 }, { 41, 42 }) - evo.multi_set(e2, { f2, f2 }, { 43, 44 }) - end - assert(evo.is_alive(e1) and evo.is_empty(e1)) - assert(evo.is_alive(e2) and evo.is_empty(e2)) - assert(evo.commit()) - assert(evo.has(e1, f1) and evo.get(e1, f1) == 41) - assert(evo.has(e1, f2) and evo.get(e1, f2) == 42) - assert(evo.has(e2, f2) and evo.get(e2, f2) == 44) - end -end - -do - local f1, f2, f3 = evo.id(3) - - evo.set(f3, evo.TAG) - - local last_set_entity = 0 - local last_set_component = 0 - - evo.set(f1, evo.ON_SET, function(e, f, c) - assert(f == f1) - last_set_entity = e - last_set_component = c - end) - - evo.set(f2, evo.ON_SET, function(e, f, c) - assert(f == f2) - last_set_entity = e - last_set_component = c - end) - - evo.set(f3, evo.ON_SET, function(e, f, c) - assert(f == f3) - last_set_entity = e - last_set_component = c - end) - - do - local e = evo.id() - evo.multi_set(e, { f1, f2 }, { 41, 42 }) - assert(last_set_entity == e and last_set_component == 42) - end - - do - local e = evo.id() - evo.multi_set(e, { f1, f2, f3 }, { 41, 42, 43 }) - assert(last_set_entity == e and last_set_component == nil) - end -end - -do - local f1, f2 = evo.id(2) - - do - local e = evo.id() - evo.multi_set(e, {}) - evo.multi_set(e, {}, {}) - evo.multi_set(e, {}, { 41 }) - assert(evo.is_alive(e) and evo.is_empty(e)) - - evo.multi_set(e, { f1 }, { 21 }) - evo.multi_set(e, { f1 }, { 41 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 41) - assert(not evo.has(e, f2) and evo.get(e, f2) == nil) - - evo.multi_set(e, { f2 }, { 22 }) - evo.multi_set(e, { f2 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 41) - assert(evo.has(e, f2) and evo.get(e, f2) == true) - evo.multi_set(e, { f2 }, { 42, 43 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 41) - assert(evo.has(e, f2) and evo.get(e, f2) == 42) - end - - do - local e1, e2 = evo.id(2) - evo.defer() - do - evo.multi_set(e1, { f1, f2 }, { 21, 22 }) - evo.multi_set(e1, { f1, f2 }, { 41, 42 }) - - evo.multi_set(e2, { f1, f2 }, { 31, 32 }) - evo.multi_set(e2, { f1, f2 }, { 51, 52 }) - end - assert(evo.is_alive(e1) and evo.is_empty(e1)) - assert(evo.is_alive(e2) and evo.is_empty(e2)) - assert(evo.commit()) - assert(evo.has(e1, f1) and evo.get(e1, f1) == 41) - assert(evo.has(e1, f2) and evo.get(e1, f2) == 42) - assert(evo.has(e2, f1) and evo.get(e2, f1) == 51) - assert(evo.has(e2, f2) and evo.get(e2, f2) == 52) - end -end - -do - local f1, f2, f3 = evo.id(3) - - evo.set(f3, evo.TAG) - - local last_set_entity = 0 - local last_set_component = 0 - - evo.set(f1, evo.ON_SET, function(e, f, c) - assert(f == f1) - last_set_entity = e - last_set_component = c - end) - - evo.set(f2, evo.ON_SET, function(e, f, c) - assert(f == f2) - last_set_entity = e - last_set_component = c - end) - - evo.set(f3, evo.ON_SET, function(e, f, c) - assert(f == f3) - last_set_entity = e - last_set_component = c - end) - - do - local e = evo.id() - evo.multi_set(e, { f1, f2 }, { 21, 22 }) - assert(last_set_entity == e and last_set_component == 22) - - evo.multi_set(e, { f1, f2 }, { 41, 42 }) - assert(last_set_entity == e and last_set_component == 42) - end - - do - local e = evo.id() - evo.multi_set(e, { f1, f2, f3 }, { 21, 22, 23 }) - assert(last_set_entity == e and last_set_component == nil) - - last_set_entity, last_set_component = 0, 0 - evo.multi_set(e, { f1, f2, f3 }, { 41, 42, 43 }) - assert(last_set_entity == e and last_set_component == nil) - assert(evo.has(e, f1) and evo.get(e, f1) == 41) - assert(evo.has(e, f2) and evo.get(e, f2) == 42) - assert(evo.has(e, f3) and evo.get(e, f3) == nil) - end -end - -do - local f1, f2, f3, f4 = evo.id(4) - - evo.set(f3, evo.TAG) - - do - local e = evo.id() - evo.multi_set(e, { f1, f2, f3 }, { 41, 42, 43 }) - assert(evo.has_all(e, f1, f2, f3)) - - evo.multi_remove(e, {}) - evo.multi_remove(e, { f4 }) - assert(evo.has_all(e, f1, f2, f3)) - - evo.multi_remove(e, { f3 }) - assert(evo.has(e, f1) and evo.has(e, f2) and not evo.has(e, f3)) - assert(evo.get(e, f1) == 41 and evo.get(e, f2) == 42 and evo.get(e, f3) == nil) - - evo.multi_remove(e, { f1, f2, f4 }) - assert(not evo.has_any(e, f1, f2, f3)) - assert(evo.get(e, f1) == nil and evo.get(e, f2) == nil and evo.get(e, f3) == nil) - end - - do - local e = evo.id() - evo.multi_set(e, { f1, f2, f3 }, { 41, 42, 43 }) - assert(evo.has_all(e, f1, f2, f3)) - evo.defer() - evo.multi_remove(e, { f1, f2 }) - assert(evo.has_all(e, f1, f2, f3)) - assert(evo.commit()) - assert(not evo.has(e, f1) and not evo.has(e, f2) and evo.has(e, f3)) - end -end - -do - local f1, f2, f3 = evo.id(3) - - evo.set(f3, evo.TAG) - - local last_remove_entity = 0 - local last_remove_component = 0 - - evo.set(f1, evo.ON_REMOVE, function(e, f, c) - assert(f == f1) - last_remove_entity = e - last_remove_component = c - end) - - evo.set(f2, evo.ON_REMOVE, function(e, f, c) - assert(f == f2) - last_remove_entity = e - last_remove_component = c - end) - - evo.set(f3, evo.ON_REMOVE, function(e, f, c) - assert(f == f3) - last_remove_entity = e - last_remove_component = c - end) - - do - local e = evo.id() - evo.multi_remove(e, { f1, f2 }) - assert(last_remove_entity == 0 and last_remove_component == 0) - - evo.multi_set(e, { f1, f2, f3 }, { 41, 42 }) - assert(last_remove_entity == 0 and last_remove_component == 0) - evo.multi_remove(e, { f1, f2 }) - assert(last_remove_entity == e and last_remove_component == 42) - evo.multi_remove(e, { f3 }) - assert(last_remove_entity == e and last_remove_component == nil) - end -end - -do - local f1, f2, f3 = evo.id(3) - - do - local e1, e2 = evo.id(2) - evo.multi_set(e1, { f1, f2, f3 }, { 41, 42, 43 }) - evo.multi_set(e2, { f1, f2, f3 }, { 44, 45, 46 }) - - evo.multi_remove(e1, { f1, f2 }) - - do - local chunk, entities = evo.chunk(f1, f2, f3) - assert(entities and #entities == 1 and entities[1] == e2) - assert(chunk and evo.components(chunk, f2)[1] == 45) - end - - do - local chunk, entities = evo.chunk(f3) - assert(entities and #entities == 1 and entities[1] == e1) - assert(chunk and evo.components(chunk, f3)[1] == 43) - end - end -end - -do - local f1, f2, f3, f4 = evo.id(4) - - evo.set(f3, evo.DEFAULT, 43) - evo.set(f4, evo.TAG) - - - do - local e = evo.id() - evo.multi_set(e, {}) - evo.multi_set(e, {}, {}) - evo.multi_set(e, {}, { 41 }) - assert(evo.is_alive(e) and evo.is_empty(e)) - - evo.multi_set(e, { f1 }) - assert(evo.has(e, f1) and evo.get(e, f1) == true) - - evo.multi_set(e, { f1 }) - assert(evo.has(e, f1) and evo.get(e, f1) == true) - - evo.multi_set(e, { f1 }, { 41 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 41) - - evo.multi_set(e, { f2 }, { 42 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 41) - assert(evo.has(e, f2) and evo.get(e, f2) == 42) - - evo.multi_set(e, { f2 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 41) - assert(evo.has(e, f2) and evo.get(e, f2) == true) - - evo.multi_set(e, { f2, f3 }, { 42 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 41) - assert(evo.has(e, f2) and evo.get(e, f2) == 42) - assert(evo.has(e, f3) and evo.get(e, f3) == 43) - - evo.multi_set(e, { f3, f4 }, { 33, 44 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 41) - assert(evo.has(e, f2) and evo.get(e, f2) == 42) - assert(evo.has(e, f3) and evo.get(e, f3) == 33) - assert(evo.has(e, f4) and evo.get(e, f4) == nil) - end -end - -do - local f1, f2, f3 = evo.id(3) - - evo.set(f2, evo.DEFAULT, 42) - evo.set(f3, evo.TAG) - - local last_assign_entity = 0 - local last_assign_new_component = 0 - local last_assign_old_component = 0 - - evo.set(f1, evo.ON_ASSIGN, function(e, f, nc, oc) - assert(f == f1) - last_assign_entity = e - last_assign_new_component = nc - last_assign_old_component = oc - end) - - evo.set(f2, evo.ON_ASSIGN, function(e, f, nc, oc) - assert(f == f2) - last_assign_entity = e - last_assign_new_component = nc - last_assign_old_component = oc - end) - - evo.set(f3, evo.ON_ASSIGN, function(e, f, nc, oc) - assert(f == f3) - last_assign_entity = e - last_assign_new_component = nc - last_assign_old_component = oc - end) - - local last_insert_entity = 0 - local last_insert_component = 0 - - evo.set(f1, evo.ON_INSERT, function(e, f, nc) - assert(f == f1) - last_insert_entity = e - last_insert_component = nc - end) - - evo.set(f2, evo.ON_INSERT, function(e, f, nc) - assert(f == f2) - last_insert_entity = e - last_insert_component = nc - end) - - evo.set(f3, evo.ON_INSERT, function(e, f, nc) - assert(f == f3) - last_insert_entity = e - last_insert_component = nc - end) - - do - last_assign_entity, last_assign_old_component, last_assign_new_component = 0, 0, 0 - last_insert_entity, last_insert_component = 0, 0 - - local e = evo.id() - evo.multi_set(e, { f1 }) - assert(last_assign_entity == 0 and last_assign_old_component == 0 and last_assign_new_component == 0) - assert(last_insert_entity == e and last_insert_component == true) - - last_assign_entity, last_assign_old_component, last_assign_new_component = 0, 0, 0 - last_insert_entity, last_insert_component = 0, 0 - - evo.multi_set(e, { f1 }, { 41 }) - assert(last_assign_entity == e and last_assign_old_component == true and last_assign_new_component == 41) - assert(last_insert_entity == 0 and last_insert_component == 0) - - last_assign_entity, last_assign_old_component, last_assign_new_component = 0, 0, 0 - last_insert_entity, last_insert_component = 0, 0 - - evo.multi_set(e, { f1, f2 }, { 11 }) - assert(last_assign_entity == e and last_assign_old_component == 41 and last_assign_new_component == 11) - assert(last_insert_entity == e and last_insert_component == 42) - end -end - -do - local f1 = evo.id() - - local assign_entity_sum = 0 - local assign_component_sum = 0 - local insert_entity_sum = 0 - local insert_component_sum = 0 - local remove_entity_sum = 0 - local remove_component_sum = 0 - - evo.set(f1, evo.ON_ASSIGN, function(e, f, c) - assert(f == f1) - assign_entity_sum = assign_entity_sum + e - assign_component_sum = assign_component_sum + c - end) - - evo.set(f1, evo.ON_INSERT, function(e, f, c) - assert(f == f1) - insert_entity_sum = insert_entity_sum + e - insert_component_sum = insert_component_sum + c - end) - - evo.set(f1, evo.ON_REMOVE, function(e, f, c) - assert(f == f1) - remove_entity_sum = remove_entity_sum + e - remove_component_sum = remove_component_sum + c - end) - - do - assign_entity_sum, assign_component_sum = 0, 0 - insert_entity_sum, insert_component_sum = 0, 0 - - local e = evo.id() - evo.multi_set(e, { f1, f1 }, { 41, 42 }) - - assert(assign_entity_sum == e and assign_component_sum == 42) - assert(insert_entity_sum == e and insert_component_sum == 41) - end - - do - assign_entity_sum, assign_component_sum = 0, 0 - insert_entity_sum, insert_component_sum = 0, 0 - - local e = evo.id() - evo.multi_set(e, { f1, f1, f1 }, { 41, 42, 43 }) - - assert(assign_entity_sum == e + e and assign_component_sum == 42 + 43) - assert(insert_entity_sum == e and insert_component_sum == 41) - end - - do - assign_entity_sum, assign_component_sum = 0, 0 - insert_entity_sum, insert_component_sum = 0, 0 - - local e = evo.id() - evo.set(e, f1, 41) - evo.multi_set(e, { f1, f1 }, { 42, 43 }) - - assert(assign_entity_sum == e + e and assign_component_sum == 42 + 43) - assert(insert_entity_sum == e and insert_component_sum == 41) - end - - do - assign_entity_sum, assign_component_sum = 0, 0 - insert_entity_sum, insert_component_sum = 0, 0 - - local e = evo.id() - evo.multi_set(e, { f1, f1 }, { 41, 42 }) - - assert(insert_entity_sum == e and insert_component_sum == 41) - end - - do - remove_entity_sum, remove_component_sum = 0, 0 - - local e = evo.id() - evo.set(e, f1, 41) - evo.multi_remove(e, { f1, f1 }) - - assert(remove_entity_sum == e and remove_component_sum == 41) - end -end - do local f1, f2 = evo.id(2) local qb = evo.builder() do - local q = qb:build() + local q = qb:clear():spawn() local includes, excludes = evo.get(q, evo.INCLUDES, evo.EXCLUDES) assert(includes == nil) @@ -3072,7 +2568,7 @@ do end do - local q = qb:include(f1):build() + local q = qb:clear():include(f1):spawn() local includes, excludes = evo.get(q, evo.INCLUDES, evo.EXCLUDES) assert(#includes == 1 and includes[1] == f1) @@ -3080,7 +2576,7 @@ do end do - local q = qb:include(f1, f2):build() + local q = qb:clear():include(f1, f2):spawn() local includes, excludes = evo.get(q, evo.INCLUDES, evo.EXCLUDES) assert(#includes == 2 and includes[1] == f1 and includes[2] == f2) @@ -3088,7 +2584,7 @@ do end do - local q = qb:include(f1):include(f2):build() + local q = qb:clear():include(f1):include(f2):spawn() local includes, excludes = evo.get(q, evo.INCLUDES, evo.EXCLUDES) assert(#includes == 2 and includes[1] == f1 and includes[2] == f2) @@ -3096,7 +2592,7 @@ do end do - local q = qb:exclude(f1):build() + local q = qb:clear():exclude(f1):spawn() local includes, excludes = evo.get(q, evo.INCLUDES, evo.EXCLUDES) assert(includes == nil) @@ -3104,7 +2600,7 @@ do end do - local q = qb:exclude(f1, f2):build() + local q = qb:clear():exclude(f1, f2):spawn() local includes, excludes = evo.get(q, evo.INCLUDES, evo.EXCLUDES) assert(includes == nil) @@ -3112,7 +2608,7 @@ do end do - local q = qb:exclude(f1):exclude(f2):build() + local q = qb:clear():exclude(f1):exclude(f2):spawn() local includes, excludes = evo.get(q, evo.INCLUDES, evo.EXCLUDES) assert(includes == nil) @@ -3120,10 +2616,11 @@ do end do + qb:clear() qb:include(f1) qb:exclude(f2) - local q = qb:build() + local q = qb:spawn() local includes, excludes = evo.get(q, evo.INCLUDES, evo.EXCLUDES) assert(#includes == 1 and includes[1] == f1) @@ -3136,25 +2633,25 @@ do local eb = evo.builder() do - local e = eb:build() - assert(evo.is_alive(e) and evo.is_empty(e)) + local e = eb:clear():spawn() + assert(evo.alive(e) and evo.empty(e)) end do - local e = eb:set(f1, 41):build() + local e = eb:clear():set(f1, 41):spawn() assert(evo.has(e, f1) and evo.get(e, f1) == 41) assert(not evo.has(e, f2) and evo.get(e, f2) == nil) end do - local e = eb:set(f1, 41):set(f2, 42):build() + local e = eb:clear():set(f1, 41):set(f2, 42):spawn() assert(evo.has(e, f1) and evo.get(e, f1) == 41) assert(evo.has(e, f2) and evo.get(e, f2) == 42) end do - local e = eb:build() - assert(evo.is_alive(e) and evo.is_empty(e)) + local e = eb:clear():spawn() + assert(evo.alive(e) and evo.empty(e)) end end @@ -3162,8 +2659,8 @@ do local f1, f2 = evo.id(2) local eb = evo.builder() - local e1 = eb:set(f1, 1):set(f2, 2):build() - local e2 = eb:set(f1, 11):build() + local e1 = eb:clear():set(f1, 1):set(f2, 2):spawn() + local e2 = eb:clear():set(f1, 11):spawn() assert(evo.has(e1, f1) and evo.get(e1, f1) == 1) assert(evo.has(e1, f2) and evo.get(e1, f2) == 2) @@ -3178,66 +2675,62 @@ do evo.set(f3, evo.TAG) do - local e = evo.spawn_with() - assert(evo.is_alive(e) and evo.is_empty(e)) + local e = evo.spawn() + assert(evo.alive(e) and evo.empty(e)) end do - local e = evo.spawn_with({}) - assert(evo.is_alive(e) and evo.is_empty(e)) + local e = evo.spawn({}) + assert(evo.alive(e) and evo.empty(e)) end do - local e1 = evo.spawn_with({ f1 }) + local e1 = evo.spawn({ [f1] = true }) assert(evo.has(e1, f1) and evo.get(e1, f1) == true) - local e2 = evo.spawn_with({ f1 }, {}) + local e2 = evo.spawn({ [f1] = true }) assert(evo.has(e2, f1) and evo.get(e2, f1) == true) - local e3 = evo.spawn_with({ f1 }, { 41 }) + local e3 = evo.spawn({ [f1] = 41 }) assert(evo.has(e3, f1) and evo.get(e3, f1) == 41) end do - local e1 = evo.spawn_with({ f1, f2 }) + local e1 = evo.spawn({ [f1] = true, [f2] = true }) assert(evo.has_all(e1, f1, f2)) assert(evo.get(e1, f1) == true and evo.get(e1, f2) == true) - local e2 = evo.spawn_with({ f1, f2 }, {}) + local e2 = evo.spawn({ [f1] = true, [f2] = true }) assert(evo.has_all(e2, f1, f2)) assert(evo.get(e2, f1) == true and evo.get(e2, f2) == true) - local e3 = evo.spawn_with({ f1, f2 }, { 41 }) + local e3 = evo.spawn({ [f1] = 41, [f2] = true }) assert(evo.has_all(e3, f1, f2)) assert(evo.get(e3, f1) == 41 and evo.get(e3, f2) == true) - local e4 = evo.spawn_with({ f1, f2 }, { nil, 42 }) + local e4 = evo.spawn({ [f1] = true, [f2] = 42 }) assert(evo.has_all(e4, f1, f2)) assert(evo.get(e4, f1) == true and evo.get(e4, f2) == 42) - local e5 = evo.spawn_with({ f1, f2 }, { 41, 42 }) + local e5 = evo.spawn({ [f1] = 41, [f2] = 42 }) assert(evo.has_all(e5, f1, f2)) assert(evo.get(e5, f1) == 41 and evo.get(e5, f2) == 42) - - local e6 = evo.spawn_with({ f1, f2 }, { 41, 42, 43 }) - assert(evo.has_all(e6, f1, f2)) - assert(evo.get(e6, f1) == 41 and evo.get(e6, f2) == 42) end do - local e1 = evo.spawn_with({ f3 }) + local e1 = evo.spawn({ [f3] = true }) assert(evo.has(e1, f3)) assert(evo.get(e1, f3) == nil) - local e2 = evo.spawn_with({ f2, f3 }) + local e2 = evo.spawn({ [f2] = true, [f3] = true }) assert(evo.has_all(e2, f2, f3)) assert(evo.get(e2, f2) == true and evo.get(e2, f3) == nil) - local e3 = evo.spawn_with({ f2, f3 }, { 42 }) + local e3 = evo.spawn({ [f2] = 42, [f3] = true }) assert(evo.has_all(e3, f2, f3)) assert(evo.get(e3, f2) == 42 and evo.get(e3, f3) == nil) - local e4 = evo.spawn_with({ f2, f3 }, { 42, 43, 44 }) + local e4 = evo.spawn({ [f2] = 42, [f3] = 43 }) assert(evo.has_all(e4, f2, f3)) assert(evo.get(e4, f2) == 42 and evo.get(e4, f3) == nil) end @@ -3250,66 +2743,66 @@ do evo.set(f3, evo.TAG) do - local e = evo.spawn_with() - assert(evo.is_alive(e) and evo.is_empty(e)) + local e = evo.spawn() + assert(evo.alive(e) and evo.empty(e)) end do - local e = evo.spawn_with({}) - assert(evo.is_alive(e) and evo.is_empty(e)) + local e = evo.spawn({}) + assert(evo.alive(e) and evo.empty(e)) end do - local e1 = evo.spawn_with({ f1 }) + local e1 = evo.spawn({ [f1] = true }) assert(evo.has(e1, f1) and evo.get(e1, f1) == true) - local e2 = evo.spawn_with({ f1 }, {}) + local e2 = evo.spawn({ [f1] = true }) assert(evo.has(e2, f1) and evo.get(e2, f1) == true) - local e3 = evo.spawn_with({ f1 }, { 41 }) + local e3 = evo.spawn({ [f1] = 41 }) assert(evo.has(e3, f1) and evo.get(e3, f1) == 41) end do - local e1 = evo.spawn_with({ f1, f2 }) + local e1 = evo.spawn({ [f1] = true, [f2] = 21 }) assert(evo.has_all(e1, f1, f2)) assert(evo.get(e1, f1) == true and evo.get(e1, f2) == 21) - local e2 = evo.spawn_with({ f1, f2 }, {}) + local e2 = evo.spawn({ [f1] = true, [f2] = 21 }) assert(evo.has_all(e2, f1, f2)) assert(evo.get(e2, f1) == true and evo.get(e2, f2) == 21) - local e3 = evo.spawn_with({ f1, f2 }, { 41 }) + local e3 = evo.spawn({ [f1] = 41, [f2] = 21 }) assert(evo.has_all(e3, f1, f2)) assert(evo.get(e3, f1) == 41 and evo.get(e3, f2) == 21) - local e4 = evo.spawn_with({ f1, f2 }, { nil, 42 }) + local e4 = evo.spawn({ [f1] = true, [f2] = 42 }) assert(evo.has_all(e4, f1, f2)) assert(evo.get(e4, f1) == true and evo.get(e4, f2) == 42) - local e5 = evo.spawn_with({ f1, f2 }, { 41, 42 }) + local e5 = evo.spawn({ [f1] = 41, [f2] = 42 }) assert(evo.has_all(e5, f1, f2)) assert(evo.get(e5, f1) == 41 and evo.get(e5, f2) == 42) - local e6 = evo.spawn_with({ f1, f2 }, { 41, 42, 43 }) + local e6 = evo.spawn({ [f1] = 41, [f2] = 42 }) assert(evo.has_all(e6, f1, f2)) assert(evo.get(e6, f1) == 41 and evo.get(e6, f2) == 42) end do - local e1 = evo.spawn_with({ f3 }) + local e1 = evo.spawn({ [f3] = true }) assert(evo.has(e1, f3)) assert(evo.get(e1, f3) == nil) - local e2 = evo.spawn_with({ f2, f3 }) + local e2 = evo.spawn({ [f2] = 21, [f3] = true }) assert(evo.has_all(e2, f2, f3)) assert(evo.get(e2, f2) == 21 and evo.get(e2, f3) == nil) - local e3 = evo.spawn_with({ f2, f3 }, { 42 }) + local e3 = evo.spawn({ [f2] = 42, [f3] = true }) assert(evo.has_all(e3, f2, f3)) assert(evo.get(e3, f2) == 42 and evo.get(e3, f3) == nil) - local e4 = evo.spawn_with({ f2, f3 }, { 42, 43, 44 }) + local e4 = evo.spawn({ [f2] = 42, [f3] = 43 }) assert(evo.has_all(e4, f2, f3)) assert(evo.get(e4, f2) == 42 and evo.get(e4, f3) == nil) end @@ -3334,7 +2827,7 @@ do local last_insert_entity = 0 local last_insert_component = 0 - local q = evo.builder():include(cf):build() + local q = evo.builder():include(cf):spawn() evo.batch_set(q, evo.ON_SET, function(e, f, c) last_set_entity = e @@ -3358,7 +2851,7 @@ do set_count, insert_count = 0, 0 last_set_entity, last_set_component = 0, 0 last_insert_entity, last_insert_component = 0, 0 - local e = evo.spawn_with({ f1 }) + local e = evo.spawn({ [f1] = true }) assert(set_count == 1 and insert_count == 1) assert(last_set_entity == e and last_set_component == true) assert(last_insert_entity == e and last_insert_component == true) @@ -3368,7 +2861,7 @@ do set_count, insert_count = 0, 0 last_set_entity, last_set_component = 0, 0 last_insert_entity, last_insert_component = 0, 0 - local e = evo.spawn_with({ f2 }) + local e = evo.spawn({ [f2] = 21 }) assert(set_count == 1 and insert_count == 1) assert(last_set_entity == e and last_set_component == 21) assert(last_insert_entity == e and last_insert_component == 21) @@ -3378,7 +2871,7 @@ do set_count, insert_count = 0, 0 last_set_entity, last_set_component = 0, 0 last_insert_entity, last_insert_component = 0, 0 - local e = evo.spawn_with({ f1, f2 }) + local e = evo.spawn({ [f2] = 21, [f1] = true }) assert(set_count == 2 and insert_count == 2) assert(last_set_entity == e and last_set_component == 21) assert(last_insert_entity == e and last_insert_component == 21) @@ -3388,7 +2881,7 @@ do set_count, insert_count = 0, 0 last_set_entity, last_set_component = 0, 0 last_insert_entity, last_insert_component = 0, 0 - local e = evo.spawn_with({ f3 }, { 33 }) + local e = evo.spawn({ [f3] = true }) assert(set_count == 1 and insert_count == 1) assert(last_set_entity == e and last_set_component == nil) assert(last_insert_entity == e and last_insert_component == nil) @@ -3398,220 +2891,7 @@ do set_count, insert_count = 0, 0 last_set_entity, last_set_component = 0, 0 last_insert_entity, last_insert_component = 0, 0 - local e = evo.spawn_with({ f3, f2 }, { 33, 22 }) - assert(set_count == 2 and insert_count == 2) - assert(last_set_entity == e and last_set_component == nil) - assert(last_insert_entity == e and last_insert_component == nil) - end -end - -do - local f1, f2, f3, f4 = evo.id(4) - - evo.set(f3, evo.DEFAULT, 33) - evo.set(f4, evo.TAG) - - do - local e = evo.spawn_at() - assert(evo.is_alive(e) and evo.is_empty(e)) - end - - do - local c = evo.chunk(f1) - - local e1 = evo.spawn_at(c) - assert(evo.has(e1, f1) and evo.get(e1, f1) == true) - - local e2 = evo.spawn_at(c, { f1 }) - assert(evo.has(e2, f1) and evo.get(e2, f1) == true) - - local e3 = evo.spawn_at(c, { f1, f2 }) - assert(evo.has(e3, f1) and evo.get(e3, f1) == true) - assert(evo.has(e3, f2) and evo.get(e3, f2) == true) - - local e4 = evo.spawn_at(c, { f1, f2 }, { 41 }) - assert(evo.has(e4, f1) and evo.get(e4, f1) == 41) - assert(evo.has(e4, f2) and evo.get(e4, f2) == true) - - local e5 = evo.spawn_at(c, { f1, f2 }, { 41, 42 }) - assert(evo.has(e5, f1) and evo.get(e5, f1) == 41) - assert(evo.has(e5, f2) and evo.get(e5, f2) == 42) - - local e6 = evo.spawn_at(c, { f2 }, { 42 }) - assert(evo.has(e6, f1) and evo.get(e6, f1) == true) - assert(evo.has(e6, f2) and evo.get(e6, f2) == 42) - end - - do - local c = evo.chunk(f1, f2) - - local e1 = evo.spawn_at(c) - assert(evo.has(e1, f1) and evo.get(e1, f1) == true) - assert(evo.has(e1, f2) and evo.get(e1, f2) == true) - - local e2 = evo.spawn_at(c, { f1 }) - assert(evo.has(e2, f1) and evo.get(e2, f1) == true) - assert(evo.has(e2, f2) and evo.get(e2, f2) == true) - - local e3 = evo.spawn_at(c, { f1, f2 }) - assert(evo.has(e3, f1) and evo.get(e3, f1) == true) - assert(evo.has(e3, f2) and evo.get(e3, f2) == true) - - local e4 = evo.spawn_at(c, { f1, f2, f3 }) - assert(evo.has(e4, f1) and evo.get(e4, f1) == true) - assert(evo.has(e4, f2) and evo.get(e4, f2) == true) - assert(evo.has(e4, f3) and evo.get(e4, f3) == 33) - - local e5 = evo.spawn_at(c, { f1, f2 }, { 41 }) - assert(evo.has(e5, f1) and evo.get(e5, f1) == 41) - assert(evo.has(e5, f2) and evo.get(e5, f2) == true) - - local e6 = evo.spawn_at(c, { f1, f2 }, { 41, 42 }) - assert(evo.has(e6, f1) and evo.get(e6, f1) == 41) - assert(evo.has(e6, f2) and evo.get(e6, f2) == 42) - - local e7 = evo.spawn_at(c, { f1, f2, f3 }, { 41, 42, 43 }) - assert(evo.has(e7, f1) and evo.get(e7, f1) == 41) - assert(evo.has(e7, f2) and evo.get(e7, f2) == 42) - assert(evo.has(e7, f3) and evo.get(e7, f3) == 43) - - local e8 = evo.spawn_at(c, { f3 }, { 43 }) - assert(evo.has(e8, f1) and evo.get(e8, f1) == true) - assert(evo.has(e8, f2) and evo.get(e8, f2) == true) - assert(evo.has(e8, f3) and evo.get(e8, f3) == 43) - - local e9 = evo.spawn_at(c, { f2 }, { 42 }) - assert(evo.has(e9, f1) and evo.get(e9, f1) == true) - assert(evo.has(e9, f2) and evo.get(e9, f2) == 42) - assert(not evo.has(e9, f3) and evo.get(e9, f3) == nil) - end - - do - local c = evo.chunk(f2, f3, f4) - - local e1 = evo.spawn_at(c) - assert(evo.has(e1, f2) and evo.get(e1, f2) == true) - assert(evo.has(e1, f3) and evo.get(e1, f3) == 33) - assert(evo.has(e1, f4) and evo.get(e1, f4) == nil) - - local e2 = evo.spawn_at(c, { f1 }) - assert(evo.has(e2, f1) and evo.get(e2, f1) == true) - assert(evo.has(e2, f2) and evo.get(e2, f2) == true) - assert(evo.has(e2, f3) and evo.get(e2, f3) == 33) - assert(evo.has(e2, f4) and evo.get(e2, f4) == nil) - - local e3 = evo.spawn_at(c, { f1 }, { 41 }) - assert(evo.has(e3, f1) and evo.get(e3, f1) == 41) - assert(evo.has(e3, f2) and evo.get(e3, f2) == true) - assert(evo.has(e3, f3) and evo.get(e3, f3) == 33) - assert(evo.has(e3, f4) and evo.get(e3, f4) == nil) - - local e4 = evo.spawn_at(c, { f1, f3, f4 }, { 41, 43, 44 }) - assert(evo.has(e4, f1) and evo.get(e4, f1) == 41) - assert(evo.has(e4, f2) and evo.get(e4, f2) == true) - assert(evo.has(e4, f3) and evo.get(e4, f3) == 43) - assert(evo.has(e4, f4) and evo.get(e4, f4) == nil) - end - - do - local c = evo.chunk(f1, f2, f3) - - local e1 = evo.spawn_at(c, { f1, f2, f3 }) - assert(evo.has(e1, f1) and evo.get(e1, f1) == true) - assert(evo.has(e1, f2) and evo.get(e1, f2) == true) - assert(evo.has(e1, f3) and evo.get(e1, f3) == 33) - end -end - -do - local cf = evo.id() - local f1, f2, f3 = evo.id(3) - - evo.set(f1, cf) - evo.set(f2, cf) - evo.set(f3, cf) - - evo.set(f2, evo.DEFAULT, 22) - evo.set(f3, evo.TAG) - - local set_count = 0 - local insert_count = 0 - - local last_set_entity = 0 - local last_set_component = 0 - local last_insert_entity = 0 - local last_insert_component = 0 - - local q = evo.builder():include(cf):build() - - evo.batch_set(q, evo.ON_SET, function(e, f, c) - last_set_entity = e - assert(f == f1 or f == f2 or f == f3) - last_set_component = c - set_count = set_count + 1 - end) - - evo.batch_set(q, evo.ON_INSERT, function(e, f, c) - last_insert_entity = e - assert(f == f1 or f == f2 or f == f3) - last_insert_component = c - insert_count = insert_count + 1 - end) - - assert(set_count == 0 and insert_count == 0) - assert(last_set_entity == 0 and last_set_component == 0) - assert(last_insert_entity == 0 and last_insert_component == 0) - - do - set_count, insert_count = 0, 0 - last_set_entity, last_set_component = 0, 0 - last_insert_entity, last_insert_component = 0, 0 - local c = evo.chunk(f1) - local e = evo.spawn_at(c) - assert(set_count == 1 and insert_count == 1) - assert(last_set_entity == e and last_set_component == true) - assert(last_insert_entity == e and last_insert_component == true) - end - - do - set_count, insert_count = 0, 0 - last_set_entity, last_set_component = 0, 0 - last_insert_entity, last_insert_component = 0, 0 - local c = evo.chunk(f2) - local e = evo.spawn_at(c) - assert(set_count == 1 and insert_count == 1) - assert(last_set_entity == e and last_set_component == 22) - assert(last_insert_entity == e and last_insert_component == 22) - end - - do - set_count, insert_count = 0, 0 - last_set_entity, last_set_component = 0, 0 - last_insert_entity, last_insert_component = 0, 0 - local c = evo.chunk(f2, f1) - local e = evo.spawn_at(c) - assert(set_count == 2 and insert_count == 2) - assert(last_set_entity == e and last_set_component == 22) - assert(last_insert_entity == e and last_insert_component == 22) - end - - do - set_count, insert_count = 0, 0 - last_set_entity, last_set_component = 0, 0 - last_insert_entity, last_insert_component = 0, 0 - local c = evo.chunk(f3) - local e = evo.spawn_at(c) - assert(set_count == 1 and insert_count == 1) - assert(last_set_entity == e and last_set_component == nil) - assert(last_insert_entity == e and last_insert_component == nil) - end - - do - set_count, insert_count = 0, 0 - last_set_entity, last_set_component = 0, 0 - last_insert_entity, last_insert_component = 0, 0 - local c = evo.chunk(f3, f2) - local e = evo.spawn_at(c, { f3, f2 }, { 33, 22 }) + local e = evo.spawn({ [f3] = 33, [f2] = 22 }) assert(set_count == 2 and insert_count == 2) assert(last_set_entity == e and last_set_component == nil) assert(last_insert_entity == e and last_insert_component == nil) @@ -3626,107 +2906,107 @@ do do assert(evo.defer()) - local e = evo.spawn_with() - assert(evo.is_alive(e) and evo.is_empty(e)) + local e = evo.spawn() + assert(evo.alive(e) and evo.empty(e)) assert(evo.commit()) - assert(evo.is_alive(e) and evo.is_empty(e)) + assert(evo.alive(e) and evo.empty(e)) end do assert(evo.defer()) - local e = evo.spawn_with({}) - assert(evo.is_alive(e) and evo.is_empty(e)) + local e = evo.spawn({}) + assert(evo.alive(e) and evo.empty(e)) assert(evo.commit()) - assert(evo.is_alive(e) and evo.is_empty(e)) + assert(evo.alive(e) and evo.empty(e)) end do assert(evo.defer()) - local e1 = evo.spawn_with({ f1 }) - assert(evo.is_alive(e1) and evo.is_empty(e1)) + local e1 = evo.spawn({ [f1] = true }) + assert(evo.alive(e1) and evo.empty(e1)) assert(evo.commit()) - assert(evo.is_alive(e1) and not evo.is_empty(e1)) + assert(evo.alive(e1) and not evo.empty(e1)) assert(evo.has(e1, f1) and evo.get(e1, f1) == true) assert(evo.defer()) - local e2 = evo.spawn_with({ f1 }, {}) - assert(evo.is_alive(e2) and evo.is_empty(e2)) + local e2 = evo.spawn({ [f1] = true }) + assert(evo.alive(e2) and evo.empty(e2)) assert(evo.commit()) - assert(evo.is_alive(e2) and not evo.is_empty(e2)) + assert(evo.alive(e2) and not evo.empty(e2)) assert(evo.has(e2, f1) and evo.get(e2, f1) == true) assert(evo.defer()) - local e3 = evo.spawn_with({ f1 }, { 41 }) - assert(evo.is_alive(e3) and evo.is_empty(e3)) + local e3 = evo.spawn({ [f1] = 41 }) + assert(evo.alive(e3) and evo.empty(e3)) assert(evo.commit()) - assert(evo.is_alive(e3) and not evo.is_empty(e3)) + assert(evo.alive(e3) and not evo.empty(e3)) assert(evo.has(e3, f1) and evo.get(e3, f1) == 41) end do assert(evo.defer()) - local e1 = evo.spawn_with({ f1, f2 }) - assert(evo.is_alive(e1) and evo.is_empty(e1)) + local e1 = evo.spawn({ [f1] = true, [f2] = true }) + assert(evo.alive(e1) and evo.empty(e1)) assert(evo.commit()) - assert(evo.is_alive(e1) and not evo.is_empty(e1)) + assert(evo.alive(e1) and not evo.empty(e1)) assert(evo.has(e1, f1) and evo.get(e1, f1) == true) assert(evo.has(e1, f2) and evo.get(e1, f2) == true) assert(evo.defer()) - local e2 = evo.spawn_with({ f1, f2 }, {}) - assert(evo.is_alive(e2) and evo.is_empty(e2)) + local e2 = evo.spawn({ [f1] = true, [f2] = true }) + assert(evo.alive(e2) and evo.empty(e2)) assert(evo.commit()) - assert(evo.is_alive(e2) and not evo.is_empty(e2)) + assert(evo.alive(e2) and not evo.empty(e2)) assert(evo.has(e2, f1) and evo.get(e2, f1) == true) assert(evo.has(e2, f2) and evo.get(e2, f2) == true) assert(evo.defer()) - local e3 = evo.spawn_with({ f1, f2 }, { 41 }) - assert(evo.is_alive(e3) and evo.is_empty(e3)) + local e3 = evo.spawn({ [f1] = 41, [f2] = true }) + assert(evo.alive(e3) and evo.empty(e3)) assert(evo.commit()) - assert(evo.is_alive(e3) and not evo.is_empty(e3)) + assert(evo.alive(e3) and not evo.empty(e3)) assert(evo.has(e3, f1) and evo.get(e3, f1) == 41) assert(evo.has(e3, f2) and evo.get(e3, f2) == true) assert(evo.defer()) - local e4 = evo.spawn_with({ f1, f2 }, { nil, 42 }) - assert(evo.is_alive(e4) and evo.is_empty(e4)) + local e4 = evo.spawn({ [f1] = true, [f2] = 42 }) + assert(evo.alive(e4) and evo.empty(e4)) assert(evo.commit()) - assert(evo.is_alive(e4) and not evo.is_empty(e4)) + assert(evo.alive(e4) and not evo.empty(e4)) assert(evo.has(e4, f1) and evo.get(e4, f1) == true) assert(evo.has(e4, f2) and evo.get(e4, f2) == 42) assert(evo.defer()) - local e5 = evo.spawn_with({ f1, f2 }, { 41, 42 }) - assert(evo.is_alive(e5) and evo.is_empty(e5)) + local e5 = evo.spawn({ [f1] = 41, [f2] = 42 }) + assert(evo.alive(e5) and evo.empty(e5)) assert(evo.commit()) - assert(evo.is_alive(e5) and not evo.is_empty(e5)) + assert(evo.alive(e5) and not evo.empty(e5)) assert(evo.has(e5, f1) and evo.get(e5, f1) == 41) assert(evo.has(e5, f2) and evo.get(e5, f2) == 42) assert(evo.defer()) - local e6 = evo.spawn_with({ f1, f2 }, { 41, 42, 43 }) - assert(evo.is_alive(e6) and evo.is_empty(e6)) + local e6 = evo.spawn({ [f1] = 41, [f2] = 42 }) + assert(evo.alive(e6) and evo.empty(e6)) assert(evo.commit()) - assert(evo.is_alive(e6) and not evo.is_empty(e6)) + assert(evo.alive(e6) and not evo.empty(e6)) assert(evo.has(e6, f1) and evo.get(e6, f1) == 41) assert(evo.has(e6, f2) and evo.get(e6, f2) == 42) end do assert(evo.defer()) - local e1 = evo.spawn_with({ f3, f4 }) - assert(evo.is_alive(e1) and evo.is_empty(e1)) + local e1 = evo.spawn({ [f3] = 3, [f4] = true }) + assert(evo.alive(e1) and evo.empty(e1)) assert(evo.commit()) - assert(evo.is_alive(e1) and not evo.is_empty(e1)) + assert(evo.alive(e1) and not evo.empty(e1)) assert(evo.has(e1, f3) and evo.get(e1, f3) == 3) assert(evo.has(e1, f4) and evo.get(e1, f4) == nil) assert(evo.defer()) - local e2 = evo.spawn_with({ f3, f4 }, { 33, 44 }) - assert(evo.is_alive(e2) and evo.is_empty(e2)) + local e2 = evo.spawn({ [f3] = 33, [f4] = 44 }) + assert(evo.alive(e2) and evo.empty(e2)) assert(evo.commit()) - assert(evo.is_alive(e2) and not evo.is_empty(e2)) + assert(evo.alive(e2) and not evo.empty(e2)) assert(evo.has(e2, f3) and evo.get(e2, f3) == 33) assert(evo.has(e2, f4) and evo.get(e2, f4) == nil) end @@ -3734,996 +3014,7 @@ end do local f1, f2, f3, f4, f5 = evo.id(5) - - local e1 = evo.builder():set(f1, 11):build() - local e2 = evo.builder():set(f1, 21):set(f2, 22):build() - local e3 = evo.builder():set(f1, 31):set(f2, 32):set(f3, 33):build() - local e4 = evo.builder():set(f1, 41):set(f2, 42):set(f3, 43):set(f4, 44):build() - - do - local q = evo.builder():include(f1):build() - evo.batch_multi_remove(q, {}) - evo.batch_multi_remove(q, { f5 }) - end - - do - local q = evo.builder():include(f3):build() - - evo.batch_multi_remove(q, { f4 }) - assert(evo.has_all(e4, f1, f2, f3) and not evo.has(e4, f4)) - assert(evo.get(e4, f1) == 41) - assert(evo.get(e4, f2) == 42) - assert(evo.get(e4, f3) == 43) - assert(evo.get(e4, f4) == nil) - - for chunk in evo.execute(q) do - assert(next(evo.components(chunk, f4)) == nil) - end - - do - local chunk, entities = evo.chunk(f1, f2, f3) - assert(chunk and entities) - assert(#entities == 2) - assert(entities[1] == e3, entities[2] == e4) - assert(evo.components(chunk, f2)[1] == 32 and evo.components(chunk, f3)[1] == 33) - assert(evo.components(chunk, f2)[2] == 42 and evo.components(chunk, f3)[2] == 43) - end - - do - local chunk, entities = evo.chunk(f1, f2, f3, f4) - assert(chunk) - assert(next(evo.components(chunk, f4)) == nil) - assert(#entities == 0) - end - end - - do - local q = evo.builder():include(f2):build() - - evo.batch_multi_remove(q, { f1 }) - assert(evo.has_all(e1, f1) and not evo.has_any(e1, f2, f3, f4)) - assert(evo.has_all(e2, f2) and not evo.has_any(e2, f1, f3, f4)) - assert(evo.has_all(e3, f2, f3) and not evo.has_any(e3, f1, f4)) - assert(evo.has_all(e4, f2, f3) and not evo.has_any(e4, f1, f4)) - - for chunk in evo.execute(q) do - assert(next(evo.components(chunk, f1)) == nil) - end - - evo.batch_multi_remove(q, { f2, f3 }) - assert(evo.has_all(e1, f1) and not evo.has_any(e1, f2, f3, f4)) - assert(not evo.has_any(e2, f1, f2, f3, f4)) - assert(not evo.has_any(e3, f1, f2, f3, f4)) - assert(not evo.has_any(e4, f1, f2, f3, f4)) - - for chunk in evo.execute(q) do - assert(next(evo.components(chunk, f2)) == nil) - assert(next(evo.components(chunk, f3)) == nil) - end - - do - local chunk, entities = evo.chunk(f1, f2) - assert(chunk) - assert(next(evo.components(chunk, f1)) == nil) - assert(next(evo.components(chunk, f2)) == nil) - assert(#entities == 0) - end - - do - local chunk, entities = evo.chunk(f1, f2, f3) - assert(chunk) - assert(next(evo.components(chunk, f1)) == nil) - assert(next(evo.components(chunk, f2)) == nil) - assert(next(evo.components(chunk, f3)) == nil) - assert(#entities == 0) - end - end - - do - local q = evo.builder():include(f1):build() - - assert(evo.defer()) - evo.batch_multi_remove(q, { f1 }) - assert(evo.has(e1, f1)) - assert(evo.commit()) - assert(not evo.has(e1, f1)) - end -end - -do - local f1, f2 = evo.id(2) - - evo.set(f2, evo.TAG) - - local last_remove_entity = 0 - local last_remove_component = 0 - local sum_removed_components = 0 - - evo.set(f1, evo.ON_REMOVE, function(e, f, c) - assert(f == f1) - last_remove_entity = e - last_remove_component = c - sum_removed_components = sum_removed_components + c - end) - - evo.set(f2, evo.ON_REMOVE, function(e, f, c) - assert(f == f2) - last_remove_entity = e - last_remove_component = c - end) - - local _ = evo.spawn_with({ f1 }, { 11 }) - local e2 = evo.spawn_with({ f1, f2 }, { 21, 22 }) - assert(last_remove_entity == 0 and last_remove_component == 0) - - do - last_remove_entity = 0 - last_remove_component = 0 - sum_removed_components = 0 - - local q = evo.builder():include(f1):build() - - evo.batch_multi_remove(q, { f1, f1 }) - assert(last_remove_entity == e2 and last_remove_component == 21) - assert(sum_removed_components == 11 + 21) - end - - do - last_remove_entity = 0 - last_remove_component = 0 - sum_removed_components = 0 - - local q = evo.builder():include(f2):build() - - evo.batch_multi_remove(q, { f2 }) - assert(last_remove_entity == e2 and last_remove_component == nil) - assert(sum_removed_components == 0) - end -end - -do - local f1, f2, f3, f4, f5 = evo.id(5) - - local e1 = evo.builder():set(f1, 11):build() - local e2 = evo.builder():set(f1, 21):set(f2, 22):build() - local e3 = evo.builder():set(f1, 31):set(f2, 32):set(f3, 33):build() - local e4 = evo.builder():set(f1, 41):set(f2, 42):set(f3, 43):set(f4, 44):build() - - assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == nil and evo.get(e1, f3) == nil) - assert(evo.get(e2, f1) == 21 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil) - assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == 33) - assert(evo.get(e4, f1) == 41 and evo.get(e4, f2) == 42 and evo.get(e4, f3) == 43 and evo.get(e4, f4) == 44) - - do - local q = evo.builder():include(f1):build() - evo.batch_multi_set(q, {}) - end - - do - local q = evo.builder():include(f1, f5):build() - evo.batch_multi_set(q, { f5 }) - end - - do - local q = evo.builder():include(f3, f4):build() - - evo.batch_multi_set(q, { f4 }, { 54 }) - assert(evo.get(e3, f3) == 33 and evo.get(e3, f4) == nil) - assert(evo.get(e4, f3) == 43 and evo.get(e4, f4) == 54) - end - - do - local q = evo.builder():include(f2):build() - - evo.batch_multi_set(q, { f1 }, { 51, 52 }) - assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == nil and evo.get(e1, f3) == nil) - assert(evo.get(e2, f1) == 51 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil) - assert(evo.get(e3, f1) == 51 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == 33) - assert(evo.get(e4, f1) == 51 and evo.get(e4, f2) == 42 and evo.get(e4, f3) == 43 and evo.get(e4, f4) == 54) - - evo.batch_multi_set(q, { f2, f3 }, { 52, 53 }) - assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == nil and evo.get(e1, f3) == nil) - assert(evo.get(e2, f1) == 51 and evo.get(e2, f2) == 52 and evo.get(e2, f3) == 53) - assert(evo.get(e3, f1) == 51 and evo.get(e3, f2) == 52 and evo.get(e3, f3) == 53) - assert(evo.get(e4, f1) == 51 and evo.get(e4, f2) == 52 and evo.get(e4, f3) == 53 and evo.get(e4, f4) == 54) - end -end - -do - local f1, f2, f3, f4, f5 = evo.id(4) - - evo.set(f2, evo.DEFAULT, 41) - evo.set(f3, evo.TAG) - - local e1 = evo.builder():set(f1, 11):build() - local e2 = evo.builder():set(f1, 21):set(f2, 22):build() - local e3 = evo.builder():set(f1, 31):set(f2, 32):set(f3, 33):build() - local e4 = evo.builder():set(f1, 41):set(f2, 42):set(f3, 43):set(f4, 44):build() - - assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == nil and evo.get(e1, f3) == nil) - assert(evo.get(e2, f1) == 21 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil) - assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == nil) - assert(evo.get(e4, f1) == 41 and evo.get(e4, f2) == 42 and evo.get(e4, f3) == nil and evo.get(e4, f4) == 44) - - do - local q = evo.builder():include(f1):build() - evo.batch_multi_set(q, {}) - evo.batch_multi_set(q, { f5 }) - end - - do - local q = evo.builder():include(f3, f4):build() - - evo.batch_multi_set(q, { f4 }, { 54 }) - assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == nil and evo.get(e1, f3) == nil) - assert(evo.get(e2, f1) == 21 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil) - assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == nil) - assert(evo.get(e4, f1) == 41 and evo.get(e4, f2) == 42 and evo.get(e4, f3) == nil and evo.get(e4, f4) == 54) - end - - do - local q = evo.builder():include(f2):build() - - evo.batch_multi_set(q, { f1 }, { 51, 52 }) - assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == nil and evo.get(e1, f3) == nil) - assert(evo.get(e2, f1) == 51 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil) - assert(evo.get(e3, f1) == 51 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == nil) - assert(evo.get(e4, f1) == 51 and evo.get(e4, f2) == 42 and evo.get(e4, f3) == nil and evo.get(e4, f4) == 54) - - evo.batch_multi_set(q, { f2, f3 }, { 52, 53 }) - assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == nil and evo.get(e1, f3) == nil) - assert(evo.get(e2, f1) == 51 and evo.get(e2, f2) == 52 and evo.get(e2, f3) == nil) - assert(evo.get(e3, f1) == 51 and evo.get(e3, f2) == 52 and evo.get(e3, f3) == nil) - assert(evo.get(e4, f1) == 51 and evo.get(e4, f2) == 52 and evo.get(e4, f3) == nil and evo.get(e4, f4) == 54) - end - - do - local q = evo.builder():include(f1):build() - - evo.batch_multi_set(q, { f1 }) - assert(evo.get(e1, f1) == true and evo.get(e1, f2) == nil and evo.get(e1, f3) == nil) - assert(evo.get(e2, f1) == true and evo.get(e2, f2) == 52 and evo.get(e2, f3) == nil) - assert(evo.get(e3, f1) == true and evo.get(e3, f2) == 52 and evo.get(e3, f3) == nil) - assert(evo.get(e4, f1) == true and evo.get(e4, f2) == 52 and evo.get(e4, f3) == nil and evo.get(e4, f4) == 54) - - evo.batch_multi_set(q, { f2 }) - assert(evo.get(e1, f1) == true and evo.get(e1, f2) == 41 and evo.get(e1, f3) == nil) - assert(evo.get(e2, f1) == true and evo.get(e2, f2) == 41 and evo.get(e2, f3) == nil) - assert(evo.get(e3, f1) == true and evo.get(e3, f2) == 41 and evo.get(e3, f3) == nil) - assert(evo.get(e4, f1) == true and evo.get(e4, f2) == 41 and evo.get(e4, f3) == nil and evo.get(e4, f4) == 54) - end -end - -do - local f1, f2, f3 = evo.id(3) - - evo.set(f2, evo.DEFAULT, 42) - evo.set(f3, evo.TAG) - - local sum_entity = 0 - local last_assign_entity = 0 - local last_assign_new_component = 0 - local last_assign_old_component = 0 - - evo.set(f1, evo.ON_ASSIGN, function(e, f, nc, oc) - assert(f == f1) - sum_entity = sum_entity + e - last_assign_entity = e - last_assign_new_component = nc - last_assign_old_component = oc - end) - - evo.set(f2, evo.ON_ASSIGN, function(e, f, nc, oc) - assert(f == f2) - sum_entity = sum_entity + e - last_assign_entity = e - last_assign_new_component = nc - last_assign_old_component = oc - end) - - evo.set(f3, evo.ON_ASSIGN, function(e, f, nc, oc) - assert(f == f3) - sum_entity = sum_entity + e - last_assign_entity = e - last_assign_new_component = nc - last_assign_old_component = oc - end) - - local e1 = evo.builder():set(f1, 11):build() - local e2 = evo.builder():set(f1, 21):set(f2, 22):build() - local e3 = evo.builder():set(f1, 31):set(f2, 32):set(f3, 33):build() - - do - local q = evo.builder():include(f3):build() - - sum_entity = 0 - last_assign_entity = 0 - last_assign_new_component = 0 - last_assign_old_component = 0 - - evo.batch_multi_set(q, { f2 }, {}) - assert(sum_entity == e3) - assert(last_assign_entity == e3) - assert(last_assign_new_component == 42) - assert(last_assign_old_component == 32) - end - - do - local q = evo.builder():include(f1):build() - - sum_entity = 0 - last_assign_entity = 0 - last_assign_new_component = 0 - last_assign_old_component = 0 - - evo.batch_multi_set(q, { f1 }, { 51 }) - assert(sum_entity == e1 + e2 + e3) - assert(last_assign_entity == e3) - assert(last_assign_new_component == 51) - assert(last_assign_old_component == 31) - end - - do - local q = evo.builder():include(f1):build() - - sum_entity = 0 - last_assign_entity = 0 - last_assign_new_component = 0 - last_assign_old_component = 0 - - evo.batch_multi_set(q, { f1, f1 }, { 61, 61 }) - assert(sum_entity == e1 + e2 + e3 + e1 + e2 + e3) - assert(last_assign_entity == e3) - assert(last_assign_new_component == 61) - assert(last_assign_old_component == 61) - end - - do - local q = evo.builder():include(f1, f3):build() - - sum_entity = 0 - last_assign_entity = 0 - last_assign_new_component = 0 - last_assign_old_component = 0 - - evo.batch_multi_set(q, { f3 }, { 63 }) - assert(sum_entity == e3) - assert(last_assign_entity == e3) - assert(last_assign_new_component == nil) - assert(last_assign_old_component == nil) - end -end - -do - local f1, f2, f3, f4 = evo.id(4) - - local e1 = evo.builder():set(f1, 11):build() - local e2 = evo.builder():set(f1, 21):set(f2, 22):build() - local e3 = evo.builder():set(f1, 31):set(f2, 32):set(f3, 33):build() - local e4 = evo.builder():set(f1, 41):set(f2, 42):set(f3, 43):set(f4, 44):build() - - do - local q = evo.builder():include(f1):build() - - evo.batch_multi_set(q, {}) - end - - do - local q = evo.builder():include(f3):exclude(f4):build() - - evo.batch_multi_set(q, { f4 }) - assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == 33 and evo.get(e3, f4) == true) - assert(evo.get(e4, f1) == 41 and evo.get(e4, f2) == 42 and evo.get(e4, f3) == 43 and evo.get(e4, f4) == 44) - - do - local c123, c123_es = evo.chunk(f1, f2, f3) - assert(c123 and #c123_es == 0) - assert(#evo.components(c123, f1) == 0) - assert(#evo.components(c123, f2) == 0) - assert(#evo.components(c123, f3) == 0) - - local c1234, c1234_es = evo.chunk(f1, f2, f3, f4) - assert(c1234 and #c1234_es == 2) - assert(#evo.components(c1234, f1) == 2) - assert(#evo.components(c1234, f2) == 2) - assert(#evo.components(c1234, f3) == 2) - assert(#evo.components(c1234, f4) == 2) - end - end - - do - local q = evo.builder():include(f1):exclude(f3, f4):build() - - evo.batch_multi_set(q, { f3, f4 }, { 53, 54 }) - assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == nil and evo.get(e1, f3) == 53 and evo.get(e1, f4) == 54) - assert(evo.get(e2, f1) == 21 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == 53 and evo.get(e2, f4) == 54) - assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == 33 and evo.get(e3, f4) == true) - assert(evo.get(e4, f1) == 41 and evo.get(e4, f2) == 42 and evo.get(e4, f3) == 43 and evo.get(e4, f4) == 44) - - do - local c1, c1_es = evo.chunk(f1) - assert(c1 and #c1_es == 0) - assert(#evo.components(c1, f1) == 0) - end - - do - local c12, c12_es = evo.chunk(f1, f2) - assert(c12 and #c12_es == 0) - assert(#evo.components(c12, f1) == 0) - assert(#evo.components(c12, f2) == 0) - end - - do - local c134, c134_es = evo.chunk(f1, f3, f4) - assert(c134 and #c134_es == 1) - assert(#evo.components(c134, f1) == 1) - assert(#evo.components(c134, f3) == 1) - assert(#evo.components(c134, f4) == 1) - end - - do - local c1234, c1234_es = evo.chunk(f1, f2, f3, f4) - assert(c1234 and #c1234_es == 3) - assert(#evo.components(c1234, f1) == 3) - assert(#evo.components(c1234, f2) == 3) - assert(#evo.components(c1234, f3) == 3) - assert(#evo.components(c1234, f4) == 3) - end - end -end - -do - local f1, f2, f3, f4 = evo.id(4) - - evo.set(f2, evo.DEFAULT, 41) - evo.set(f3, evo.TAG) - - local e1 = evo.builder():set(f1, 11):build() - local e2 = evo.builder():set(f1, 21):set(f2, 22):build() - local e3 = evo.builder():set(f1, 31):set(f2, 32):set(f3, 33):build() - local e4 = evo.builder():set(f1, 41):set(f2, 42):set(f3, 43):set(f4, 44):build() - - assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == nil and evo.get(e1, f3) == nil) - assert(evo.get(e2, f1) == 21 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil) - assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == nil) - assert(evo.get(e4, f1) == 41 and evo.get(e4, f2) == 42 and evo.get(e4, f3) == nil and evo.get(e4, f4) == 44) - - do - local q = evo.builder():include(f1):build() - evo.batch_multi_set(q, {}) - end - - do - local q = evo.builder():include(f1):exclude(f2):build() - evo.batch_multi_set(q, { f2 }) - - assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == 41 and evo.get(e1, f3) == nil) - assert(evo.get(e2, f1) == 21 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil) - assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == nil) - assert(evo.get(e4, f1) == 41 and evo.get(e4, f2) == 42 and evo.get(e4, f3) == nil and evo.get(e4, f4) == 44) - end -end - -do - local f1, f2, f3, f4, f5 = evo.id(5) - - evo.set(f2, evo.DEFAULT, 42) - evo.set(f3, evo.TAG) - - local sum_entity = 0 - local last_insert_entity = 0 - local last_insert_component = 0 - - evo.set(f1, evo.ON_INSERT, function(e, f, c) - assert(f == f1) - sum_entity = sum_entity + e - last_insert_entity = e - last_insert_component = c - end) - - evo.set(f2, evo.ON_INSERT, function(e, f, c) - assert(f == f2) - sum_entity = sum_entity + e - last_insert_entity = e - last_insert_component = c - end) - - evo.set(f3, evo.ON_INSERT, function(e, f, c) - assert(f == f3) - sum_entity = sum_entity + e - last_insert_entity = e - last_insert_component = c - end) - - evo.set(f4, evo.ON_INSERT, function(e, f, c) - assert(f == f4) - sum_entity = sum_entity + e - last_insert_entity = e - last_insert_component = c - end) - - evo.set(f5, evo.ON_INSERT, function(e, f, c) - assert(f == f5) - sum_entity = sum_entity + e - last_insert_entity = e - last_insert_component = c - end) - - local e1 = evo.builder():set(f1, 11):build() - local e2 = evo.builder():set(f1, 21):set(f2, 22):build() - local e3 = evo.builder():set(f1, 31):set(f2, 32):set(f3, 33):build() - - do - local q = evo.builder():include(f1):exclude(f2):build() - - sum_entity = 0 - last_insert_entity = 0 - last_insert_component = 0 - - evo.batch_multi_set(q, { f2 }) - assert(sum_entity == e1) - assert(last_insert_entity == e1) - assert(last_insert_component == 42) - assert(evo.has(e1, f1) and evo.has(e1, f2) and not evo.has(e1, f3)) - assert(evo.has(e2, f1) and evo.has(e2, f2) and not evo.has(e2, f3)) - assert(evo.has(e3, f1) and evo.has(e3, f2) and evo.has(e3, f3)) - assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == 42 and evo.get(e1, f3) == nil) - assert(evo.get(e2, f1) == 21 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil) - assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == nil) - end - - do - local q = evo.builder():include(f2):exclude(f3):build() - - sum_entity = 0 - last_insert_entity = 0 - last_insert_component = 0 - - evo.batch_multi_set(q, { f3 }) - assert(sum_entity == e1 + e2) - assert(last_insert_entity == e1) - assert(last_insert_component == nil) - assert(evo.has(e1, f1) and evo.has(e1, f2) and evo.has(e1, f3)) - assert(evo.has(e2, f1) and evo.has(e2, f2) and evo.has(e2, f3)) - assert(evo.has(e3, f1) and evo.has(e3, f2) and evo.has(e3, f3)) - assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == 42 and evo.get(e1, f3) == nil) - assert(evo.get(e2, f1) == 21 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil) - assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == nil) - end - - do - local q = evo.builder():include(f1, f2, f3):build() - - sum_entity = 0 - last_insert_entity = 0 - last_insert_component = 0 - - evo.batch_multi_set(q, { f3, f4, f5, f5 }, { 53, 54, 55, 65 }) - assert(sum_entity == e1 + e2 + e3 + e1 + e2 + e3) - assert(last_insert_entity == e1) - assert(last_insert_component == 55) - assert(evo.has_all(e1, f1, f2, f3, f4, f5)) - assert(evo.has_all(e2, f1, f2, f3, f4, f5)) - assert(evo.has_all(e3, f1, f2, f3, f4, f5)) - assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == 42 and evo.get(e1, f3) == nil) - assert(evo.get(e2, f1) == 21 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil) - assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == nil) - assert(evo.get(e1, f4) == 54 and evo.get(e1, f5) == 65) - assert(evo.get(e2, f4) == 54 and evo.get(e2, f5) == 65) - assert(evo.get(e3, f4) == 54 and evo.get(e3, f5) == 65) - end -end - -do - local f1, f2, f3, f4 = evo.id(4) - - evo.set(f2, evo.DEFAULT, 52) - evo.set(f4, evo.TAG) - - local e1a = evo.builder():set(f1, 11):build() - local e1b = evo.builder():set(f1, 11):build() - - local e2a = evo.builder():set(f1, 21):set(f2, 22):build() - local e2b = evo.builder():set(f1, 21):set(f2, 22):build() - - local e3a = evo.builder():set(f1, 31):set(f2, 32):set(f3, 33):build() - local e3b = evo.builder():set(f1, 31):set(f2, 32):set(f3, 33):build() - - local e4a = evo.builder():set(f1, 41):set(f2, 42):set(f3, 43):set(f4, 44):build() - local e4b = evo.builder():set(f1, 41):set(f2, 42):set(f3, 43):set(f4, 44):build() - - do - local q = evo.builder():include(f1):build() - evo.batch_multi_set(q, {}) - end - - do - local q = evo.builder():include(f3):exclude(f4):build() - evo.batch_multi_set(q, { f3 }) - assert(evo.get(e1a, f1) == 11 and evo.get(e1a, f2) == nil and evo.get(e1a, f3) == nil) - assert(evo.get(e1b, f1) == 11 and evo.get(e1b, f2) == nil and evo.get(e1b, f3) == nil) - assert(evo.get(e2a, f1) == 21 and evo.get(e2a, f2) == 22 and evo.get(e2a, f3) == nil) - assert(evo.get(e2b, f1) == 21 and evo.get(e2b, f2) == 22 and evo.get(e2b, f3) == nil) - assert(evo.get(e3a, f1) == 31 and evo.get(e3a, f2) == 32 and evo.get(e3a, f3) == true) - assert(evo.get(e3b, f1) == 31 and evo.get(e3b, f2) == 32 and evo.get(e3b, f3) == true) - assert(evo.get(e4a, f1) == 41 and evo.get(e4a, f2) == 42 and evo.get(e4a, f3) == 43 and evo.get(e4a, f4) == nil) - assert(evo.get(e4b, f1) == 41 and evo.get(e4b, f2) == 42 and evo.get(e4b, f3) == 43 and evo.get(e4b, f4) == nil) - end - - do - local q = evo.builder():include(f3):exclude(f4):build() - evo.batch_multi_set(q, { f3 }, { 43, 44 }) - assert(evo.get(e1a, f1) == 11 and evo.get(e1a, f2) == nil and evo.get(e1a, f3) == nil) - assert(evo.get(e1b, f1) == 11 and evo.get(e1b, f2) == nil and evo.get(e1b, f3) == nil) - assert(evo.get(e2a, f1) == 21 and evo.get(e2a, f2) == 22 and evo.get(e2a, f3) == nil) - assert(evo.get(e2b, f1) == 21 and evo.get(e2b, f2) == 22 and evo.get(e2b, f3) == nil) - assert(evo.get(e3a, f1) == 31 and evo.get(e3a, f2) == 32 and evo.get(e3a, f3) == 43) - assert(evo.get(e3b, f1) == 31 and evo.get(e3b, f2) == 32 and evo.get(e3b, f3) == 43) - assert(evo.get(e4a, f1) == 41 and evo.get(e4a, f2) == 42 and evo.get(e4a, f3) == 43 and evo.get(e4a, f4) == nil) - assert(evo.get(e4b, f1) == 41 and evo.get(e4b, f2) == 42 and evo.get(e4b, f3) == 43 and evo.get(e4b, f4) == nil) - end - - do - local q = evo.builder():include(f2):exclude(f3, f4):build() - evo.batch_multi_set(q, { f2 }, {}) - assert(evo.get(e1a, f1) == 11 and evo.get(e1a, f2) == nil and evo.get(e1a, f3) == nil) - assert(evo.get(e1b, f1) == 11 and evo.get(e1b, f2) == nil and evo.get(e1b, f3) == nil) - assert(evo.get(e2a, f1) == 21 and evo.get(e2a, f2) == 52 and evo.get(e2a, f3) == nil) - assert(evo.get(e2b, f1) == 21 and evo.get(e2b, f2) == 52 and evo.get(e2b, f3) == nil) - assert(evo.get(e3a, f1) == 31 and evo.get(e3a, f2) == 32 and evo.get(e3a, f3) == 43) - assert(evo.get(e3b, f1) == 31 and evo.get(e3b, f2) == 32 and evo.get(e3b, f3) == 43) - assert(evo.get(e4a, f1) == 41 and evo.get(e4a, f2) == 42 and evo.get(e4a, f3) == 43 and evo.get(e4a, f4) == nil) - assert(evo.get(e4b, f1) == 41 and evo.get(e4b, f2) == 42 and evo.get(e4b, f3) == 43 and evo.get(e4b, f4) == nil) - end - - do - local q = evo.builder():include(f2):exclude(f3, f4):build() - evo.batch_multi_set(q, { f2 }, { 62, 63 }) - assert(evo.get(e1a, f1) == 11 and evo.get(e1a, f2) == nil and evo.get(e1a, f3) == nil) - assert(evo.get(e1b, f1) == 11 and evo.get(e1b, f2) == nil and evo.get(e1b, f3) == nil) - assert(evo.get(e2a, f1) == 21 and evo.get(e2a, f2) == 62 and evo.get(e2a, f3) == nil) - assert(evo.get(e2b, f1) == 21 and evo.get(e2b, f2) == 62 and evo.get(e2b, f3) == nil) - assert(evo.get(e3a, f1) == 31 and evo.get(e3a, f2) == 32 and evo.get(e3a, f3) == 43) - assert(evo.get(e3b, f1) == 31 and evo.get(e3b, f2) == 32 and evo.get(e3b, f3) == 43) - assert(evo.get(e4a, f1) == 41 and evo.get(e4a, f2) == 42 and evo.get(e4a, f3) == 43 and evo.get(e4a, f4) == nil) - assert(evo.get(e4b, f1) == 41 and evo.get(e4b, f2) == 42 and evo.get(e4b, f3) == 43 and evo.get(e4b, f4) == nil) - end -end - -do - local fc = evo.id() - evo.set(fc, evo.TAG) - - local f1, f2, f3, f4 = evo.id(4) - - evo.set(f2, evo.DEFAULT, 52) - evo.set(f4, evo.TAG) - - evo.set(f1, fc) - evo.set(f2, fc) - evo.set(f3, fc) - evo.set(f4, fc) - - local sum_entity = 0 - local last_assign_entity = 0 - local last_assign_component = 0 - - do - local q = evo.builder():include(fc):build() - evo.batch_set(q, evo.ON_ASSIGN, function(e, f, c) - assert(f == f1 or f == f2 or f == f3 or f == f4) - sum_entity = sum_entity + e - last_assign_entity = e - last_assign_component = c - end) - end - - local e2a = evo.builder():set(f1, 21):set(f2, 22):build() - local e2b = evo.builder():set(f1, 21):set(f2, 22):build() - - local e3a = evo.builder():set(f1, 31):set(f2, 32):set(f3, 33):build() - local e3b = evo.builder():set(f1, 31):set(f2, 32):set(f3, 33):build() - - local e4a = evo.builder():set(f1, 41):set(f2, 42):set(f3, 43):set(f4, 44):build() - local e4b = evo.builder():set(f1, 41):set(f2, 42):set(f3, 43):set(f4, 44):build() - - do - local q = evo.builder():include(f1):build() - evo.batch_multi_set(q, {}) - end - - do - local q = evo.builder():include(f2):exclude(f3, f4):build() - - sum_entity = 0 - last_assign_entity = 0 - last_assign_component = 0 - - evo.batch_multi_set(q, { f2 }) - assert(sum_entity == e2a + e2b) - assert(last_assign_entity == e2b) - assert(last_assign_component == 52) - assert(evo.get(e2a, f2) == 52 and evo.get(e2b, f2) == 52) - - sum_entity = 0 - last_assign_entity = 0 - last_assign_component = 0 - - evo.batch_multi_set(q, { f2, f2 }) - assert(sum_entity == e2a + e2b + e2a + e2b) - assert(last_assign_entity == e2b) - assert(last_assign_component == 52) - assert(evo.get(e2a, f2) == 52 and evo.get(e2b, f2) == 52) - end - - do - local q = evo.builder():include(f2):exclude(f3, f4):build() - - sum_entity = 0 - last_assign_entity = 0 - last_assign_component = 0 - - evo.batch_multi_set(q, { f2 }, { 62, 63 }) - assert(sum_entity == e2a + e2b) - assert(last_assign_entity == e2b) - assert(last_assign_component == 62) - assert(evo.get(e2a, f2) == 62 and evo.get(e2b, f2) == 62) - - sum_entity = 0 - last_assign_entity = 0 - last_assign_component = 0 - - evo.batch_multi_set(q, { f2, f2 }, { 62, 63 }) - assert(sum_entity == e2a + e2b + e2a + e2b) - assert(last_assign_entity == e2b) - assert(last_assign_component == 63) - assert(evo.get(e2a, f2) == 63 and evo.get(e2b, f2) == 63) - end - - do - local q = evo.builder():include(f3):exclude(f4):build() - - sum_entity = 0 - last_assign_entity = 0 - last_assign_component = 0 - - evo.batch_multi_set(q, { f3 }) - assert(sum_entity == e3a + e3b) - assert(last_assign_entity == e3b) - assert(last_assign_component == true) - assert(evo.get(e3a, f3) == true and evo.get(e3b, f3) == true) - end - - do - local q = evo.builder():include(f4):build() - - sum_entity = 0 - last_assign_entity = 0 - last_assign_component = 0 - - evo.batch_multi_set(q, { f4 }, { 62, 63 }) - assert(sum_entity == e4a + e4b) - assert(last_assign_entity == e4b) - assert(last_assign_component == nil) - assert(evo.has(e4a, f4) and evo.has(e4b, f4)) - assert(evo.get(e4a, f4) == nil and evo.get(e4b, f4) == nil) - - sum_entity = 0 - last_assign_entity = 0 - last_assign_component = 0 - - evo.batch_multi_set(q, { f4, f4 }, { 62, 63 }) - assert(sum_entity == e4a + e4b + e4a + e4b) - assert(last_assign_entity == e4b) - assert(last_assign_component == nil) - assert(evo.get(e2a, f4) == nil and evo.get(e2b, f4) == nil) - end -end - -do - local f1, f2, f3, f4 = evo.id(4) - - evo.set(f2, evo.DEFAULT, 52) - evo.set(f4, evo.TAG) - - local e1a = evo.builder():set(f1, 11):build() - local e1b = evo.builder():set(f1, 11):build() - - local e2a = evo.builder():set(f1, 21):set(f2, 22):build() - local e2b = evo.builder():set(f1, 21):set(f2, 22):build() - - local e3a = evo.builder():set(f1, 31):set(f2, 32):set(f3, 33):build() - local e3b = evo.builder():set(f1, 31):set(f2, 32):set(f3, 33):build() - - do - local q = evo.builder():include(f2):exclude(f3, f4):build() - evo.batch_multi_set(q, { f3 }) - assert(evo.get(e2a, f1) == 21 and evo.get(e2a, f2) == 22 and evo.get(e2a, f3) == true) - assert(evo.get(e2b, f1) == 21 and evo.get(e2b, f2) == 22 and evo.get(e2b, f3) == true) - assert(evo.get(e3a, f1) == 31 and evo.get(e3a, f2) == 32 and evo.get(e3a, f3) == 33) - assert(evo.get(e3b, f1) == 31 and evo.get(e3b, f2) == 32 and evo.get(e3b, f3) == 33) - do - local c12, c12_es = evo.chunk(f1, f2) - assert(c12 and #c12_es == 0) - assert(#evo.components(c12, f1) == 0) - assert(#evo.components(c12, f2) == 0) - - local c123, c123_es = evo.chunk(f1, f2, f3) - assert(c123 and #c123_es == 4) - assert(#evo.components(c123, f1) == 4) - assert(#evo.components(c123, f2) == 4) - assert(#evo.components(c123, f3) == 4) - end - end - - do - local q = evo.builder():include(f2, f3):exclude(f4):build() - evo.batch_multi_set(q, { f2, f3, f4, f4 }, { 62, 63, 64, 65 }) - assert(evo.has_all(e2a, f2, f3, f4) and evo.has_all(e2b, f2, f3, f4)) - assert(evo.get(e2a, f1) == 21 and evo.get(e2a, f2) == 62 and evo.get(e2a, f3) == 63 and evo.get(e2a, f4) == nil) - assert(evo.get(e2b, f1) == 21 and evo.get(e2b, f2) == 62 and evo.get(e2b, f3) == 63 and evo.get(e2b, f4) == nil) - assert(evo.get(e3a, f1) == 31 and evo.get(e3a, f2) == 62 and evo.get(e3a, f3) == 63 and evo.get(e3a, f4) == nil) - assert(evo.get(e3b, f1) == 31 and evo.get(e3b, f2) == 62 and evo.get(e3b, f3) == 63 and evo.get(e3b, f4) == nil) - end - - do - local q = evo.builder():include(f1):exclude(f2, f3, f4):build() - evo.batch_multi_set(q, { f2, f1 }, { nil, 71 }) - assert(evo.get(e1a, f1) == 71 and evo.get(e1a, f2) == 52) - assert(evo.get(e1b, f1) == 71 and evo.get(e1b, f2) == 52) - do - local c1, c1_es = evo.chunk(f1) - assert(c1 and #c1_es == 0) - assert(#evo.components(c1, f1) == 0) - - local c12, c12_es = evo.chunk(f1, f2) - assert(c12 and #c12_es == 2) - assert(#evo.components(c12, f1) == 2) - assert(#evo.components(c12, f2) == 2) - end - end -end - -do - local fc = evo.id() - evo.set(fc, evo.TAG) - - local f0, f1, f2, f3, f4 = evo.id(5) - - evo.set(f2, evo.DEFAULT, 52) - evo.set(f1, evo.TAG) - - evo.set(f0, fc) - evo.set(f1, fc) - evo.set(f2, fc) - evo.set(f3, fc) - evo.set(f4, fc) - - local sum_entity = 0 - local last_assign_entity = 0 - local last_assign_component = 0 - local last_insert_entity = 0 - local last_insert_component = 0 - - do - local q = evo.builder():include(fc):build() - evo.batch_set(q, evo.ON_ASSIGN, function(e, f, c) - assert(f == f0 or f == f1 or f == f2 or f == f3 or f == f4) - sum_entity = sum_entity + e - last_assign_entity = e - last_assign_component = c - end) - evo.batch_set(q, evo.ON_INSERT, function(e, f, c) - assert(f == f0 or f == f1 or f == f2 or f == f3 or f == f4) - sum_entity = sum_entity + e - last_insert_entity = e - last_insert_component = c - end) - end - - local e0a = evo.builder():set(f0, 0):build() - local e0b = evo.builder():set(f0, 0):build() - - local e3a = evo.builder():set(f1, 31):set(f2, 32):set(f3, 33):build() - local e3b = evo.builder():set(f1, 31):set(f2, 32):set(f3, 33):build() - - do - local q = evo.builder():include(f0):build() - - sum_entity = 0 - last_assign_entity, last_assign_component = 0, 0 - last_insert_entity, last_insert_component = 0, 0 - - evo.batch_multi_set(q, { f1, f2 }, { 51 }) - assert(sum_entity == e0a + e0b + e0a + e0b) - assert(last_assign_entity == 0) - assert(last_assign_component == 0) - assert(last_insert_entity == e0b) - assert(last_insert_component == 52) - assert(evo.get(e0a, f0) == 0 and evo.get(e0a, f1) == nil and evo.get(e0a, f2) == 52 and evo.get(e0a, f3) == nil) - assert(evo.get(e0b, f0) == 0 and evo.get(e0b, f1) == nil and evo.get(e0b, f2) == 52 and evo.get(e0b, f3) == nil) - - sum_entity = 0 - last_assign_entity, last_assign_component = 0, 0 - last_insert_entity, last_insert_component = 0, 0 - - evo.batch_multi_set(q, { f1, f3, f2 }, { 61 }) - assert(sum_entity == e0a + e0b + e0a + e0b + e0a + e0b) - assert(last_assign_entity == e0b) - assert(last_assign_component == 52) - assert(last_insert_entity == e0b) - assert(last_insert_component == true) - assert(evo.get(e0a, f0) == 0 and evo.get(e0a, f1) == nil and evo.get(e0a, f2) == 52 and evo.get(e0a, f3) == true) - assert(evo.get(e0b, f0) == 0 and evo.get(e0b, f1) == nil and evo.get(e0b, f2) == 52 and evo.get(e0b, f3) == true) - end - - do - local q = evo.builder():include(f3):exclude(f0, f4):build() - - sum_entity = 0 - last_assign_entity, last_assign_component = 0, 0 - last_insert_entity, last_insert_component = 0, 0 - - evo.batch_multi_set(q, { f3, f4 }, { 53, 54 }) - assert(sum_entity == e3a + e3b + e3a + e3b) - assert(last_assign_entity == e3b) - assert(last_assign_component == 53) - assert(last_insert_entity == e3b) - assert(last_insert_component == 54) - assert(evo.get(e3a, f1) == nil and evo.get(e3a, f2) == 32 and evo.get(e3a, f3) == 53 and evo.get(e3a, f4) == 54) - assert(evo.get(e3b, f1) == nil and evo.get(e3b, f2) == 32 and evo.get(e3b, f3) == 53 and evo.get(e3b, f4) == 54) - end -end - -do - local f1, f2, f3, f4 = evo.id(4) - - local e1 = evo.builder():set(f1, 11):build() - local e2 = evo.builder():set(f1, 21):set(f2, 22):build() - local e3 = evo.builder():set(f1, 31):set(f2, 32):set(f3, 33):build() - - assert(evo.defer()) - do - do - local q = evo.builder():include(f1):exclude(f2):build() - evo.batch_multi_set(q, { f2 }, { 42 }) - end - do - local q = evo.builder():include(f1, f3):build() - evo.batch_multi_set(q, { f3 }, { 43 }) - end - do - local q = evo.builder():include(f1):build() - assert(not evo.batch_multi_remove(q, { f1 })) - end - assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == nil and evo.get(e1, f3) == nil) - assert(evo.get(e2, f1) == 21 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil) - assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == 33) - end - assert(evo.commit()) - do - assert(evo.get(e1, f1) == nil and evo.get(e1, f2) == 42 and evo.get(e1, f3) == nil) - assert(evo.get(e2, f1) == nil and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil) - assert(evo.get(e3, f1) == nil and evo.get(e3, f2) == 32 and evo.get(e3, f3) == 43) - end - assert(evo.defer()) - do - local q = evo.builder():include(f2):build() - do - evo.batch_multi_set(q, { f3, f4 }, { 53, 54 }) - end - end - assert(evo.commit()) - do - assert(evo.get(e1, f1) == nil and evo.get(e1, f2) == 42 and evo.get(e1, f3) == 53 and evo.get(e1, f4) == 54) - assert(evo.get(e2, f1) == nil and evo.get(e2, f2) == 22 and evo.get(e2, f3) == 53 and evo.get(e2, f4) == 54) - assert(evo.get(e3, f1) == nil and evo.get(e3, f2) == 32 and evo.get(e3, f3) == 53 and evo.get(e3, f4) == 54) - end -end - -do - local f1, f2, f3, f4, f5 = evo.id(5) - local e = evo.builder():set(f1, 11):set(f2, 22):set(f3, 33):set(f4, 44):set(f5, 55):build() + local e = evo.builder():set(f1, 11):set(f2, 22):set(f3, 33):set(f4, 44):set(f5, 55):spawn() do local c1 = evo.get(e, f1) @@ -4764,13 +3055,13 @@ do evo.set(f2, evo.DEFAULT, 42) - local e1a = evo.builder():set(f1, 11):build() - local e1b = evo.builder():set(f1, 11):build() + local e1a = evo.builder():set(f1, 11):spawn() + local e1b = evo.builder():set(f1, 11):spawn() - local e2a = evo.builder():set(f1, 11):set(f2, 22):build() - local e2b = evo.builder():set(f1, 11):set(f2, 22):build() + local e2a = evo.builder():set(f1, 11):set(f2, 22):spawn() + local e2b = evo.builder():set(f1, 11):set(f2, 22):spawn() - local q = evo.builder():include(f1):build() + local q = evo.builder():include(f1):spawn() evo.set(q, evo.EXCLUDES, { f2 }) evo.batch_set(q, f2) @@ -4818,7 +3109,7 @@ do local last_insert_component = 0 do - local q = evo.builder():include(fc):build() + local q = evo.builder():include(fc):spawn() evo.batch_set(q, evo.ON_ASSIGN, function(e, f, c) assert(f == f1 or f == f2 or f == f3 or f == f4) sum_entity = sum_entity + e @@ -4833,14 +3124,14 @@ do end) end - local e1a = evo.builder():set(f1, 11):build() - local e1b = evo.builder():set(f1, 11):build() + local e1a = evo.builder():set(f1, 11):spawn() + local e1b = evo.builder():set(f1, 11):spawn() - local e2a = evo.builder():set(f1, 11):set(f2, 22):build() - local e2b = evo.builder():set(f1, 11):set(f2, 22):build() + local e2a = evo.builder():set(f1, 11):set(f2, 22):spawn() + local e2b = evo.builder():set(f1, 11):set(f2, 22):spawn() do - local q = evo.builder():include(f1):exclude(f2):build() + local q = evo.builder():include(f1):exclude(f2):spawn() sum_entity = 0 last_insert_entity = 0 @@ -4858,7 +3149,7 @@ do end do - local q = evo.builder():include(f2):build() + local q = evo.builder():include(f2):spawn() sum_entity = 0 last_insert_entity = 0 @@ -4874,7 +3165,7 @@ do end do - local q = evo.builder():include(f2):build() + local q = evo.builder():include(f2):spawn() sum_entity = 0 last_insert_entity = 0 @@ -4890,7 +3181,7 @@ do end do - local q = evo.builder():include(f3):build() + local q = evo.builder():include(f3):spawn() sum_entity = 0 last_assign_entity = 0 @@ -4912,53 +3203,6 @@ do end end -do - local f1, f2 = evo.id(2) - - do - local e = evo.id() - assert(evo.defer()) - do - local s = evo.multi_set(e, { f1 }, { 11 }) - assert(not s) - assert(not evo.has_any(e, f1)) - end - assert(evo.commit()) - do - assert(evo.has_all(e, f1)) - assert(evo.get(e, f1) == 11) - end - assert(evo.defer()) - do - local s = evo.multi_set(e, { f1, f2 }, { 21, 22 }) - assert(not s) - assert(not evo.has_any(e, f2)) - end - assert(evo.commit()) - do - assert(evo.has_all(e, f1, f2)) - assert(evo.get(e, f1) == 21 and evo.get(e, f2) == 22) - end - end -end - -do - local f1, f2 = evo.id(2) - - assert(evo.defer()) - local c2, c12 = evo.chunk(f2), evo.chunk(f2, f1) - local e2 = evo.spawn_at(c2, { f2 }, { 22 }) - local e12 = evo.spawn_at(c12, { f1, f2 }, { 11, 12 }) - assert(evo.is_alive(e2) and evo.is_empty(e2)) - assert(evo.is_alive(e12) and evo.is_empty(e12)) - assert(evo.commit()) - assert(evo.is_alive(e2) and not evo.is_empty(e2)) - assert(evo.is_alive(e12) and not evo.is_empty(e12)) - assert(evo.has(e2, f2) and evo.get(e2, f2) == 22) - assert(evo.has(e12, f1) and evo.get(e12, f1) == 11) - assert(evo.has(e12, f2) and evo.get(e12, f2) == 12) -end - do local id = evo.pack(7, 3) local index, version = evo.unpack(id) @@ -4977,29 +3221,6 @@ do assert(index == 0xFFFFF and version == 0xFFFFF) end -do - local f1, f2 = evo.id(2) - - local e = evo.id() - - evo.set(e, f1, 11) - evo.set(e, f1) - - evo.set(e, f2, 22) - evo.set(e, f2) - - assert(evo.get(e, f1) == true and evo.get(e, f2) == true) - - evo.destroy(e) - assert(not evo.has(e, f1) and not evo.has(e, f2)) - assert(not evo.has_all(e, f1, f2) and not evo.has_any(e, f1, f2)) - - evo.remove(e, f1) - evo.clear(e) - - evo.multi_remove(e, { f1 }) -end - do local f1 = evo.id(2) @@ -5014,120 +3235,28 @@ do evo.clear(e) end -do - local f1, f2, f3 = evo.id(3) - - evo.set(f2, evo.DEFAULT, 42) - evo.set(f3, evo.TAG) - - local last_assign_f2_new_component = 0 - local last_assign_f2_old_component = 0 - - local last_insert_f2_new_component = 0 - local last_insert_f3_new_component = 0 - - evo.set(f2, evo.ON_ASSIGN, function(_, f, nc, oc) - assert(f == f2) - last_assign_f2_new_component = nc - last_assign_f2_old_component = oc - end) - - evo.set(f2, evo.ON_INSERT, function(_, f, nc) - assert(f == f2) - last_insert_f2_new_component = nc - end) - - evo.set(f3, evo.ON_INSERT, function(_, f, nc) - assert(f == f3) - last_insert_f3_new_component = nc - end) - - do - local e = evo.id() - - evo.multi_set(e, { f1, f2, f3 }, { 11, 22 }) - assert(evo.has_all(e, f1, f2, f3)) - assert(evo.get(e, f1) == 11 and evo.get(e, f2) == 22 and evo.get(e, f3) == nil) - assert(last_assign_f2_new_component == 0 and last_assign_f2_old_component == 0) - - evo.multi_set(e, { f1, f2, f3, f3 }, {}) - assert(evo.has_all(e, f1, f2, f3)) - assert(evo.get(e, f1) == true and evo.get(e, f2) == 42 and evo.get(e, f3) == nil) - assert(last_assign_f2_new_component == 42 and last_assign_f2_old_component == 22) - assert(last_insert_f3_new_component == nil) - - evo.multi_set(e, { f1, f2, f3 }, { 11, 22, 33 }) - assert(evo.get(e, f1) == 11 and evo.get(e, f2) == 22 and evo.get(e, f3) == nil) - evo.multi_set(e, { f1, f2, f3 }, {}) - assert(evo.get(e, f1) == true and evo.get(e, f2) == 42 and evo.get(e, f3) == nil) - end - - do - local e = evo.id() - - evo.multi_set(e, { f1, f1, f3, f3 }, {}) - assert(evo.has_all(e, f1, f3)) - assert(evo.get(e, f1) == true and evo.get(e, f3) == nil) - end - - do - local e = evo.id() - - evo.multi_set(e, { f1, f1, f2, f2, f3 }, {}) - assert(evo.has_all(e, f1, f2, f3)) - assert(evo.get(e, f1) == true and evo.get(e, f2) == 42 and evo.get(e, f3) == nil) - end - - do - local e = evo.id() - - last_insert_f2_new_component = 0 - - evo.multi_set(e, { f2, f2 }, { nil, 22 }) - assert(evo.get(e, f2) == 22) - assert(last_insert_f2_new_component == 42) - end -end - -do - local f1, f2 = evo.id(2) - - evo.set(f1, evo.DEFAULT, 41) - - do - local e = evo.id() - - evo.multi_set(e, { f1, f2 }) - assert(evo.get(e, f1) == 41 and evo.get(e, f2) == true) - evo.multi_set(e, { f1, f2 }, { 11, 22 }) - assert(evo.get(e, f1) == 11 and evo.get(e, f2) == 22) - evo.multi_set(e, { f1, f2 }) - assert(evo.get(e, f1) == 41 and evo.get(e, f2) == true) - end -end - do local f1, f2, f3, f4, f5 = evo.id(5) - local e = evo.spawn_with({ f1, f2, f3, f4, f5 }, { 1, 2, 3, 4, 5 }) + 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) do - local c1, c2 = evo.components(c, f1, f2) + 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) end do - local c1, c2, c3 = evo.components(c, f1, f2, f3) + 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) end do - local c1, c2, c3, c4 = evo.components(c, f1, f2, f3, f4) + 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) @@ -5135,7 +3264,7 @@ do end do - local c1, c2, c3, c4, c5 = evo.components(c, f1, f2, f3, f4, f5) + 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) @@ -5230,29 +3359,6 @@ do assert(assign_count == 2 and insert_count == 2 and remove_count == 2) end - do - assign_count = 0 - insert_count = 0 - remove_count = 0 - - local e = evo.id() - - evo.multi_set(e, { f1 }, { 41 }) - assert(evo.get(e, f1) == 41) - assert(evo.get(e, f2) == 41) - assert(assign_count == 0 and insert_count == 2 and remove_count == 0) - - evo.multi_set(e, { f1 }, { 51 }) - assert(evo.get(e, f1) == 51) - assert(evo.get(e, f2) == 51) - assert(assign_count == 2 and insert_count == 2 and remove_count == 0) - - evo.multi_remove(e, { f1 }) - assert(evo.get(e, f1) == nil) - assert(evo.get(e, f2) == nil) - assert(assign_count == 2 and insert_count == 2 and remove_count == 2) - end - do assign_count = 0 insert_count = 0 @@ -5276,29 +3382,6 @@ do assert(assign_count == 2 and insert_count == 2 and remove_count == 2) end - do - assign_count = 0 - insert_count = 0 - remove_count = 0 - - local e = evo.id() - - evo.multi_set(e, { f1 }, { 41 }) - assert(evo.get(e, f1) == 41) - assert(evo.get(e, f2) == 41) - assert(assign_count == 0 and insert_count == 2 and remove_count == 0) - - evo.multi_set(e, { f1 }, { 51 }) - assert(evo.get(e, f1) == 51) - assert(evo.get(e, f2) == 51) - assert(assign_count == 2 and insert_count == 2 and remove_count == 0) - - evo.multi_remove(e, { f1 }) - assert(evo.get(e, f1) == nil) - assert(evo.get(e, f2) == nil) - assert(assign_count == 2 and insert_count == 2 and remove_count == 2) - end - do assign_count = 0 insert_count = 0 @@ -5386,72 +3469,11 @@ do assert(evo.get(e, f1) == nil) assert(evo.get(e, f2) == nil) end) - - do - assign_count = 0 - insert_count = 0 - remove_count = 0 - - local e = evo.id() - evo.multi_set(e, { f1, f2 }, { 41, 42 }) - - assert(assign_count == 0 and insert_count == 2 and remove_count == 0) - end - - do - assign_count = 0 - insert_count = 0 - remove_count = 0 - - local e = evo.id() - evo.multi_set(e, { f1, f2 }, { 41, 42 }) - - assert(assign_count == 0 and insert_count == 2 and remove_count == 0) - end - - do - assign_count = 0 - insert_count = 0 - remove_count = 0 - - local e = evo.id() - evo.multi_set(e, { f1, f2 }, { 41, 42 }) - evo.multi_set(e, { f1, f2 }, { 51, 52 }) - evo.multi_remove(e, { f1, f2 }) - - assert(assign_count == 2 and insert_count == 2 and remove_count == 2) - end - - do - assign_count = 0 - insert_count = 0 - remove_count = 0 - - local e = evo.id() - evo.multi_set(e, { f1, f2 }, { 41, 42 }) - evo.multi_set(e, { f1, f2 }, { 51, 52 }) - evo.clear(e) - - assert(assign_count == 2 and insert_count == 2 and remove_count == 2) - end - - do - assign_count = 0 - insert_count = 0 - remove_count = 0 - - local e = evo.id() - evo.multi_set(e, { f1, f2 }, { 41, 42 }) - evo.multi_set(e, { f1, f2 }, { 51, 52 }) - evo.destroy(e) - - assert(assign_count == 2 and insert_count == 2 and remove_count == 2) - end end do local f0, f1 = evo.id(2) - local q0 = evo.builder():include(f0):build() + local q0 = evo.builder():include(f0):spawn() local assign_count = 0 local insert_count = 0 @@ -5517,110 +3539,6 @@ do end end -do - local f0, f1, f2 = evo.id(3) - local q0 = evo.builder():include(f0):build() - - local assign_count = 0 - local insert_count = 0 - local remove_count = 0 - - local e1, e2 = evo.id(2) - - evo.set(f1, evo.ON_ASSIGN, function(e, f, c) - assign_count = assign_count + 1 - assert(e == e1 or e == e2) - assert(f == f1) - assert(c == 51) - assert(evo.get(e1, f1) == 51) - assert(evo.get(e2, f1) == 51) - assert(evo.get(e1, f2) == 52) - assert(evo.get(e2, f2) == 52) - end) - - evo.set(f2, evo.ON_ASSIGN, function(e, f, c) - assign_count = assign_count + 1 - assert(e == e1 or e == e2) - assert(f == f2) - assert(c == 52) - assert(evo.get(e1, f1) == 51) - assert(evo.get(e2, f1) == 51) - assert(evo.get(e1, f2) == 52) - assert(evo.get(e2, f2) == 52) - end) - - evo.set(f1, evo.ON_INSERT, function(e, f, c) - insert_count = insert_count + 1 - assert(e == e1 or e == e2) - assert(f == f1) - assert(c == 41) - assert(evo.get(e1, f1) == 41) - assert(evo.get(e2, f1) == 41) - assert(evo.get(e1, f2) == 42) - assert(evo.get(e2, f2) == 42) - end) - - evo.set(f2, evo.ON_INSERT, function(e, f, c) - insert_count = insert_count + 1 - assert(e == e1 or e == e2) - assert(f == f2) - assert(c == 42) - assert(evo.get(e1, f1) == 41) - assert(evo.get(e2, f1) == 41) - assert(evo.get(e1, f2) == 42) - assert(evo.get(e2, f2) == 42) - end) - - evo.set(f1, evo.ON_REMOVE, function(e, f, c) - remove_count = remove_count + 1 - assert(e == e1 or e == e2) - assert(f == f1) - assert(c == 51) - assert(evo.get(e1, f1) == nil) - assert(evo.get(e2, f1) == nil) - assert(evo.get(e1, f2) == nil) - assert(evo.get(e2, f2) == nil) - end) - - evo.set(f2, evo.ON_REMOVE, function(e, f, c) - remove_count = remove_count + 1 - assert(e == e1 or e == e2) - assert(f == f2) - assert(c == 52) - assert(evo.get(e1, f2) == nil) - assert(evo.get(e2, f2) == nil) - assert(evo.get(e1, f1) == nil) - assert(evo.get(e2, f1) == nil) - end) - - do - assign_count = 0 - insert_count = 0 - remove_count = 0 - - evo.set(e1, f0) - evo.set(e2, f0) - - evo.batch_multi_set(q0, { f1, f2 }, { 41, 42 }) - assert(assign_count == 0 and insert_count == 4 and remove_count == 0) - - evo.batch_multi_set(q0, { f1, f2 }, { 51, 52 }) - assert(assign_count == 4 and insert_count == 4 and remove_count == 0) - - evo.batch_multi_remove(q0, { f1, f2 }) - assert(assign_count == 4 and insert_count == 4 and remove_count == 4) - - evo.batch_multi_set(q0, { f1, f2 }, { 41, 42 }) - assert(assign_count == 4 and insert_count == 8 and remove_count == 4) - - evo.batch_multi_set(q0, { f1, f2 }, { 51, 52 }) - assert(assign_count == 8 and insert_count == 8 and remove_count == 4) - - evo.batch_multi_remove(q0, { f1, f2 }) - assert(assign_count == 8 and insert_count == 8 and remove_count == 8) - end -end - do local f1, f2, f3, f4, f5 = evo.id(5) @@ -5791,16 +3709,16 @@ end do local f1, f2 = evo.id(2) - local q1 = evo.builder():include(f1):build() + local q1 = evo.builder():include(f1):spawn() - local e1a = evo.builder():set(f1, 1):build() - local e1b = evo.builder():set(f1, 11):build() + local e1a = evo.builder():set(f1, 1):spawn() + local e1b = evo.builder():set(f1, 11):spawn() do local c1, c1_es = evo.chunk(f1) assert(c1 and c1_es and #c1_es == 2) assert(c1_es[1] == e1a and c1_es[2] == e1b) - assert(evo.components(c1, f1)[1] == 1 and evo.components(c1, f1)[2] == 11) + assert(c1:components(f1)[1] == 1 and c1:components(f1)[2] == 11) end evo.batch_set(q1, f2, 2) @@ -5812,18 +3730,18 @@ do local c12, c12_es = evo.chunk(f1, f2) assert(c12 and c12_es and #c12_es == 2) assert(c12_es[1] == e1a and c12_es[2] == e1b) - assert(evo.components(c12, f1)[1] == 1 and evo.components(c12, f1)[2] == 11) - assert(evo.components(c12, f2)[1] == 2 and evo.components(c12, f2)[2] == 2) + assert(c12:components(f1)[1] == 1 and c12:components(f1)[2] == 11) + assert(c12:components(f2)[1] == 2 and c12:components(f2)[2] == 2) end - local e1c = evo.builder():set(f1, 111):build() - local e1d = evo.builder():set(f1, 1111):build() + local e1c = evo.builder():set(f1, 111):spawn() + local e1d = evo.builder():set(f1, 1111):spawn() do local c1, c1_es = evo.chunk(f1) assert(c1 and c1_es and #c1_es == 2) assert(c1_es[1] == e1c and c1_es[2] == e1d) - assert(evo.components(c1, f1)[1] == 111 and evo.components(c1, f1)[2] == 1111) + assert(c1:components(f1)[1] == 111 and c1:components(f1)[2] == 1111) end evo.set(q1, evo.EXCLUDES, { f2 }) @@ -5837,28 +3755,28 @@ do 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(evo.components(c12, f1)[1] == 1 and evo.components(c12, f1)[2] == 11) - assert(evo.components(c12, f1)[3] == 111 and evo.components(c12, f1)[4] == 1111) - assert(evo.components(c12, f2)[1] == 2 and evo.components(c12, f2)[2] == 2) - assert(evo.components(c12, f2)[3] == 22 and evo.components(c12, f2)[4] == 22) + assert(c12:components(f1)[1] == 1 and c12:components(f1)[2] == 11) + assert(c12:components(f1)[3] == 111 and c12:components(f1)[4] == 1111) + assert(c12:components(f2)[1] == 2 and c12:components(f2)[2] == 2) + assert(c12:components(f2)[3] == 22 and c12:components(f2)[4] == 22) end end do local f1, f2, f3 = evo.id(3) - local q1 = evo.builder():include(f1):build() + local q1 = evo.builder():include(f1):spawn() - local e123a = evo.builder():set(f1, 1):set(f2, 2):set(f3, 3):build() - local e123b = evo.builder():set(f1, 11):set(f2, 22):set(f3, 33):build() + local e123a = evo.builder():set(f1, 1):set(f2, 2):set(f3, 3):spawn() + local e123b = evo.builder():set(f1, 11):set(f2, 22):set(f3, 33):spawn() do local c123, c123_es = evo.chunk(f1, f2, f3) assert(c123 and c123_es and #c123_es == 2) assert(c123_es[1] == e123a and c123_es[2] == e123b) - assert(evo.components(c123, f1)[1] == 1 and evo.components(c123, f1)[2] == 11) - assert(evo.components(c123, f2)[1] == 2 and evo.components(c123, f2)[2] == 22) - assert(evo.components(c123, f3)[1] == 3 and evo.components(c123, f3)[2] == 33) + assert(c123:components(f1)[1] == 1 and c123:components(f1)[2] == 11) + assert(c123:components(f2)[1] == 2 and c123:components(f2)[2] == 22) + assert(c123:components(f3)[1] == 3 and c123:components(f3)[2] == 33) end evo.batch_remove(q1, f2) @@ -5867,19 +3785,19 @@ do local c13, c13_es = evo.chunk(f3, f1) assert(c13 and c13_es and #c13_es == 2) assert(c13_es[1] == e123a and c13_es[2] == e123b) - assert(evo.components(c13, f1)[1] == 1 and evo.components(c13, f1)[2] == 11) - assert(evo.components(c13, f2)[1] == nil and evo.components(c13, f2)[2] == nil) - assert(evo.components(c13, f3)[1] == 3 and evo.components(c13, f3)[2] == 33) + assert(c13:components(f1)[1] == 1 and c13:components(f1)[2] == 11) + assert(c13:components(f2)[1] == nil and c13:components(f2)[2] == nil) + assert(c13:components(f3)[1] == 3 and c13:components(f3)[2] == 33) end - local e3a = evo.builder():set(f3, 3):build() - local e3b = evo.builder():set(f3, 33):build() + local e3a = evo.builder():set(f3, 3):spawn() + local e3b = evo.builder():set(f3, 33):spawn() do local c3, c3_es = evo.chunk(f3) assert(c3 and c3_es and #c3_es == 2) assert(c3_es[1] == e3a and c3_es[2] == e3b) - assert(evo.components(c3, f3)[1] == 3 and evo.components(c3, f3)[2] == 33) + assert(c3:components(f3)[1] == 3 and c3:components(f3)[2] == 33) end evo.batch_remove(q1, f1) @@ -5889,39 +3807,22 @@ do 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(evo.components(c3, f1)[1] == nil and evo.components(c3, f1)[2] == nil) - assert(evo.components(c3, f1)[3] == nil and evo.components(c3, f1)[4] == nil) - assert(evo.components(c3, f2)[1] == nil and evo.components(c3, f2)[2] == nil) - assert(evo.components(c3, f2)[3] == nil and evo.components(c3, f2)[4] == nil) - assert(evo.components(c3, f3)[1] == 3 and evo.components(c3, f3)[2] == 33) - assert(evo.components(c3, f3)[3] == 3 and evo.components(c3, f3)[4] == 33) - end -end - -do - do - local f = evo.builder():default():build() - assert(evo.has(f, evo.DEFAULT)) - end - - do - local f = evo.builder():single():build() - assert(evo.has(f, f)) - end - - do - local f = evo.builder():single(42):build() - assert(evo.has(f, f) and evo.get(f, f) == 42) + assert(c3:components(f1)[1] == nil and c3:components(f1)[2] == nil) + assert(c3:components(f1)[3] == nil and c3:components(f1)[4] == nil) + assert(c3:components(f2)[1] == nil and c3:components(f2)[2] == nil) + assert(c3:components(f2)[3] == nil and c3:components(f2)[4] == nil) + assert(c3:components(f3)[1] == 3 and c3:components(f3)[2] == 33) + assert(c3:components(f3)[3] == 3 and c3:components(f3)[4] == 33) end end do local f1, f2 = evo.id(2) - local e1a = evo.builder():set(f1, 1):build() - local e1b = evo.builder():set(f1, 2):build() + local e1a = evo.builder():set(f1, 1):spawn() + local e1b = evo.builder():set(f1, 2):spawn() - local e12 = evo.builder():set(f1, 3):set(f2, 4):build() + local e12 = evo.builder():set(f1, 3):set(f2, 4):spawn() do local c1, c1_es, c1_ec = evo.chunk(f1) @@ -5937,13 +3838,13 @@ do end do - local f = evo.builder():build() + local f = evo.builder():spawn() assert(evo.get(f, evo.NAME) == nil) - local q = evo.builder():build() + local q = evo.builder():spawn() assert(evo.get(q, evo.NAME) == nil) - local s = evo.builder():build() + local s = evo.builder():spawn() assert(evo.get(s, evo.NAME) == nil) end @@ -5953,56 +3854,28 @@ do local sb = evo.builder() do - local f = fb:name('fragment'):build() + local f = fb:name('fragment'):spawn() assert(evo.get(f, evo.NAME) == 'fragment') - local q = qb:name('query'):build() + local q = qb:name('query'):spawn() assert(evo.get(q, evo.NAME) == 'query') - local s = sb:name('system'):build() + local s = sb:name('system'):spawn() assert(evo.get(s, evo.NAME) == 'system') end do - local f = fb:build() + local f = fb:clear():spawn() assert(evo.get(f, evo.NAME) == nil) - local q = qb:build() + local q = qb:clear():spawn() assert(evo.get(q, evo.NAME) == nil) - local s = sb:build() + local s = sb:clear():spawn() assert(evo.get(s, evo.NAME) == nil) end end -do - local fb = evo.builder() - local qb = evo.builder() - local sb = evo.builder() - - do - local f = fb:single(false):build() - assert(evo.get(f, f) == false) - - local q = qb:single(false):build() - assert(evo.get(q, q) == false) - - local s = sb:single(false):build() - assert(evo.get(s, s) == false) - end - - do - local f = fb:build() - assert(evo.get(f, f) == nil) - - local q = qb:build() - assert(evo.get(q, q) == nil) - - local s = sb:build() - assert(evo.get(s, s) == nil) - end -end - do local f1, f2 = evo.id(2) @@ -6010,21 +3883,21 @@ do local c2 = assert(evo.chunk(f2)) local c12 = assert(evo.chunk(f1, f2)) - local e1a = evo.builder():set(f1, 1):build() - local e1b = evo.builder():set(f1, 2):build() + local e1a = evo.builder():set(f1, 1):spawn() + local e1b = evo.builder():set(f1, 2):spawn() - local e12a = evo.builder():set(f1, 3):set(f2, 4):build() - local e12b = evo.builder():set(f1, 5):set(f2, 6):build() + local e12a = evo.builder():set(f1, 3):set(f2, 4):spawn() + local e12b = evo.builder():set(f1, 5):set(f2, 6):spawn() do - local c1_es, c1_ec = evo.entities(c1) + local c1_es, c1_ec = c1:entities() 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 = evo.entities(c2) + local c2_es, c2_ec = c2:entities() assert(c2_es and #c2_es == 0 and c2_ec == 0) - local c12_es, c12_ec = evo.entities(c12) + local c12_es, c12_ec = c12:entities() assert(c12_es and #c12_es == 2 and c12_ec == 2) assert(c12_es[1] == e12a and c12_es[2] == e12b) end @@ -6035,14 +3908,14 @@ do evo.set(e1b, f2, 8) do - local c1_es, c1_ec = evo.entities(c1) + local c1_es, c1_ec = c1:entities() assert(c1_es and #c1_es == 0 and c1_ec == 0) - local c2_es, c2_ec = evo.entities(c2) + local c2_es, c2_ec = c2:entities() 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 = evo.entities(c12) + local c12_es, c12_ec = c12:entities() assert(c12_es and #c12_es == 2 and c12_ec == 2) assert(c12_es[1] == e1a and c12_es[2] == e1b) end @@ -6054,11 +3927,11 @@ do evo.set(f2, f1) evo.destroy(f1) do - assert(not evo.is_alive(f1)) - assert(evo.is_alive(f2)) - assert(evo.is_empty(f2)) + assert(not evo.alive(f1)) + assert(evo.alive(f2)) + assert(evo.empty(f2)) - local c1_es, c1_ec = evo.entities(c1) + local c1_es, c1_ec = c1:entities() assert(c1_es and #c1_es == 0 and c1_ec == 0) end end @@ -6069,7 +3942,7 @@ do evo.set(f1, f1) evo.destroy(f1) do - local c1_es, c1_ec = evo.entities(c1) + local c1_es, c1_ec = c1:entities() assert(c1_es and #c1_es == 0 and c1_ec == 0) end end @@ -6084,26 +3957,26 @@ do evo.set(f2, f1) evo.set(f2, f2) do - local c1_es, c1_ec = evo.entities(c1) + local c1_es, c1_ec = c1:entities() assert(c1_es and #c1_es == 0 and c1_ec == 0) - local c2_es, c2_ec = evo.entities(c2) + local c2_es, c2_ec = c2:entities() assert(c2_es and #c2_es == 0 and c2_ec == 0) - local c12_es, c12_ec = evo.entities(c12) + local c12_es, c12_ec = c12:entities() 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 = evo.entities(c1) + local c1_es, c1_ec = c1:entities() assert(c1_es and #c1_es == 0 and c1_ec == 0) - local c2_es, c2_ec = evo.entities(c2) + local c2_es, c2_ec = c2:entities() assert(c2_es and #c2_es == 1 and c2_ec == 1) assert(c2_es[1] == f2) - local c12_es, c12_ec = evo.entities(c12) + local c12_es, c12_ec = c12:entities() assert(c12_es and #c12_es == 0 and c12_ec == 0) end end @@ -6118,25 +3991,25 @@ do evo.set(f2, f1) evo.set(f2, f2) do - local c1_es, c1_ec = evo.entities(c1) + local c1_es, c1_ec = c1:entities() assert(c1_es and #c1_es == 0 and c1_ec == 0) - local c2_es, c2_ec = evo.entities(c2) + local c2_es, c2_ec = c2:entities() assert(c2_es and #c2_es == 0 and c2_ec == 0) - local c12_es, c12_ec = evo.entities(c12) + local c12_es, c12_ec = c12:entities() 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 = evo.entities(c1) + local c1_es, c1_ec = c1:entities() assert(c1_es and #c1_es == 0 and c1_ec == 0) - local c2_es, c2_ec = evo.entities(c2) + local c2_es, c2_ec = c2:entities() assert(c2_es and #c2_es == 0 and c2_ec == 0) - local c12_es, c12_ec = evo.entities(c12) + local c12_es, c12_ec = c12:entities() assert(c12_es and #c12_es == 0 and c12_ec == 0) end end @@ -6148,20 +4021,20 @@ do evo.set(f2, f1) evo.set(f3, f2) do - local c1_es, c1_ec = evo.entities(c1) + local c1_es, c1_ec = c1:entities() assert(c1_es and #c1_es == 1 and c1_ec == 1) assert(c1_es[1] == f2) - local c2_es, c2_ec = evo.entities(c2) + local c2_es, c2_ec = c2:entities() 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 = evo.entities(c1) + local c1_es, c1_ec = c1:entities() assert(c1_es and #c1_es == 0 and c1_ec == 0) - local c2_es, c2_ec = evo.entities(c2) + local c2_es, c2_ec = c2:entities() assert(c2_es and #c2_es == 1 and c2_ec == 1) assert(c2_es[1] == f3) end @@ -6175,20 +4048,20 @@ do evo.set(f2, f1) evo.set(f3, f2) do - local c1_es, c1_ec = evo.entities(c1) + local c1_es, c1_ec = c1:entities() assert(c1_es and #c1_es == 1 and c1_ec == 1) assert(c1_es[1] == f2) - local c2_es, c2_ec = evo.entities(c2) + local c2_es, c2_ec = c2:entities() 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 = evo.entities(c1) + local c1_es, c1_ec = c1:entities() assert(c1_es and #c1_es == 0 and c1_ec == 0) - local c2_es, c2_ec = evo.entities(c2) + local c2_es, c2_ec = c2:entities() assert(c2_es and #c2_es == 1 and c2_ec == 1) assert(c2_es[1] == f3) end @@ -6202,20 +4075,20 @@ do evo.set(f2, f1) evo.set(f3, f2) do - local c1_es, c1_ec = evo.entities(c1) + local c1_es, c1_ec = c1:entities() assert(c1_es and #c1_es == 1 and c1_ec == 1) assert(c1_es[1] == f2) - local c2_es, c2_ec = evo.entities(c2) + local c2_es, c2_ec = c2:entities() 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 = evo.entities(c1) + local c1_es, c1_ec = c1:entities() assert(c1_es and #c1_es == 0 and c1_ec == 0) - local c2_es, c2_ec = evo.entities(c2) + local c2_es, c2_ec = c2:entities() assert(c2_es and #c2_es == 0 and c2_ec == 0) end end @@ -6226,7 +4099,7 @@ do evo.set(f2, ft) evo.set(f3, ft) evo.set(f3, evo.DESTROY_POLICY, evo.DESTROY_POLICY_DESTROY_ENTITY) - local qt = evo.builder():include(ft):build() + local qt = evo.builder():include(ft):spawn() local c4 = assert(evo.chunk(f4)) local c14 = assert(evo.chunk(f1, f4)) @@ -6234,28 +4107,28 @@ do local c234 = assert(evo.chunk(f2, f3, f4)) local c124 = assert(evo.chunk(f1, f2, f4)) - local e14 = evo.builder():set(f1, 1):set(f4, 2):build() - local e24 = evo.builder():set(f2, 3):set(f4, 4):build() - local e234 = evo.builder():set(f2, 5):set(f3, 6):set(f4, 7):build() - local e124 = evo.builder():set(f1, 8):set(f2, 6):set(f4, 9):build() + local e14 = evo.builder():set(f1, 1):set(f4, 2):spawn() + local e24 = evo.builder():set(f2, 3):set(f4, 4):spawn() + local e234 = evo.builder():set(f2, 5):set(f3, 6):set(f4, 7):spawn() + local e124 = evo.builder():set(f1, 8):set(f2, 6):set(f4, 9):spawn() evo.batch_destroy(qt) do - local c4_es, c4_ec = evo.entities(c4) + local c4_es, c4_ec = c4:entities() 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(#evo.entities(c14) == 0) - assert(#evo.entities(c24) == 0) - assert(#evo.entities(c124) == 0) - assert(#evo.entities(c234) == 0) + assert(#c14:entities() == 0) + assert(#c24:entities() == 0) + assert(#c124:entities() == 0) + assert(#c234:entities() == 0) - assert(evo.is_alive(e14) and not evo.is_empty(e14)) - assert(evo.is_alive(e24) and not evo.is_empty(e24)) - assert(not evo.is_alive(e234) and evo.is_empty(e234)) - assert(evo.is_alive(e124) and not evo.is_empty(e124)) + assert(evo.alive(e14) and not evo.empty(e14)) + assert(evo.alive(e24) and not evo.empty(e24)) + assert(not evo.alive(e234) and evo.empty(e234)) + assert(evo.alive(e124) and not evo.empty(e124)) end do @@ -6276,10 +4149,10 @@ do evo.destroy(f1) do - assert(not evo.is_alive(f1)) + assert(not evo.alive(f1)) assert(remove_count == 1) - local c1_es, c1_ec = evo.entities(c1) + local c1_es, c1_ec = c1:entities() assert(c1_es and #c1_es == 0 and c1_ec == 0) end end @@ -6302,10 +4175,10 @@ do evo.destroy(f1) do - assert(not evo.is_alive(f1)) + assert(not evo.alive(f1)) assert(remove_count == 1) - local c1_es, c1_ec = evo.entities(c1) + local c1_es, c1_ec = c1:entities() assert(c1_es and #c1_es == 0 and c1_ec == 0) end end @@ -6322,14 +4195,14 @@ do local c13 = evo.chunk(f1, f3) local c123 = evo.chunk(f1, f2, f3) - local e1a = evo.builder():set(f1, 1):build() - local e1b = evo.builder():set(f1, 2):build() + local e1a = evo.builder():set(f1, 1):spawn() + local e1b = evo.builder():set(f1, 2):spawn() - local e12a = evo.builder():set(f1, 3):set(f2, 4):build() - local e12b = evo.builder():set(f1, 5):set(f2, 6):build() + local e12a = evo.builder():set(f1, 3):set(f2, 4):spawn() + local e12b = evo.builder():set(f1, 5):set(f2, 6):spawn() - local e123a = evo.builder():set(f1, 7):set(f2, 8):set(f3, 9):build() - local e123b = evo.builder():set(f1, 10):set(f2, 11):set(f3, 12):build() + local e123a = evo.builder():set(f1, 7):set(f2, 8):set(f3, 9):spawn() + local e123b = evo.builder():set(f1, 10):set(f2, 11):set(f3, 12):spawn() evo.destroy(f2) @@ -6338,27 +4211,27 @@ do end do - local c1_es, c1_ec = evo.entities(c1) + 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_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 = evo.entities(c12) + local c12_es, c12_ec = c12:entities() assert(c12 and c12_es and c12_ec) assert(c12_ec == 0 and #c12_es == 0) end do - local c13_es, c13_ec = evo.entities(c13) + 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_es[1] == e123a and c13_es[2] == e123b) end do - local c123_es, c123_ec = evo.entities(c123) + local c123_es, c123_ec = c123:entities() assert(c123 and c123_es and c123_ec) assert(c123_ec == 0 and #c123_es == 0) end @@ -6371,8 +4244,8 @@ do evo.set(f2, f1) evo.set(f1, evo.DESTROY_POLICY, evo.DESTROY_POLICY_DESTROY_ENTITY) evo.destroy(f1) - assert(not evo.is_alive(f1)) - assert(not evo.is_alive(f2)) + assert(not evo.alive(f1)) + assert(not evo.alive(f2)) end do @@ -6381,8 +4254,8 @@ do evo.set(f2, f1) evo.set(f1, evo.DESTROY_POLICY, evo.DESTROY_POLICY_REMOVE_FRAGMENT) evo.destroy(f1) - assert(not evo.is_alive(f1)) - assert(evo.is_alive(f2) and evo.is_empty(f2)) + assert(not evo.alive(f1)) + assert(evo.alive(f2) and evo.empty(f2)) end end @@ -6391,22 +4264,22 @@ do evo.set(f1, evo.DESTROY_POLICY, evo.DESTROY_POLICY_DESTROY_ENTITY) - local e12a = evo.builder():set(f1, 1):set(f2, 2):build() - local e12b = evo.builder():set(f1, 3):set(f2, 4):build() - local e_e12a_e12b = evo.builder():set(e12a, 11):set(e12b, 22):build() + local e12a = evo.builder():set(f1, 1):set(f2, 2):spawn() + local e12b = evo.builder():set(f1, 3):set(f2, 4):spawn() + local e_e12a_e12b = evo.builder():set(e12a, 11):set(e12b, 22):spawn() - local e2a = evo.builder():set(f2, 5):build() - local e2b = evo.builder():set(f2, 6):build() - local e_e2a_e2b = evo.builder():set(e2a, 55):set(e2b, 66):build() + local e2a = evo.builder():set(f2, 5):spawn() + local e2b = evo.builder():set(f2, 6):spawn() + local e_e2a_e2b = evo.builder():set(e2a, 55):set(e2b, 66):spawn() evo.destroy(f1) do - assert(not evo.is_alive(e12a) and not evo.is_alive(e12b)) - assert(evo.is_alive(e_e12a_e12b) and evo.is_empty(e_e12a_e12b)) + assert(not evo.alive(e12a) and not evo.alive(e12b)) + assert(evo.alive(e_e12a_e12b) and evo.empty(e_e12a_e12b)) - assert(evo.is_alive(e2a) and evo.is_alive(e2b)) - assert(evo.is_alive(e_e2a_e2b) and not evo.is_empty(e_e2a_e2b)) + assert(evo.alive(e2a) and evo.alive(e2b)) + assert(evo.alive(e_e2a_e2b) and not evo.empty(e_e2a_e2b)) end do @@ -6423,34 +4296,23 @@ do evo.set(f1, evo.NAME, "f1") evo.set(f2, evo.NAME, "f2") - do - local c12 = evo.chunk(f1, f2) - - local f3 = evo.id() - evo.set(f3, evo.TAG) - local c123 = evo.chunk(f2, f1, f3) - evo.spawn_at(c123) - - assert(c12, c123) - end - evo.set(f1, evo.DESTROY_POLICY, evo.DESTROY_POLICY_REMOVE_FRAGMENT) - local e12a = evo.builder():set(f1, 1):set(f2, 2):build() - local e12b = evo.builder():set(f1, 3):set(f2, 4):build() - local e_e12a_e12b = evo.builder():set(e12a, 11):set(e12b, 22):build() + local e12a = evo.builder():set(f1, 1):set(f2, 2):spawn() + local e12b = evo.builder():set(f1, 3):set(f2, 4):spawn() + local e_e12a_e12b = evo.builder():set(e12a, 11):set(e12b, 22):spawn() - local e2a = evo.builder():set(f2, 5):build() - local e2b = evo.builder():set(f2, 6):build() - local e_e2a_e2b = evo.builder():set(e2a, 55):set(e2b, 66):build() + local e2a = evo.builder():set(f2, 5):spawn() + local e2b = evo.builder():set(f2, 6):spawn() + local e_e2a_e2b = evo.builder():set(e2a, 55):set(e2b, 66):spawn() evo.destroy(f1) do - assert(evo.is_alive(e12a) and evo.is_alive(e12b)) - assert(evo.is_alive(e_e12a_e12b) and not evo.is_empty(e_e12a_e12b)) - assert(evo.is_alive(e2a) and evo.is_alive(e2b)) - assert(evo.is_alive(e_e2a_e2b) and not evo.is_empty(e_e2a_e2b)) + assert(evo.alive(e12a) and evo.alive(e12b)) + assert(evo.alive(e_e12a_e12b) and not evo.empty(e_e12a_e12b)) + assert(evo.alive(e2a) and evo.alive(e2b)) + assert(evo.alive(e_e2a_e2b) and not evo.empty(e_e2a_e2b)) end do @@ -6464,9 +4326,9 @@ end do local fb = evo.builder() - local f1 = fb:build() - local f2 = fb:destroy_policy(evo.DESTROY_POLICY_DESTROY_ENTITY):build() - local f3 = fb:destroy_policy(evo.DESTROY_POLICY_REMOVE_FRAGMENT):build() + local f1 = fb:spawn() + local f2 = fb:destroy_policy(evo.DESTROY_POLICY_DESTROY_ENTITY):spawn() + local f3 = fb:destroy_policy(evo.DESTROY_POLICY_REMOVE_FRAGMENT):spawn() assert(evo.get(f1, evo.DESTROY_POLICY) == nil) assert(evo.get(f2, evo.DESTROY_POLICY) == evo.DESTROY_POLICY_DESTROY_ENTITY) @@ -6481,26 +4343,26 @@ do assert(c1 and c23) - assert(#evo.fragments(c1) == 1) - assert(evo.fragments(c1)[1] == f1) + assert(#c1:fragments() == 1) + assert(c1:fragments()[1] == f1) - assert(#evo.fragments(c23) == 2) - assert(evo.fragments(c23)[1] == f2) - assert(evo.fragments(c23)[2] == f3) + assert(#c23:fragments() == 2) + assert(c23:fragments()[1] == f2) + assert(c23:fragments()[2] == f3) end do local f0, f1, f2, f3 = evo.id(4) - local e1 = evo.builder():set(f0, 0):set(f1, 1):build() - local e12 = evo.builder():set(f0, 0):set(f1, 2):set(f2, 3):build() - local e123 = evo.builder():set(f0, 0):set(f1, 4):set(f2, 5):set(f3, 6):build() + local e1 = evo.builder():set(f0, 0):set(f1, 1):spawn() + local e12 = evo.builder():set(f0, 0):set(f1, 2):set(f2, 3):spawn() + local e123 = evo.builder():set(f0, 0):set(f1, 4):set(f2, 5):set(f3, 6):spawn() - evo.builder():set(f1, 41):build() - evo.builder():set(f1, 42):set(f2, 43):build() + evo.builder():set(f1, 41):spawn() + evo.builder():set(f1, 42):set(f2, 43):spawn() do - local q1 = evo.builder():include(f0, f1):build() + local q1 = evo.builder():include(f0, f1):spawn() local iter, state = evo.execute(q1) @@ -6521,7 +4383,7 @@ do end do - local q1 = evo.builder():include(f0, f1):exclude(f3):build() + local q1 = evo.builder():include(f0, f1):exclude(f3):spawn() local iter, state = evo.execute(q1) @@ -6540,7 +4402,7 @@ end do local f1, f2 = evo.id(2) - local q12 = evo.builder():include(f1, f2):build() + local q12 = evo.builder():include(f1, f2):spawn() do local iter, state = evo.execute(q12) @@ -6551,11 +4413,11 @@ end do local f1, f2 = evo.id(2) - local qe12 = evo.builder():exclude(f1, f2):build() + local qe12 = evo.builder():exclude(f1, f2):spawn() - evo.builder():set(f1, 1):build() - evo.builder():set(f2, 2):build() - local e12 = evo.builder():set(f1, 3):set(f2, 4):build() + evo.builder():set(f1, 1):spawn() + evo.builder():set(f2, 2):spawn() + local e12 = evo.builder():set(f1, 3):set(f2, 4):spawn() local c1 = evo.chunk(f1) local c2 = evo.chunk(f2) @@ -6615,17 +4477,17 @@ do local old_c1 = assert(evo.chunk(f1)) local old_c12 = assert(evo.chunk(f1, f2)) - local e1 = evo.builder():set(f1, 1):build() + local e1 = evo.builder():set(f1, 1):spawn() evo.collect_garbage() - local e12 = evo.builder():set(f1, 2):set(f2, 3):build() + local e12 = evo.builder():set(f1, 2):set(f2, 3):spawn() do - assert(evo.is_alive(old_c1)) + assert(old_c1:alive()) assert(old_c1 == evo.chunk(f1)) - local old_c1_es, old_c1_ec = evo.entities(old_c1) + 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] == e1) @@ -6634,10 +4496,10 @@ do do local new_c12 = assert(evo.chunk(f1, f2)) - assert(not evo.is_alive(old_c12)) + assert(not old_c12:alive()) assert(old_c12 ~= new_c12) - local new_c12_es, new_c12_ec = evo.entities(new_c12) + 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] == e12) @@ -6651,12 +4513,12 @@ do do local new_c1 = assert(evo.chunk(f1)) - assert(not evo.is_alive(old_c1)) + assert(not old_c1:alive()) assert(old_c1 ~= new_c1) local new_c12 = assert(evo.chunk(f1, f2)) - assert(not evo.is_alive(old_c12)) + assert(not old_c12:alive()) assert(old_c12 ~= new_c12) end end @@ -6669,12 +4531,12 @@ do evo.collect_garbage() - assert(evo.is_alive(old_c1)) + assert(old_c1:alive()) assert(old_c1 == evo.chunk(f1)) assert(evo.commit()) - assert(not evo.is_alive(old_c1)) + assert(not old_c1:alive()) assert(old_c1 ~= evo.chunk(f1)) end @@ -6688,8 +4550,8 @@ do evo.clear(e1, e2) - assert(evo.is_alive(e1) and evo.is_empty(e1)) - assert(evo.is_alive(e2) and evo.is_empty(e2)) + assert(evo.alive(e1) and evo.empty(e1)) + assert(evo.alive(e2) and evo.empty(e2)) end do @@ -6704,11 +4566,11 @@ do 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)) + assert(evo.alive(e1) and evo.empty(e1)) + assert(evo.alive(e2) and evo.empty(e2)) + assert(evo.alive(e3) and evo.empty(e3)) + assert(evo.alive(e4) and evo.empty(e4)) + assert(evo.alive(e5) and evo.empty(e5)) end end @@ -6724,15 +4586,15 @@ do assert(evo.defer()) do 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)) + assert(evo.alive(e1) and not evo.empty(e1)) + assert(evo.alive(e2) and not evo.empty(e2)) + assert(evo.alive(e3) and not evo.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)) + assert(evo.alive(e1) and evo.empty(e1)) + assert(evo.alive(e2) and evo.empty(e2)) + assert(evo.alive(e3) and evo.empty(e3)) end do @@ -6748,19 +4610,19 @@ do assert(evo.defer()) do 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)) + assert(evo.alive(e1) and not evo.empty(e1)) + assert(evo.alive(e2) and not evo.empty(e2)) + assert(evo.alive(e3) and not evo.empty(e3)) + assert(evo.alive(e4) and not evo.empty(e4)) + assert(evo.alive(e5) and not evo.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)) + assert(evo.alive(e1) and evo.empty(e1)) + assert(evo.alive(e2) and evo.empty(e2)) + assert(evo.alive(e3) and evo.empty(e3)) + assert(evo.alive(e4) and evo.empty(e4)) + assert(evo.alive(e5) and evo.empty(e5)) end end @@ -6774,8 +4636,8 @@ do 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)) + assert(not evo.alive(e1) and evo.empty(e1)) + assert(not evo.alive(e2) and evo.empty(e2)) end do @@ -6790,11 +4652,11 @@ do 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)) + assert(not evo.alive(e1) and evo.empty(e1)) + assert(not evo.alive(e2) and evo.empty(e2)) + assert(not evo.alive(e3) and evo.empty(e3)) + assert(not evo.alive(e4) and evo.empty(e4)) + assert(not evo.alive(e5) and evo.empty(e5)) end end @@ -6810,15 +4672,15 @@ do assert(evo.defer()) do 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)) + assert(evo.alive(e1) and not evo.empty(e1)) + assert(evo.alive(e2) and not evo.empty(e2)) + assert(evo.alive(e3) and not evo.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)) + assert(not evo.alive(e1) and evo.empty(e1)) + assert(not evo.alive(e2) and evo.empty(e2)) + assert(not evo.alive(e3) and evo.empty(e3)) end do @@ -6834,19 +4696,19 @@ do assert(evo.defer()) do 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)) + assert(evo.alive(e1) and not evo.empty(e1)) + assert(evo.alive(e2) and not evo.empty(e2)) + assert(evo.alive(e3) and not evo.empty(e3)) + assert(evo.alive(e4) and not evo.empty(e4)) + assert(evo.alive(e5) and not evo.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)) + assert(not evo.alive(e1) and evo.empty(e1)) + assert(not evo.alive(e2) and evo.empty(e2)) + assert(not evo.alive(e3) and evo.empty(e3)) + assert(not evo.alive(e4) and evo.empty(e4)) + assert(not evo.alive(e5) and evo.empty(e5)) end end @@ -6856,8 +4718,8 @@ do evo.set(e1, f1, f1) evo.set(e2, f1, f1) 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)) + assert(evo.alive(e1) and evo.empty(e1)) + assert(evo.alive(e2) and evo.empty(e2)) end do @@ -6866,8 +4728,8 @@ do evo.set(e1, f1, f1) evo.set(e2, f1, f1) 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)) + assert(not evo.alive(e1) and evo.empty(e1)) + assert(not evo.alive(e2) and evo.empty(e2)) end do @@ -6883,13 +4745,13 @@ do evo.batch_clear() - assert(evo.is_alive(e1) and not evo.is_empty(e1)) - assert(evo.is_alive(e2) and not evo.is_empty(e2)) + assert(evo.alive(e1) and not evo.empty(e1)) + assert(evo.alive(e2) and not evo.empty(e2)) evo.batch_clear(q1, q2, q1, q1) - assert(evo.is_alive(e1) and evo.is_empty(e1)) - assert(evo.is_alive(e2) and evo.is_empty(e2)) + assert(evo.alive(e1) and evo.empty(e1)) + assert(evo.alive(e2) and evo.empty(e2)) end do @@ -6906,13 +4768,13 @@ do assert(evo.defer()) do evo.batch_clear(q2, q1, q2, q2) - assert(evo.is_alive(e1) and not evo.is_empty(e1)) - assert(evo.is_alive(e2) and not evo.is_empty(e2)) + assert(evo.alive(e1) and not evo.empty(e1)) + assert(evo.alive(e2) and not evo.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)) + assert(evo.alive(e1) and evo.empty(e1)) + assert(evo.alive(e2) and evo.empty(e2)) end do @@ -6928,13 +4790,13 @@ do evo.batch_destroy() - assert(evo.is_alive(e1) and not evo.is_empty(e1)) - assert(evo.is_alive(e2) and not evo.is_empty(e2)) + assert(evo.alive(e1) and not evo.empty(e1)) + assert(evo.alive(e2) and not evo.empty(e2)) evo.batch_destroy(q1, q2, q1, q1) - 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.alive(e1) and evo.empty(e1)) + assert(not evo.alive(e2) and evo.empty(e2)) end do @@ -6951,125 +4813,125 @@ do assert(evo.defer()) do evo.batch_destroy(q2, q1, q2, q2) - assert(evo.is_alive(e1) and not evo.is_empty(e1)) - assert(evo.is_alive(e2) and not evo.is_empty(e2)) + assert(evo.alive(e1) and not evo.empty(e1)) + assert(evo.alive(e2) and not evo.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)) + assert(not evo.alive(e1) and evo.empty(e1)) + assert(not evo.alive(e2) and evo.empty(e2)) end do local a1, a2, a3, a4, a5 = evo.id(5) - assert(evo.is_alive(a1)) - assert(evo.is_alive_all()) - assert(evo.is_alive_all(a1)) - assert(evo.is_alive_all(a1, a2)) - assert(evo.is_alive_all(a1, a2, a3)) - assert(evo.is_alive_all(a1, a2, a3, a4)) - assert(evo.is_alive_all(a1, a2, a3, a4, a5)) + assert(evo.alive(a1)) + assert(evo.alive_all()) + assert(evo.alive_all(a1)) + assert(evo.alive_all(a1, a2)) + assert(evo.alive_all(a1, a2, a3)) + assert(evo.alive_all(a1, a2, a3, a4)) + assert(evo.alive_all(a1, a2, a3, a4, a5)) - assert(not evo.is_alive_any()) - assert(evo.is_alive_any(a1)) - assert(evo.is_alive_any(a1, a2)) - assert(evo.is_alive_any(a1, a2, a3)) - assert(evo.is_alive_any(a1, a2, a3, a4)) - assert(evo.is_alive_any(a1, a2, a3, a4, a5)) + assert(not evo.alive_any()) + assert(evo.alive_any(a1)) + assert(evo.alive_any(a1, a2)) + assert(evo.alive_any(a1, a2, a3)) + assert(evo.alive_any(a1, a2, a3, a4)) + assert(evo.alive_any(a1, a2, a3, a4, a5)) local d1, d2 = evo.id(2) evo.destroy(d1, d2) - assert(not evo.is_alive(d1)) - assert(not evo.is_alive_all(d1)) - assert(not evo.is_alive_all(d1, d2)) - assert(not evo.is_alive_all(d1, a1)) - assert(not evo.is_alive_all(a1, d1)) - assert(not evo.is_alive_all(d1, d2, a1)) - assert(not evo.is_alive_all(d1, a1, a2)) - assert(not evo.is_alive_all(d1, a1, a2, d2, a3)) - assert(not evo.is_alive_all(d1, a1, a2, d2, a3, d1)) + assert(not evo.alive(d1)) + assert(not evo.alive_all(d1)) + assert(not evo.alive_all(d1, d2)) + assert(not evo.alive_all(d1, a1)) + assert(not evo.alive_all(a1, d1)) + assert(not evo.alive_all(d1, d2, a1)) + assert(not evo.alive_all(d1, a1, a2)) + assert(not evo.alive_all(d1, a1, a2, d2, a3)) + assert(not evo.alive_all(d1, a1, a2, d2, a3, d1)) - assert(not evo.is_alive_any(d1)) - assert(not evo.is_alive_any(d1, d2)) - assert(evo.is_alive_any(d1, a1)) - assert(evo.is_alive_any(a1, d1)) - assert(evo.is_alive_any(d1, d2, a1)) - assert(evo.is_alive_any(d1, a1, a2)) - assert(evo.is_alive_any(d1, a1, a2, d2, a3)) - assert(evo.is_alive_any(d1, a1, a2, d2, a3, d1)) + assert(not evo.alive_any(d1)) + assert(not evo.alive_any(d1, d2)) + assert(evo.alive_any(d1, a1)) + assert(evo.alive_any(a1, d1)) + assert(evo.alive_any(d1, d2, a1)) + assert(evo.alive_any(d1, a1, a2)) + assert(evo.alive_any(d1, a1, a2, d2, a3)) + assert(evo.alive_any(d1, a1, a2, d2, a3, d1)) end do local e1, e2, e3, e4, e5 = evo.id(5) - assert(evo.is_empty(e1)) - assert(evo.is_empty_all()) - assert(evo.is_empty_all(e1)) - assert(evo.is_empty_all(e1, e2)) - assert(evo.is_empty_all(e1, e2, e3)) - assert(evo.is_empty_all(e1, e2, e3, e4)) - assert(evo.is_empty_all(e1, e2, e3, e4, e5)) + assert(evo.empty(e1)) + assert(evo.empty_all()) + assert(evo.empty_all(e1)) + assert(evo.empty_all(e1, e2)) + assert(evo.empty_all(e1, e2, e3)) + assert(evo.empty_all(e1, e2, e3, e4)) + assert(evo.empty_all(e1, e2, e3, e4, e5)) - assert(not evo.is_empty_any()) - assert(evo.is_empty_any(e1)) - assert(evo.is_empty_any(e1, e2)) - assert(evo.is_empty_any(e1, e2, e3)) - assert(evo.is_empty_any(e1, e2, e3, e4)) - assert(evo.is_empty_any(e1, e2, e3, e4, e5)) + assert(not evo.empty_any()) + assert(evo.empty_any(e1)) + assert(evo.empty_any(e1, e2)) + assert(evo.empty_any(e1, e2, e3)) + assert(evo.empty_any(e1, e2, e3, e4)) + assert(evo.empty_any(e1, e2, e3, e4, e5)) local d1, d2 = evo.id(2) evo.destroy(d1, d2) - assert(evo.is_empty(d1)) - assert(evo.is_empty_all(d1)) - assert(evo.is_empty_all(d1, d2)) - assert(evo.is_empty_all(d1, e1)) - assert(evo.is_empty_all(e1, d1)) - assert(evo.is_empty_all(d1, d2, e1)) - assert(evo.is_empty_all(d1, e1, e2)) - assert(evo.is_empty_all(d1, e1, e2, d2, e3)) - assert(evo.is_empty_all(d1, e1, e2, d2, e3, d1)) + assert(evo.empty(d1)) + assert(evo.empty_all(d1)) + assert(evo.empty_all(d1, d2)) + assert(evo.empty_all(d1, e1)) + assert(evo.empty_all(e1, d1)) + assert(evo.empty_all(d1, d2, e1)) + assert(evo.empty_all(d1, e1, e2)) + assert(evo.empty_all(d1, e1, e2, d2, e3)) + assert(evo.empty_all(d1, e1, e2, d2, e3, d1)) - assert(evo.is_empty_any(d1)) - assert(evo.is_empty_any(d1, d2)) - assert(evo.is_empty_any(d1, e1)) - assert(evo.is_empty_any(e1, d1)) - assert(evo.is_empty_any(d1, d2, e1)) - assert(evo.is_empty_any(d1, e1, e2)) - assert(evo.is_empty_any(d1, e1, e2, d2, e3)) - assert(evo.is_empty_any(d1, e1, e2, d2, e3, d1)) + assert(evo.empty_any(d1)) + assert(evo.empty_any(d1, d2)) + assert(evo.empty_any(d1, e1)) + assert(evo.empty_any(e1, d1)) + assert(evo.empty_any(d1, d2, e1)) + assert(evo.empty_any(d1, e1, e2)) + assert(evo.empty_any(d1, e1, e2, d2, e3)) + assert(evo.empty_any(d1, e1, e2, d2, e3, d1)) local f1, f2 = evo.id(2) evo.set(f1, f1) evo.set(f2, f2) - assert(not evo.is_empty(f1)) - assert(not evo.is_empty_all(f1)) - assert(not evo.is_empty_all(f1, f2)) - assert(not evo.is_empty_all(f1, e1)) - assert(not evo.is_empty_all(e1, f1)) - assert(not evo.is_empty_all(f1, f2, e1)) - assert(not evo.is_empty_all(f1, e1, e2)) - assert(not evo.is_empty_all(f1, e1, e2, f2, e3)) - assert(not evo.is_empty_all(f1, e1, e2, f2, e3, f1)) + assert(not evo.empty(f1)) + assert(not evo.empty_all(f1)) + assert(not evo.empty_all(f1, f2)) + assert(not evo.empty_all(f1, e1)) + assert(not evo.empty_all(e1, f1)) + assert(not evo.empty_all(f1, f2, e1)) + assert(not evo.empty_all(f1, e1, e2)) + assert(not evo.empty_all(f1, e1, e2, f2, e3)) + assert(not evo.empty_all(f1, e1, e2, f2, e3, f1)) - assert(not evo.is_empty_any(f1)) - assert(not evo.is_empty_any(f1, f2)) - assert(evo.is_empty_any(f1, e1)) - assert(evo.is_empty_any(e1, f1)) - assert(evo.is_empty_any(f1, f2, e1)) - assert(evo.is_empty_any(f1, e1, e2)) - assert(evo.is_empty_any(f1, e1, e2, f2, e3)) - assert(evo.is_empty_any(f1, e1, e2, f2, e3, f1)) + assert(not evo.empty_any(f1)) + assert(not evo.empty_any(f1, f2)) + assert(evo.empty_any(f1, e1)) + assert(evo.empty_any(e1, f1)) + assert(evo.empty_any(f1, f2, e1)) + assert(evo.empty_any(f1, e1, e2)) + assert(evo.empty_any(f1, e1, e2, f2, e3)) + assert(evo.empty_any(f1, e1, e2, f2, e3, f1)) end do local f1, f2, f3, f4, f5, f6 = evo.id(6) - local e2 = evo.spawn_with({ f1, f2 }) - local e5 = evo.spawn_with({ f1, f2, f3, f4, f5 }) + local e2 = evo.spawn({ [f1] = true, [f2] = true }) + local e5 = evo.spawn({ [f1] = 41, [f2] = 42, [f3] = 43, [f4] = 44, [f5] = 45 }) assert(evo.has_all(e2, f1)) assert(evo.has_all(e2, f1, f2)) @@ -7091,8 +4953,8 @@ end do local f1, f2, f3, f4, f5, f6, f7 = evo.id(7) - local e2 = evo.spawn_with({ f1, f2 }) - local e5 = evo.spawn_with({ f1, f2, f3, f4, f5 }) + local e2 = evo.spawn({ [f1] = true, [f2] = true }) + local e5 = evo.spawn({ [f1] = 41, [f2] = 42, [f3] = 43, [f4] = 44, [f5] = 45 }) assert(evo.has_all(e2)) assert(not evo.has_any(e2)) @@ -7123,899 +4985,446 @@ do assert(not evo.has_any(e5, f7, f7, f6)) end -do - local f1 = evo.id() - - local c1 = assert(evo.chunk(f1)) - assert(evo.is_alive(c1) and evo.is_empty(c1)) - - local e1 = evo.spawn_at(c1) - assert(evo.is_alive(c1) and not evo.is_empty(c1)) - - evo.destroy(e1) - assert(evo.is_alive(c1) and evo.is_empty(c1)) - - evo.collect_garbage() - assert(not evo.is_alive(c1) and evo.is_empty(c1)) -end - -do - local f1, f2 = evo.id(2) - - local c1 = assert(evo.chunk(f1)) - local c12 = assert(evo.chunk(f1, f2)) - - assert(evo.is_alive(c1)) - assert(evo.is_alive(c12)) - assert(evo.is_alive_all()) - assert(evo.is_alive_all(c1)) - assert(evo.is_alive_all(c1, c12)) - assert(not evo.is_alive_any()) - assert(evo.is_alive_any(c1)) - assert(evo.is_alive_any(c1, c12)) - - assert(evo.is_empty(c1)) - assert(evo.is_empty(c12)) - assert(evo.is_empty_all()) - assert(evo.is_empty_all(c1)) - assert(evo.is_empty_all(c1, c12)) - assert(not evo.is_empty_any()) - assert(evo.is_empty_any(c1)) - assert(evo.is_empty_any(c1, c12)) - - local e12 = evo.spawn_at(c12) - - assert(evo.is_alive(c1)) - assert(evo.is_alive(c12)) - assert(evo.is_alive_all()) - assert(evo.is_alive_all(c1)) - assert(evo.is_alive_all(c1, c12)) - assert(not evo.is_alive_any()) - assert(evo.is_alive_any(c1)) - assert(evo.is_alive_any(c1, c12)) - - assert(evo.is_empty(c1)) - assert(not evo.is_empty(c12)) - assert(evo.is_empty_all()) - assert(evo.is_empty_all(c1)) - assert(not evo.is_empty_all(c1, c12)) - assert(not evo.is_empty_any()) - assert(evo.is_empty_any(c1)) - assert(evo.is_empty_any(c1, c12)) - - evo.remove(e12, f2) - - assert(evo.is_alive(c1)) - assert(evo.is_alive(c12)) - assert(evo.is_alive_all()) - assert(evo.is_alive_all(c1)) - assert(evo.is_alive_all(c1, c12)) - assert(not evo.is_alive_any()) - assert(evo.is_alive_any(c1)) - assert(evo.is_alive_any(c1, c12)) - - assert(not evo.is_empty(c1)) - assert(evo.is_empty(c12)) - assert(evo.is_empty_all()) - assert(not evo.is_empty_all(c1)) - assert(not evo.is_empty_all(c1, c12)) - assert(not evo.is_empty_any()) - assert(not evo.is_empty_any(c1)) - assert(evo.is_empty_any(c1, c12)) - - evo.collect_garbage() - - assert(evo.is_alive(c1)) - assert(not evo.is_alive(c12)) - assert(evo.is_alive_all()) - assert(evo.is_alive_all(c1)) - assert(not evo.is_alive_all(c1, c12)) - assert(not evo.is_alive_any()) - assert(evo.is_alive_any(c1)) - assert(evo.is_alive_any(c1, c12)) - - assert(not evo.is_empty(c1)) - assert(evo.is_empty(c12)) - assert(evo.is_empty_all()) - assert(not evo.is_empty_all(c1)) - assert(not evo.is_empty_all(c1, c12)) - assert(not evo.is_empty_any()) - assert(not evo.is_empty_any(c1)) - assert(evo.is_empty_any(c1, c12)) - - evo.remove(e12, f1) - - assert(evo.is_alive(c1)) - assert(not evo.is_alive(c12)) - assert(evo.is_alive_all()) - assert(evo.is_alive_all(c1)) - assert(not evo.is_alive_all(c1, c12)) - assert(not evo.is_alive_any()) - assert(evo.is_alive_any(c1)) - assert(evo.is_alive_any(c1, c12)) - - assert(evo.is_empty(c1)) - assert(evo.is_empty(c12)) - assert(evo.is_empty_all()) - assert(evo.is_empty_all(c1)) - assert(evo.is_empty_all(c1, c12)) - assert(not evo.is_empty_any()) - assert(evo.is_empty_any(c1)) - assert(evo.is_empty_any(c1, c12)) - - evo.collect_garbage() - - assert(not evo.is_alive(c1)) - assert(not evo.is_alive(c12)) - assert(evo.is_alive_all()) - assert(not evo.is_alive_all(c1)) - assert(not evo.is_alive_all(c1, c12)) - assert(not evo.is_alive_any()) - assert(not evo.is_alive_any(c1)) - assert(not evo.is_alive_any(c1, c12)) - - assert(evo.is_empty(c1)) - assert(evo.is_empty(c12)) - assert(evo.is_empty_all()) - assert(evo.is_empty_all(c1)) - assert(evo.is_empty_all(c1, c12)) - assert(not evo.is_empty_any()) - assert(evo.is_empty_any(c1)) - assert(evo.is_empty_any(c1, c12)) -end - do local f1, f2 = evo.id(2) local c1 = assert(evo.chunk(f1)) local c12 = assert(evo.chunk(f1, f2)) - assert(evo.has(c1, f1)) - assert(not evo.has(c1, f2)) - assert(evo.has(c12, f1)) - assert(evo.has(c12, f2)) + assert(c1:has(f1)) + assert(not c1:has(f2)) + assert(c12:has(f1)) + assert(c12:has(f2)) - assert(evo.has_all(c1)) - assert(evo.has_all(c1, f1)) - assert(not evo.has_all(c1, f1, f2)) - assert(evo.has_all(c12)) - assert(evo.has_all(c12, f1)) - assert(evo.has_all(c12, f1, f2)) + assert(c1:has_all()) + assert(c1:has_all(f1)) + assert(not c1:has_all(f1, f2)) + assert(c12:has_all()) + assert(c12:has_all(f1)) + assert(c12:has_all(f1, f2)) - assert(not evo.has_any(c1)) - assert(evo.has_any(c1, f1)) - assert(evo.has_any(c1, f1, f2)) - assert(not evo.has_any(c12)) - assert(evo.has_any(c12, f1)) - assert(evo.has_any(c12, f1, f2)) + assert(not c1:has_any()) + assert(c1:has_any(f1)) + assert(c1:has_any(f1, f2)) + assert(not c12:has_any()) + assert(c12:has_any(f1)) + assert(c12:has_any(f1, f2)) evo.collect_garbage() - assert(not evo.is_alive_any(c1, c12)) + assert(not c1:alive()) + assert(not c12:alive()) - assert(evo.has(c1, f1)) - assert(not evo.has(c1, f2)) - assert(evo.has(c12, f1)) - assert(evo.has(c12, f2)) + assert(c1:has(f1)) + assert(not c1:has(f2)) + assert(c12:has(f1)) + assert(c12:has(f2)) - assert(evo.has_all(c1)) - assert(evo.has_all(c1, f1)) - assert(not evo.has_all(c1, f1, f2)) - assert(evo.has_all(c12)) - assert(evo.has_all(c12, f1)) - assert(evo.has_all(c12, f1, f2)) + assert(c1:has_all()) + assert(c1:has_all(f1)) + assert(not c1:has_all(f1, f2)) + assert(c12:has_all()) + assert(c12:has_all(f1)) + assert(c12:has_all(f1, f2)) - assert(not evo.has_any(c1)) - assert(evo.has_any(c1, f1)) - assert(evo.has_any(c1, f1, f2)) - assert(not evo.has_any(c12)) - assert(evo.has_any(c12, f1)) - assert(evo.has_any(c12, f1, f2)) + assert(not c1:has_any()) + assert(c1:has_any(f1)) + assert(c1:has_any(f1, f2)) + assert(not c12:has_any()) + assert(c12:has_any(f1)) + assert(c12:has_any(f1, f2)) end do local gb = evo.builder() - local g1 = gb:build() - local g2 = gb:name('g2'):build() - local g3 = gb:single(42):build() - local g4 = gb:name('g4'):single(43):build() + local g1 = gb:clear():spawn() + local g2 = gb:clear():name('g2'):spawn() assert(not evo.has(g1, evo.NAME) and not evo.has(g1, g1)) assert(evo.get(g2, evo.NAME) == 'g2' and not evo.has(g2, g2)) - assert(not evo.has(g3, evo.NAME) and evo.get(g3, g3) == 42) - assert(evo.get(g4, evo.NAME) == 'g4' and evo.get(g4, g4) == 43) end do - local g = evo.builder():build() - local s = evo.builder():group(g):build() + local g = evo.builder():spawn() + local s = evo.builder():group(g):spawn() assert(evo.get(s, evo.GROUP) == g) end -do - local f1 = evo.id() - local c1 = evo.chunk(f1) - - assert(evo.defer()) - evo.collect_garbage() - local e1 = evo.spawn_at(c1, { f1 }, { 42 }) - assert(evo.commit()) - - assert(evo.is_alive(c1)) - assert(evo.get(e1, f1) == 42) - - assert(evo.defer()) - evo.collect_garbage() - assert(evo.commit()) - - assert(evo.is_alive(c1)) - - evo.destroy(e1) - assert(not evo.is_alive(e1)) - - assert(evo.defer()) - evo.collect_garbage() - assert(evo.commit()) - - assert(not evo.is_alive(c1)) -end - -do - local f1 = evo.id() - local c1 = evo.chunk(f1) - - assert(evo.defer()) - evo.collect_garbage() - local e1 = evo.spawn_with({ f1 }, { 42 }) - assert(evo.commit()) - - assert(evo.is_alive(c1)) - assert(evo.get(e1, f1) == 42) - - assert(evo.defer()) - evo.collect_garbage() - assert(evo.commit()) - - assert(evo.is_alive(c1)) - - evo.destroy(e1) - assert(not evo.is_alive(e1)) - - assert(evo.defer()) - evo.collect_garbage() - assert(evo.commit()) - - assert(not evo.is_alive(c1)) -end - -do - local q1, q2, fq = evo.id(3) - - evo.set(q1, fq) - evo.set(q2, fq) - - local qf = evo.id() - evo.set(qf, evo.INCLUDES, { fq }) - - local f1, f2 = evo.id(2) - - local fs = { f1, f2 } - evo.batch_multi_set(qf, { evo.INCLUDES }, { fs }) - - do - local q1_fs = evo.get(q1, evo.INCLUDES) - assert(q1_fs and q1_fs ~= fs) - assert(#q1_fs == #fs) - assert(q1_fs[1] == fs[1] and q1_fs[2] == fs[2]) - end - - do - local q2_fs = evo.get(q2, evo.INCLUDES) - assert(q2_fs and q2_fs ~= fs) - assert(#q2_fs == #fs) - assert(q2_fs[1] == fs[1] and q2_fs[2] == fs[2]) - end - - do - local q1_fs = evo.get(q1, evo.INCLUDES) - local q2_fs = evo.get(q2, evo.INCLUDES) - assert(q1_fs ~= q2_fs) - end -end - -do - local q1, q2 = evo.id(2) - - local f1, f2 = evo.id(2) - - local fs = { f1, f2 } - evo.multi_set(q1, { evo.INCLUDES }, { fs }) - evo.multi_set(q2, { evo.INCLUDES }, { fs }) - - do - local q1_fs = evo.get(q1, evo.INCLUDES) - assert(q1_fs and q1_fs ~= fs) - assert(#q1_fs == #fs) - assert(q1_fs[1] == fs[1] and q1_fs[2] == fs[2]) - end - - do - local q2_fs = evo.get(q2, evo.INCLUDES) - assert(q2_fs and q2_fs ~= fs) - assert(#q2_fs == #fs) - assert(q2_fs[1] == fs[1] and q2_fs[2] == fs[2]) - end - - do - local q1_fs = evo.get(q1, evo.INCLUDES) - local q2_fs = evo.get(q2, evo.INCLUDES) - assert(q1_fs ~= q2_fs) - end -end - do -- evo.set - -- evo.multi_set 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 do - local f = evo.builder():build() + local f = evo.builder():spawn() do - local e1, e2, e3, e4 = evo.id(4) + local e1, e2 = evo.id(2) evo.set(e1, f) evo.set(e2, f) - evo.multi_set(e3, { f }) - evo.multi_set(e4, { f }) assert(evo.get(e1, f) == true) assert(evo.get(e2, f) == true) - assert(evo.get(e3, f) == true) - assert(evo.get(e4, f) == true) evo.set(e1, f, v2(1, 2)) evo.set(e2, f, v2(3, 4)) - evo.multi_set(e3, { f }, { v2(5, 6) }) - evo.multi_set(e4, { f }, { v2(7, 8) }) assert(evo.get(e1, f).x == 1 and evo.get(e1, f).y == 2) assert(evo.get(e2, f).x == 3 and evo.get(e2, f).y == 4) - assert(evo.get(e3, f).x == 5 and evo.get(e3, f).y == 6) - assert(evo.get(e4, f).x == 7 and evo.get(e4, f).y == 8) evo.set(e1, f) evo.set(e2, f) - evo.multi_set(e3, { f }) - evo.multi_set(e4, { f }) assert(evo.get(e1, f) == true) assert(evo.get(e2, f) == true) - assert(evo.get(e3, f) == true) - assert(evo.get(e4, f) == true) end do - local e1, e2, e3, e4 = evo.id(4) + local e1, e2 = evo.id(2) evo.set(e1, f, v2(1, 2)) evo.set(e2, f, v2(3, 4)) - evo.multi_set(e3, { f }, { v2(5, 6) }) - evo.multi_set(e4, { f }, { v2(7, 8) }) assert(evo.get(e1, f).x == 1 and evo.get(e1, f).y == 2) assert(evo.get(e2, f).x == 3 and evo.get(e2, f).y == 4) - assert(evo.get(e3, f).x == 5 and evo.get(e3, f).y == 6) - assert(evo.get(e4, f).x == 7 and evo.get(e4, f).y == 8) evo.set(e1, f) evo.set(e2, f) - evo.multi_set(e3, { f }) - evo.multi_set(e4, { f }) assert(evo.get(e1, f) == true) assert(evo.get(e2, f) == true) - assert(evo.get(e3, f) == true) - assert(evo.get(e4, f) == true) end end do - local f = evo.builder():default(v2(11, 22)):build() + local f = evo.builder():default(v2(11, 22)):spawn() do - local e1, e2, e3, e4 = evo.id(4) + local e1, e2 = evo.id(3) evo.set(e1, f) evo.set(e2, f) - evo.multi_set(e3, { f }) - evo.multi_set(e4, { f }) assert(evo.get(e1, f).x == 11 and evo.get(e1, f).y == 22) assert(evo.get(e2, f).x == 11 and evo.get(e2, f).y == 22) assert(evo.get(e1, f) == evo.get(e2, f)) - assert(evo.get(e3, f).x == 11 and evo.get(e3, f).y == 22) - assert(evo.get(e4, f).x == 11 and evo.get(e4, f).y == 22) - assert(evo.get(e3, f) == evo.get(e4, f)) evo.set(e1, f, v2(1, 2)) evo.set(e2, f, v2(3, 4)) - evo.multi_set(e3, { f }, { v2(5, 6) }) - evo.multi_set(e4, { f }, { v2(7, 8) }) assert(evo.get(e1, f).x == 1 and evo.get(e1, f).y == 2) assert(evo.get(e2, f).x == 3 and evo.get(e2, f).y == 4) assert(evo.get(e1, f) ~= evo.get(e2, f)) - assert(evo.get(e3, f).x == 5 and evo.get(e3, f).y == 6) - assert(evo.get(e4, f).x == 7 and evo.get(e4, f).y == 8) - assert(evo.get(e3, f) ~= evo.get(e4, f)) evo.set(e1, f) evo.set(e2, f) - evo.multi_set(e3, { f }) - evo.multi_set(e4, { f }) assert(evo.get(e1, f).x == 11 and evo.get(e1, f).y == 22) assert(evo.get(e2, f).x == 11 and evo.get(e2, f).y == 22) assert(evo.get(e1, f) == evo.get(e2, f)) - assert(evo.get(e3, f).x == 11 and evo.get(e3, f).y == 22) - assert(evo.get(e4, f).x == 11 and evo.get(e4, f).y == 22) - assert(evo.get(e3, f) == evo.get(e4, f)) end do - local e1, e2, e3, e4 = evo.id(4) + local e1, e2 = evo.id(2) evo.set(e1, f, v2(1, 2)) evo.set(e2, f, v2(3, 4)) - evo.multi_set(e3, { f }, { v2(5, 6) }) - evo.multi_set(e4, { f }, { v2(7, 8) }) assert(evo.get(e1, f).x == 1 and evo.get(e1, f).y == 2) assert(evo.get(e2, f).x == 3 and evo.get(e2, f).y == 4) assert(evo.get(e1, f) ~= evo.get(e2, f)) - assert(evo.get(e3, f).x == 5 and evo.get(e3, f).y == 6) - assert(evo.get(e4, f).x == 7 and evo.get(e4, f).y == 8) - assert(evo.get(e3, f) ~= evo.get(e4, f)) evo.set(e1, f) evo.set(e2, f) - evo.multi_set(e3, { f }) - evo.multi_set(e4, { f }) assert(evo.get(e1, f).x == 11 and evo.get(e1, f).y == 22) assert(evo.get(e2, f).x == 11 and evo.get(e2, f).y == 22) assert(evo.get(e1, f) == evo.get(e2, f)) - assert(evo.get(e3, f).x == 11 and evo.get(e3, f).y == 22) - assert(evo.get(e4, f).x == 11 and evo.get(e4, f).y == 22) - assert(evo.get(e3, f) == evo.get(e4, f)) end end do - local f = evo.builder():default(v2(11, 22)):duplicate(v2_clone):build() + local f = evo.builder():default(v2(11, 22)):duplicate(v2_clone):spawn() do - local e1, e2, e3, e4 = evo.id(4) + local e1, e2 = evo.id(2) evo.set(e1, f) evo.set(e2, f) - evo.multi_set(e3, { f }) - evo.multi_set(e4, { f }) assert(evo.get(e1, f).x == 11 and evo.get(e1, f).y == 22) assert(evo.get(e2, f).x == 11 and evo.get(e2, f).y == 22) assert(evo.get(e1, f) ~= evo.get(e2, f)) - assert(evo.get(e3, f).x == 11 and evo.get(e3, f).y == 22) - assert(evo.get(e4, f).x == 11 and evo.get(e4, f).y == 22) - assert(evo.get(e3, f) ~= evo.get(e4, f)) evo.set(e1, f, v2(1, 2)) evo.set(e2, f, v2(3, 4)) - evo.multi_set(e3, { f }, { v2(5, 6) }) - evo.multi_set(e4, { f }, { v2(7, 8) }) assert(evo.get(e1, f).x == 1 and evo.get(e1, f).y == 2) assert(evo.get(e2, f).x == 3 and evo.get(e2, f).y == 4) assert(evo.get(e1, f) ~= evo.get(e2, f)) - assert(evo.get(e3, f).x == 5 and evo.get(e3, f).y == 6) - assert(evo.get(e4, f).x == 7 and evo.get(e4, f).y == 8) - assert(evo.get(e3, f) ~= evo.get(e4, f)) evo.set(e1, f) evo.set(e2, f) - evo.multi_set(e3, { f }) - evo.multi_set(e4, { f }) assert(evo.get(e1, f).x == 11 and evo.get(e1, f).y == 22) assert(evo.get(e2, f).x == 11 and evo.get(e2, f).y == 22) assert(evo.get(e1, f) ~= evo.get(e2, f)) - assert(evo.get(e3, f).x == 11 and evo.get(e3, f).y == 22) - assert(evo.get(e4, f).x == 11 and evo.get(e4, f).y == 22) - assert(evo.get(e3, f) ~= evo.get(e4, f)) end do - local e1, e2, e3, e4 = evo.id(4) + local e1, e2 = evo.id(2) evo.set(e1, f, v2(1, 2)) evo.set(e2, f, v2(3, 4)) - evo.multi_set(e3, { f }, { v2(5, 6) }) - evo.multi_set(e4, { f }, { v2(7, 8) }) assert(evo.get(e1, f).x == 1 and evo.get(e1, f).y == 2) assert(evo.get(e2, f).x == 3 and evo.get(e2, f).y == 4) assert(evo.get(e1, f) ~= evo.get(e2, f)) - assert(evo.get(e3, f).x == 5 and evo.get(e3, f).y == 6) - assert(evo.get(e4, f).x == 7 and evo.get(e4, f).y == 8) - assert(evo.get(e3, f) ~= evo.get(e4, f)) evo.set(e1, f) evo.set(e2, f) - evo.multi_set(e3, { f }) - evo.multi_set(e4, { f }) assert(evo.get(e1, f).x == 11 and evo.get(e1, f).y == 22) assert(evo.get(e2, f).x == 11 and evo.get(e2, f).y == 22) assert(evo.get(e1, f) ~= evo.get(e2, f)) - assert(evo.get(e3, f).x == 11 and evo.get(e3, f).y == 22) - assert(evo.get(e4, f).x == 11 and evo.get(e4, f).y == 22) - assert(evo.get(e3, f) ~= evo.get(e4, f)) end end do - local f = evo.builder():duplicate(v2_clone):build() + local f = evo.builder():duplicate(v2_clone):spawn() do - local e1, e2, e3, e4 = evo.id(4) + local e1, e2 = evo.id(2) evo.set(e1, f) evo.set(e2, f) - evo.multi_set(e3, { f }) - evo.multi_set(e4, { f }) assert(evo.get(e1, f) == true) assert(evo.get(e2, f) == true) assert(evo.get(e1, f) == evo.get(e2, f)) - assert(evo.get(e3, f) == true) - assert(evo.get(e4, f) == true) - assert(evo.get(e3, f) == evo.get(e4, f)) evo.set(e1, f, v2(1, 2)) evo.set(e2, f, v2(3, 4)) - evo.multi_set(e3, { f }, { v2(5, 6) }) - evo.multi_set(e4, { f }, { v2(7, 8) }) assert(evo.get(e1, f).x == 1 and evo.get(e1, f).y == 2) assert(evo.get(e2, f).x == 3 and evo.get(e2, f).y == 4) assert(evo.get(e1, f) ~= evo.get(e2, f)) - assert(evo.get(e3, f).x == 5 and evo.get(e3, f).y == 6) - assert(evo.get(e4, f).x == 7 and evo.get(e4, f).y == 8) - assert(evo.get(e3, f) ~= evo.get(e4, f)) evo.set(e1, f) evo.set(e2, f) - evo.multi_set(e3, { f }) - evo.multi_set(e4, { f }) assert(evo.get(e1, f) == true) assert(evo.get(e2, f) == true) assert(evo.get(e1, f) == evo.get(e2, f)) - assert(evo.get(e3, f) == true) - assert(evo.get(e4, f) == true) - assert(evo.get(e3, f) == evo.get(e4, f)) end do - local e1, e2, e3, e4 = evo.id(4) + local e1, e2 = evo.id(2) evo.set(e1, f, v2(1, 2)) evo.set(e2, f, v2(3, 4)) - evo.multi_set(e3, { f }, { v2(5, 6) }) - evo.multi_set(e4, { f }, { v2(7, 8) }) assert(evo.get(e1, f).x == 1 and evo.get(e1, f).y == 2) assert(evo.get(e2, f).x == 3 and evo.get(e2, f).y == 4) assert(evo.get(e1, f) ~= evo.get(e2, f)) - assert(evo.get(e3, f).x == 5 and evo.get(e3, f).y == 6) - assert(evo.get(e4, f).x == 7 and evo.get(e4, f).y == 8) - assert(evo.get(e3, f) ~= evo.get(e4, f)) evo.set(e1, f) evo.set(e2, f) - evo.multi_set(e3, { f }) - evo.multi_set(e4, { f }) assert(evo.get(e1, f) == true) assert(evo.get(e2, f) == true) assert(evo.get(e1, f) == evo.get(e2, f)) - assert(evo.get(e3, f) == true) - assert(evo.get(e4, f) == true) - assert(evo.get(e3, f) == evo.get(e4, f)) end end end do - -- evo.batch_set - -- evo.batch_multi_set - 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 do - local f = evo.builder():build() + local f = evo.builder():spawn() - local t1 = evo.builder():tag():build() - local qt1 = evo.builder():include(t1):build() - - local t2 = evo.builder():tag():build() - local qt2 = evo.builder():include(t2):build() + local t1 = evo.builder():tag():spawn() + local qt1 = evo.builder():include(t1):spawn() do - local e1, e2, e3, e4 = evo.id(4) - evo.set(e1, t1); evo.set(e2, t1); evo.set(e3, t2); evo.set(e4, t2) + local e1, e2 = evo.id(2) + evo.set(e1, t1); evo.set(e2, t1) evo.batch_set(qt1, f) - evo.batch_multi_set(qt2, { f }) assert(evo.get(e1, f) == true) assert(evo.get(e2, f) == true) - assert(evo.get(e3, f) == true) - assert(evo.get(e4, f) == true) evo.batch_set(qt1, f, v2(1, 2)) - evo.batch_multi_set(qt2, { f }, { v2(3, 4) }) assert(evo.get(e1, f).x == 1 and evo.get(e1, f).y == 2) assert(evo.get(e2, f).x == 1 and evo.get(e2, f).y == 2) assert(evo.get(e1, f) == evo.get(e2, f)) - assert(evo.get(e3, f).x == 3 and evo.get(e3, f).y == 4) - assert(evo.get(e4, f).x == 3 and evo.get(e4, f).y == 4) - assert(evo.get(e3, f) == evo.get(e4, f)) evo.batch_set(qt1, f) - evo.batch_multi_set(qt2, { f }) assert(evo.get(e1, f) == true) assert(evo.get(e2, f) == true) - assert(evo.get(e3, f) == true) - assert(evo.get(e4, f) == true) end do - local e1, e2, e3, e4 = evo.id(4) - evo.set(e1, t1); evo.set(e2, t1); evo.set(e3, t2); evo.set(e4, t2) + local e1, e2 = evo.id(2) + evo.set(e1, t1); evo.set(e2, t1) evo.batch_set(qt1, f, v2(1, 2)) - evo.batch_multi_set(qt2, { f }, { v2(3, 4) }) assert(evo.get(e1, f).x == 1 and evo.get(e1, f).y == 2) assert(evo.get(e2, f).x == 1 and evo.get(e2, f).y == 2) assert(evo.get(e1, f) == evo.get(e2, f)) - assert(evo.get(e3, f).x == 3 and evo.get(e3, f).y == 4) - assert(evo.get(e4, f).x == 3 and evo.get(e4, f).y == 4) - assert(evo.get(e3, f) == evo.get(e4, f)) evo.batch_set(qt1, f) - evo.batch_multi_set(qt2, { f }) assert(evo.get(e1, f) == true) assert(evo.get(e2, f) == true) - assert(evo.get(e3, f) == true) - assert(evo.get(e4, f) == true) end end do - local f = evo.builder():default(v2(11, 22)):build() + local f = evo.builder():default(v2(11, 22)):spawn() - local t1 = evo.builder():tag():build() - local qt1 = evo.builder():include(t1):build() - - local t2 = evo.builder():tag():build() - local qt2 = evo.builder():include(t2):build() + local t1 = evo.builder():tag():spawn() + local qt1 = evo.builder():include(t1):spawn() do - local e1, e2, e3, e4 = evo.id(4) - evo.set(e1, t1); evo.set(e2, t1); evo.set(e3, t2); evo.set(e4, t2) + local e1, e2 = evo.id(2) + evo.set(e1, t1); evo.set(e2, t1) evo.batch_set(qt1, f) - evo.batch_multi_set(qt2, { f }) assert(evo.get(e1, f).x == 11 and evo.get(e1, f).y == 22) assert(evo.get(e2, f).x == 11 and evo.get(e2, f).y == 22) assert(evo.get(e1, f) == evo.get(e2, f)) - assert(evo.get(e3, f).x == 11 and evo.get(e3, f).y == 22) - assert(evo.get(e4, f).x == 11 and evo.get(e4, f).y == 22) - assert(evo.get(e3, f) == evo.get(e4, f)) evo.batch_set(qt1, f, v2(1, 2)) - evo.batch_multi_set(qt2, { f }, { v2(3, 4) }) assert(evo.get(e1, f).x == 1 and evo.get(e1, f).y == 2) assert(evo.get(e2, f).x == 1 and evo.get(e2, f).y == 2) assert(evo.get(e1, f) == evo.get(e2, f)) - assert(evo.get(e3, f).x == 3 and evo.get(e3, f).y == 4) - assert(evo.get(e4, f).x == 3 and evo.get(e4, f).y == 4) - assert(evo.get(e3, f) == evo.get(e4, f)) evo.batch_set(qt1, f) - evo.batch_multi_set(qt2, { f }) assert(evo.get(e1, f).x == 11 and evo.get(e1, f).y == 22) assert(evo.get(e2, f).x == 11 and evo.get(e2, f).y == 22) assert(evo.get(e1, f) == evo.get(e2, f)) - assert(evo.get(e3, f).x == 11 and evo.get(e3, f).y == 22) - assert(evo.get(e4, f).x == 11 and evo.get(e4, f).y == 22) - assert(evo.get(e3, f) == evo.get(e4, f)) end do - local e1, e2, e3, e4 = evo.id(4) - evo.set(e1, t1); evo.set(e2, t1); evo.set(e3, t2); evo.set(e4, t2) + local e1, e2 = evo.id(2) + evo.set(e1, t1); evo.set(e2, t1) evo.batch_set(qt1, f, v2(1, 2)) - evo.batch_multi_set(qt2, { f }, { v2(3, 4) }) assert(evo.get(e1, f).x == 1 and evo.get(e1, f).y == 2) assert(evo.get(e2, f).x == 1 and evo.get(e2, f).y == 2) assert(evo.get(e1, f) == evo.get(e2, f)) - assert(evo.get(e3, f).x == 3 and evo.get(e3, f).y == 4) - assert(evo.get(e4, f).x == 3 and evo.get(e4, f).y == 4) - assert(evo.get(e3, f) == evo.get(e4, f)) evo.batch_set(qt1, f) - evo.batch_multi_set(qt2, { f }) assert(evo.get(e1, f).x == 11 and evo.get(e1, f).y == 22) assert(evo.get(e2, f).x == 11 and evo.get(e2, f).y == 22) assert(evo.get(e1, f) == evo.get(e2, f)) - assert(evo.get(e3, f).x == 11 and evo.get(e3, f).y == 22) - assert(evo.get(e4, f).x == 11 and evo.get(e4, f).y == 22) - assert(evo.get(e3, f) == evo.get(e4, f)) end end do - local f = evo.builder():default(v2(11, 22)):duplicate(v2_clone):build() + local f = evo.builder():default(v2(11, 22)):duplicate(v2_clone):spawn() - local t1 = evo.builder():tag():build() - local qt1 = evo.builder():include(t1):build() - - local t2 = evo.builder():tag():build() - local qt2 = evo.builder():include(t2):build() + local t1 = evo.builder():tag():spawn() + local qt1 = evo.builder():include(t1):spawn() do - local e1, e2, e3, e4 = evo.id(4) - evo.set(e1, t1); evo.set(e2, t1); evo.set(e3, t2); evo.set(e4, t2) + local e1, e2 = evo.id(2) + evo.set(e1, t1); evo.set(e2, t1) evo.batch_set(qt1, f) - evo.batch_multi_set(qt2, { f }) assert(evo.get(e1, f).x == 11 and evo.get(e1, f).y == 22) assert(evo.get(e2, f).x == 11 and evo.get(e2, f).y == 22) assert(evo.get(e1, f) ~= evo.get(e2, f)) - assert(evo.get(e3, f).x == 11 and evo.get(e3, f).y == 22) - assert(evo.get(e4, f).x == 11 and evo.get(e4, f).y == 22) - assert(evo.get(e3, f) ~= evo.get(e4, f)) evo.batch_set(qt1, f, v2(1, 2)) - evo.batch_multi_set(qt2, { f }, { v2(3, 4) }) assert(evo.get(e1, f).x == 1 and evo.get(e1, f).y == 2) assert(evo.get(e2, f).x == 1 and evo.get(e2, f).y == 2) assert(evo.get(e1, f) ~= evo.get(e2, f)) - assert(evo.get(e3, f).x == 3 and evo.get(e3, f).y == 4) - assert(evo.get(e4, f).x == 3 and evo.get(e4, f).y == 4) - assert(evo.get(e3, f) ~= evo.get(e4, f)) evo.batch_set(qt1, f) - evo.batch_multi_set(qt2, { f }) assert(evo.get(e1, f).x == 11 and evo.get(e1, f).y == 22) assert(evo.get(e2, f).x == 11 and evo.get(e2, f).y == 22) assert(evo.get(e1, f) ~= evo.get(e2, f)) - assert(evo.get(e3, f).x == 11 and evo.get(e3, f).y == 22) - assert(evo.get(e4, f).x == 11 and evo.get(e4, f).y == 22) - assert(evo.get(e3, f) ~= evo.get(e4, f)) end do - local e1, e2, e3, e4 = evo.id(4) - evo.set(e1, t1); evo.set(e2, t1); evo.set(e3, t2); evo.set(e4, t2) + local e1, e2 = evo.id(2) + evo.set(e1, t1); evo.set(e2, t1) evo.batch_set(qt1, f, v2(1, 2)) - evo.batch_multi_set(qt2, { f }, { v2(3, 4) }) assert(evo.get(e1, f).x == 1 and evo.get(e1, f).y == 2) assert(evo.get(e2, f).x == 1 and evo.get(e2, f).y == 2) assert(evo.get(e1, f) ~= evo.get(e2, f)) - assert(evo.get(e3, f).x == 3 and evo.get(e3, f).y == 4) - assert(evo.get(e4, f).x == 3 and evo.get(e4, f).y == 4) - assert(evo.get(e3, f) ~= evo.get(e4, f)) evo.batch_set(qt1, f) - evo.batch_multi_set(qt2, { f }) assert(evo.get(e1, f).x == 11 and evo.get(e1, f).y == 22) assert(evo.get(e2, f).x == 11 and evo.get(e2, f).y == 22) assert(evo.get(e1, f) ~= evo.get(e2, f)) - assert(evo.get(e3, f).x == 11 and evo.get(e3, f).y == 22) - assert(evo.get(e4, f).x == 11 and evo.get(e4, f).y == 22) - assert(evo.get(e3, f) ~= evo.get(e4, f)) end end do - local f = evo.builder():duplicate(v2_clone):build() + local f = evo.builder():duplicate(v2_clone):spawn() - local t1 = evo.builder():tag():build() - local qt1 = evo.builder():include(t1):build() - - local t2 = evo.builder():tag():build() - local qt2 = evo.builder():include(t2):build() + local t1 = evo.builder():tag():spawn() + local qt1 = evo.builder():include(t1):spawn() do - local e1, e2, e3, e4 = evo.id(4) - evo.set(e1, t1); evo.set(e2, t1); evo.set(e3, t2); evo.set(e4, t2) + local e1, e2 = evo.id(2) + evo.set(e1, t1); evo.set(e2, t1) evo.batch_set(qt1, f) - evo.batch_multi_set(qt2, { f }) assert(evo.get(e1, f) == true) assert(evo.get(e2, f) == true) assert(evo.get(e1, f) == evo.get(e2, f)) - assert(evo.get(e3, f) == true) - assert(evo.get(e4, f) == true) - assert(evo.get(e3, f) == evo.get(e4, f)) evo.batch_set(qt1, f, v2(1, 2)) - evo.batch_multi_set(qt2, { f }, { v2(3, 4) }) assert(evo.get(e1, f).x == 1 and evo.get(e1, f).y == 2) assert(evo.get(e2, f).x == 1 and evo.get(e2, f).y == 2) assert(evo.get(e1, f) ~= evo.get(e2, f)) - assert(evo.get(e3, f).x == 3 and evo.get(e3, f).y == 4) - assert(evo.get(e4, f).x == 3 and evo.get(e4, f).y == 4) - assert(evo.get(e3, f) ~= evo.get(e4, f)) evo.batch_set(qt1, f) - evo.batch_multi_set(qt2, { f }) assert(evo.get(e1, f) == true) assert(evo.get(e2, f) == true) assert(evo.get(e1, f) == evo.get(e2, f)) - assert(evo.get(e3, f) == true) - assert(evo.get(e4, f) == true) - assert(evo.get(e3, f) == evo.get(e4, f)) end do - local e1, e2, e3, e4 = evo.id(4) - evo.set(e1, t1); evo.set(e2, t1); evo.set(e3, t2); evo.set(e4, t2) + local e1, e2 = evo.id(2) + evo.set(e1, t1); evo.set(e2, t1) evo.batch_set(qt1, f, v2(1, 2)) - evo.batch_multi_set(qt2, { f }, { v2(3, 4) }) assert(evo.get(e1, f).x == 1 and evo.get(e1, f).y == 2) assert(evo.get(e2, f).x == 1 and evo.get(e2, f).y == 2) assert(evo.get(e1, f) ~= evo.get(e2, f)) - assert(evo.get(e3, f).x == 3 and evo.get(e3, f).y == 4) - assert(evo.get(e4, f).x == 3 and evo.get(e4, f).y == 4) - assert(evo.get(e3, f) ~= evo.get(e4, f)) evo.batch_set(qt1, f) - evo.batch_multi_set(qt2, { f }) assert(evo.get(e1, f) == true) assert(evo.get(e2, f) == true) assert(evo.get(e1, f) == evo.get(e2, f)) - assert(evo.get(e3, f) == true) - assert(evo.get(e4, f) == true) - assert(evo.get(e3, f) == evo.get(e4, f)) end end end @@ -8023,28 +5432,14 @@ end do local function v2(x, y) return { x = x or 0, y = y or 0 } end - local f1 = evo.builder():default(v2(10, 11)):build() - local f2 = evo.builder():default(v2(11, 22)):build() - - local fs, cs = { f1, f2 }, { v2(1, 2) } - local c12 = evo.chunk(f1, f2) + local f1 = evo.builder():default(v2(10, 11)):spawn() + local f2 = evo.builder():default(v2(11, 22)):spawn() do - local e1 = evo.spawn_at(c12, fs, cs) - local e2 = evo.spawn_at(c12, fs, cs) + local cs = { [f1] = v2(1, 2), [f2] = v2(11, 22) } - assert(evo.get(e1, f1).x == 1 and evo.get(e1, f1).y == 2) - assert(evo.get(e2, f1).x == 1 and evo.get(e2, f1).y == 2) - assert(evo.get(e1, f1) == evo.get(e2, f1)) - - assert(evo.get(e1, f2).x == 11 and evo.get(e1, f2).y == 22) - assert(evo.get(e2, f2).x == 11 and evo.get(e2, f2).y == 22) - assert(evo.get(e1, f2) == evo.get(e2, f2)) - end - - do - local e1 = evo.spawn_with(fs, cs) - local e2 = evo.spawn_with(fs, cs) + local e1 = evo.spawn(cs) + local e2 = evo.spawn(cs) assert(evo.get(e1, f1).x == 1 and evo.get(e1, f1).y == 2) assert(evo.get(e2, f1).x == 1 and evo.get(e2, f1).y == 2) @@ -8060,28 +5455,14 @@ 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 = evo.builder():default(v2(10, 11)):duplicate(v2_clone):build() - local f2 = evo.builder():default(v2(11, 22)):duplicate(v2_clone):build() - - local fs, cs = { f1, f2 }, { v2(1, 2) } - local c12 = evo.chunk(f1, f2) + local f1 = evo.builder():default(v2(10, 11)):duplicate(v2_clone):spawn() + local f2 = evo.builder():default(v2(11, 22)):duplicate(v2_clone):spawn() do - local e1 = evo.spawn_at(c12, fs, cs) - local e2 = evo.spawn_at(c12, fs, cs) + local cs = { [f1] = v2(1, 2), [f2] = v2(11, 22) } - assert(evo.get(e1, f1).x == 1 and evo.get(e1, f1).y == 2) - assert(evo.get(e2, f1).x == 1 and evo.get(e2, f1).y == 2) - assert(evo.get(e1, f1) ~= evo.get(e2, f1)) - - assert(evo.get(e1, f2).x == 11 and evo.get(e1, f2).y == 22) - assert(evo.get(e2, f2).x == 11 and evo.get(e2, f2).y == 22) - assert(evo.get(e1, f2) ~= evo.get(e2, f2)) - end - - do - local e1 = evo.spawn_with(fs, cs) - local e2 = evo.spawn_with(fs, cs) + local e1 = evo.spawn(cs) + local e2 = evo.spawn(cs) assert(evo.get(e1, f1).x == 1 and evo.get(e1, f1).y == 2) assert(evo.get(e2, f1).x == 1 and evo.get(e2, f1).y == 2) @@ -8093,351 +5474,14 @@ do end end -do - local f1, f2 = evo.id(2) - - evo.set(f1, evo.DEFAULT, 42) - - do - local e = evo.spawn_at(nil, { f1 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - assert(not evo.has(e, f2) and evo.get(e, f2) == nil) - end - - do - local e = evo.spawn_at(nil, { f1 }, {}) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - assert(not evo.has(e, f2) and evo.get(e, f2) == nil) - end - - do - local e = evo.spawn_at(nil, { f1 }, { 43 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 43) - assert(not evo.has(e, f2) and evo.get(e, f2) == nil) - end - - do - local e = evo.spawn_at(nil, { f1 }, { 43, 44 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 43) - assert(not evo.has(e, f2) and evo.get(e, f2) == nil) - end - - do - local e = evo.spawn_at(nil, { f1, f2 }, {}) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - assert(evo.has(e, f2) and evo.get(e, f2) == true) - end - - do - local e = evo.spawn_at(nil, { f1, f2 }, { nil, 44 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - assert(evo.has(e, f2) and evo.get(e, f2) == 44) - end - - do - local e = evo.spawn_at(nil, { f1, f2 }, { nil, 44, 45 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - assert(evo.has(e, f2) and evo.get(e, f2) == 44) - end - - do - local c1 = evo.chunk(f1) - local e = evo.spawn_at(c1) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - assert(not evo.has(e, f2) and evo.get(e, f2) == nil) - end - - do - local c1 = evo.chunk(f1) - local e = evo.spawn_at(c1, {}) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - assert(not evo.has(e, f2) and evo.get(e, f2) == nil) - end - - do - local c1 = evo.chunk(f1) - local e = evo.spawn_at(c1, { f1 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - assert(not evo.has(e, f2) and evo.get(e, f2) == nil) - end - - do - local c1 = evo.chunk(f1) - local e = evo.spawn_at(c1, { f1 }, { 43 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 43) - assert(not evo.has(e, f2) and evo.get(e, f2) == nil) - end - - do - local c1 = evo.chunk(f1) - local e = evo.spawn_at(c1, { f1 }, { 43, 44 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 43) - assert(not evo.has(e, f2) and evo.get(e, f2) == nil) - end - - do - local c1 = evo.chunk(f1) - local e = evo.spawn_at(c1, { f2 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - assert(evo.has(e, f2) and evo.get(e, f2) == true) - end - - do - local c1 = evo.chunk(f1) - local e = evo.spawn_at(c1, { f2 }, { 43 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - assert(evo.has(e, f2) and evo.get(e, f2) == 43) - end - - do - local c1 = evo.chunk(f1) - local e = evo.spawn_at(c1, { f2, f1 }, { 43 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - assert(evo.has(e, f2) and evo.get(e, f2) == 43) - end - - do - local c1 = evo.chunk(f1) - local e = evo.spawn_at(c1, { f2, f1 }, { 43, 44 }) - assert(evo.has(e, f1) and evo.get(e, f1) == 44) - assert(evo.has(e, f2) and evo.get(e, f2) == 43) - end -end - -do - local f1, f2, f3 = evo.id(3) - - evo.set(f1, evo.NAME, 'f1') - evo.set(f2, evo.NAME, 'f2') - - evo.set(f1, evo.DEFAULT, 42) - evo.set(f3, evo.TAG) - - do - local p = evo.id() - - do - local e = evo.spawn_as(p) - assert(evo.is_alive(e) and evo.is_empty(e)) - end - - do - local e = evo.spawn_as(p, {}) - assert(evo.is_alive(e) and evo.is_empty(e)) - end - - do - local e = evo.spawn_as(p, {}, {}) - assert(evo.is_alive(e) and evo.is_empty(e)) - end - - do - local e = evo.spawn_as(p, {}, { 43 }) - assert(evo.is_alive(e) and evo.is_empty(e)) - end - end - - do - local p = evo.id() - - do - local e = evo.spawn_as(p, { f1 }) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - end - - do - local e = evo.spawn_as(p, { f1 }, {}) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - end - - do - local e = evo.spawn_as(p, { f1 }, { 43 }) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 43) - end - - do - local e = evo.spawn_as(p, { f1 }, { 43, 44 }) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 43) - end - - do - local e = evo.spawn_as(p, { f1, f2 }) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - assert(evo.has(e, f2) and evo.get(e, f2) == true) - end - - do - local e = evo.spawn_as(p, { f2 }) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(not evo.has(e, f1) and evo.get(e, f1) == nil) - assert(evo.has(e, f2) and evo.get(e, f2) == true) - end - - do - local e = evo.spawn_as(p, { f2 }, { 44 }) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(not evo.has(e, f1) and evo.get(e, f1) == nil) - assert(evo.has(e, f2) and evo.get(e, f2) == 44) - end - - do - local e = evo.spawn_as(p, { f2, f1 }, { 44, 43 }) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 43) - assert(evo.has(e, f2) and evo.get(e, f2) == 44) - end - - do - local e = evo.spawn_as(p, { f1, f2, f3 }, { 43, 44 }) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 43) - assert(evo.has(e, f2) and evo.get(e, f2) == 44) - assert(evo.has(e, f3) and evo.get(e, f3) == nil) - end - - do - local e = evo.spawn_as(p, { f1, f2, f3 }, { 43, 44, 45 }) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 43) - assert(evo.has(e, f2) and evo.get(e, f2) == 44) - assert(evo.has(e, f3) and evo.get(e, f3) == nil) - end - end - - do - local p = evo.id() - evo.set(p, f1, 42) - - do - local e = evo.spawn_as(p) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - end - - do - local e = evo.spawn_as(p, {}) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - end - - do - local e = evo.spawn_as(p, {}, {}) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - end - - do - local e = evo.spawn_as(p, {}, { 43 }) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - end - end - - do - local p = evo.id() - evo.set(p, f1, 43) - - do - local e = evo.spawn_as(p, { f1 }) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - end - - do - local e = evo.spawn_as(p, { f1 }, {}) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - end - - do - local e = evo.spawn_as(p, { f1 }, { 44 }) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 44) - end - - do - local e = evo.spawn_as(p, { f1 }, { 44, 45 }) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 44) - end - - do - local e = evo.spawn_as(p, { f2 }) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 43) - assert(evo.has(e, f2) and evo.get(e, f2) == true) - end - - do - local e = evo.spawn_as(p, { f2 }, {}) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 43) - assert(evo.has(e, f2) and evo.get(e, f2) == true) - end - - do - local e = evo.spawn_as(p, { f2 }, { 45 }) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 43) - assert(evo.has(e, f2) and evo.get(e, f2) == 45) - end - - do - local e = evo.spawn_as(p, { f1, f2 }, {}) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 42) - assert(evo.has(e, f2) and evo.get(e, f2) == true) - end - - do - local e = evo.spawn_as(p, { f1, f2 }, { 44, 45 }) - assert(evo.is_alive(e) and not evo.is_empty(e)) - assert(evo.has(e, f1) and evo.get(e, f1) == 44) - assert(evo.has(e, f2) and evo.get(e, f2) == 45) - end - end -end - -do - local f1, f2 = evo.id(2) - - local p = evo.id() - - assert(evo.defer()) - evo.set(p, f1, 42) - local e1 = evo.spawn_as(p) - local e2 = evo.spawn_as(p, { f2 }, { 44 }) - local e3 = evo.spawn_as(p, { f1, f2 }, { 43, 44 }) - 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.commit()) - - assert(evo.is_alive(e1) and not evo.is_empty(e1)) - assert(evo.has(e1, f1) and evo.get(e1, f1) == 42) - - assert(evo.is_alive(e2) and not evo.is_empty(e2)) - assert(evo.has(e2, f1) and evo.get(e2, f1) == 42) - assert(evo.has(e2, f2) and evo.get(e2, f2) == 44) - - assert(evo.is_alive(e3) and not evo.is_empty(e3)) - assert(evo.has(e3, f1) and evo.get(e3, f1) == 43) - assert(evo.has(e3, f2) and evo.get(e3, f2) == 44) -end - do local f1, f2, f3 = evo.id(3) do - local p1 = evo.spawn_as(nil, { f2, f3 }, { 42, 43 }) - local e1 = evo.spawn_as(p1, { f1 }, { 41 }) + local p1 = evo.spawn { [f2] = 42, [f3] = 43 } + local e1 = evo.clone(p1, { [f1] = 41 }) - assert(evo.is_alive_all(p1, e1) and not evo.is_empty_any(p1, e1)) + assert(evo.alive_all(p1, e1) and not evo.empty_any(p1, e1)) assert(not evo.has(p1, f1) and evo.get(p1, f1) == nil) assert(evo.has(p1, f2) and evo.get(p1, f2) == 42) @@ -8455,10 +5499,10 @@ do evo.set(f2, evo.DUPLICATE, function(v) return v * 2 end) do - local p1 = evo.spawn_as(nil, { f2, f3 }, { 42, 43 }) - local e1 = evo.spawn_as(p1, { f1 }, { 41 }) + local p1 = evo.spawn { [f2] = 42, [f3] = 43 } + local e1 = evo.clone(p1, { [f1] = 41 }) - assert(evo.is_alive_all(p1, e1) and not evo.is_empty_any(p1, e1)) + assert(evo.alive_all(p1, e1) and not evo.empty_any(p1, e1)) assert(not evo.has(p1, f1) and evo.get(p1, f1) == nil) assert(evo.has(p1, f2) and evo.get(p1, f2) == 84) @@ -8476,8 +5520,8 @@ do local f1, f2 = evo.id(2) do - local e1 = b:set(f1, 41):build() - local e2 = b:set(f2, 42):build() + local e1 = b:clear():set(f1, 41):spawn() + local e2 = b:clear():set(f2, 42):spawn() assert(evo.has(e1, f1) and evo.get(e1, f1) == 41) assert(not evo.has(e1, f2) and evo.get(e1, f2) == nil) @@ -8487,9 +5531,9 @@ do end do - local e1 = b:set(f1, 41):build(true) - local e2 = b:set(f2, 42):build(true) - local e3 = b:clear():set(f2, 43):build() + local e1 = b:clear():set(f1, 41):spawn() + local e2 = b:set(f2, 42):spawn() + local e3 = b:clear():set(f2, 43):spawn() assert(evo.has(e1, f1) and evo.get(e1, f1) == 41) assert(not evo.has(e1, f2) and evo.get(e1, f2) == nil) @@ -8504,8 +5548,8 @@ do do assert(evo.defer()) - local e1 = b:set(f1, 41):build() - local e2 = b:set(f2, 42):build() + local e1 = b:clear():set(f1, 41):spawn() + local e2 = b:clear():set(f2, 42):spawn() assert(not evo.has_any(e1, f1, f2)) assert(not evo.has_any(e2, f1, f2)) @@ -8522,9 +5566,9 @@ do do assert(evo.defer()) - local e1 = b:set(f1, 41):build(true) - local e2 = b:set(f2, 42):build(true) - local e3 = b:clear():set(f2, 43):build() + local e1 = b:clear():set(f1, 41):spawn() + local e2 = b:set(f2, 42):spawn() + local e3 = b:clear():set(f2, 43):spawn() assert(not evo.has_any(e1, f1, f2)) assert(not evo.has_any(e2, f1, f2)) @@ -8549,8 +5593,8 @@ do local f1, f2 = evo.id(2) do - local e1 = b:set(f1, 41):build() - local e2 = b:prefab(e1):set(f2, 42):build() + local e1 = b:set(f1, 41):spawn() + local e2 = b:set(f2, 42):clone(e1) assert(evo.has(e1, f1) and evo.get(e1, f1) == 41) assert(not evo.has(e1, f2) and evo.get(e1, f2) == nil) @@ -8560,9 +5604,9 @@ do end do - local e1 = b:set(f1, 41):build() - local e2 = b:prefab(e1):set(f2, 42):build() - local e3 = b:clear():set(f2, 43):build() + local e1 = b:clear():set(f1, 41):spawn() + local e2 = b:set(f2, 42):clone(e1) + local e3 = b:clear():set(f2, 43):spawn() assert(evo.has(e1, f1) and evo.get(e1, f1) == 41) assert(not evo.has(e1, f2) and evo.get(e1, f2) == nil) @@ -8577,8 +5621,8 @@ do do assert(evo.defer()) - local e1 = b:set(f1, 41):build() - local e2 = b:prefab(e1):set(f2, 42):build() + local e1 = b:clear():set(f1, 41):spawn() + local e2 = b:set(f2, 42):clone(e1) assert(not evo.has_any(e1, f1, f2)) assert(not evo.has_any(e2, f1, f2)) @@ -8595,9 +5639,9 @@ do do assert(evo.defer()) - local e1 = b:set(f1, 41):build() - local e2 = b:prefab(e1):set(f2, 42):build() - local e3 = b:clear():set(f2, 43):build() + local e1 = b:clear():set(f1, 41):spawn() + local e2 = b:set(f2, 42):clone(e1) + local e3 = b:clear():set(f2, 43):spawn() assert(not evo.has_any(e1, f1, f2)) assert(not evo.has_any(e2, f1, f2)) @@ -8632,7 +5676,7 @@ do assert(not b:has_any(f1, f2)) do - local e = b:build(true) + local e = b:spawn() assert(not evo.has(e, f1) and evo.get(e, f1) == nil) assert(not evo.has(e, f2) and evo.get(e, f2) == nil) @@ -8647,7 +5691,7 @@ do assert(b:has_any(f1, f2)) do - local e = b:build(true) + local e = b:spawn() assert(evo.has(e, f1) and evo.get(e, f1) == 41) assert(not evo.has(e, f2) and evo.get(e, f2) == nil) @@ -8662,7 +5706,7 @@ do assert(b:has_any(f1, f2)) do - local e = b:build(true) + local e = b:spawn() assert(evo.has(e, f1) and evo.get(e, f1) == 41) assert(evo.has(e, f2) and evo.get(e, f2) == 42) @@ -8677,7 +5721,7 @@ do assert(b:has_any(f1, f2)) do - local e = b:build(true) + local e = b:spawn() assert(not evo.has(e, f1) and evo.get(e, f1) == nil) assert(evo.has(e, f2) and evo.get(e, f2) == 42) @@ -8692,7 +5736,7 @@ do assert(not b:has(f2) and b:get(f2) == nil) do - local e = b:build(true) + local e = b:spawn() assert(not evo.has(e, f1) and evo.get(e, f1) == nil) assert(not evo.has(e, f2) and evo.get(e, f2) == nil) @@ -8798,7 +5842,7 @@ do assert(b == b:remove(f1)) assert(not b:has(f1) and b:get(f1) == nil) assert(b:has(f2) and b:get(f2) == 22) - local e = b:build() + local e = b:spawn() assert(not evo.has(e, f1) and evo.get(e, f1) == nil) assert(evo.has(e, f2) and evo.get(e, f2) == 22) end @@ -8808,7 +5852,7 @@ do assert(b == b:remove(f3, f1)) assert(not b:has(f1) and b:get(f1) == nil) assert(b:has(f2) and b:get(f2) == 22) - local e = b:build() + local e = b:spawn() assert(not evo.has(e, f1) and evo.get(e, f1) == nil) assert(evo.has(e, f2) and evo.get(e, f2) == 22) end @@ -8818,7 +5862,7 @@ do assert(b == b:remove(f1, f2)) assert(not b:has(f1) and b:get(f1) == nil) assert(not b:has(f2) and b:get(f2) == nil) - local e = b:build() + local e = b:spawn() assert(not evo.has(e, f1) and evo.get(e, f1) == nil) assert(not evo.has(e, f2) and evo.get(e, f2) == nil) end @@ -8828,36 +5872,450 @@ do assert(b == b:remove(f2, f1, f1)) assert(not b:has(f1) and b:get(f1) == nil) assert(not b:has(f2) and b:get(f2) == nil) - local e = b:build() + local e = b:spawn() assert(not evo.has(e, f1) and evo.get(e, f1) == nil) assert(not evo.has(e, f2) and evo.get(e, f2) == nil) end end do - local f1 = evo.id(1) + local f1, f2 = evo.id(2) do - local b = evo.builder():set(f1, 11):single(1) + local e = evo.spawn() + assert(evo.alive(e) and evo.empty(e)) + end - local e1 = b:build(true) - assert(evo.has(e1, e1) and evo.get(e1, e1) == 1) - assert(evo.has(e1, f1) and evo.get(e1, f1) == 11) + do + local e = evo.spawn({}) + assert(evo.alive(e) and evo.empty(e)) + end - assert(not b:has(e1) and b:get(e1) == nil) + do + local e = evo.spawn({ [f1] = 1 }) + assert(evo.alive(e) and not evo.empty(e)) + assert(evo.has(e, f1) and evo.get(e, f1) == 1) + assert(not evo.has(e, f2) and evo.get(e, f2) == nil) + end - local e2 = b:build() - - assert(not evo.has(e2, e1) and evo.get(e2, e1) == nil) - - assert(evo.has(e2, e2) and evo.get(e2, e2) == 1) - assert(evo.has(e2, f1) and evo.get(e2, f1) == 11) - - local e3 = b:build() - - assert(not evo.has(e3, e1) and evo.get(e3, e1) == nil) - assert(not evo.has(e3, e2) and evo.get(e3, e2) == nil) - assert(not evo.has(e3, e3) and evo.get(e3, e3) == nil) - assert(not evo.has(e3, f1) and evo.get(e3, f1) == nil) + do + local e = evo.spawn({ [f1] = 1, [f2] = 2 }) + assert(evo.alive(e) and not evo.empty(e)) + assert(evo.has(e, f1) and evo.get(e, f1) == 1) + assert(evo.has(e, f2) and evo.get(e, f2) == 2) + end +end + +do + local f1, f2, f3 = evo.id(3) + + do + local p = evo.spawn() + + local e1 = evo.clone(p) + assert(evo.alive(e1) and evo.empty(e1)) + + local e2 = evo.clone(p, {}) + assert(evo.alive(e2) and evo.empty(e2)) + + local e3 = evo.clone(p, { [f1] = 11 }) + assert(evo.alive(e3) and not evo.empty(e3)) + assert(evo.has(e3, f1) and evo.get(e3, f1) == 11) + assert(not evo.has(e3, f2) and evo.get(e3, f2) == nil) + + local e4 = evo.clone(p, { [f1] = 11, [f2] = 22 }) + assert(evo.alive(e4) and not evo.empty(e4)) + assert(evo.has(e4, f1) and evo.get(e4, f1) == 11) + assert(evo.has(e4, f2) and evo.get(e4, f2) == 22) + + local e5 = evo.clone(p, { [f3] = 33 }) + assert(evo.alive(e5) and not evo.empty(e5)) + assert(not evo.has(e5, f1) and evo.get(e5, f1) == nil) + assert(not evo.has(e5, f2) and evo.get(e5, f2) == nil) + assert(evo.has(e5, f3) and evo.get(e5, f3) == 33) + + local e6 = evo.clone(p, { [f1] = 11, [f2] = 22, [f3] = 33 }) + assert(evo.alive(e6) and not evo.empty(e6)) + assert(evo.has(e6, f1) and evo.get(e6, f1) == 11) + assert(evo.has(e6, f2) and evo.get(e6, f2) == 22) + assert(evo.has(e6, f3) and evo.get(e6, f3) == 33) + end + + do + local p = evo.spawn({ [f1] = 1 }) + + local e1 = evo.clone(p) + assert(evo.alive(e1) and not evo.empty(e1)) + assert(evo.has(e1, f1) and evo.get(e1, f1) == 1) + assert(not evo.has(e1, f2) and evo.get(e1, f2) == nil) + + local e2 = evo.clone(p, {}) + assert(evo.alive(e2) and not evo.empty(e2)) + assert(evo.has(e2, f1) and evo.get(e2, f1) == 1) + assert(not evo.has(e2, f2) and evo.get(e2, f2) == nil) + + local e3 = evo.clone(p, { [f1] = 11 }) + assert(evo.alive(e3) and not evo.empty(e3)) + assert(evo.has(e3, f1) and evo.get(e3, f1) == 11) + assert(not evo.has(e3, f2) and evo.get(e3, f2) == nil) + + local e4 = evo.clone(p, { [f2] = 22 }) + assert(evo.alive(e4) and not evo.empty(e4)) + assert(evo.has(e4, f1) and evo.get(e4, f1) == 1) + assert(evo.has(e4, f2) and evo.get(e4, f2) == 22) + + local e5 = evo.clone(p, { [f1] = 11, [f2] = 22 }) + assert(evo.alive(e5) and not evo.empty(e5)) + assert(evo.has(e5, f1) and evo.get(e5, f1) == 11) + assert(evo.has(e5, f2) and evo.get(e5, f2) == 22) + + local e6 = evo.clone(p, { [f3] = 33 }) + assert(evo.alive(e6) and not evo.empty(e6)) + assert(evo.has(e6, f1) and evo.get(e6, f1) == 1) + assert(not evo.has(e6, f2) and evo.get(e6, f2) == nil) + assert(evo.has(e6, f3) and evo.get(e6, f3) == 33) + + local e7 = evo.clone(p, { [f1] = 11, [f2] = 22, [f3] = 33 }) + assert(evo.alive(e7) and not evo.empty(e7)) + assert(evo.has(e7, f1) and evo.get(e7, f1) == 11) + assert(evo.has(e7, f2) and evo.get(e7, f2) == 22) + assert(evo.has(e7, f3) and evo.get(e7, f3) == 33) + end + + do + local p = evo.spawn({ [f1] = 1, [f2] = 2 }) + + local e1 = evo.clone(p) + assert(evo.alive(e1) and not evo.empty(e1)) + assert(evo.has(e1, f1) and evo.get(e1, f1) == 1) + assert(evo.has(e1, f2) and evo.get(e1, f2) == 2) + + local e2 = evo.clone(p, {}) + assert(evo.alive(e2) and not evo.empty(e2)) + assert(evo.has(e2, f1) and evo.get(e2, f1) == 1) + assert(evo.has(e2, f2) and evo.get(e2, f2) == 2) + + local e3 = evo.clone(p, { [f1] = 11 }) + assert(evo.alive(e3) and not evo.empty(e3)) + assert(evo.has(e3, f1) and evo.get(e3, f1) == 11) + assert(evo.has(e3, f2) and evo.get(e3, f2) == 2) + + local e4 = evo.clone(p, { [f2] = 22 }) + assert(evo.alive(e4) and not evo.empty(e4)) + assert(evo.has(e4, f1) and evo.get(e4, f1) == 1) + assert(evo.has(e4, f2) and evo.get(e4, f2) == 22) + + local e5 = evo.clone(p, { [f1] = 11, [f2] = 22 }) + assert(evo.alive(e5) and not evo.empty(e5)) + assert(evo.has(e5, f1) and evo.get(e5, f1) == 11) + assert(evo.has(e5, f2) and evo.get(e5, f2) == 22) + + local e6 = evo.clone(p, { [f3] = 33 }) + assert(evo.alive(e6) and not evo.empty(e6)) + assert(evo.has(e6, f1) and evo.get(e6, f1) == 1) + assert(evo.has(e6, f2) and evo.get(e6, f2) == 2) + assert(evo.has(e6, f3) and evo.get(e6, f3) == 33) + + local e7 = evo.clone(p, { [f1] = 11, [f2] = 22, [f3] = 33 }) + assert(evo.alive(e7) and not evo.empty(e7)) + assert(evo.has(e7, f1) and evo.get(e7, f1) == 11) + assert(evo.has(e7, f2) and evo.get(e7, f2) == 22) + assert(evo.has(e7, f3) and evo.get(e7, f3) == 33) + end +end + +do + local f1, f2, f3 = evo.id(3) + + do + assert(evo.defer()) + + local e1 = evo.spawn() + local e2 = evo.spawn({}) + local e3 = evo.spawn({ [f1] = 11 }) + local e4 = evo.spawn({ [f1] = 11, [f2] = 22 }) + + assert(evo.alive(e1) and evo.empty(e1)) + assert(evo.alive(e2) and evo.empty(e2)) + assert(evo.alive(e3) and evo.empty(e3)) + assert(evo.alive(e4) and evo.empty(e4)) + + assert(evo.commit()) + + assert(evo.alive(e1) and evo.empty(e1)) + assert(evo.alive(e2) and evo.empty(e2)) + assert(evo.alive(e3) and not evo.empty(e3)) + assert(evo.alive(e4) and not evo.empty(e4)) + + assert(evo.has(e3, f1) and evo.get(e3, f1) == 11) + assert(not evo.has(e3, f2) and evo.get(e3, f2) == nil) + + assert(evo.has(e4, f1) and evo.get(e4, f1) == 11) + assert(evo.has(e4, f2) and evo.get(e4, f2) == 22) + end + + do + local p1 = evo.spawn() + local p2 = evo.spawn({ [f1] = 1 }) + local p3 = evo.spawn({ [f1] = 1, [f2] = 2 }) + + assert(evo.defer()) + + local e1a = evo.clone(p1) + local e1b = evo.clone(p1, {}) + local e1c = evo.clone(p1, { [f1] = 11 }) + local e1d = evo.clone(p1, { [f2] = 22 }) + local e1e = evo.clone(p1, { [f1] = 11, [f2] = 22 }) + local e1f = evo.clone(p1, { [f3] = 33 }) + local e1g = evo.clone(p1, { [f1] = 11, [f2] = 22, [f3] = 33 }) + + local e2a = evo.clone(p2) + local e2b = evo.clone(p2, {}) + local e2c = evo.clone(p2, { [f1] = 11 }) + local e2d = evo.clone(p2, { [f2] = 22 }) + local e2e = evo.clone(p2, { [f1] = 11, [f2] = 22 }) + local e2f = evo.clone(p2, { [f3] = 33 }) + local e2g = evo.clone(p2, { [f1] = 11, [f2] = 22, [f3] = 33 }) + + local e3a = evo.clone(p3) + local e3b = evo.clone(p3, {}) + local e3c = evo.clone(p3, { [f1] = 11 }) + local e3d = evo.clone(p3, { [f2] = 22 }) + local e3e = evo.clone(p3, { [f1] = 11, [f2] = 22 }) + local e3f = evo.clone(p3, { [f3] = 33 }) + local e3g = evo.clone(p3, { [f1] = 11, [f2] = 22, [f3] = 33 }) + + assert(evo.alive_all(e1a, e1b, e1c, e1d, e1e, e1f, e1g)) + assert(evo.alive_all(e2a, e2b, e2c, e2d, e2e, e2f, e2g)) + assert(evo.alive_all(e3a, e3b, e3c, e3d, e3e, e3f, e3g)) + + assert(evo.empty_all(e1a, e1b, e1c, e1d, e1e, e1f, e1g)) + assert(evo.empty_all(e2a, e2b, e2c, e2d, e2e, e2f, e2g)) + assert(evo.empty_all(e3a, e3b, e3c, e3d, e3e, e3f, e3g)) + + assert(evo.commit()) + + assert(not evo.has(e1a, f1) and not evo.has(e1a, f2)) + assert(not evo.has(e1b, f1) and not evo.has(e1b, f2)) + + assert(evo.has(e1c, f1) and evo.get(e1c, f1) == 11 and not evo.has(e1c, f2)) + assert(not evo.has(e1d, f1) and evo.has(e1d, f2) and evo.get(e1d, f2) == 22) + + assert(not evo.has(e1f, f1) and evo.get(e1f, f1) == nil) + assert(not evo.has(e1f, f2) and evo.get(e1f, f2) == nil) + assert(evo.has(e1f, f3) and evo.get(e1f, f3) == 33) + + assert(evo.has(e1g, f1) and evo.get(e1g, f1) == 11) + assert(evo.has(e1g, f2) and evo.get(e1g, f2) == 22) + assert(evo.has(e1g, f3) and evo.get(e1g, f3) == 33) + + assert(evo.has(e2a, f1) and evo.get(e2a, f1) == 1) + assert(not evo.has(e2a, f2) and evo.get(e2a, f2) == nil) + + assert(evo.has(e2b, f1) and evo.get(e2b, f1) == 1) + assert(not evo.has(e2b, f2) and evo.get(e2b, f2) == nil) + + assert(evo.has(e2c, f1) and evo.get(e2c, f1) == 11) + assert(not evo.has(e2c, f2) and evo.get(e2c, f2) == nil) + + assert(evo.has(e2d, f1) and evo.get(e2d, f1) == 1) + assert(evo.has(e2d, f2) and evo.get(e2d, f2) == 22) + + assert(evo.has(e2e, f1) and evo.get(e2e, f1) == 11) + assert(evo.has(e2e, f2) and evo.get(e2e, f2) == 22) + + assert(evo.has(e2f, f1) and evo.get(e2f, f1) == 1) + assert(not evo.has(e2f, f2) and evo.get(e2f, f2) == nil) + assert(evo.has(e2f, f3) and evo.get(e2f, f3) == 33) + + assert(evo.has(e2g, f1) and evo.get(e2g, f1) == 11) + assert(evo.has(e2g, f2) and evo.get(e2g, f2) == 22) + assert(evo.has(e2g, f3) and evo.get(e2g, f3) == 33) + + assert(evo.has(e3a, f1) and evo.get(e3a, f1) == 1) + assert(evo.has(e3a, f2) and evo.get(e3a, f2) == 2) + + assert(evo.has(e3b, f1) and evo.get(e3b, f1) == 1) + assert(evo.has(e3b, f2) and evo.get(e3b, f2) == 2) + + assert(evo.has(e3c, f1) and evo.get(e3c, f1) == 11) + assert(evo.has(e3c, f2) and evo.get(e3c, f2) == 2) + + assert(evo.has(e3d, f1) and evo.get(e3d, f1) == 1) + assert(evo.has(e3d, f2) and evo.get(e3d, f2) == 22) + + assert(evo.has(e3e, f1) and evo.get(e3e, f1) == 11) + assert(evo.has(e3e, f2) and evo.get(e3e, f2) == 22) + + assert(evo.has(e3f, f1) and evo.get(e3f, f1) == 1) + assert(evo.has(e3f, f2) and evo.get(e3f, f2) == 2) + assert(evo.has(e3f, f3) and evo.get(e3f, f3) == 33) + + assert(evo.has(e3g, f1) and evo.get(e3g, f1) == 11) + assert(evo.has(e3g, f2) and evo.get(e3g, f2) == 22) + assert(evo.has(e3g, f3) and evo.get(e3g, f3) == 33) + end +end + +do + local f1, f2, f3 = evo.id(3) + + evo.set(f2, evo.UNIQUE) + evo.set(f3, evo.UNIQUE) + + do + local p = evo.spawn { [f1] = 11, [f2] = 22 } + local e = evo.clone(p) + + assert(evo.has(p, f1) and evo.get(p, f1) == 11) + assert(evo.has(p, f2) and evo.get(p, f2) == 22) + + assert(evo.has(e, f1) and evo.get(e, f1) == 11) + assert(not evo.has(e, f2) and evo.get(e, f2) == nil) + end + + do + local p = evo.spawn { [f1] = 11, [f2] = 22, [f3] = 33 } + local e = evo.clone(p) + + assert(evo.has(p, f1) and evo.get(p, f1) == 11) + assert(evo.has(p, f2) and evo.get(p, f2) == 22) + assert(evo.has(p, f3) and evo.get(p, f3) == 33) + + assert(evo.has(e, f1) and evo.get(e, f1) == 11) + assert(not evo.has(e, f2) and evo.get(e, f2) == nil) + assert(not evo.has(e, f3) and evo.get(e, f3) == nil) + end + + do + local p = evo.spawn { [f2] = 22 } + local e = evo.clone(p) + + assert(not evo.has(p, f1) and evo.get(p, f1) == nil) + assert(evo.has(p, f2) and evo.get(p, f2) == 22) + assert(not evo.has(p, f3) and evo.get(p, f3) == nil) + + assert(not evo.has(e, f1) and evo.get(e, f1) == nil) + assert(not evo.has(e, f2) and evo.get(e, f2) == nil) + assert(not evo.has(e, f3) and evo.get(e, f3) == nil) + end + do + local p = evo.spawn { [f2] = 22, [f3] = 33 } + local e = evo.clone(p) + + assert(not evo.has(p, f1) and evo.get(p, f1) == nil) + assert(evo.has(p, f2) and evo.get(p, f2) == 22) + assert(evo.has(p, f3) and evo.get(p, f3) == 33) + + assert(not evo.has(e, f1) and evo.get(e, f1) == nil) + assert(not evo.has(e, f2) and evo.get(e, f2) == nil) + assert(not evo.has(e, f3) and evo.get(e, f3) == nil) + end + + do + local p = evo.spawn { [f1] = 11, [f2] = 22 } + local e = evo.clone(p, { [f2] = 2 }) + + assert(evo.has(p, f1) and evo.get(p, f1) == 11) + assert(evo.has(p, f2) and evo.get(p, f2) == 22) + + assert(evo.has(e, f1) and evo.get(e, f1) == 11) + assert(evo.has(e, f2) and evo.get(e, f2) == 2) + end + + do + local p = evo.spawn { [f1] = 11, [f2] = 22 } + local e = evo.clone(p, { [f2] = 2, [f3] = 3 }) + + assert(evo.has(p, f1) and evo.get(p, f1) == 11) + assert(evo.has(p, f2) and evo.get(p, f2) == 22) + + assert(evo.has(e, f1) and evo.get(e, f1) == 11) + assert(evo.has(e, f2) and evo.get(e, f2) == 2) + assert(evo.has(e, f3) and evo.get(e, f3) == 3) + end +end + +do + local f1, f2, f3 = evo.id(3) + + evo.set(f2, evo.UNIQUE) + + do + local p = evo.spawn { [f1] = 11, [f2] = 22, [f3] = 33 } + local e = evo.clone(p) + + assert(evo.has(p, f1) and evo.get(p, f1) == 11) + assert(evo.has(p, f2) and evo.get(p, f2) == 22) + assert(evo.has(p, f3) and evo.get(p, f3) == 33) + + assert(evo.has(e, f1) and evo.get(e, f1) == 11) + assert(not evo.has(e, f2) and evo.get(e, f2) == nil) + assert(evo.has(e, f3) and evo.get(e, f3) == 33) + end +end + +do + local f1, f2 = evo.id(2) + + local p = evo.builder():prefab():set(f1, 11):set(f2, 22):spawn() + local e = evo.clone(p) + + do + local q = evo.builder():include(f1, f2):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(f1, f2)) + assert(entity_count == 1 and entity_list[1] == e) + end + + do + local q = evo.builder():exclude(f1):spawn() + + for c in evo.execute(q) do + local fs, fc = c:fragments() + for i = 1, fc do assert(not evo.has(fs[i], evo.EXPLICIT)) end + end + end + + do + local q = evo.builder():spawn() + + for c in evo.execute(q) do + local fs, fc = c:fragments() + for i = 1, fc do assert(not evo.has(fs[i], evo.EXPLICIT)) end + end + end +end + +do + local f1, f2 = evo.id(2) + + evo.set(f2, evo.EXPLICIT) + + local e1 = evo.builder():set(f1, 11):spawn() + local e2 = evo.builder():set(f1, 11):set(f2, 22):spawn() + + do + local q = evo.builder():include(f1):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(f1)) + assert(entity_count == 1 and entity_list[1] == e1) + chunk, entity_list, entity_count = iter(state) + assert(not chunk and not entity_list and not entity_count) + end + + do + local q = evo.builder():include(f1, f2):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(f1, f2)) + assert(entity_count == 1 and entity_list[1] == e2) + chunk, entity_list, entity_count = iter(state) + assert(not chunk and not entity_list and not entity_count) end end diff --git a/develop/usbench.lua b/develop/usbench.lua index 293ce8a..5983134 100644 --- a/develop/usbench.lua +++ b/develop/usbench.lua @@ -40,9 +40,9 @@ basics.describe_bench(string.format('Evolved Entity Cycle (Defer): %d entities', function(a, b, A, B) evo.defer() do - for chunk, entities in evo.execute(A) do - local as = evo.components(chunk, a) - for i = 1, #entities do + for chunk, _, entity_count in evo.execute(A) do + local as = chunk:components(a) + for i = 1, entity_count do evo.set(evo.id(), b, as[i]) end end @@ -54,11 +54,11 @@ basics.describe_bench(string.format('Evolved Entity Cycle (Defer): %d entities', local a, b = evo.id(2) for i = 1, N do - evo.builder():set(a, i):build() + evo.builder():set(a, i):spawn() end - local A = evo.builder():include(a):build() - local B = evo.builder():include(b):build() + local A = evo.builder():include(a):spawn() + local B = evo.builder():include(b):spawn() return a, b, A, B end, function(_, _, A, _) @@ -68,15 +68,17 @@ basics.describe_bench(string.format('Evolved Entity Cycle (Defer): %d entities', basics.describe_bench(string.format('Evolved Entity Cycle (Manual): %d entities', N), function(a, b, A, B) local to_create = {} + local to_create_count = 0 - for chunk, entities in evo.execute(A) do - local as = evo.components(chunk, a) - for i = 1, #entities do - to_create[#to_create + 1] = as[i] + for chunk, _, entity_count in evo.execute(A) do + local as = chunk:components(a) + for i = 1, entity_count do + to_create_count = to_create_count + 1 + to_create[to_create_count] = as[i] end end - for i = 1, #to_create do + for i = 1, to_create_count do local e = evo.id() evo.set(e, b, to_create[i]) end @@ -86,11 +88,11 @@ basics.describe_bench(string.format('Evolved Entity Cycle (Manual): %d entities' local a, b = evo.id(2) for i = 1, N do - evo.builder():set(a, i):build() + evo.builder():set(a, i):spawn() end - local A = evo.builder():include(a):build() - local B = evo.builder():include(b):build() + local A = evo.builder():include(a):spawn() + local B = evo.builder():include(b):spawn() return a, b, A, B end, function(_, _, A, _) @@ -143,23 +145,23 @@ basics.describe_bench(string.format('Evolved Simple Iteration: %d entities', N), ---@param CD evolved.query ---@param CE evolved.query function(a, b, c, d, e, AB, CD, CE) - for chunk, entities in evo.execute(AB) do - local as, bs = evo.components(chunk, a, b) - for i = 1, #entities do + for chunk, _, entity_count in evo.execute(AB) do + local as, bs = chunk:components(a, b) + for i = 1, entity_count do as[i], bs[i] = bs[i], as[i] end end - for chunk, entities in evo.execute(CD) do - local cs, ds = evo.components(chunk, c, d) - for i = 1, #entities do + for chunk, _, entity_count in evo.execute(CD) do + local cs, ds = chunk:components(c, d) + for i = 1, entity_count do cs[i], ds[i] = ds[i], cs[i] end end - for chunk, entities in evo.execute(CE) do - local cs, es = evo.components(chunk, c, e) - for i = 1, #entities do + for chunk, _, entity_count in evo.execute(CE) do + local cs, es = chunk:components(c, e) + for i = 1, entity_count do cs[i], es[i] = es[i], cs[i] end end @@ -167,15 +169,15 @@ basics.describe_bench(string.format('Evolved Simple Iteration: %d entities', N), local a, b, c, d, e = evo.id(5) for i = 1, N do - evo.builder():set(a, i):set(b, i):build() - evo.builder():set(a, i):set(b, i):set(c, i):build() - evo.builder():set(a, i):set(b, i):set(c, i):set(d, i):build() - evo.builder():set(a, i):set(b, i):set(c, i):set(e, i):build() + evo.builder():set(a, i):set(b, i):spawn() + evo.builder():set(a, i):set(b, i):set(c, i):spawn() + evo.builder():set(a, i):set(b, i):set(c, i):set(d, i):spawn() + evo.builder():set(a, i):set(b, i):set(c, i):set(e, i):spawn() end - local AB = evo.builder():include(a, b):build() - local CD = evo.builder():include(c, d):build() - local CE = evo.builder():include(c, e):build() + local AB = evo.builder():include(a, b):spawn() + local CD = evo.builder():include(c, d):spawn() + local CE = evo.builder():include(c, e):spawn() return a, b, c, d, e, AB, CD, CE end, function(_, _, _, _, _, AB, CD, CE) @@ -239,37 +241,37 @@ basics.describe_bench(string.format('Evolved Packed Iteration: %d entities', N), ---@param D evolved.query ---@param E evolved.query function(a, b, c, d, e, A, B, C, D, E) - for chunk, entities in evo.execute(A) do - local as = evo.components(chunk, a) - for i = 1, #entities do + for chunk, _, entity_count in evo.execute(A) do + local as = chunk:components(a) + for i = 1, entity_count do as[i] = as[i] * 2 end end - for chunk, entities in evo.execute(B) do - local bs = evo.components(chunk, b) - for i = 1, #entities do + for chunk, _, entity_count in evo.execute(B) do + local bs = chunk:components(b) + for i = 1, entity_count do bs[i] = bs[i] * 2 end end - for chunk, entities in evo.execute(C) do - local cs = evo.components(chunk, c) - for i = 1, #entities do + for chunk, _, entity_count in evo.execute(C) do + local cs = chunk:components(c) + for i = 1, entity_count do cs[i] = cs[i] * 2 end end - for chunk, entities in evo.execute(D) do - local ds = evo.components(chunk, d) - for i = 1, #entities do + for chunk, _, entity_count in evo.execute(D) do + local ds = chunk:components(d) + for i = 1, entity_count do ds[i] = ds[i] * 2 end end - for chunk, entities in evo.execute(E) do - local es = evo.components(chunk, e) - for i = 1, #entities do + for chunk, _, entity_count in evo.execute(E) do + local es = chunk:components(e) + for i = 1, entity_count do es[i] = es[i] * 2 end end @@ -277,14 +279,14 @@ basics.describe_bench(string.format('Evolved Packed Iteration: %d entities', N), local a, b, c, d, e = evo.id(5) for i = 1, N do - evo.builder():set(a, i):set(b, i):set(c, i):set(d, i):set(e, i):build() + evo.builder():set(a, i):set(b, i):set(c, i):set(d, i):set(e, i):spawn() end - local A = evo.builder():include(a):build() - local B = evo.builder():include(b):build() - local C = evo.builder():include(c):build() - local D = evo.builder():include(d):build() - local E = evo.builder():include(e):build() + local A = evo.builder():include(a):spawn() + local B = evo.builder():include(b):spawn() + local C = evo.builder():include(c):spawn() + local D = evo.builder():include(d):spawn() + local E = evo.builder():include(e):spawn() return a, b, c, d, e, A, B, C, D, E end, function(_, _, _, _, _, A, _, _, _, _) @@ -334,16 +336,16 @@ basics.describe_bench(string.format('Evolved Fragmented Iteration: %d entities', ---@param Data evolved.query ---@param Last evolved.query function(data, last, Data, Last) - for chunk, entities in evo.execute(Data) do - local ds = evo.components(chunk, data) - for i = 1, #entities do + for chunk, _, entity_count in evo.execute(Data) do + local ds = chunk:components(data) + for i = 1, entity_count do ds[i] = ds[i] * 2 end end - for chunk, entities in evo.execute(Last) do - local ls = evo.components(chunk, last) - for i = 1, #entities do + for chunk, _, entity_count in evo.execute(Last) do + local ls = chunk:components(last) + for i = 1, entity_count do ls[i] = ls[i] * 2 end end @@ -359,16 +361,14 @@ basics.describe_bench(string.format('Evolved Fragmented Iteration: %d entities', for _, char in ipairs(chars) do for i = 1, N do - evo.builder():set(char, i):set(data, i):build() + evo.builder():set(char, i):set(data, i):spawn() end end - local Data = evo.builder():include(data):build() - local Last = evo.builder():include(chars[#chars]):build() + local Data = evo.builder():include(data):spawn() + local Last = evo.builder():include(chars[#chars]):spawn() return data, chars[#chars], Data, Last end, function(_, _, Data, _) evo.batch_destroy(Data) end) - -print '----------------------------------------' diff --git a/evolved.lua b/evolved.lua index 1868e26..45372a7 100644 --- a/evolved.lua +++ b/evolved.lua @@ -49,29 +49,6 @@ local evolved = { ---@alias evolved.insert_hook fun(entity: evolved.entity, fragment: evolved.fragment, new_component: evolved.component) ---@alias evolved.remove_hook fun(entity: evolved.entity, fragment: evolved.fragment, component: evolved.component) ----@class (exact) evolved.chunk ----@field package __parent? evolved.chunk ----@field package __child_set table ----@field package __child_list evolved.chunk[] ----@field package __child_count integer ----@field package __entity_list evolved.entity[] ----@field package __entity_count integer ----@field package __fragment evolved.fragment ----@field package __fragment_set table ----@field package __fragment_list evolved.fragment[] ----@field package __fragment_count integer ----@field package __component_count integer ----@field package __component_indices table ----@field package __component_storages evolved.storage[] ----@field package __component_fragments evolved.fragment[] ----@field package __with_fragment_edges table ----@field package __without_fragment_edges table ----@field package __unreachable_or_collected boolean ----@field package __has_setup_hooks boolean ----@field package __has_assign_hooks boolean ----@field package __has_insert_hooks boolean ----@field package __has_remove_hooks boolean - ---@class (exact) evolved.each_state ---@field package [1] integer structural_changes ---@field package [2] evolved.chunk entity_chunk @@ -125,12 +102,53 @@ local __query_sorted_excludes = {} ---@type table +---@field package __child_list evolved.chunk[] +---@field package __child_count integer +---@field package __entity_list evolved.entity[] +---@field package __entity_count integer +---@field package __fragment evolved.fragment +---@field package __fragment_set table +---@field package __fragment_list evolved.fragment[] +---@field package __fragment_count integer +---@field package __component_count integer +---@field package __component_indices table +---@field package __component_storages evolved.storage[] +---@field package __component_fragments evolved.fragment[] +---@field package __with_fragment_edges table +---@field package __without_fragment_edges table +---@field package __unreachable_or_collected boolean +---@field package __has_setup_hooks boolean +---@field package __has_assign_hooks boolean +---@field package __has_insert_hooks boolean +---@field package __has_remove_hooks boolean +---@field package __has_unique_major boolean +---@field package __has_unique_minors boolean +---@field package __has_unique_fragments boolean +---@field package __has_explicit_major boolean +---@field package __has_explicit_minors boolean +---@field package __has_explicit_fragments boolean +local __chunk_mt = {} +__chunk_mt.__index = __chunk_mt + +---@class evolved.builder +---@field package __components table +local __builder_mt = {} +__builder_mt.__index = __builder_mt + +--- +--- +--- +--- +--- + local __lua_next = next local __lua_pcall = pcall local __lua_select = select local __lua_setmetatable = setmetatable local __lua_table_sort = table.sort -local __lua_type = type ---@type fun(narray: integer, nhash: integer): table local __lua_table_new = (function() @@ -363,8 +381,9 @@ local __table_pool_tag = { entity_list = 7, fragment_set = 8, fragment_list = 9, - component_list = 10, - __count = 10, + component_map = 10, + component_list = 11, + __count = 11, } ---@class (exact) evolved.table_pool @@ -605,22 +624,18 @@ local function __execute_iterator(execute_state) local chunk_child_list = chunk.__child_list local chunk_child_count = chunk.__child_count - if exclude_set then - for i = 1, chunk_child_count do - local chunk_child = chunk_child_list[i] - local chunk_child_fragment = chunk_child.__fragment + for i = 1, chunk_child_count do + local chunk_child = chunk_child_list[i] + local chunk_child_fragment = chunk_child.__fragment - if not exclude_set[chunk_child_fragment] then - chunk_stack_size = chunk_stack_size + 1 - chunk_stack[chunk_stack_size] = chunk_child - end + local is_chunk_child_matched = + (not chunk_child.__has_explicit_major) and + (not exclude_set or not exclude_set[chunk_child_fragment]) + + if is_chunk_child_matched then + chunk_stack_size = chunk_stack_size + 1 + chunk_stack[chunk_stack_size] = chunk_child end - else - __lua_table_move( - chunk_child_list, 1, chunk_child_count, - chunk_stack_size + 1, chunk_stack) - - chunk_stack_size = chunk_stack_size + chunk_child_count end local chunk_entity_list = chunk.__entity_list @@ -644,9 +659,16 @@ end local __TAG = __acquire_id() local __NAME = __acquire_id() + +local __UNIQUE = __acquire_id() +local __EXPLICIT = __acquire_id() + local __DEFAULT = __acquire_id() local __DUPLICATE = __acquire_id() +local __PREFAB = __acquire_id() +local __DISABLED = __acquire_id() + local __INCLUDES = __acquire_id() local __EXCLUDES = __acquire_id() @@ -663,8 +685,6 @@ local __EXECUTE = __acquire_id() local __PROLOGUE = __acquire_id() local __EPILOGUE = __acquire_id() -local __DISABLED = __acquire_id() - local __DESTROY_POLICY = __acquire_id() local __DESTROY_POLICY_DESTROY_ENTITY = __acquire_id() local __DESTROY_POLICY_REMOVE_FRAGMENT = __acquire_id() @@ -676,24 +696,40 @@ local __DESTROY_POLICY_REMOVE_FRAGMENT = __acquire_id() --- local __safe_tbls = { + ---@type evolved.entity[] + __EMPTY_ENTITY_LIST = __lua_setmetatable({}, { + __tostring = function() return 'empty entity list' end, + __newindex = function() __error_fmt 'attempt to modify empty entity list' end + }), + ---@type table __EMPTY_FRAGMENT_SET = __lua_setmetatable({}, { - __newindex = function() __error_fmt('attempt to modify empty fragment set') end + __tostring = function() return 'empty fragment set' end, + __newindex = function() __error_fmt 'attempt to modify empty fragment set' end }), ---@type evolved.fragment[] __EMPTY_FRAGMENT_LIST = __lua_setmetatable({}, { - __newindex = function() __error_fmt('attempt to modify empty fragment list') end + __tostring = function() return 'empty fragment list' end, + __newindex = function() __error_fmt 'attempt to modify empty fragment list' end + }), + + ---@type table + __EMPTY_COMPONENT_MAP = __lua_setmetatable({}, { + __tostring = function() return 'empty component map' end, + __newindex = function() __error_fmt 'attempt to modify empty component map' end }), ---@type evolved.component[] __EMPTY_COMPONENT_LIST = __lua_setmetatable({}, { - __newindex = function() __error_fmt('attempt to modify empty component list') end + __tostring = function() return 'empty component list' end, + __newindex = function() __error_fmt 'attempt to modify empty component list' end }), ---@type evolved.component[] __EMPTY_COMPONENT_STORAGE = __lua_setmetatable({}, { - __newindex = function() __error_fmt('attempt to modify empty component storage') end + __tostring = function() return 'empty component storage' end, + __newindex = function() __error_fmt 'attempt to modify empty component storage' end }), } @@ -711,13 +747,16 @@ local __evolved_unpack local __evolved_defer local __evolved_commit -local __evolved_is_alive -local __evolved_is_alive_all -local __evolved_is_alive_any +local __evolved_spawn +local __evolved_clone -local __evolved_is_empty -local __evolved_is_empty_all -local __evolved_is_empty_any +local __evolved_alive +local __evolved_alive_all +local __evolved_alive_any + +local __evolved_empty +local __evolved_empty_all +local __evolved_empty_any local __evolved_has local __evolved_has_all @@ -730,35 +769,20 @@ local __evolved_remove local __evolved_clear local __evolved_destroy -local __evolved_multi_set -local __evolved_multi_remove - local __evolved_batch_set local __evolved_batch_remove local __evolved_batch_clear local __evolved_batch_destroy -local __evolved_batch_multi_set -local __evolved_batch_multi_remove - -local __evolved_chunk - -local __evolved_entities -local __evolved_fragments -local __evolved_components - local __evolved_each local __evolved_execute local __evolved_process -local __evolved_spawn_at -local __evolved_spawn_as -local __evolved_spawn_with - local __evolved_debug_mode local __evolved_collect_garbage +local __evolved_chunk local __evolved_builder --- @@ -861,113 +885,6 @@ end local __debug_fns = {} ----@type metatable -__debug_fns.chunk_mt = {} -__debug_fns.chunk_mt.__index = __debug_fns.chunk_mt - ----@type metatable -__debug_fns.chunk_fragment_set_mt = {} -__debug_fns.chunk_fragment_set_mt.__index = __debug_fns.chunk_fragment_set_mt - ----@type metatable -__debug_fns.chunk_fragment_list_mt = {} -__debug_fns.chunk_fragment_list_mt.__index = __debug_fns.chunk_fragment_list_mt - ----@type metatable -__debug_fns.chunk_component_indices_mt = {} -__debug_fns.chunk_component_indices_mt.__index = __debug_fns.chunk_component_indices_mt - ----@type metatable -__debug_fns.chunk_component_storages_mt = {} -__debug_fns.chunk_component_storages_mt.__index = __debug_fns.chunk_component_storages_mt - ----@type metatable -__debug_fns.chunk_component_fragments_mt = {} -__debug_fns.chunk_component_fragments_mt.__index = __debug_fns.chunk_component_fragments_mt - ---- ---- ---- ---- ---- - ----@param self evolved.chunk -function __debug_fns.chunk_mt.__tostring(self) - local items = {} ---@type string[] - - for fragment_index, fragment in ipairs(self.__fragment_list) do - items[fragment_index] = __id_name(fragment) - end - - return string.format('<%s>', table.concat(items, ', ')) -end - ----@param self table -function __debug_fns.chunk_fragment_set_mt.__tostring(self) - local items = {} ---@type string[] - - for fragment, fragment_index in pairs(self) do - items[fragment_index] = string.format('(%s -> %d)', - __id_name(fragment), fragment_index) - end - - return string.format('{%s}', table.concat(items, ', ')) -end - ----@param self evolved.fragment[] -function __debug_fns.chunk_fragment_list_mt.__tostring(self) - local items = {} ---@type string[] - - for fragment_index, fragment in ipairs(self) do - items[fragment_index] = string.format('(%d -> %s)', - fragment_index, __id_name(fragment)) - end - - return string.format('[%s]', table.concat(items, ', ')) -end - ----@param self table -function __debug_fns.chunk_component_indices_mt.__tostring(self) - local items = {} ---@type string[] - - for component_fragment, component_index in pairs(self) do - items[component_index] = string.format('(%s -> %d)', - __id_name(component_fragment), component_index) - end - - return string.format('{%s}', table.concat(items, ', ')) -end - ----@param self evolved.storage[] -function __debug_fns.chunk_component_storages_mt.__tostring(self) - local items = {} ---@type string[] - - for component_index, component_storage in ipairs(self) do - items[component_index] = string.format('(%d -> #%d)', - component_index, #component_storage) - end - - return string.format('[%s]', table.concat(items, ', ')) -end - ----@param self evolved.fragment[] -function __debug_fns.chunk_component_fragments_mt.__tostring(self) - local items = {} ---@type string[] - - for component_index, component_fragment in ipairs(self) do - items[component_index] = string.format('(%d -> %s)', - component_index, __id_name(component_fragment)) - end - - return string.format('[%s]', table.concat(items, ', ')) -end - ---- ---- ---- ---- ---- - ---@param chunk evolved.chunk function __debug_fns.validate_chunk(chunk) if chunk.__unreachable_or_collected then @@ -1028,6 +945,13 @@ function __debug_fns.validate_fragment_list(fragment_list, fragment_count) end end +---@param components table +function __debug_fns.validate_component_map(components) + for fragment in __lua_next, components do + __debug_fns.validate_fragment(fragment) + end +end + ---@param query evolved.query function __debug_fns.validate_query(query) local query_index = query % 0x100000 @@ -1067,10 +991,10 @@ end ---@nodiscard local function __new_chunk(chunk_parent, chunk_fragment) ---@type table - local chunk_fragment_set = __lua_setmetatable({}, __debug_fns.chunk_fragment_set_mt) + local chunk_fragment_set = {} ---@type evolved.fragment[] - local chunk_fragment_list = __lua_setmetatable({}, __debug_fns.chunk_fragment_list_mt) + local chunk_fragment_list = {} ---@type integer local chunk_fragment_count = 0 @@ -1079,26 +1003,34 @@ local function __new_chunk(chunk_parent, chunk_fragment) local chunk_component_count = 0 ---@type table - local chunk_component_indices = __lua_setmetatable({}, __debug_fns.chunk_component_indices_mt) + local chunk_component_indices = {} ---@type evolved.storage[] - local chunk_component_storages = __lua_setmetatable({}, __debug_fns.chunk_component_storages_mt) + local chunk_component_storages = {} ---@type evolved.fragment[] - local chunk_component_fragments = __lua_setmetatable({}, __debug_fns.chunk_component_fragments_mt) + local chunk_component_fragments = {} - local has_setup_hooks = (chunk_parent and chunk_parent.__has_setup_hooks) + local has_setup_hooks = (chunk_parent ~= nil and chunk_parent.__has_setup_hooks) or __evolved_has_any(chunk_fragment, __DEFAULT, __DUPLICATE) - local has_assign_hooks = (chunk_parent and chunk_parent.__has_assign_hooks) + local has_assign_hooks = (chunk_parent ~= nil and chunk_parent.__has_assign_hooks) or __evolved_has_any(chunk_fragment, __ON_SET, __ON_ASSIGN) - local has_insert_hooks = (chunk_parent and chunk_parent.__has_insert_hooks) + local has_insert_hooks = (chunk_parent ~= nil and chunk_parent.__has_insert_hooks) or __evolved_has_any(chunk_fragment, __ON_SET, __ON_INSERT) - local has_remove_hooks = (chunk_parent and chunk_parent.__has_remove_hooks) + local has_remove_hooks = (chunk_parent ~= nil and chunk_parent.__has_remove_hooks) or __evolved_has(chunk_fragment, __ON_REMOVE) + local has_unique_major = __evolved_has(chunk_fragment, __UNIQUE) + local has_unique_minors = chunk_parent ~= nil and chunk_parent.__has_unique_fragments + local has_unique_fragments = has_unique_major or has_unique_minors + + local has_explicit_major = __evolved_has(chunk_fragment, __EXPLICIT) + local has_explicit_minors = chunk_parent ~= nil and chunk_parent.__has_explicit_fragments + local has_explicit_fragments = has_explicit_major or has_explicit_minors + ---@type evolved.chunk local chunk = __lua_setmetatable({ __parent = nil, @@ -1122,7 +1054,13 @@ local function __new_chunk(chunk_parent, chunk_fragment) __has_assign_hooks = has_assign_hooks, __has_insert_hooks = has_insert_hooks, __has_remove_hooks = has_remove_hooks, - }, __debug_fns.chunk_mt) + __has_unique_major = has_unique_major, + __has_unique_minors = has_unique_minors, + __has_unique_fragments = has_unique_fragments, + __has_explicit_major = has_explicit_major, + __has_explicit_minors = has_explicit_minors, + __has_explicit_fragments = has_explicit_fragments, + }, __chunk_mt) if chunk_parent then local parent_fragment_list = chunk_parent.__fragment_list @@ -1239,17 +1177,11 @@ local function __chunk_with_fragment(chunk, fragment) end ---@param chunk? evolved.chunk ----@param fragment_list evolved.fragment[] ----@param fragment_count integer +---@param components table ---@return evolved.chunk? ---@nodiscard -local function __chunk_with_fragment_list(chunk, fragment_list, fragment_count) - if fragment_count == 0 then - return chunk - end - - for i = 1, fragment_count do - local fragment = fragment_list[i] +local function __chunk_with_components(chunk, components) + for fragment in __lua_next, components do chunk = __chunk_with_fragment(chunk, fragment) end @@ -1313,51 +1245,37 @@ local function __chunk_without_fragments(chunk, ...) end ---@param chunk? evolved.chunk ----@param fragment_list evolved.fragment[] ----@param fragment_count integer ---@return evolved.chunk? ---@nodiscard -local function __chunk_without_fragment_list(chunk, fragment_list, fragment_count) - if fragment_count == 0 then +local function __chunk_without_unique_fragments(chunk) + if not chunk then + return nil + end + + if not chunk.__has_unique_fragments then return chunk end - for i = 1, fragment_count do - local fragment = fragment_list[i] - chunk = __chunk_without_fragment(chunk, fragment) + while chunk and chunk.__has_unique_major do + chunk = chunk.__parent end - return chunk -end + local new_chunk = nil ---- ---- ---- ---- ---- + if chunk then + local chunk_fragment_list = chunk.__fragment_list + local chunk_fragment_count = chunk.__fragment_count ----@param chunk evolved.chunk ----@return evolved.chunk chunk -local function __chunk_pin(chunk) - local chunk_pin_count = __pinned_chunks[chunk] or 0 + for i = 1, chunk_fragment_count do + local fragment = chunk_fragment_list[i] - __pinned_chunks[chunk] = chunk_pin_count + 1 - - return chunk -end - ----@param chunk evolved.chunk ----@return evolved.chunk -local function __chunk_unpin(chunk) - local chunk_pin_count = __pinned_chunks[chunk] or 0 - - if chunk_pin_count <= 0 then - __error_fmt('unbalanced pin/unpin') + if not __evolved_has(fragment, __UNIQUE) then + new_chunk = __chunk_with_fragment(new_chunk, fragment) + end + end end - __pinned_chunks[chunk] = chunk_pin_count > 1 and chunk_pin_count - 1 or nil - - return chunk + return new_chunk end --- @@ -1384,23 +1302,22 @@ local function __chunk_fragments(head_fragment, ...) return chunk end ----@param fragment_list evolved.fragment[] ----@param fragment_count integer +---@param components table ---@return evolved.chunk? ---@nodiscard -local function __chunk_fragment_list(fragment_list, fragment_count) - if fragment_count == 0 then +local function __chunk_components(components) + local root_fragment = __lua_next(components) + + if not root_fragment then return end - local root_fragment = fragment_list[1] local chunk = __root_chunks[root_fragment] or __chunk_with_fragment(nil, root_fragment) - for i = 2, fragment_count do - local child_fragment = fragment_list[i] - chunk = chunk.__with_fragment_edges[child_fragment] - or __chunk_with_fragment(chunk, child_fragment) + for tail_fragment in __lua_next, components, root_fragment do + chunk = chunk.__with_fragment_edges[tail_fragment] + or __chunk_with_fragment(chunk, tail_fragment) end return chunk @@ -1608,20 +1525,13 @@ local __defer_remove local __defer_clear local __defer_destroy -local __defer_multi_set -local __defer_multi_remove - local __defer_batch_set local __defer_batch_remove local __defer_batch_clear local __defer_batch_destroy -local __defer_batch_multi_set -local __defer_batch_multi_remove - -local __defer_spawn_entity_at -local __defer_spawn_entity_as -local __defer_spawn_entity_with +local __defer_spawn_entity +local __defer_clone_entity local __defer_call_hook @@ -1683,15 +1593,14 @@ local function __detach_all_entities(chunk) end ---@param entity evolved.entity ----@param chunk? evolved.chunk ----@param fragment_list evolved.fragment[] ----@param fragment_count integer ----@param component_list evolved.component[] -local function __spawn_entity_at(entity, chunk, fragment_list, fragment_count, component_list) +---@param components table +local function __spawn_entity(entity, components) if __defer_depth <= 0 then __error_fmt('spawn entity operations should be deferred') end + local chunk = __chunk_components(components) + if not chunk then return end @@ -1699,10 +1608,8 @@ local function __spawn_entity_at(entity, chunk, fragment_list, fragment_count, c local chunk_entity_list = chunk.__entity_list local chunk_entity_count = chunk.__entity_count - local chunk_component_count = chunk.__component_count local chunk_component_indices = chunk.__component_indices local chunk_component_storages = chunk.__component_storages - local chunk_component_fragments = chunk.__component_fragments local place = chunk_entity_count + 1 chunk.__entity_count = place @@ -1719,52 +1626,15 @@ local function __spawn_entity_at(entity, chunk, fragment_list, fragment_count, c end if chunk.__has_setup_hooks then - for component_index = 1, chunk_component_count do - local fragment = chunk_component_fragments[component_index] - - ---@type evolved.default?, evolved.duplicate? - local fragment_default, fragment_duplicate = - __evolved_get(fragment, __DEFAULT, __DUPLICATE) - - local new_component = fragment_default - - if new_component ~= nil and fragment_duplicate then - new_component = fragment_duplicate(new_component) - end - - if new_component == nil then - new_component = true - end - - local component_storage = chunk_component_storages[component_index] - - component_storage[place] = new_component - end - else - for component_index = 1, chunk_component_count do - local new_component = true - - local component_storage = chunk_component_storages[component_index] - - component_storage[place] = new_component - end - end - - if chunk.__has_setup_hooks then - for i = 1, fragment_count do - local fragment = fragment_list[i] + for fragment, component in __lua_next, components do local component_index = chunk_component_indices[fragment] if component_index then - ---@type evolved.default?, evolved.duplicate? - local fragment_default, fragment_duplicate = - __evolved_get(fragment, __DEFAULT, __DUPLICATE) + ---@type evolved.duplicate? + local fragment_duplicate = + __evolved_get(fragment, __DUPLICATE) - local new_component = component_list[i] - - if new_component == nil then - new_component = fragment_default - end + local new_component = component if new_component ~= nil and fragment_duplicate then new_component = fragment_duplicate(new_component) @@ -1780,16 +1650,11 @@ local function __spawn_entity_at(entity, chunk, fragment_list, fragment_count, c end end else - for i = 1, fragment_count do - local fragment = fragment_list[i] + for fragment, component in __lua_next, components do local component_index = chunk_component_indices[fragment] if component_index then - local new_component = component_list[i] - - if new_component == nil then - new_component = true - end + local new_component = component local component_storage = chunk_component_storages[component_index] @@ -1837,20 +1702,20 @@ local function __spawn_entity_at(entity, chunk, fragment_list, fragment_count, c end ---@param entity evolved.entity ----@param prefab? evolved.entity ----@param fragment_list evolved.fragment[] ----@param fragment_count integer ----@param component_list evolved.component[] -local function __spawn_entity_as(entity, prefab, fragment_list, fragment_count, component_list) +---@param prefab evolved.entity +---@param components table +local function __clone_entity(entity, prefab, components) if __defer_depth <= 0 then - __error_fmt('spawn entity operations should be deferred') + __error_fmt('clone entity operations should be deferred') end - local prefab_index = prefab and prefab % 0x100000 - local prefab_chunk = prefab and __entity_chunks[prefab_index] - local prefab_place = prefab and __entity_places[prefab_index] + local prefab_index = prefab % 0x100000 + local prefab_chunk = __entity_chunks[prefab_index] + local prefab_place = __entity_places[prefab_index] - local chunk = __chunk_with_fragment_list(prefab_chunk, fragment_list, fragment_count) + local chunk = __chunk_with_components( + __chunk_without_unique_fragments(prefab_chunk), + components) if not chunk then return @@ -1884,185 +1749,64 @@ local function __spawn_entity_as(entity, prefab, fragment_list, fragment_count, if prefab_chunk.__has_setup_hooks then for prefab_component_index = 1, prefab_component_count do local fragment = prefab_component_fragments[prefab_component_index] + local component_index = chunk_component_indices[fragment] - ---@type evolved.duplicate? - local fragment_duplicate = - __evolved_get(fragment, __DUPLICATE) + if component_index then + ---@type evolved.duplicate? + local fragment_duplicate = + __evolved_get(fragment, __DUPLICATE) - local prefab_component_storage = prefab_component_storages[prefab_component_index] - local prefab_component = prefab_component_storage[prefab_place] + local prefab_component_storage = prefab_component_storages[prefab_component_index] + local prefab_component = prefab_component_storage[prefab_place] - local new_component = prefab_component + local new_component = prefab_component - if new_component ~= nil and fragment_duplicate then - new_component = fragment_duplicate(new_component) + if new_component ~= nil and fragment_duplicate then + new_component = fragment_duplicate(new_component) + end + + if new_component == nil then + new_component = true + end + + local component_storage = chunk_component_storages[component_index] + + component_storage[place] = new_component end - - if new_component == nil then - new_component = true - end - - local entity_component_index = chunk_component_indices[fragment] - local entity_component_storage = chunk_component_storages[entity_component_index] - - entity_component_storage[place] = new_component end else for prefab_component_index = 1, prefab_component_count do local fragment = prefab_component_fragments[prefab_component_index] + local component_index = chunk_component_indices[fragment] - local prefab_component_storage = prefab_component_storages[prefab_component_index] - local prefab_component = prefab_component_storage[prefab_place] + if component_index then + local prefab_component_storage = prefab_component_storages[prefab_component_index] + local prefab_component = prefab_component_storage[prefab_place] - local new_component = prefab_component + local new_component = prefab_component - if new_component == nil then - new_component = true + if new_component == nil then + new_component = true + end + + local component_storage = chunk_component_storages[component_index] + + component_storage[place] = new_component end - - local entity_component_index = chunk_component_indices[fragment] - local entity_component_storage = chunk_component_storages[entity_component_index] - - entity_component_storage[place] = new_component end end end if chunk.__has_setup_hooks then - for i = 1, fragment_count do - local fragment = fragment_list[i] + for fragment, component in __lua_next, components do local component_index = chunk_component_indices[fragment] if component_index then - ---@type evolved.default?, evolved.duplicate? - local fragment_default, fragment_duplicate = - __evolved_get(fragment, __DEFAULT, __DUPLICATE) + ---@type evolved.duplicate? + local fragment_duplicate = + __evolved_get(fragment, __DUPLICATE) - local new_component = component_list[i] - - if new_component == nil then - new_component = fragment_default - end - - if new_component ~= nil and fragment_duplicate then - new_component = fragment_duplicate(new_component) - end - - if new_component == nil then - new_component = true - end - - local entity_component_storage = chunk_component_storages[component_index] - - entity_component_storage[place] = new_component - end - end - else - for i = 1, fragment_count do - local fragment = fragment_list[i] - local component_index = chunk_component_indices[fragment] - - if component_index then - local new_component = component_list[i] - - if new_component == nil then - new_component = true - end - - local entity_component_storage = chunk_component_storages[component_index] - - entity_component_storage[place] = new_component - end - end - end - - if chunk.__has_insert_hooks then - local chunk_fragment_list = chunk.__fragment_list - local chunk_fragment_count = chunk.__fragment_count - - for chunk_fragment_index = 1, chunk_fragment_count do - local fragment = chunk_fragment_list[chunk_fragment_index] - - ---@type evolved.set_hook?, evolved.insert_hook? - local fragment_on_set, fragment_on_insert = - __evolved_get(fragment, __ON_SET, __ON_INSERT) - - local component_index = chunk_component_indices[fragment] - - if component_index then - local component_storage = chunk_component_storages[component_index] - - local new_component = component_storage[place] - - if fragment_on_set then - __defer_call_hook(fragment_on_set, entity, fragment, new_component) - end - - if fragment_on_insert then - __defer_call_hook(fragment_on_insert, entity, fragment, new_component) - end - else - if fragment_on_set then - __defer_call_hook(fragment_on_set, entity, fragment) - end - - if fragment_on_insert then - __defer_call_hook(fragment_on_insert, entity, fragment) - end - end - end - end -end - ----@param entity evolved.entity ----@param chunk? evolved.chunk ----@param fragment_list evolved.fragment[] ----@param fragment_count integer ----@param component_list evolved.component[] -local function __spawn_entity_with(entity, chunk, fragment_list, fragment_count, component_list) - if __defer_depth <= 0 then - __error_fmt('spawn entity operations should be deferred') - end - - if not chunk then - return - end - - local chunk_entity_list = chunk.__entity_list - local chunk_entity_count = chunk.__entity_count - - local chunk_component_indices = chunk.__component_indices - local chunk_component_storages = chunk.__component_storages - - local place = chunk_entity_count + 1 - chunk.__entity_count = place - - chunk_entity_list[place] = entity - - do - local entity_index = entity % 0x100000 - - __entity_chunks[entity_index] = chunk - __entity_places[entity_index] = place - - __structural_changes = __structural_changes + 1 - end - - if chunk.__has_setup_hooks then - for i = 1, fragment_count do - local fragment = fragment_list[i] - local component_index = chunk_component_indices[fragment] - - if component_index then - ---@type evolved.default?, evolved.duplicate? - local fragment_default, fragment_duplicate = - __evolved_get(fragment, __DEFAULT, __DUPLICATE) - - local new_component = component_list[i] - - if new_component == nil then - new_component = fragment_default - end + local new_component = component if new_component ~= nil and fragment_duplicate then new_component = fragment_duplicate(new_component) @@ -2078,16 +1822,11 @@ local function __spawn_entity_with(entity, chunk, fragment_list, fragment_count, end end else - for i = 1, fragment_count do - local fragment = fragment_list[i] + for fragment, component in __lua_next, components do local component_index = chunk_component_indices[fragment] if component_index then - local new_component = component_list[i] - - if new_component == nil then - new_component = true - end + local new_component = component local component_storage = chunk_component_storages[component_index] @@ -2144,9 +1883,6 @@ local __chunk_set local __chunk_remove local __chunk_clear -local __chunk_multi_set -local __chunk_multi_remove - --- --- --- @@ -2897,525 +2633,6 @@ function __chunk_clear(chunk) __structural_changes = __structural_changes + 1 end ----@param old_chunk evolved.chunk ----@param fragments evolved.fragment[] ----@param fragment_count integer ----@param components evolved.component[] -function __chunk_multi_set(old_chunk, fragments, fragment_count, components) - if __defer_depth <= 0 then - __error_fmt('batched chunk operations should be deferred') - end - - if fragment_count == 0 then - return - end - - local new_chunk = __chunk_with_fragment_list(old_chunk, fragments, fragment_count) - - if not new_chunk then - return - end - - local old_entity_list = old_chunk.__entity_list - local old_entity_count = old_chunk.__entity_count - - if old_entity_count == 0 then - return - end - - local old_fragment_set = old_chunk.__fragment_set - local old_component_count = old_chunk.__component_count - local old_component_indices = old_chunk.__component_indices - local old_component_storages = old_chunk.__component_storages - local old_component_fragments = old_chunk.__component_fragments - - if old_chunk == new_chunk then - local old_chunk_has_setup_hooks = old_chunk.__has_setup_hooks - local old_chunk_has_assign_hooks = old_chunk.__has_assign_hooks - - for i = 1, fragment_count do - local fragment = fragments[i] - - ---@type evolved.default?, evolved.duplicate?, evolved.set_hook?, evolved.assign_hook? - local fragment_default, fragment_duplicate, fragment_on_set, fragment_on_assign - - if old_chunk_has_setup_hooks or old_chunk_has_assign_hooks then - fragment_default, fragment_duplicate, fragment_on_set, fragment_on_assign = - __evolved_get(fragment, __DEFAULT, __DUPLICATE, __ON_SET, __ON_ASSIGN) - end - - if fragment_on_set or fragment_on_assign then - local old_component_index = old_component_indices[fragment] - - if old_component_index then - local old_component_storage = old_component_storages[old_component_index] - - if fragment_duplicate then - for old_place = 1, old_entity_count do - local entity = old_entity_list[old_place] - - local new_component = components[i] - if new_component == nil then new_component = fragment_default end - if new_component ~= nil then new_component = fragment_duplicate(new_component) end - if new_component == nil then new_component = true end - - local old_component = old_component_storage[old_place] - old_component_storage[old_place] = new_component - - if fragment_on_set then - __defer_call_hook(fragment_on_set, entity, fragment, new_component, old_component) - end - - if fragment_on_assign then - __defer_call_hook(fragment_on_assign, entity, fragment, new_component, old_component) - end - end - else - local new_component = components[i] - if new_component == nil then new_component = fragment_default end - if new_component == nil then new_component = true end - - for old_place = 1, old_entity_count do - local entity = old_entity_list[old_place] - - local old_component = old_component_storage[old_place] - old_component_storage[old_place] = new_component - - if fragment_on_set then - __defer_call_hook(fragment_on_set, entity, fragment, new_component, old_component) - end - - if fragment_on_assign then - __defer_call_hook(fragment_on_assign, entity, fragment, new_component, old_component) - end - end - end - else - for old_place = 1, old_entity_count do - local entity = old_entity_list[old_place] - - if fragment_on_set then - __defer_call_hook(fragment_on_set, entity, fragment) - end - - if fragment_on_assign then - __defer_call_hook(fragment_on_assign, entity, fragment) - end - end - end - else - local old_component_index = old_component_indices[fragment] - - if old_component_index then - local old_component_storage = old_component_storages[old_component_index] - - if fragment_duplicate then - for old_place = 1, old_entity_count do - local new_component = components[i] - if new_component == nil then new_component = fragment_default end - if new_component ~= nil then new_component = fragment_duplicate(new_component) end - if new_component == nil then new_component = true end - old_component_storage[old_place] = new_component - end - else - local new_component = components[i] - if new_component == nil then new_component = fragment_default end - if new_component == nil then new_component = true end - for old_place = 1, old_entity_count do - old_component_storage[old_place] = new_component - end - end - else - -- nothing - end - end - end - else - local new_entity_list = new_chunk.__entity_list - local new_entity_count = new_chunk.__entity_count - - local new_component_indices = new_chunk.__component_indices - local new_component_storages = new_chunk.__component_storages - - local new_chunk_has_setup_hooks = new_chunk.__has_setup_hooks - local new_chunk_has_assign_hooks = new_chunk.__has_assign_hooks - local new_chunk_has_insert_hooks = new_chunk.__has_insert_hooks - - if new_entity_count == 0 then - old_chunk.__entity_list, new_chunk.__entity_list = - new_entity_list, old_entity_list - - old_entity_list, new_entity_list = - new_entity_list, old_entity_list - - for old_ci = 1, old_component_count do - local old_f = old_component_fragments[old_ci] - local new_ci = new_component_indices[old_f] - old_component_storages[old_ci], new_component_storages[new_ci] = - new_component_storages[new_ci], old_component_storages[old_ci] - end - - new_chunk.__entity_count = old_entity_count - else - __lua_table_move( - old_entity_list, 1, old_entity_count, - new_entity_count + 1, new_entity_list) - - for old_ci = 1, old_component_count do - local old_f = old_component_fragments[old_ci] - local old_cs = old_component_storages[old_ci] - local new_ci = new_component_indices[old_f] - local new_cs = new_component_storages[new_ci] - __lua_table_move(old_cs, 1, old_entity_count, new_entity_count + 1, new_cs) - end - - new_chunk.__entity_count = new_entity_count + old_entity_count - end - - do - local entity_chunks = __entity_chunks - local entity_places = __entity_places - - for new_place = new_entity_count + 1, new_entity_count + old_entity_count do - local entity = new_entity_list[new_place] - local entity_index = entity % 0x100000 - entity_chunks[entity_index] = new_chunk - entity_places[entity_index] = new_place - end - - __detach_all_entities(old_chunk) - end - - ---@type table - local inserted_set = __acquire_table(__table_pool_tag.fragment_set) - - for i = 1, fragment_count do - local fragment = fragments[i] - - ---@type evolved.default?, evolved.duplicate?, evolved.set_hook?, evolved.assign_hook?, evolved.insert_hook? - local fragment_default, fragment_duplicate, fragment_on_set, fragment_on_assign, fragment_on_insert - - if new_chunk_has_setup_hooks or new_chunk_has_assign_hooks or new_chunk_has_insert_hooks then - fragment_default, fragment_duplicate, fragment_on_set, fragment_on_assign, fragment_on_insert = - __evolved_get(fragment, __DEFAULT, __DUPLICATE, __ON_SET, __ON_ASSIGN, __ON_INSERT) - end - - if inserted_set[fragment] or old_fragment_set[fragment] then - if fragment_on_set or fragment_on_assign then - local new_component_index = new_component_indices[fragment] - - if new_component_index then - local new_component_storage = new_component_storages[new_component_index] - - if fragment_duplicate then - for new_place = new_entity_count + 1, new_entity_count + old_entity_count do - local entity = new_entity_list[new_place] - - local new_component = components[i] - if new_component == nil then new_component = fragment_default end - if new_component ~= nil then new_component = fragment_duplicate(new_component) end - if new_component == nil then new_component = true end - - local old_component = new_component_storage[new_place] - new_component_storage[new_place] = new_component - - if fragment_on_set then - __defer_call_hook(fragment_on_set, entity, fragment, new_component, old_component) - end - - if fragment_on_assign then - __defer_call_hook(fragment_on_assign, entity, fragment, new_component, old_component) - end - end - else - local new_component = components[i] - if new_component == nil then new_component = fragment_default end - if new_component == nil then new_component = true end - - for new_place = new_entity_count + 1, new_entity_count + old_entity_count do - local entity = new_entity_list[new_place] - - local old_component = new_component_storage[new_place] - new_component_storage[new_place] = new_component - - if fragment_on_set then - __defer_call_hook(fragment_on_set, entity, fragment, new_component, old_component) - end - - if fragment_on_assign then - __defer_call_hook(fragment_on_assign, entity, fragment, new_component, old_component) - end - end - end - else - for new_place = new_entity_count + 1, new_entity_count + old_entity_count do - local entity = new_entity_list[new_place] - - if fragment_on_set then - __defer_call_hook(fragment_on_set, entity, fragment) - end - - if fragment_on_assign then - __defer_call_hook(fragment_on_assign, entity, fragment) - end - end - end - else - local new_component_index = new_component_indices[fragment] - - if new_component_index then - local new_component_storage = new_component_storages[new_component_index] - - if fragment_duplicate then - for new_place = new_entity_count + 1, new_entity_count + old_entity_count do - local new_component = components[i] - if new_component == nil then new_component = fragment_default end - if new_component ~= nil then new_component = fragment_duplicate(new_component) end - if new_component == nil then new_component = true end - new_component_storage[new_place] = new_component - end - else - local new_component = components[i] - if new_component == nil then new_component = fragment_default end - if new_component == nil then new_component = true end - for new_place = new_entity_count + 1, new_entity_count + old_entity_count do - new_component_storage[new_place] = new_component - end - end - else - -- nothing - end - end - else - inserted_set[fragment] = true - - if fragment_on_set or fragment_on_insert then - local new_component_index = new_component_indices[fragment] - - if new_component_index then - local new_component_storage = new_component_storages[new_component_index] - - if fragment_duplicate then - for new_place = new_entity_count + 1, new_entity_count + old_entity_count do - local entity = new_entity_list[new_place] - - local new_component = components[i] - if new_component == nil then new_component = fragment_default end - if new_component ~= nil then new_component = fragment_duplicate(new_component) end - if new_component == nil then new_component = true end - - new_component_storage[new_place] = new_component - - if fragment_on_set then - __defer_call_hook(fragment_on_set, entity, fragment, new_component) - end - - if fragment_on_insert then - __defer_call_hook(fragment_on_insert, entity, fragment, new_component) - end - end - else - local new_component = components[i] - if new_component == nil then new_component = fragment_default end - if new_component == nil then new_component = true end - - for new_place = new_entity_count + 1, new_entity_count + old_entity_count do - local entity = new_entity_list[new_place] - - new_component_storage[new_place] = new_component - - if fragment_on_set then - __defer_call_hook(fragment_on_set, entity, fragment, new_component) - end - - if fragment_on_insert then - __defer_call_hook(fragment_on_insert, entity, fragment, new_component) - end - end - end - else - for new_place = new_entity_count + 1, new_entity_count + old_entity_count do - local entity = new_entity_list[new_place] - - if fragment_on_set then - __defer_call_hook(fragment_on_set, entity, fragment) - end - - if fragment_on_insert then - __defer_call_hook(fragment_on_insert, entity, fragment) - end - end - end - else - local new_component_index = new_component_indices[fragment] - - if new_component_index then - local new_component_storage = new_component_storages[new_component_index] - - if fragment_duplicate then - for new_place = new_entity_count + 1, new_entity_count + old_entity_count do - local new_component = components[i] - if new_component == nil then new_component = fragment_default end - if new_component ~= nil then new_component = fragment_duplicate(new_component) end - if new_component == nil then new_component = true end - new_component_storage[new_place] = new_component - end - else - local new_component = components[i] - if new_component == nil then new_component = fragment_default end - if new_component == nil then new_component = true end - for new_place = new_entity_count + 1, new_entity_count + old_entity_count do - new_component_storage[new_place] = new_component - end - end - else - -- nothing - end - end - end - end - - __release_table(__table_pool_tag.fragment_set, inserted_set) - - __structural_changes = __structural_changes + 1 - end -end - ----@param old_chunk evolved.chunk ----@param fragments evolved.fragment[] ----@param fragment_count integer -function __chunk_multi_remove(old_chunk, fragments, fragment_count) - if __defer_depth <= 0 then - __error_fmt('batched chunk operations should be deferred') - end - - if fragment_count == 0 then - return - end - - local new_chunk = __chunk_without_fragment_list(old_chunk, fragments, fragment_count) - - if old_chunk == new_chunk then - return - end - - local old_entity_list = old_chunk.__entity_list - local old_entity_count = old_chunk.__entity_count - - if old_entity_count == 0 then - return - end - - local old_fragment_set = old_chunk.__fragment_set - local old_component_indices = old_chunk.__component_indices - local old_component_storages = old_chunk.__component_storages - - if old_chunk.__has_remove_hooks then - ---@type table - local removed_set = __acquire_table(__table_pool_tag.fragment_set) - - for i = 1, fragment_count do - local fragment = fragments[i] - - if not removed_set[fragment] and old_fragment_set[fragment] then - removed_set[fragment] = true - - ---@type evolved.remove_hook? - local fragment_on_remove = __evolved_get(fragment, __ON_REMOVE) - - if fragment_on_remove then - local old_component_index = old_component_indices[fragment] - - if old_component_index then - local old_component_storage = old_component_storages[old_component_index] - - for old_place = 1, old_entity_count do - local entity = old_entity_list[old_place] - local old_component = old_component_storage[old_place] - __defer_call_hook(fragment_on_remove, entity, fragment, old_component) - end - else - for old_place = 1, old_entity_count do - local entity = old_entity_list[old_place] - __defer_call_hook(fragment_on_remove, entity, fragment) - end - end - end - end - end - - __release_table(__table_pool_tag.fragment_set, removed_set) - end - - if new_chunk then - local new_entity_list = new_chunk.__entity_list - local new_entity_count = new_chunk.__entity_count - - local new_component_count = new_chunk.__component_count - local new_component_storages = new_chunk.__component_storages - local new_component_fragments = new_chunk.__component_fragments - - if new_entity_count == 0 then - old_chunk.__entity_list, new_chunk.__entity_list = - new_entity_list, old_entity_list - - old_entity_list, new_entity_list = - new_entity_list, old_entity_list - - for new_ci = 1, new_component_count do - local new_f = new_component_fragments[new_ci] - local old_ci = old_component_indices[new_f] - old_component_storages[old_ci], new_component_storages[new_ci] = - new_component_storages[new_ci], old_component_storages[old_ci] - end - - new_chunk.__entity_count = old_entity_count - else - __lua_table_move( - old_entity_list, 1, old_entity_count, - new_entity_count + 1, new_entity_list) - - for new_ci = 1, new_component_count do - local new_f = new_component_fragments[new_ci] - local new_cs = new_component_storages[new_ci] - local old_ci = old_component_indices[new_f] - local old_cs = old_component_storages[old_ci] - __lua_table_move(old_cs, 1, old_entity_count, new_entity_count + 1, new_cs) - end - - new_chunk.__entity_count = new_entity_count + old_entity_count - end - - do - local entity_chunks = __entity_chunks - local entity_places = __entity_places - - for new_place = new_entity_count + 1, new_entity_count + old_entity_count do - local entity = new_entity_list[new_place] - local entity_index = entity % 0x100000 - entity_chunks[entity_index] = new_chunk - entity_places[entity_index] = new_place - end - - __detach_all_entities(old_chunk) - end - else - local entity_chunks = __entity_chunks - local entity_places = __entity_places - - for old_place = 1, old_entity_count do - local entity = old_entity_list[old_place] - local entity_index = entity % 0x100000 - entity_chunks[entity_index] = nil - entity_places[entity_index] = nil - end - - __detach_all_entities(old_chunk) - end - - __structural_changes = __structural_changes + 1 -end - --- --- --- @@ -3495,24 +2712,17 @@ local __defer_op = { clear = 3, destroy = 4, - multi_set = 5, - multi_remove = 6, + batch_set = 5, + batch_remove = 6, + batch_clear = 7, + batch_destroy = 8, - batch_set = 7, - batch_remove = 8, - batch_clear = 9, - batch_destroy = 10, + spawn_entity = 9, + clone_entity = 10, - batch_multi_set = 11, - batch_multi_remove = 12, + call_hook = 11, - spawn_entity_at = 13, - spawn_entity_as = 14, - spawn_entity_with = 15, - - call_hook = 16, - - __count = 16, + __count = 11, } ---@type table @@ -3759,71 +2969,6 @@ __defer_ops[__defer_op.destroy] = function(bytes, index) return 1 + entity_count end ----@param entity evolved.entity ----@param fragments evolved.fragment[] ----@param fragment_count integer ----@param components evolved.component[] ----@param component_count integer -function __defer_multi_set(entity, fragments, fragment_count, components, component_count) - ---@type evolved.fragment[] - local fragment_list = __acquire_table(__table_pool_tag.fragment_list) - __lua_table_move(fragments, 1, fragment_count, 1, fragment_list) - - ---@type evolved.component[] - local component_list = __acquire_table(__table_pool_tag.component_list) - __lua_table_move(components, 1, component_count, 1, component_list) - - local length = __defer_length - local bytecode = __defer_bytecode - - bytecode[length + 1] = __defer_op.multi_set - bytecode[length + 2] = entity - bytecode[length + 3] = fragment_list - bytecode[length + 4] = component_list - - __defer_length = length + 4 -end - -__defer_ops[__defer_op.multi_set] = function(bytes, index) - local entity = bytes[index + 0] - local fragments = bytes[index + 1] - local components = bytes[index + 2] - - __evolved_multi_set(entity, fragments, components) - __release_table(__table_pool_tag.fragment_list, fragments) - __release_table(__table_pool_tag.component_list, components) - - return 3 -end - ----@param entity evolved.entity ----@param fragments evolved.fragment[] ----@param fragment_count integer -function __defer_multi_remove(entity, fragments, fragment_count) - ---@type evolved.fragment[] - local fragment_list = __acquire_table(__table_pool_tag.fragment_list) - __lua_table_move(fragments, 1, fragment_count, 1, fragment_list) - - local length = __defer_length - local bytecode = __defer_bytecode - - bytecode[length + 1] = __defer_op.multi_remove - bytecode[length + 2] = entity - bytecode[length + 3] = fragment_list - - __defer_length = length + 3 -end - -__defer_ops[__defer_op.multi_remove] = function(bytes, index) - local entity = bytes[index + 0] - local fragments = bytes[index + 1] - - __evolved_multi_remove(entity, fragments) - __release_table(__table_pool_tag.fragment_list, fragments) - - return 2 -end - ---@param query evolved.query ---@param fragment evolved.fragment ---@param component evolved.component @@ -4064,240 +3209,86 @@ __defer_ops[__defer_op.batch_destroy] = function(bytes, index) return 1 + argument_count end ----@param query evolved.query ----@param fragments evolved.fragment[] ----@param fragment_count integer ----@param components evolved.component[] ----@param component_count integer -function __defer_batch_multi_set(query, fragments, fragment_count, components, component_count) - ---@type evolved.fragment[] - local fragment_list = __acquire_table(__table_pool_tag.fragment_list) - __lua_table_move(fragments, 1, fragment_count, 1, fragment_list) +---@param entity evolved.entity +---@param components table +function __defer_spawn_entity(entity, components) + ---@type table + local component_map = __acquire_table(__table_pool_tag.component_map) - ---@type evolved.component[] - local component_list = __acquire_table(__table_pool_tag.component_list) - __lua_table_move(components, 1, component_count, 1, component_list) + for fragment, component in __lua_next, components do + component_map[fragment] = component + end local length = __defer_length local bytecode = __defer_bytecode - bytecode[length + 1] = __defer_op.batch_multi_set - bytecode[length + 2] = query - bytecode[length + 3] = fragment_list - bytecode[length + 4] = component_list - - __defer_length = length + 4 -end - -__defer_ops[__defer_op.batch_multi_set] = function(bytes, index) - local query = bytes[index + 0] - local fragments = bytes[index + 1] - local components = bytes[index + 2] - - __evolved_batch_multi_set(query, fragments, components) - __release_table(__table_pool_tag.fragment_list, fragments) - __release_table(__table_pool_tag.component_list, components) - - return 3 -end - ----@param query evolved.query ----@param fragments evolved.fragment[] ----@param fragment_count integer -function __defer_batch_multi_remove(query, fragments, fragment_count) - ---@type evolved.fragment[] - local fragment_list = __acquire_table(__table_pool_tag.fragment_list) - __lua_table_move(fragments, 1, fragment_count, 1, fragment_list) - - local length = __defer_length - local bytecode = __defer_bytecode - - bytecode[length + 1] = __defer_op.batch_multi_remove - bytecode[length + 2] = query - bytecode[length + 3] = fragment_list + bytecode[length + 1] = __defer_op.spawn_entity + bytecode[length + 2] = entity + bytecode[length + 3] = component_map __defer_length = length + 3 end -__defer_ops[__defer_op.batch_multi_remove] = function(bytes, index) - local query = bytes[index + 0] - local fragments = bytes[index + 1] +__defer_ops[__defer_op.spawn_entity] = function(bytes, index) + local entity = bytes[index + 0] + local component_map = bytes[index + 1] - __evolved_batch_multi_remove(query, fragments) - __release_table(__table_pool_tag.fragment_list, fragments) + if __debug_mode then + __debug_fns.validate_entity(entity) + __debug_fns.validate_component_map(component_map) + end + + __evolved_defer() + do + __spawn_entity(entity, component_map) + __release_table(__table_pool_tag.component_map, component_map) + end + __evolved_commit() return 2 end ---@param entity evolved.entity ----@param chunk? evolved.chunk ----@param fragments evolved.fragment[] ----@param fragment_count integer ----@param components evolved.component[] ----@param component_count integer -function __defer_spawn_entity_at(entity, chunk, fragments, fragment_count, components, component_count) - if component_count > fragment_count then - component_count = fragment_count +---@param prefab evolved.entity +---@param components table +function __defer_clone_entity(entity, prefab, components) + ---@type table + local component_map = __acquire_table(__table_pool_tag.component_map) + + for fragment, component in __lua_next, components do + component_map[fragment] = component end - ---@type evolved.fragment[] - local fragment_list = __acquire_table(__table_pool_tag.fragment_list) - __lua_table_move(fragments, 1, fragment_count, 1, fragment_list) - - ---@type evolved.component[] - local component_list = __acquire_table(__table_pool_tag.component_list) - __lua_table_move(components, 1, component_count, 1, component_list) - local length = __defer_length local bytecode = __defer_bytecode - bytecode[length + 1] = __defer_op.spawn_entity_at - bytecode[length + 2] = entity - bytecode[length + 3] = chunk and __chunk_pin(chunk) - bytecode[length + 4] = fragment_list - bytecode[length + 5] = fragment_count - bytecode[length + 6] = component_list - - __defer_length = length + 6 -end - -__defer_ops[__defer_op.spawn_entity_at] = function(bytes, index) - local entity = bytes[index + 0] - local chunk = bytes[index + 1] and __chunk_unpin(bytes[index + 1]) - local fragment_list = bytes[index + 2] - local fragment_count = bytes[index + 3] - local component_list = bytes[index + 4] - - if __debug_mode then - if chunk then __debug_fns.validate_chunk(chunk) end - __debug_fns.validate_fragment_list(fragment_list, fragment_count) - end - - __evolved_defer() - do - __spawn_entity_at(entity, chunk, - fragment_list, fragment_count, - component_list) - __release_table(__table_pool_tag.fragment_list, fragment_list) - __release_table(__table_pool_tag.component_list, component_list) - end - __evolved_commit() - - return 5 -end - ----@param entity evolved.entity ----@param prefab? evolved.entity ----@param fragments evolved.fragment[] ----@param fragment_count integer ----@param components evolved.component[] ----@param component_count integer -function __defer_spawn_entity_as(entity, prefab, fragments, fragment_count, components, component_count) - if component_count > fragment_count then - component_count = fragment_count - end - - ---@type evolved.fragment[] - local fragment_list = __acquire_table(__table_pool_tag.fragment_list) - __lua_table_move(fragments, 1, fragment_count, 1, fragment_list) - - ---@type evolved.component[] - local component_list = __acquire_table(__table_pool_tag.component_list) - __lua_table_move(components, 1, component_count, 1, component_list) - - local length = __defer_length - local bytecode = __defer_bytecode - - bytecode[length + 1] = __defer_op.spawn_entity_as + bytecode[length + 1] = __defer_op.clone_entity bytecode[length + 2] = entity bytecode[length + 3] = prefab - bytecode[length + 4] = fragment_list - bytecode[length + 5] = fragment_count - bytecode[length + 6] = component_list + bytecode[length + 4] = component_map - __defer_length = length + 6 + __defer_length = length + 4 end -__defer_ops[__defer_op.spawn_entity_as] = function(bytes, index) +__defer_ops[__defer_op.clone_entity] = function(bytes, index) local entity = bytes[index + 0] local prefab = bytes[index + 1] - local fragment_list = bytes[index + 2] - local fragment_count = bytes[index + 3] - local component_list = bytes[index + 4] + local component_map = bytes[index + 2] if __debug_mode then - if prefab then __debug_fns.validate_prefab(prefab) end - __debug_fns.validate_fragment_list(fragment_list, fragment_count) + __debug_fns.validate_entity(entity) + __debug_fns.validate_prefab(prefab) + __debug_fns.validate_component_map(component_map) end __evolved_defer() do - __spawn_entity_as(entity, prefab, - fragment_list, fragment_count, - component_list) - __release_table(__table_pool_tag.fragment_list, fragment_list) - __release_table(__table_pool_tag.component_list, component_list) + __clone_entity(entity, prefab, component_map) + __release_table(__table_pool_tag.component_map, component_map) end __evolved_commit() - return 5 -end - ----@param entity evolved.entity ----@param chunk? evolved.chunk ----@param fragments evolved.fragment[] ----@param fragment_count integer ----@param components evolved.component[] ----@param component_count integer -function __defer_spawn_entity_with(entity, chunk, fragments, fragment_count, components, component_count) - if component_count > fragment_count then - component_count = fragment_count - end - - ---@type evolved.fragment[] - local fragment_list = __acquire_table(__table_pool_tag.fragment_list) - __lua_table_move(fragments, 1, fragment_count, 1, fragment_list) - - ---@type evolved.component[] - local component_list = __acquire_table(__table_pool_tag.component_list) - __lua_table_move(components, 1, component_count, 1, component_list) - - local length = __defer_length - local bytecode = __defer_bytecode - - bytecode[length + 1] = __defer_op.spawn_entity_with - bytecode[length + 2] = entity - bytecode[length + 3] = chunk and __chunk_pin(chunk) - bytecode[length + 4] = fragment_list - bytecode[length + 5] = fragment_count - bytecode[length + 6] = component_list - - __defer_length = length + 6 -end - -__defer_ops[__defer_op.spawn_entity_with] = function(bytes, index) - local entity = bytes[index + 0] - local chunk = bytes[index + 1] and __chunk_unpin(bytes[index + 1]) - local fragment_list = bytes[index + 2] - local fragment_count = bytes[index + 3] - local component_list = bytes[index + 4] - - if __debug_mode then - if chunk then __debug_fns.validate_chunk(chunk) end - __debug_fns.validate_fragment_list(fragment_list, fragment_count) - end - - __evolved_defer() - do - __spawn_entity_with(entity, chunk, - fragment_list, fragment_count, - component_list) - __release_table(__table_pool_tag.fragment_list, fragment_list) - __release_table(__table_pool_tag.component_list, component_list) - end - __evolved_commit() - - return 5 + return 3 end ---@param hook fun(...) @@ -4476,24 +3467,72 @@ function __evolved_commit() return true end ----@param chunk_or_entity evolved.chunk | evolved.entity ----@return boolean ----@nodiscard -function __evolved_is_alive(chunk_or_entity) - if __lua_type(chunk_or_entity) ~= 'number' then - local chunk = chunk_or_entity --[[@as evolved.chunk]] - return not chunk.__unreachable_or_collected - else - local entity = chunk_or_entity --[[@as evolved.entity]] - local entity_index = entity % 0x100000 - return __freelist_ids[entity_index] == entity +---@param components? table +---@return evolved.entity +function __evolved_spawn(components) + if not components then + components = __safe_tbls.__EMPTY_COMPONENT_MAP end + + if __debug_mode then + __debug_fns.validate_component_map(components) + end + + local entity = __acquire_id() + + if __defer_depth > 0 then + __defer_spawn_entity(entity, components) + else + __evolved_defer() + do + __spawn_entity(entity, components) + end + __evolved_commit() + end + + return entity end ----@param ... evolved.chunk | evolved.entity chunks_or_entities +---@param prefab evolved.entity +---@param components? table +---@return evolved.entity +function __evolved_clone(prefab, components) + if not components then + components = __safe_tbls.__EMPTY_COMPONENT_MAP + end + + if __debug_mode then + __debug_fns.validate_prefab(prefab) + __debug_fns.validate_component_map(components) + end + + local entity = __acquire_id() + + if __defer_depth > 0 then + __defer_clone_entity(entity, prefab, components) + else + __evolved_defer() + do + __clone_entity(entity, prefab, components) + end + __evolved_commit() + end + + return entity +end + +---@param entity evolved.entity ---@return boolean ---@nodiscard -function __evolved_is_alive_all(...) +function __evolved_alive(entity) + local entity_index = entity % 0x100000 + return __freelist_ids[entity_index] == entity +end + +---@param ... evolved.entity entities +---@return boolean +---@nodiscard +function __evolved_alive_all(...) local argument_count = __lua_select('#', ...) if argument_count == 0 then @@ -4503,30 +3542,21 @@ function __evolved_is_alive_all(...) local freelist_ids = __freelist_ids for argument_index = 1, argument_count do - ---@type evolved.chunk | evolved.entity - local chunk_or_entity = __lua_select(argument_index, ...) - - if __lua_type(chunk_or_entity) ~= 'number' then - local chunk = chunk_or_entity --[[@as evolved.chunk]] - if chunk.__unreachable_or_collected then - return false - end - else - local entity = chunk_or_entity --[[@as evolved.entity]] - local entity_index = entity % 0x100000 - if freelist_ids[entity_index] ~= entity then - return false - end + ---@type evolved.entity + local entity = __lua_select(argument_index, ...) + local entity_index = entity % 0x100000 + if freelist_ids[entity_index] ~= entity then + return false end end return true end ----@param ... evolved.chunk | evolved.entity chunks_or_entities +---@param ... evolved.entity entities ---@return boolean ---@nodiscard -function __evolved_is_alive_any(...) +function __evolved_alive_any(...) local argument_count = __lua_select('#', ...) if argument_count == 0 then @@ -4536,44 +3566,29 @@ function __evolved_is_alive_any(...) local freelist_ids = __freelist_ids for argument_index = 1, argument_count do - ---@type evolved.chunk | evolved.entity - local chunk_or_entity = __lua_select(argument_index, ...) - - if __lua_type(chunk_or_entity) ~= 'number' then - local chunk = chunk_or_entity --[[@as evolved.chunk]] - if not chunk.__unreachable_or_collected then - return true - end - else - local entity = chunk_or_entity --[[@as evolved.entity]] - local entity_index = entity % 0x100000 - if freelist_ids[entity_index] == entity then - return true - end + ---@type evolved.entity + local entity = __lua_select(argument_index, ...) + local entity_index = entity % 0x100000 + if freelist_ids[entity_index] == entity then + return true end end return false end ----@param chunk_or_entity evolved.chunk | evolved.entity +---@param entity evolved.entity ---@return boolean ---@nodiscard -function __evolved_is_empty(chunk_or_entity) - if __lua_type(chunk_or_entity) ~= 'number' then - local chunk = chunk_or_entity --[[@as evolved.chunk]] - return chunk.__unreachable_or_collected or chunk.__entity_count == 0 - else - local entity = chunk_or_entity --[[@as evolved.entity]] - local entity_index = entity % 0x100000 - return __freelist_ids[entity_index] ~= entity or not __entity_chunks[entity_index] - end +function __evolved_empty(entity) + local entity_index = entity % 0x100000 + return __freelist_ids[entity_index] ~= entity or not __entity_chunks[entity_index] end ----@param ... evolved.chunk | evolved.entity chunks_or_entities +---@param ... evolved.entity entities ---@return boolean ---@nodiscard -function __evolved_is_empty_all(...) +function __evolved_empty_all(...) local argument_count = __lua_select('#', ...) if argument_count == 0 then @@ -4583,30 +3598,21 @@ function __evolved_is_empty_all(...) local freelist_ids = __freelist_ids for argument_index = 1, argument_count do - ---@type evolved.chunk | evolved.entity - local chunk_or_entity = __lua_select(argument_index, ...) - - if __lua_type(chunk_or_entity) ~= 'number' then - local chunk = chunk_or_entity --[[@as evolved.chunk]] - if not chunk.__unreachable_or_collected and chunk.__entity_count > 0 then - return false - end - else - local entity = chunk_or_entity --[[@as evolved.entity]] - local entity_index = entity % 0x100000 - if freelist_ids[entity_index] == entity and __entity_chunks[entity_index] then - return false - end + ---@type evolved.entity + local entity = __lua_select(argument_index, ...) + local entity_index = entity % 0x100000 + if freelist_ids[entity_index] == entity and __entity_chunks[entity_index] then + return false end end return true end ----@param ... evolved.chunk | evolved.entity chunks_or_entities +---@param ... evolved.entity entities ---@return boolean ---@nodiscard -function __evolved_is_empty_any(...) +function __evolved_empty_any(...) local argument_count = __lua_select('#', ...) if argument_count == 0 then @@ -4616,105 +3622,75 @@ function __evolved_is_empty_any(...) local freelist_ids = __freelist_ids for argument_index = 1, argument_count do - ---@type evolved.chunk | evolved.entity - local chunk_or_entity = __lua_select(argument_index, ...) - - if __lua_type(chunk_or_entity) ~= 'number' then - local chunk = chunk_or_entity --[[@as evolved.chunk]] - if chunk.__unreachable_or_collected or chunk.__entity_count == 0 then - return true - end - else - local entity = chunk_or_entity --[[@as evolved.entity]] - local entity_index = entity % 0x100000 - if freelist_ids[entity_index] ~= entity or not __entity_chunks[entity_index] then - return true - end + ---@type evolved.entity + local entity = __lua_select(argument_index, ...) + local entity_index = entity % 0x100000 + if freelist_ids[entity_index] ~= entity or not __entity_chunks[entity_index] then + return true end end return false end ----@param chunk_or_entity evolved.chunk | evolved.entity +---@param entity evolved.entity ---@param fragment evolved.fragment ---@return boolean ---@nodiscard -function __evolved_has(chunk_or_entity, fragment) - if __lua_type(chunk_or_entity) ~= 'number' then - local chunk = chunk_or_entity --[[@as evolved.chunk]] - return __chunk_has_fragment(chunk, fragment) - else - local entity = chunk_or_entity --[[@as evolved.entity]] +function __evolved_has(entity, fragment) + local entity_index = entity % 0x100000 - local entity_index = entity % 0x100000 - - if __freelist_ids[entity_index] ~= entity then - return false - end - - local chunk = __entity_chunks[entity_index] - - if not chunk then - return false - end - - return __chunk_has_fragment(chunk, fragment) + if __freelist_ids[entity_index] ~= entity then + return false end + + local chunk = __entity_chunks[entity_index] + + if not chunk then + return false + end + + return __chunk_has_fragment(chunk, fragment) end ----@param chunk_or_entity evolved.chunk | evolved.entity +---@param entity evolved.entity ---@param ... evolved.fragment fragments ---@return boolean ---@nodiscard -function __evolved_has_all(chunk_or_entity, ...) - if __lua_type(chunk_or_entity) ~= 'number' then - local chunk = chunk_or_entity --[[@as evolved.chunk]] - return __chunk_has_all_fragments(chunk, ...) - else - local entity = chunk_or_entity --[[@as evolved.entity]] +function __evolved_has_all(entity, ...) + local entity_index = entity % 0x100000 - local entity_index = entity % 0x100000 - - if __freelist_ids[entity_index] ~= entity then - return __lua_select('#', ...) == 0 - end - - local chunk = __entity_chunks[entity_index] - - if not chunk then - return __lua_select('#', ...) == 0 - end - - return __chunk_has_all_fragments(chunk, ...) + if __freelist_ids[entity_index] ~= entity then + return __lua_select('#', ...) == 0 end + + local chunk = __entity_chunks[entity_index] + + if not chunk then + return __lua_select('#', ...) == 0 + end + + return __chunk_has_all_fragments(chunk, ...) end ----@param chunk_or_entity evolved.chunk | evolved.entity +---@param entity evolved.entity ---@param ... evolved.fragment fragments ---@return boolean ---@nodiscard -function __evolved_has_any(chunk_or_entity, ...) - if __lua_type(chunk_or_entity) ~= 'number' then - local chunk = chunk_or_entity --[[@as evolved.chunk]] - return __chunk_has_any_fragments(chunk, ...) - else - local entity = chunk_or_entity --[[@as evolved.entity]] +function __evolved_has_any(entity, ...) + local entity_index = entity % 0x100000 - local entity_index = entity % 0x100000 - - if __freelist_ids[entity_index] ~= entity then - return false - end - - local chunk = __entity_chunks[entity_index] - - if not chunk then - return false - end - - return __chunk_has_any_fragments(chunk, ...) + if __freelist_ids[entity_index] ~= entity then + return false end + + local chunk = __entity_chunks[entity_index] + + if not chunk then + return false + end + + return __chunk_has_any_fragments(chunk, ...) end ---@param entity evolved.entity @@ -5128,332 +4104,6 @@ function __evolved_destroy(...) __evolved_commit() end ----@param entity evolved.entity ----@param fragments evolved.fragment[] ----@param components? evolved.component[] -function __evolved_multi_set(entity, fragments, components) - local fragment_count = #fragments - - if fragment_count == 0 then - return - end - - if not components then - components = __safe_tbls.__EMPTY_COMPONENT_LIST - end - - if __debug_mode then - __debug_fns.validate_entity(entity) - __debug_fns.validate_fragment_list(fragments, fragment_count) - end - - if __defer_depth > 0 then - __defer_multi_set(entity, fragments, fragment_count, components, #components) - return - end - - local entity_index = entity % 0x100000 - - local entity_chunks = __entity_chunks - local entity_places = __entity_places - - local old_chunk = entity_chunks[entity_index] - local old_place = entity_places[entity_index] - - local new_chunk = __chunk_with_fragment_list(old_chunk, fragments, fragment_count) - - if not new_chunk then - return - end - - __evolved_defer() - - if old_chunk == new_chunk then - local old_component_indices = old_chunk.__component_indices - local old_component_storages = old_chunk.__component_storages - - local old_chunk_has_setup_hooks = old_chunk.__has_setup_hooks - local old_chunk_has_assign_hooks = old_chunk.__has_assign_hooks - - for i = 1, fragment_count do - local fragment = fragments[i] - - ---@type evolved.default?, evolved.duplicate?, evolved.set_hook?, evolved.assign_hook? - local fragment_default, fragment_duplicate, fragment_on_set, fragment_on_assign - - if old_chunk_has_setup_hooks or old_chunk_has_assign_hooks then - fragment_default, fragment_duplicate, fragment_on_set, fragment_on_assign = - __evolved_get(fragment, __DEFAULT, __DUPLICATE, __ON_SET, __ON_ASSIGN) - end - - local old_component_index = old_component_indices[fragment] - - if old_component_index then - local old_component_storage = old_component_storages[old_component_index] - - local new_component = components[i] - if new_component == nil then new_component = fragment_default end - if new_component ~= nil and fragment_duplicate then new_component = fragment_duplicate(new_component) end - if new_component == nil then new_component = true end - - if fragment_on_set or fragment_on_assign then - local old_component = old_component_storage[old_place] - old_component_storage[old_place] = new_component - - if fragment_on_set then - __defer_call_hook(fragment_on_set, entity, fragment, new_component, old_component) - end - - if fragment_on_assign then - __defer_call_hook(fragment_on_assign, entity, fragment, new_component, old_component) - end - else - old_component_storage[old_place] = new_component - end - else - if fragment_on_set then - __defer_call_hook(fragment_on_set, entity, fragment) - end - - if fragment_on_assign then - __defer_call_hook(fragment_on_assign, entity, fragment) - end - end - end - else - local new_entity_list = new_chunk.__entity_list - local new_entity_count = new_chunk.__entity_count - - local new_component_indices = new_chunk.__component_indices - local new_component_storages = new_chunk.__component_storages - - local new_chunk_has_setup_hooks = new_chunk.__has_setup_hooks - local new_chunk_has_assign_hooks = new_chunk.__has_assign_hooks - local new_chunk_has_insert_hooks = new_chunk.__has_insert_hooks - - local old_fragment_set = old_chunk and old_chunk.__fragment_set or __safe_tbls.__EMPTY_FRAGMENT_SET - - local new_place = new_entity_count + 1 - new_chunk.__entity_count = new_place - - new_entity_list[new_place] = entity - - if old_chunk then - local old_component_count = old_chunk.__component_count - local old_component_storages = old_chunk.__component_storages - local old_component_fragments = old_chunk.__component_fragments - - for old_ci = 1, old_component_count do - local old_f = old_component_fragments[old_ci] - local old_cs = old_component_storages[old_ci] - local new_ci = new_component_indices[old_f] - local new_cs = new_component_storages[new_ci] - new_cs[new_place] = old_cs[old_place] - end - - __detach_entity(old_chunk, old_place) - end - - do - entity_chunks[entity_index] = new_chunk - entity_places[entity_index] = new_place - - __structural_changes = __structural_changes + 1 - end - - ---@type table - local inserted_set = __acquire_table(__table_pool_tag.fragment_set) - - for i = 1, fragment_count do - local fragment = fragments[i] - - ---@type evolved.default?, evolved.duplicate?, evolved.set_hook?, evolved.assign_hook?, evolved.insert_hook? - local fragment_default, fragment_duplicate, fragment_on_set, fragment_on_assign, fragment_on_insert - - if new_chunk_has_setup_hooks or new_chunk_has_assign_hooks or new_chunk_has_insert_hooks then - fragment_default, fragment_duplicate, fragment_on_set, fragment_on_assign, fragment_on_insert = - __evolved_get(fragment, __DEFAULT, __DUPLICATE, __ON_SET, __ON_ASSIGN, __ON_INSERT) - end - - if inserted_set[fragment] or old_fragment_set[fragment] then - local new_component_index = new_component_indices[fragment] - - if new_component_index then - local new_component_storage = new_component_storages[new_component_index] - - local new_component = components[i] - if new_component == nil then new_component = fragment_default end - if new_component ~= nil and fragment_duplicate then new_component = fragment_duplicate(new_component) end - if new_component == nil then new_component = true end - - if fragment_on_set or fragment_on_assign then - local old_component = new_component_storage[new_place] - new_component_storage[new_place] = new_component - - if fragment_on_set then - __defer_call_hook(fragment_on_set, entity, fragment, new_component, old_component) - end - - if fragment_on_assign then - __defer_call_hook(fragment_on_assign, entity, fragment, new_component, old_component) - end - else - new_component_storage[new_place] = new_component - end - else - if fragment_on_set then - __defer_call_hook(fragment_on_set, entity, fragment) - end - - if fragment_on_assign then - __defer_call_hook(fragment_on_assign, entity, fragment) - end - end - else - inserted_set[fragment] = true - - local new_component_index = new_component_indices[fragment] - - if new_component_index then - local new_component_storage = new_component_storages[new_component_index] - - local new_component = components[i] - if new_component == nil then new_component = fragment_default end - if new_component ~= nil and fragment_duplicate then new_component = fragment_duplicate(new_component) end - if new_component == nil then new_component = true end - - new_component_storage[new_place] = new_component - - if fragment_on_set then - __defer_call_hook(fragment_on_set, entity, fragment, new_component) - end - - if fragment_on_insert then - __defer_call_hook(fragment_on_insert, entity, fragment, new_component) - end - else - if fragment_on_set then - __defer_call_hook(fragment_on_set, entity, fragment) - end - - if fragment_on_insert then - __defer_call_hook(fragment_on_insert, entity, fragment) - end - end - end - end - - __release_table(__table_pool_tag.fragment_set, inserted_set) - end - - __evolved_commit() -end - ----@param entity evolved.entity ----@param fragments evolved.fragment[] -function __evolved_multi_remove(entity, fragments) - local fragment_count = #fragments - - if fragment_count == 0 then - return - end - - local entity_index = entity % 0x100000 - - if __freelist_ids[entity_index] ~= entity then - -- this entity is not alive, nothing to remove - return - end - - if __defer_depth > 0 then - __defer_multi_remove(entity, fragments, fragment_count) - return - end - - local entity_chunks = __entity_chunks - local entity_places = __entity_places - - local old_chunk = entity_chunks[entity_index] - local old_place = entity_places[entity_index] - - local new_chunk = __chunk_without_fragment_list(old_chunk, fragments, fragment_count) - - if old_chunk == new_chunk then - return - end - - __evolved_defer() - - do - local old_fragment_set = old_chunk.__fragment_set - local old_component_indices = old_chunk.__component_indices - local old_component_storages = old_chunk.__component_storages - - if old_chunk.__has_remove_hooks then - ---@type table - local removed_set = __acquire_table(__table_pool_tag.fragment_set) - - for i = 1, fragment_count do - local fragment = fragments[i] - - if not removed_set[fragment] and old_fragment_set[fragment] then - removed_set[fragment] = true - - ---@type evolved.remove_hook? - local fragment_on_remove = __evolved_get(fragment, __ON_REMOVE) - - if fragment_on_remove then - local old_component_index = old_component_indices[fragment] - - if old_component_index then - local old_component_storage = old_component_storages[old_component_index] - local old_component = old_component_storage[old_place] - __defer_call_hook(fragment_on_remove, entity, fragment, old_component) - else - __defer_call_hook(fragment_on_remove, entity, fragment) - end - end - end - end - - __release_table(__table_pool_tag.fragment_set, removed_set) - end - - if new_chunk then - local new_entity_list = new_chunk.__entity_list - local new_entity_count = new_chunk.__entity_count - - local new_component_count = new_chunk.__component_count - local new_component_storages = new_chunk.__component_storages - local new_component_fragments = new_chunk.__component_fragments - - local new_place = new_entity_count + 1 - new_chunk.__entity_count = new_place - - new_entity_list[new_place] = entity - - for new_ci = 1, new_component_count do - local new_f = new_component_fragments[new_ci] - local new_cs = new_component_storages[new_ci] - local old_ci = old_component_indices[new_f] - local old_cs = old_component_storages[old_ci] - new_cs[new_place] = old_cs[old_place] - end - end - - do - __detach_entity(old_chunk, old_place) - - entity_chunks[entity_index] = new_chunk - entity_places[entity_index] = new_chunk and new_chunk.__entity_count - - __structural_changes = __structural_changes + 1 - end - end - - __evolved_commit() -end - ---@param query evolved.query ---@param fragment evolved.fragment ---@param component evolved.component @@ -5658,192 +4308,6 @@ function __evolved_batch_destroy(...) __evolved_commit() end ----@param query evolved.query ----@param fragments evolved.fragment[] ----@param components? evolved.component[] -function __evolved_batch_multi_set(query, fragments, components) - local fragment_count = #fragments - - if fragment_count == 0 then - return - end - - if not components then - components = __safe_tbls.__EMPTY_COMPONENT_LIST - end - - if __debug_mode then - __debug_fns.validate_query(query) - __debug_fns.validate_fragment_list(fragments, fragment_count) - end - - if __defer_depth > 0 then - __defer_batch_multi_set(query, fragments, fragment_count, components, #components) - return - end - - __evolved_defer() - - do - ---@type evolved.chunk[] - local chunk_list = __acquire_table(__table_pool_tag.chunk_list) - local chunk_count = 0 - - for chunk in __evolved_execute(query) do - chunk_count = chunk_count + 1 - chunk_list[chunk_count] = chunk - end - - for chunk_index = 1, chunk_count do - local chunk = chunk_list[chunk_index] - __chunk_multi_set(chunk, fragments, fragment_count, components) - end - - __release_table(__table_pool_tag.chunk_list, chunk_list) - end - - __evolved_commit() -end - ----@param query evolved.query ----@param fragments evolved.fragment[] -function __evolved_batch_multi_remove(query, fragments) - local fragment_count = #fragments - - if fragment_count == 0 then - return - end - - local query_index = query % 0x100000 - - if __freelist_ids[query_index] ~= query then - -- this query is not alive, nothing to remove - return - end - - if __defer_depth > 0 then - __defer_batch_multi_remove(query, fragments, fragment_count) - return - end - - __evolved_defer() - - do - ---@type evolved.chunk[] - local chunk_list = __acquire_table(__table_pool_tag.chunk_list) - local chunk_count = 0 - - for chunk in __evolved_execute(query) do - chunk_count = chunk_count + 1 - chunk_list[chunk_count] = chunk - end - - for chunk_index = 1, chunk_count do - local chunk = chunk_list[chunk_index] - __chunk_multi_remove(chunk, fragments, fragment_count) - end - - __release_table(__table_pool_tag.chunk_list, chunk_list) - end - - __evolved_commit() -end - ---- ---- ---- ---- ---- - ----@param head_fragment evolved.fragment ----@param ... evolved.fragment tail_fragments ----@return evolved.chunk chunk ----@return evolved.entity[] entity_list ----@return integer entity_count ----@nodiscard -function __evolved_chunk(head_fragment, ...) - local chunk = __chunk_fragments(head_fragment, ...) - return chunk, chunk.__entity_list, chunk.__entity_count -end - ----@param chunk evolved.chunk ----@return evolved.entity[] entity_list ----@return integer entity_count ----@nodiscard -function __evolved_entities(chunk) - return chunk.__entity_list, chunk.__entity_count -end - ----@param chunk evolved.chunk ----@return evolved.fragment[] fragments ----@return integer fragment_count ----@nodiscard -function __evolved_fragments(chunk) - return chunk.__fragment_list, chunk.__fragment_count -end - ----@param chunk evolved.chunk ----@param ... evolved.fragment fragments ----@return evolved.storage ... storages ----@nodiscard -function __evolved_components(chunk, ...) - local fragment_count = __lua_select('#', ...) - - if fragment_count == 0 then - return - end - - local indices = chunk.__component_indices - local storages = chunk.__component_storages - - local empty_component_storage = __safe_tbls.__EMPTY_COMPONENT_STORAGE - - if fragment_count == 1 then - local f1 = ... - local i1 = indices[f1] - return - i1 and storages[i1] or empty_component_storage - end - - if fragment_count == 2 then - local f1, f2 = ... - local i1, i2 = indices[f1], indices[f2] - return - i1 and storages[i1] or empty_component_storage, - i2 and storages[i2] or empty_component_storage - end - - if fragment_count == 3 then - local f1, f2, f3 = ... - local i1, i2, i3 = indices[f1], indices[f2], indices[f3] - return - i1 and storages[i1] or empty_component_storage, - i2 and storages[i2] or empty_component_storage, - i3 and storages[i3] or empty_component_storage - end - - if fragment_count == 4 then - local f1, f2, f3, f4 = ... - local i1, i2, i3, i4 = indices[f1], indices[f2], indices[f3], indices[f4] - return - i1 and storages[i1] or empty_component_storage, - i2 and storages[i2] or empty_component_storage, - i3 and storages[i3] or empty_component_storage, - i4 and storages[i4] or empty_component_storage - end - - do - local f1, f2, f3, f4 = ... - local i1, i2, i3, i4 = indices[f1], indices[f2], indices[f3], indices[f4] - return - i1 and storages[i1] or empty_component_storage, - i2 and storages[i2] or empty_component_storage, - i3 and storages[i3] or empty_component_storage, - i4 and storages[i4] or empty_component_storage, - __evolved_components(chunk, __lua_select(5, ...)) - end -end - ---@param entity evolved.entity ---@return evolved.each_iterator iterator ---@return evolved.each_state? iterator_state @@ -5892,6 +4356,7 @@ function __evolved_execute(query) local chunk_stack_size = 0 local query_includes = __query_sorted_includes[query] + local query_include_set = query_includes and query_includes.__item_set --[[@as table]] local query_include_list = query_includes and query_includes.__item_list --[=[@as evolved.fragment[]]=] local query_include_count = query_includes and query_includes.__item_count or 0 --[[@as integer]] @@ -5916,6 +4381,20 @@ function __evolved_execute(query) (query_exclude_count == 0 or not __chunk_has_any_fragment_list( major_chunk, query_exclude_list, query_exclude_count)) + if is_major_chunk_matched and major_chunk.__has_explicit_minors then + local major_chunk_fragment_list = major_chunk.__fragment_list + local major_chunk_fragment_count = major_chunk.__fragment_count + + for major_chunk_fragment_index = 1, major_chunk_fragment_count - 1 do + local major_chunk_fragment = major_chunk_fragment_list[major_chunk_fragment_index] + + if not query_include_set[major_chunk_fragment] and __evolved_has(major_chunk_fragment, __EXPLICIT) then + is_major_chunk_matched = false + break + end + end + end + if is_major_chunk_matched then chunk_stack_size = chunk_stack_size + 1 chunk_stack[chunk_stack_size] = major_chunk @@ -5923,15 +4402,24 @@ function __evolved_execute(query) end elseif query_exclude_count > 0 then for root_fragment, root_chunk in __lua_next, __root_chunks do - if not query_exclude_set[root_fragment] then + local is_root_chunk_matched = + not root_chunk.__has_explicit_major and + not query_exclude_set[root_fragment] + + if is_root_chunk_matched then chunk_stack_size = chunk_stack_size + 1 chunk_stack[chunk_stack_size] = root_chunk end end else for _, root_chunk in __lua_next, __root_chunks do - chunk_stack_size = chunk_stack_size + 1 - chunk_stack[chunk_stack_size] = root_chunk + local is_root_chunk_matched = + not root_chunk.__has_explicit_major + + if is_root_chunk_matched then + chunk_stack_size = chunk_stack_size + 1 + chunk_stack[chunk_stack_size] = root_chunk + end end end @@ -5961,140 +4449,6 @@ function __evolved_process(...) end end ---- ---- ---- ---- ---- - ----@param chunk? evolved.chunk ----@param fragments? evolved.fragment[] ----@param components? evolved.component[] ----@return evolved.entity entity -function __evolved_spawn_at(chunk, fragments, components) - if not fragments then - fragments = __safe_tbls.__EMPTY_FRAGMENT_LIST - end - - if not components then - components = __safe_tbls.__EMPTY_COMPONENT_LIST - end - - local fragment_count = #fragments - local component_count = #components - - if __debug_mode then - if chunk then __debug_fns.validate_chunk(chunk) end - __debug_fns.validate_fragment_list(fragments, fragment_count) - end - - local entity = __acquire_id() - local entity_chunk = __chunk_with_fragment_list(chunk, fragments, fragment_count) - - if __defer_depth > 0 then - __defer_spawn_entity_at(entity, entity_chunk, - fragments, fragment_count, - components, component_count) - return entity - end - - __evolved_defer() - do - __spawn_entity_at(entity, entity_chunk, - fragments, fragment_count, - components) - end - __evolved_commit() - - return entity -end - ----@param prefab? evolved.entity ----@param fragments? evolved.fragment[] ----@param components? evolved.component[] -function __evolved_spawn_as(prefab, fragments, components) - if not fragments then - fragments = __safe_tbls.__EMPTY_FRAGMENT_LIST - end - - if not components then - components = __safe_tbls.__EMPTY_COMPONENT_LIST - end - - local fragment_count = #fragments - local component_count = #components - - if __debug_mode then - if prefab then __debug_fns.validate_prefab(prefab) end - __debug_fns.validate_fragment_list(fragments, fragment_count) - end - - local entity = __acquire_id() - - if __defer_depth > 0 then - __defer_spawn_entity_as(entity, prefab, - fragments, fragment_count, - components, component_count) - return entity - end - - __evolved_defer() - do - __spawn_entity_as(entity, prefab, - fragments, fragment_count, - components) - end - __evolved_commit() - - return entity -end - ----@param fragments? evolved.fragment[] ----@param components? evolved.component[] ----@return evolved.entity entity -function __evolved_spawn_with(fragments, components) - if not fragments then - fragments = __safe_tbls.__EMPTY_FRAGMENT_LIST - end - - if not components then - components = __safe_tbls.__EMPTY_COMPONENT_LIST - end - - local fragment_count = #fragments - local component_count = #components - - if __debug_mode then - __debug_fns.validate_fragment_list(fragments, fragment_count) - end - - local entity = __acquire_id() - local entity_chunk = __chunk_fragment_list(fragments, fragment_count) - - if __defer_depth > 0 then - __defer_spawn_entity_with(entity, entity_chunk, - fragments, fragment_count, - components, component_count) - return entity - end - - __evolved_defer() - do - __spawn_entity_with(entity, entity_chunk, - fragments, fragment_count, - components) - end - __evolved_commit() - - return entity -end - ---- ---- ---- ---- ---- - ---@param yesno boolean function __evolved_debug_mode(yesno) __debug_mode = yesno @@ -6172,15 +4526,134 @@ end --- --- ----@class evolved.builder ----@field package __prefab? evolved.entity ----@field package __single? evolved.component ----@field package __fragment_set table ----@field package __fragment_list evolved.fragment[] ----@field package __component_list evolved.component[] ----@field package __component_count integer -local __evolved_builder_mt = {} -__evolved_builder_mt.__index = __evolved_builder_mt +---@param fragment evolved.fragment +---@param ... evolved.fragment fragments +---@return evolved.chunk chunk +---@return evolved.entity[] entity_list +---@return integer entity_count +---@nodiscard +function __evolved_chunk(fragment, ...) + local chunk = __chunk_fragments(fragment, ...) + return chunk, chunk.__entity_list, chunk.__entity_count +end + +function __chunk_mt:__tostring() + local fragment_names = {} ---@type string[] + + for i = 1, self.__fragment_count do + fragment_names[i] = __id_name(self.__fragment_list[i]) + end + + return string.format('<%s>', table.concat(fragment_names, ', ')) +end + +---@return boolean +---@nodiscard +function __chunk_mt:alive() + return not self.__unreachable_or_collected +end + +---@return boolean +---@nodiscard +function __chunk_mt:empty() + return self.__unreachable_or_collected or self.__entity_count == 0 +end + +---@param fragment evolved.fragment +---@return boolean +---@nodiscard +function __chunk_mt:has(fragment) + return __chunk_has_fragment(self, fragment) +end + +---@param ... evolved.fragment fragments +---@return boolean +---@nodiscard +function __chunk_mt:has_all(...) + return __chunk_has_all_fragments(self, ...) +end + +---@param ... evolved.fragment fragments +---@return boolean +---@nodiscard +function __chunk_mt:has_any(...) + return __chunk_has_any_fragments(self, ...) +end + +---@return evolved.entity[] entity_list +---@return integer entity_count +---@nodiscard +function __chunk_mt:entities() + return self.__entity_list, self.__entity_count +end + +---@return evolved.fragment[] fragment_list +---@return integer fragment_count +---@nodiscard +function __chunk_mt:fragments() + return self.__fragment_list, self.__fragment_count +end + +---@param ... evolved.fragment fragments +---@return evolved.storage ... storages +---@nodiscard +function __chunk_mt:components(...) + local fragment_count = __lua_select('#', ...) + + if fragment_count == 0 then + return + end + + local indices = self.__component_indices + local storages = self.__component_storages + + local empty_component_storage = __safe_tbls.__EMPTY_COMPONENT_STORAGE + + if fragment_count == 1 then + local f1 = ... + local i1 = indices[f1] + return + i1 and storages[i1] or empty_component_storage + end + + if fragment_count == 2 then + local f1, f2 = ... + local i1, i2 = indices[f1], indices[f2] + return + i1 and storages[i1] or empty_component_storage, + i2 and storages[i2] or empty_component_storage + end + + if fragment_count == 3 then + local f1, f2, f3 = ... + local i1, i2, i3 = indices[f1], indices[f2], indices[f3] + return + i1 and storages[i1] or empty_component_storage, + i2 and storages[i2] or empty_component_storage, + i3 and storages[i3] or empty_component_storage + end + + if fragment_count == 4 then + local f1, f2, f3, f4 = ... + local i1, i2, i3, i4 = indices[f1], indices[f2], indices[f3], indices[f4] + return + i1 and storages[i1] or empty_component_storage, + i2 and storages[i2] or empty_component_storage, + i3 and storages[i3] or empty_component_storage, + i4 and storages[i4] or empty_component_storage + end + + do + local f1, f2, f3, f4 = ... + local i1, i2, i3, i4 = indices[f1], indices[f2], indices[f3], indices[f4] + return + i1 and storages[i1] or empty_component_storage, + i2 and storages[i2] or empty_component_storage, + i3 and storages[i3] or empty_component_storage, + i4 and storages[i4] or empty_component_storage, + self:components(__lua_select(5, ...)) + end +end --- --- @@ -6192,93 +4665,206 @@ __evolved_builder_mt.__index = __evolved_builder_mt ---@nodiscard function __evolved_builder() return __lua_setmetatable({ - __fragment_set = {}, - __fragment_list = {}, - __component_list = {}, - __component_count = 0, - }, __evolved_builder_mt) + __components = {}, + }, __builder_mt) +end + +function __builder_mt:__tostring() + local fragment_list = {} ---@type evolved.fragment[] + local fragment_count = 0 ---@type integer + + for fragment in __lua_next, self.__components do + fragment_count = fragment_count + 1 + fragment_list[fragment_count] = fragment + end + + __lua_table_sort(fragment_list) + + local fragment_names = {} ---@type string[] + + for i = 1, fragment_count do + fragment_names[i] = __id_name(fragment_list[i]) + end + + return string.format('<%s>', table.concat(fragment_names, ', ')) +end + +---@return evolved.entity +function __builder_mt:spawn() + local components = self.__components + + if __debug_mode then + __debug_fns.validate_component_map(components) + end + + local entity = __acquire_id() + + if __defer_depth > 0 then + __defer_spawn_entity(entity, components) + else + __evolved_defer() + do + __spawn_entity(entity, components) + end + __evolved_commit() + end + + return entity +end + +---@param prefab evolved.entity +---@return evolved.entity +function __builder_mt:clone(prefab) + local components = self.__components + + if __debug_mode then + __debug_fns.validate_prefab(prefab) + __debug_fns.validate_component_map(components) + end + + local entity = __acquire_id() + + if __defer_depth > 0 then + __defer_clone_entity(entity, prefab, components) + else + __evolved_defer() + do + __clone_entity(entity, prefab, components) + end + __evolved_commit() + end + + return entity end ---@param fragment evolved.fragment ---@return boolean ---@nodiscard -function __evolved_builder_mt:has(fragment) - local component_index = self.__fragment_set[fragment] - - if not component_index then - return false - end - - if component_index > self.__component_count then - return false - end - - if fragment ~= self.__fragment_list[component_index] then - return false - end - - return true +function __builder_mt:has(fragment) + return self.__components[fragment] ~= nil end ---@param ... evolved.fragment fragments ---@return boolean ---@nodiscard -function __evolved_builder_mt:has_all(...) +function __builder_mt:has_all(...) local fragment_count = select("#", ...) if fragment_count == 0 then return true end - return self:has(...) and self:has_all(__lua_select(2, ...)) + local cs = self.__components + + if fragment_count == 1 then + local f1 = ... + return cs[f1] ~= nil + end + + if fragment_count == 2 then + local f1, f2 = ... + return cs[f1] ~= nil and cs[f2] ~= nil + end + + if fragment_count == 3 then + local f1, f2, f3 = ... + return cs[f1] ~= nil and cs[f2] ~= nil and cs[f3] ~= nil + end + + if fragment_count == 4 then + local f1, f2, f3, f4 = ... + return cs[f1] ~= nil and cs[f2] ~= nil and cs[f3] ~= nil and cs[f4] ~= nil + end + + do + local f1, f2, f3, f4 = ... + return cs[f1] ~= nil and cs[f2] ~= nil and cs[f3] ~= nil and cs[f4] ~= nil and + self:has_all(__lua_select(5, ...)) + end end ---@param ... evolved.fragment fragments ---@return boolean ---@nodiscard -function __evolved_builder_mt:has_any(...) +function __builder_mt:has_any(...) local fragment_count = select("#", ...) if fragment_count == 0 then return false end - return self:has(...) or self:has_any(__lua_select(2, ...)) + local cs = self.__components + + if fragment_count == 1 then + local f1 = ... + return cs[f1] ~= nil + end + + if fragment_count == 2 then + local f1, f2 = ... + return cs[f1] ~= nil or cs[f2] ~= nil + end + + if fragment_count == 3 then + local f1, f2, f3 = ... + return cs[f1] ~= nil or cs[f2] ~= nil or cs[f3] ~= nil + end + + if fragment_count == 4 then + local f1, f2, f3, f4 = ... + return cs[f1] ~= nil or cs[f2] ~= nil or cs[f3] ~= nil or cs[f4] ~= nil + end + + do + local f1, f2, f3, f4 = ... + return cs[f1] ~= nil or cs[f2] ~= nil or cs[f3] ~= nil or cs[f4] ~= nil or + self:has_any(__lua_select(5, ...)) + end end ---@param ... evolved.fragment fragments ---@return evolved.component ... components ---@nodiscard -function __evolved_builder_mt:get(...) +function __builder_mt:get(...) local fragment_count = select("#", ...) if fragment_count == 0 then return end - local fragment = ... + local cs = self.__components - local component_index = self.__fragment_set[fragment] - - if not component_index then - return nil, self:get(__lua_select(2, ...)) + if fragment_count == 1 then + local f1 = ... + return cs[f1] end - if component_index > self.__component_count then - return nil, self:get(__lua_select(2, ...)) + if fragment_count == 2 then + local f1, f2 = ... + return cs[f1], cs[f2] end - if fragment ~= self.__fragment_list[component_index] then - return nil, self:get(__lua_select(2, ...)) + if fragment_count == 3 then + local f1, f2, f3 = ... + return cs[f1], cs[f2], cs[f3] end - return self.__component_list[component_index], self:get(__lua_select(2, ...)) + if fragment_count == 4 then + local f1, f2, f3, f4 = ... + return cs[f1], cs[f2], cs[f3], cs[f4] + end + + do + local f1, f2, f3, f4 = ... + return cs[f1], cs[f2], cs[f3], cs[f4], + self:get(__lua_select(5, ...)) + end end ---@param fragment evolved.fragment ---@param component evolved.component ---@return evolved.builder builder -function __evolved_builder_mt:set(fragment, component) +function __builder_mt:set(fragment, component) if __debug_mode then __debug_fns.validate_fragment(fragment) end @@ -6301,120 +4887,105 @@ function __evolved_builder_mt:set(fragment, component) end end - local fragment_set = self.__fragment_set - local fragment_list = self.__fragment_list - local component_list = self.__component_list - local component_count = self.__component_count - - local component_index = fragment_set[fragment] - - if component_index - and component_index <= component_count - and fragment == fragment_list[component_index] - then - component_list[component_index] = component - else - component_count = component_count + 1 - self.__component_count = component_count - - fragment_set[fragment] = component_count - fragment_list[component_count] = fragment - component_list[component_count] = component - end + self.__components[fragment] = component return self end ---@param ... evolved.fragment fragments ---@return evolved.builder builder -function __evolved_builder_mt:remove(...) +function __builder_mt:remove(...) local fragment_count = select("#", ...) if fragment_count == 0 then return self end - local fragment = ... + local cs = self.__components - local fragment_set = self.__fragment_set - local fragment_list = self.__fragment_list - local component_list = self.__component_list - local component_count = self.__component_count - - local component_index = fragment_set[fragment] - - if component_index - and component_index <= component_count - and fragment == fragment_list[component_index] - then - if component_index ~= component_count then - local last_fragment = fragment_list[component_count] - local last_component = component_list[component_count] - - fragment_set[last_fragment] = component_index - fragment_list[component_index] = last_fragment - component_list[component_index] = last_component - end - - fragment_set[fragment] = nil - fragment_list[component_count] = nil - component_list[component_count] = nil - - component_count = component_count - 1 - self.__component_count = component_count + if fragment_count == 1 then + local f1 = ... + cs[f1] = nil + return self end - return self:remove(__lua_select(2, ...)) + if fragment_count == 2 then + local f1, f2 = ... + cs[f1] = nil; cs[f2] = nil + return self + end + + if fragment_count == 3 then + local f1, f2, f3 = ... + cs[f1] = nil; cs[f2] = nil; cs[f3] = nil + return self + end + + if fragment_count == 4 then + local f1, f2, f3, f4 = ... + cs[f1] = nil; cs[f2] = nil; cs[f3] = nil; cs[f4] = nil + return self + end + + do + local f1, f2, f3, f4 = ... + cs[f1] = nil; cs[f2] = nil; cs[f3] = nil; cs[f4] = nil + return self:remove(__lua_select(5, ...)) + end end ---@return evolved.builder builder -function __evolved_builder_mt:clear() - self.__prefab = nil - self.__single = nil - self.__component_count = 0 +function __builder_mt:clear() + __lua_table_clear(self.__components) return self end ---@return evolved.builder builder -function __evolved_builder_mt:tag() +function __builder_mt:tag() return self:set(__TAG) end ---@param name string ---@return evolved.builder builder -function __evolved_builder_mt:name(name) +function __builder_mt:name(name) return self:set(__NAME, name) end ----@param prefab evolved.entity ---@return evolved.builder builder -function __evolved_builder_mt:prefab(prefab) - self.__prefab = prefab - return self +function __builder_mt:unique() + return self:set(__UNIQUE) end ----@param single evolved.component ---@return evolved.builder builder -function __evolved_builder_mt:single(single) - self.__single = single == nil and true or single - return self +function __builder_mt:explicit() + return self:set(__EXPLICIT) end ---@param default evolved.component ---@return evolved.builder builder -function __evolved_builder_mt:default(default) +function __builder_mt:default(default) return self:set(__DEFAULT, default) end ---@param duplicate evolved.duplicate ---@return evolved.builder builder -function __evolved_builder_mt:duplicate(duplicate) +function __builder_mt:duplicate(duplicate) return self:set(__DUPLICATE, duplicate) end +---@return evolved.builder builder +function __builder_mt:prefab() + return self:set(__PREFAB) +end + +---@return evolved.builder builder +function __builder_mt:disabled() + return self:set(__DISABLED) +end + ---@param ... evolved.fragment fragments ---@return evolved.builder builder -function __evolved_builder_mt:include(...) +function __builder_mt:include(...) local argument_count = __lua_select('#', ...) if argument_count == 0 then @@ -6439,7 +5010,7 @@ end ---@param ... evolved.fragment fragments ---@return evolved.builder builder -function __evolved_builder_mt:exclude(...) +function __builder_mt:exclude(...) local argument_count = __lua_select('#', ...) if argument_count == 0 then @@ -6464,127 +5035,64 @@ end ---@param on_set evolved.set_hook ---@return evolved.builder builder -function __evolved_builder_mt:on_set(on_set) +function __builder_mt:on_set(on_set) return self:set(__ON_SET, on_set) end ---@param on_assign evolved.assign_hook ---@return evolved.builder builder -function __evolved_builder_mt:on_assign(on_assign) +function __builder_mt:on_assign(on_assign) return self:set(__ON_ASSIGN, on_assign) end ---@param on_insert evolved.insert_hook ---@return evolved.builder builder -function __evolved_builder_mt:on_insert(on_insert) +function __builder_mt:on_insert(on_insert) return self:set(__ON_INSERT, on_insert) end ---@param on_remove evolved.remove_hook ---@return evolved.builder builder -function __evolved_builder_mt:on_remove(on_remove) +function __builder_mt:on_remove(on_remove) return self:set(__ON_REMOVE, on_remove) end ---@param group evolved.system ---@return evolved.builder builder -function __evolved_builder_mt:group(group) +function __builder_mt:group(group) return self:set(__GROUP, group) end ---@param query evolved.query ---@return evolved.builder builder -function __evolved_builder_mt:query(query) +function __builder_mt:query(query) return self:set(__QUERY, query) end ---@param execute evolved.execute ---@return evolved.builder builder -function __evolved_builder_mt:execute(execute) +function __builder_mt:execute(execute) return self:set(__EXECUTE, execute) end ---@param prologue evolved.prologue ---@return evolved.builder builder -function __evolved_builder_mt:prologue(prologue) +function __builder_mt:prologue(prologue) return self:set(__PROLOGUE, prologue) end ---@param epilogue evolved.epilogue ---@return evolved.builder builder -function __evolved_builder_mt:epilogue(epilogue) +function __builder_mt:epilogue(epilogue) return self:set(__EPILOGUE, epilogue) end ----@return evolved.builder builder -function __evolved_builder_mt:disabled() - return self:set(__DISABLED) -end - ---@param destroy_policy evolved.id ---@return evolved.builder builder -function __evolved_builder_mt:destroy_policy(destroy_policy) +function __builder_mt:destroy_policy(destroy_policy) return self:set(__DESTROY_POLICY, destroy_policy) end ----@param no_clear? boolean ----@return evolved.entity entity -function __evolved_builder_mt:build(no_clear) - local prefab = self.__prefab - local single = self.__single - local fragment_list = self.__fragment_list - local component_list = self.__component_list - local component_count = self.__component_count - - if __debug_mode then - if prefab then __debug_fns.validate_prefab(prefab) end - __debug_fns.validate_fragment_list(fragment_list, component_count) - end - - local entity = __acquire_id() - - if single ~= nil then - component_count = component_count + 1 - fragment_list[component_count] = entity - component_list[component_count] = single - end - - if not no_clear then - self:clear() - end - - local entity_chunk = __chunk_fragment_list(fragment_list, component_count) - - if __defer_depth > 0 then - if prefab then - __defer_spawn_entity_as(entity, prefab, - fragment_list, component_count, - component_list, component_count) - else - __defer_spawn_entity_with(entity, entity_chunk, - fragment_list, component_count, - component_list, component_count) - end - return entity - end - - __evolved_defer() - do - if prefab then - __spawn_entity_as(entity, prefab, - fragment_list, component_count, - component_list) - else - __spawn_entity_with(entity, entity_chunk, - fragment_list, component_count, - component_list) - end - end - __evolved_commit() - - return entity -end - --- --- --- @@ -6596,23 +5104,39 @@ end local function __update_chunk_caches_trace(chunk) local chunk_parent, chunk_fragment = chunk.__parent, chunk.__fragment - local has_setup_hooks = (chunk_parent and chunk_parent.__has_setup_hooks) + local has_setup_hooks = (chunk_parent ~= nil and chunk_parent.__has_setup_hooks) or __evolved_has_any(chunk_fragment, __DEFAULT, __DUPLICATE) - local has_assign_hooks = (chunk_parent and chunk_parent.__has_assign_hooks) + local has_assign_hooks = (chunk_parent ~= nil and chunk_parent.__has_assign_hooks) or __evolved_has_any(chunk_fragment, __ON_SET, __ON_ASSIGN) - local has_insert_hooks = (chunk_parent and chunk_parent.__has_insert_hooks) + local has_insert_hooks = (chunk_parent ~= nil and chunk_parent.__has_insert_hooks) or __evolved_has_any(chunk_fragment, __ON_SET, __ON_INSERT) - local has_remove_hooks = (chunk_parent and chunk_parent.__has_remove_hooks) + local has_remove_hooks = (chunk_parent ~= nil and chunk_parent.__has_remove_hooks) or __evolved_has(chunk_fragment, __ON_REMOVE) + local has_unique_major = __evolved_has(chunk_fragment, __UNIQUE) + local has_unique_minors = chunk_parent ~= nil and chunk_parent.__has_unique_fragments + local has_unique_fragments = has_unique_major or has_unique_minors + + local has_explicit_major = __evolved_has(chunk_fragment, __EXPLICIT) + local has_explicit_minors = chunk_parent ~= nil and chunk_parent.__has_explicit_fragments + local has_explicit_fragments = has_explicit_major or has_explicit_minors + chunk.__has_setup_hooks = has_setup_hooks chunk.__has_assign_hooks = has_assign_hooks chunk.__has_insert_hooks = has_insert_hooks chunk.__has_remove_hooks = has_remove_hooks + chunk.__has_unique_major = has_unique_major + chunk.__has_unique_minors = has_unique_minors + chunk.__has_unique_fragments = has_unique_fragments + + chunk.__has_explicit_major = has_explicit_major + chunk.__has_explicit_minors = has_explicit_minors + chunk.__has_explicit_fragments = has_explicit_fragments + return true end @@ -6703,6 +5227,14 @@ local function __update_fragment_tags(fragment) __trace_fragment_chunks(fragment, __update_chunk_tags_trace, fragment) end +local function __update_fragment_uniques(fragment) + __trace_fragment_chunks(fragment, __update_chunk_caches_trace, fragment) +end + +local function __update_fragment_explicits(fragment) + __trace_fragment_chunks(fragment, __update_chunk_caches_trace, fragment) +end + ---@param fragment evolved.fragment local function __update_fragment_defaults(fragment) __trace_fragment_chunks(fragment, __update_chunk_caches_trace, fragment) @@ -6716,6 +5248,12 @@ end __evolved_set(__TAG, __ON_INSERT, __update_fragment_tags) __evolved_set(__TAG, __ON_REMOVE, __update_fragment_tags) +__evolved_set(__UNIQUE, __ON_INSERT, __update_fragment_uniques) +__evolved_set(__UNIQUE, __ON_REMOVE, __update_fragment_uniques) + +__evolved_set(__EXPLICIT, __ON_INSERT, __update_fragment_explicits) +__evolved_set(__EXPLICIT, __ON_REMOVE, __update_fragment_explicits) + __evolved_set(__DEFAULT, __ON_INSERT, __update_fragment_defaults) __evolved_set(__DEFAULT, __ON_REMOVE, __update_fragment_defaults) @@ -6730,9 +5268,16 @@ __evolved_set(__DUPLICATE, __ON_REMOVE, __update_fragment_duplicates) __evolved_set(__TAG, __NAME, 'TAG') __evolved_set(__NAME, __NAME, 'NAME') + +__evolved_set(__UNIQUE, __NAME, 'UNIQUE') +__evolved_set(__EXPLICIT, __NAME, 'EXPLICIT') + __evolved_set(__DEFAULT, __NAME, 'DEFAULT') __evolved_set(__DUPLICATE, __NAME, 'DUPLICATE') +__evolved_set(__PREFAB, __NAME, 'PREFAB') +__evolved_set(__DISABLED, __NAME, 'DISABLED') + __evolved_set(__INCLUDES, __NAME, 'INCLUDES') __evolved_set(__EXCLUDES, __NAME, 'EXCLUDES') @@ -6749,8 +5294,6 @@ __evolved_set(__EXECUTE, __NAME, 'EXECUTE') __evolved_set(__PROLOGUE, __NAME, 'PROLOGUE') __evolved_set(__EPILOGUE, __NAME, 'EPILOGUE') -__evolved_set(__DISABLED, __NAME, 'DISABLED') - __evolved_set(__DESTROY_POLICY, __NAME, 'DESTROY_POLICY') __evolved_set(__DESTROY_POLICY_DESTROY_ENTITY, __NAME, 'DESTROY_POLICY_DESTROY_ENTITY') __evolved_set(__DESTROY_POLICY_REMOVE_FRAGMENT, __NAME, 'DESTROY_POLICY_REMOVE_FRAGMENT') @@ -6763,13 +5306,28 @@ __evolved_set(__DESTROY_POLICY_REMOVE_FRAGMENT, __NAME, 'DESTROY_POLICY_REMOVE_F __evolved_set(__TAG, __TAG) +__evolved_set(__UNIQUE, __TAG) + +__evolved_set(__EXPLICIT, __TAG) + +__evolved_set(__PREFAB, __TAG) +__evolved_set(__PREFAB, __UNIQUE) +__evolved_set(__PREFAB, __EXPLICIT) + +__evolved_set(__DISABLED, __TAG) +__evolved_set(__DISABLED, __UNIQUE) +__evolved_set(__DISABLED, __EXPLICIT) + __evolved_set(__INCLUDES, __DEFAULT, {}) __evolved_set(__INCLUDES, __DUPLICATE, __list_copy) __evolved_set(__EXCLUDES, __DEFAULT, {}) __evolved_set(__EXCLUDES, __DUPLICATE, __list_copy) -__evolved_set(__DISABLED, __TAG) +__evolved_set(__ON_SET, __UNIQUE) +__evolved_set(__ON_ASSIGN, __UNIQUE) +__evolved_set(__ON_INSERT, __UNIQUE) +__evolved_set(__ON_REMOVE, __UNIQUE) --- --- @@ -6891,9 +5449,16 @@ end) evolved.TAG = __TAG evolved.NAME = __NAME + +evolved.UNIQUE = __UNIQUE +evolved.EXPLICIT = __EXPLICIT + evolved.DEFAULT = __DEFAULT evolved.DUPLICATE = __DUPLICATE +evolved.PREFAB = __PREFAB +evolved.DISABLED = __DISABLED + evolved.INCLUDES = __INCLUDES evolved.EXCLUDES = __EXCLUDES @@ -6910,8 +5475,6 @@ evolved.EXECUTE = __EXECUTE evolved.PROLOGUE = __PROLOGUE evolved.EPILOGUE = __EPILOGUE -evolved.DISABLED = __DISABLED - evolved.DESTROY_POLICY = __DESTROY_POLICY evolved.DESTROY_POLICY_DESTROY_ENTITY = __DESTROY_POLICY_DESTROY_ENTITY evolved.DESTROY_POLICY_REMOVE_FRAGMENT = __DESTROY_POLICY_REMOVE_FRAGMENT @@ -6924,54 +5487,42 @@ evolved.unpack = __evolved_unpack evolved.defer = __evolved_defer evolved.commit = __evolved_commit -evolved.is_alive = __evolved_is_alive -evolved.is_alive_all = __evolved_is_alive_all -evolved.is_alive_any = __evolved_is_alive_any +evolved.spawn = __evolved_spawn +evolved.clone = __evolved_clone -evolved.is_empty = __evolved_is_empty -evolved.is_empty_all = __evolved_is_empty_all -evolved.is_empty_any = __evolved_is_empty_any +evolved.alive = __evolved_alive +evolved.alive_all = __evolved_alive_all +evolved.alive_any = __evolved_alive_any -evolved.get = __evolved_get +evolved.empty = __evolved_empty +evolved.empty_all = __evolved_empty_all +evolved.empty_any = __evolved_empty_any evolved.has = __evolved_has evolved.has_all = __evolved_has_all evolved.has_any = __evolved_has_any +evolved.get = __evolved_get + evolved.set = __evolved_set evolved.remove = __evolved_remove evolved.clear = __evolved_clear evolved.destroy = __evolved_destroy -evolved.multi_set = __evolved_multi_set -evolved.multi_remove = __evolved_multi_remove - evolved.batch_set = __evolved_batch_set evolved.batch_remove = __evolved_batch_remove evolved.batch_clear = __evolved_batch_clear evolved.batch_destroy = __evolved_batch_destroy -evolved.batch_multi_set = __evolved_batch_multi_set -evolved.batch_multi_remove = __evolved_batch_multi_remove - -evolved.chunk = __evolved_chunk - -evolved.entities = __evolved_entities -evolved.fragments = __evolved_fragments -evolved.components = __evolved_components - evolved.each = __evolved_each evolved.execute = __evolved_execute evolved.process = __evolved_process -evolved.spawn_at = __evolved_spawn_at -evolved.spawn_as = __evolved_spawn_as -evolved.spawn_with = __evolved_spawn_with - evolved.debug_mode = __evolved_debug_mode evolved.collect_garbage = __evolved_collect_garbage +evolved.chunk = __evolved_chunk evolved.builder = __evolved_builder evolved.collect_garbage()