diff --git a/README.md b/README.md index f7703b4..58bf6d0 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ ``` TAG :: fragment NAME :: fragment + DEFAULT :: fragment DUPLICATE :: fragment @@ -98,8 +99,8 @@ process :: system... -> () spawn :: ? -> entity clone :: entity -> ? -> entity -spawn_at :: chunk?, fragment[]?, component[]? -> entity -spawn_as :: entity?, fragment[]?, component[]? -> entity +spawn_single :: component, ? -> entity +clone_single :: entity -> component -> ? -> entity debug_mode :: boolean -> () collect_garbage :: () @@ -140,9 +141,6 @@ builder:clear :: builder builder:tag :: builder builder:name :: string -> builder -builder:prefab :: entity -> builder -builder:single :: component -> builder - builder:default :: component -> builder builder:duplicate :: {component -> component} -> builder @@ -166,7 +164,11 @@ builder:disabled :: builder builder:destroy_policy :: id -> builder -builder:build :: boolean -> entity +builder:spawn :: entity +builder:clone :: entity -> entity + +builder:spawn_single :: component -> entity +builder:clone_single :: entity -> component -> entity ``` ## [License (MIT)](./LICENSE.md) diff --git a/develop/all.lua b/develop/all.lua index 721dfcf..13d3ed0 100644 --- a/develop/all.lua +++ b/develop/all.lua @@ -5,5 +5,7 @@ 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' diff --git a/develop/example.lua b/develop/example.lua index f5aec9c..1d1be94 100644 --- a/develop/example.lua +++ b/develop/example.lua @@ -18,27 +18,27 @@ local function vector2(x, y) end local groups = { - awake = evo.builder():build(), - physics = evo.builder():build(), - graphics = evo.builder():build(), - shutdown = evo.builder():build(), + awake = evo.spawn(), + physics = evo.spawn(), + graphics = evo.spawn(), + shutdown = evo.spawn(), } local singles = { - delta_time = evo.builder():single(0.016):build(), - physics_gravity = evo.builder():single(vector2(0, 9.81)):build(), + delta_time = evo.spawn_single(0.016), + physics_gravity = evo.spawn_single(vector2(0, 9.81)), } 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,8 +49,8 @@ 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) @@ -71,7 +71,7 @@ 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) @@ -94,7 +94,7 @@ 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) @@ -111,14 +111,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 7ac0238..65c16e9 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,7 +98,7 @@ 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 chunk:has_any(__table_unpack(should_be_destroyed_entity_list))) diff --git a/develop/fuzzing/destroy_fuzz.lua b/develop/fuzzing/destroy_fuzz.lua index 069cbca..de9990d 100644 --- a/develop/fuzzing/destroy_fuzz.lua +++ b/develop/fuzzing/destroy_fuzz.lua @@ -102,7 +102,7 @@ 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 chunk:has_any(__table_unpack(destroying_entity_list))) diff --git a/develop/unbench.lua b/develop/unbench.lua index 9e113fe..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) @@ -690,199 +690,3 @@ basics.describe_bench(string.format('create and destroy %d entities with 5 compo end, function() return {} end) - -print '----------------------------------------' - -basics.describe_bench(string.format('create and destroy %d entities with 1 components / spawn_at', N), - ---@param entities evolved.id[] - function(entities) - local spawn_at = evo.spawn_at - - local fragments = { F1 } - local components = { true } - - local chunk = evo.chunk(F1) - - for i = 1, N do - entities[i] = spawn_at(chunk, 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_at', N), - ---@param entities evolved.id[] - function(entities) - local spawn_at = evo.spawn_at - - local fragments = { F1, F2 } - local components = { true, true } - - local chunk = evo.chunk(F1, F2) - - for i = 1, N do - entities[i] = spawn_at(chunk, 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_at', N), - ---@param entities evolved.id[] - function(entities) - local spawn_at = evo.spawn_at - - local fragments = { F1, F2, F3 } - local components = { true, true, true } - - local chunk = evo.chunk(F1, F2, F3) - - for i = 1, N do - entities[i] = spawn_at(chunk, 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_at', N), - ---@param entities evolved.id[] - function(entities) - local spawn_at = evo.spawn_at - - local fragments = { F1, F2, F3, F4 } - local components = { true, true, true, true } - - local chunk = evo.chunk(F1, F2, F3, F4) - - for i = 1, N do - entities[i] = spawn_at(chunk, 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_at', N), - ---@param entities evolved.id[] - function(entities) - local spawn_at = evo.spawn_at - - local fragments = { F1, F2, F3, F4, F5 } - local components = { true, true, true, true, true } - - local chunk = evo.chunk(F1, F2, F3, F4, F5) - - for i = 1, N do - entities[i] = spawn_at(chunk, 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_as', N), - ---@param entities evolved.id[] - function(entities) - local spawn_as = evo.spawn_as - - local fragments = { F1 } - local components = { true } - - local prefab = evo.spawn { [F1] = true } - - 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 { [F1] = true, [F2] = true } - - 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 { [F1] = true, [F2] = true, [F3] = true } - - 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 { [F1] = true, [F2] = true, [F3] = true, [F4] = true } - - 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 { [F1] = true, [F2] = true, [F3] = true, [F4] = true, [F5] = true } - - for i = 1, N do - entities[i] = spawn_as(prefab, fragments, components) - end - - evo.batch_destroy(Q1) - end, function() - return {} - end) - -print '----------------------------------------' diff --git a/develop/untests.lua b/develop/untests.lua index 181ad4d..5889cac 100644 --- a/develop/untests.lua +++ b/develop/untests.lua @@ -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) @@ -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,7 +2484,7 @@ 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)) @@ -2498,9 +2498,9 @@ do assert(evo.is_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)) @@ -2518,12 +2518,12 @@ do assert(evo.is_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) @@ -2560,7 +2560,7 @@ do 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) @@ -2568,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) @@ -2576,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) @@ -2584,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) @@ -2592,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) @@ -2600,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) @@ -2608,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) @@ -2616,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) @@ -2632,24 +2633,24 @@ do local eb = evo.builder() do - local e = eb:build() + local e = eb:clear():spawn() assert(evo.is_alive(e) and evo.is_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() + local e = eb:clear():spawn() assert(evo.is_alive(e) and evo.is_empty(e)) end end @@ -2658,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) @@ -2826,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 @@ -2897,219 +2898,6 @@ do 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 }) - 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) @@ -3226,7 +3014,7 @@ 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) @@ -3267,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) @@ -3321,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 @@ -3336,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 @@ -3361,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 @@ -3377,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 @@ -3393,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 @@ -3415,23 +3203,6 @@ do 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) @@ -3702,7 +3473,7 @@ 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 @@ -3938,10 +3709,10 @@ 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) @@ -3963,8 +3734,8 @@ do 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) @@ -3994,10 +3765,10 @@ 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) @@ -4019,8 +3790,8 @@ do 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) @@ -4047,17 +3818,17 @@ end do do - local f = evo.builder():default():build() + local f = evo.builder():default():spawn() assert(evo.has(f, evo.DEFAULT)) end do - local f = evo.builder():single():build() + local f = evo.builder():spawn_single() assert(evo.has(f, f)) end do - local f = evo.builder():single(42):build() + local f = evo.builder():spawn_single(42) assert(evo.has(f, f) and evo.get(f, f) == 42) end end @@ -4065,10 +3836,10 @@ 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) @@ -4084,13 +3855,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 @@ -4100,24 +3871,24 @@ 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 @@ -4128,24 +3899,24 @@ do local sb = evo.builder() do - local f = fb:single(false):build() + local f = fb:spawn_single(false) assert(evo.get(f, f) == false) - local q = qb:single(false):build() + local q = qb:spawn_single(false) assert(evo.get(q, q) == false) - local s = sb:single(false):build() + local s = sb:spawn_single(false) assert(evo.get(s, s) == false) end do - local f = fb:build() + local f = fb:spawn() assert(evo.get(f, f) == nil) - local q = qb:build() + local q = qb:spawn() assert(evo.get(q, q) == nil) - local s = sb:build() + local s = sb:spawn() assert(evo.get(s, s) == nil) end end @@ -4157,11 +3928,11 @@ 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 = c1:entities() @@ -4373,7 +4144,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)) @@ -4381,10 +4152,10 @@ 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) @@ -4469,14 +4240,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) @@ -4538,13 +4309,13 @@ 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) @@ -4570,26 +4341,15 @@ 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) @@ -4611,9 +4371,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) @@ -4639,15 +4399,15 @@ 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) @@ -4668,7 +4428,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) @@ -4687,7 +4447,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) @@ -4698,11 +4458,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) @@ -4762,11 +4522,11 @@ 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(old_c1:is_alive()) @@ -5270,75 +5030,6 @@ do assert(not evo.has_any(e5, f7, f7, f6)) end -do - local f1 = evo.id() - - local c1 = assert(evo.chunk(f1)) - assert(c1:is_alive() and c1:is_empty()) - - local e1 = evo.spawn_at(c1) - assert(c1:is_alive() and not c1:is_empty()) - - evo.destroy(e1) - assert(c1:is_alive() and c1:is_empty()) - - evo.collect_garbage() - assert(not c1:is_alive() and c1:is_empty()) -end - -do - local f1, f2 = evo.id(2) - - local c1 = assert(evo.chunk(f1)) - local c12 = assert(evo.chunk(f1, f2)) - - assert(c1:is_alive()) - assert(c12:is_alive()) - - assert(c1:is_empty()) - assert(c12:is_empty()) - - local e12 = evo.spawn_at(c12) - - assert(c1:is_alive()) - assert(c12:is_alive()) - - assert(c1:is_empty()) - assert(not c12:is_empty()) - - evo.remove(e12, f2) - - assert(c1:is_alive()) - assert(c12:is_alive()) - - assert(not c1:is_empty()) - assert(c12:is_empty()) - - evo.collect_garbage() - - assert(c1:is_alive()) - assert(not c12:is_alive()) - - assert(not c1:is_empty()) - assert(c12:is_empty()) - - evo.remove(e12, f1) - - assert(c1:is_alive()) - assert(not c12:is_alive()) - - assert(c1:is_empty()) - assert(c12:is_empty()) - - evo.collect_garbage() - - assert(not c1:is_alive()) - assert(not c12:is_alive()) - - assert(c1:is_empty()) - assert(c12:is_empty()) -end - do local f1, f2 = evo.id(2) local c1 = assert(evo.chunk(f1)) @@ -5390,10 +5081,10 @@ 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() + local g3 = gb:clear():spawn_single(42) + local g4 = gb:clear():name('g4'):spawn_single(43) 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)) @@ -5402,39 +5093,11 @@ do 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(c1:is_alive()) - assert(evo.get(e1, f1) == 42) - - assert(evo.defer()) - evo.collect_garbage() - assert(evo.commit()) - - assert(c1:is_alive()) - - evo.destroy(e1) - assert(not evo.is_alive(e1)) - - assert(evo.defer()) - evo.collect_garbage() - assert(evo.commit()) - - assert(not c1:is_alive()) -end - do -- evo.set @@ -5442,7 +5105,7 @@ do 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 = evo.id(2) @@ -5484,7 +5147,7 @@ do end do - local f = evo.builder():default(v2(11, 22)):build() + local f = evo.builder():default(v2(11, 22)):spawn() do local e1, e2 = evo.id(3) @@ -5531,7 +5194,7 @@ do 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 = evo.id(2) @@ -5578,7 +5241,7 @@ do end do - local f = evo.builder():duplicate(v2_clone):build() + local f = evo.builder():duplicate(v2_clone):spawn() do local e1, e2 = evo.id(2) @@ -5630,10 +5293,10 @@ do 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 t1 = evo.builder():tag():spawn() + local qt1 = evo.builder():include(t1):spawn() do local e1, e2 = evo.id(2) @@ -5674,10 +5337,10 @@ do 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 t1 = evo.builder():tag():spawn() + local qt1 = evo.builder():include(t1):spawn() do local e1, e2 = evo.id(2) @@ -5721,10 +5384,10 @@ do 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 t1 = evo.builder():tag():spawn() + local qt1 = evo.builder():include(t1):spawn() do local e1, e2 = evo.id(2) @@ -5768,10 +5431,10 @@ do 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 t1 = evo.builder():tag():spawn() + local qt1 = evo.builder():include(t1):spawn() do local e1, e2 = evo.id(2) @@ -5818,26 +5481,8 @@ 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 c12 = evo.chunk(f1, f2) - - do - local fs = { f1, f2 } - local cs = { v2(1, 2), v2(11, 22) } - - local e1 = evo.spawn_at(c12, fs, cs) - local e2 = evo.spawn_at(c12, fs, 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) - 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 + local f1 = evo.builder():default(v2(10, 11)):spawn() + local f2 = evo.builder():default(v2(11, 22)):spawn() do local cs = { [f1] = v2(1, 2), [f2] = v2(11, 22) } @@ -5859,25 +5504,8 @@ 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 c12 = evo.chunk(f1, f2) - - do - local fs, cs = { f1, f2 }, { v2(1, 2) } - - local e1 = evo.spawn_at(c12, fs, cs) - local e2 = evo.spawn_at(c12, fs, 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) - 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 + 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 cs = { [f1] = v2(1, 2), [f2] = v2(11, 22) } @@ -5895,349 +5523,12 @@ 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)) @@ -6257,8 +5548,8 @@ 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)) @@ -6278,8 +5569,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) @@ -6289,9 +5580,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) @@ -6306,8 +5597,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)) @@ -6324,9 +5615,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)) @@ -6351,8 +5642,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) @@ -6362,9 +5653,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) @@ -6379,8 +5670,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)) @@ -6397,9 +5688,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)) @@ -6434,7 +5725,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) @@ -6449,7 +5740,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) @@ -6464,7 +5755,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) @@ -6479,7 +5770,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) @@ -6494,7 +5785,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) @@ -6600,7 +5891,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 @@ -6610,7 +5901,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 @@ -6620,7 +5911,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 @@ -6630,7 +5921,7 @@ 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 @@ -6640,22 +5931,22 @@ do local f1 = evo.id(1) do - local b = evo.builder():set(f1, 11):single(1) + local b = evo.builder():set(f1, 11) - local e1 = b:build(true) + local e1 = b:spawn_single(1) assert(evo.has(e1, e1) and evo.get(e1, e1) == 1) assert(evo.has(e1, f1) and evo.get(e1, f1) == 11) assert(not b:has(e1) and b:get(e1) == nil) - local e2 = b:build() + local e2 = b:spawn_single(1) 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() + local e3 = b:clear():spawn() assert(not evo.has(e3, e1) and evo.get(e3, e1) == nil) assert(not evo.has(e3, e2) and evo.get(e3, e2) == nil) diff --git a/develop/usbench.lua b/develop/usbench.lua index d2ebe04..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 + for chunk, _, entity_count in evo.execute(A) do local as = chunk:components(a) - for i = 1, #entities do + 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 + for chunk, _, entity_count in evo.execute(A) do local as = chunk:components(a) - for i = 1, #entities do - to_create[#to_create + 1] = as[i] + 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 + for chunk, _, entity_count in evo.execute(AB) do local as, bs = chunk:components(a, b) - for i = 1, #entities do + for i = 1, entity_count do as[i], bs[i] = bs[i], as[i] end end - for chunk, entities in evo.execute(CD) do + for chunk, _, entity_count in evo.execute(CD) do local cs, ds = chunk:components(c, d) - for i = 1, #entities do + for i = 1, entity_count do cs[i], ds[i] = ds[i], cs[i] end end - for chunk, entities in evo.execute(CE) do + for chunk, _, entity_count in evo.execute(CE) do local cs, es = chunk:components(c, e) - for i = 1, #entities do + 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 + for chunk, _, entity_count in evo.execute(A) do local as = chunk:components(a) - for i = 1, #entities do + for i = 1, entity_count do as[i] = as[i] * 2 end end - for chunk, entities in evo.execute(B) do + for chunk, _, entity_count in evo.execute(B) do local bs = chunk:components(b) - for i = 1, #entities do + for i = 1, entity_count do bs[i] = bs[i] * 2 end end - for chunk, entities in evo.execute(C) do + for chunk, _, entity_count in evo.execute(C) do local cs = chunk:components(c) - for i = 1, #entities do + for i = 1, entity_count do cs[i] = cs[i] * 2 end end - for chunk, entities in evo.execute(D) do + for chunk, _, entity_count in evo.execute(D) do local ds = chunk:components(d) - for i = 1, #entities do + for i = 1, entity_count do ds[i] = ds[i] * 2 end end - for chunk, entities in evo.execute(E) do + for chunk, _, entity_count in evo.execute(E) do local es = chunk:components(e) - for i = 1, #entities do + 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 + for chunk, _, entity_count in evo.execute(Data) do local ds = chunk:components(data) - for i = 1, #entities do + for i = 1, entity_count do ds[i] = ds[i] * 2 end end - for chunk, entities in evo.execute(Last) do + for chunk, _, entity_count in evo.execute(Last) do local ls = chunk:components(last) - for i = 1, #entities do + 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 348267d..93537c8 100644 --- a/evolved.lua +++ b/evolved.lua @@ -621,6 +621,7 @@ end local __TAG = __acquire_id() local __NAME = __acquire_id() + local __DEFAULT = __acquire_id() local __DUPLICATE = __acquire_id() @@ -725,8 +726,8 @@ local __evolved_process local __evolved_spawn local __evolved_clone -local __evolved_spawn_at -local __evolved_spawn_as +local __evolved_spawn_single +local __evolved_clone_single local __evolved_debug_mode local __evolved_collect_garbage @@ -859,44 +860,11 @@ local __debug_fns = {} __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 - ---@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 +---@field package __components table __debug_fns.builder_mt = {} __debug_fns.builder_mt.__index = __debug_fns.builder_mt ----@type metatable -__debug_fns.builder_fragment_set_mt = {} -__debug_fns.builder_fragment_set_mt.__index = __debug_fns.builder_fragment_set_mt - ----@type metatable -__debug_fns.builder_fragment_list_mt = {} -__debug_fns.builder_fragment_list_mt.__index = __debug_fns.builder_fragment_list_mt - --- --- --- @@ -905,114 +873,34 @@ __debug_fns.builder_fragment_list_mt.__index = __debug_fns.builder_fragment_list ---@param self evolved.chunk function __debug_fns.chunk_mt.__tostring(self) - local items = {} ---@type string[] + local fragment_names = {} ---@type string[] - for fragment_index, fragment in ipairs(self.__fragment_list) do - items[fragment_index] = __id_name(fragment) + for i = 1, self.__fragment_count do + fragment_names[i] = __id_name(self.__fragment_list[i]) end - return string.format('<%s>', table.concat(items, ', ')) + return string.format('<%s>', table.concat(fragment_names, ', ')) 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 self evolved.builder function __debug_fns.builder_mt.__tostring(self) - local items = {} ---@type string[] + local fragment_list = {} ---@type evolved.fragment[] + local fragment_count = 0 ---@type integer - for fragment_index, fragment in ipairs(self.__fragment_list) do - items[fragment_index] = __id_name(fragment) + for fragment in __lua_next, self.__components do + fragment_count = fragment_count + 1 + fragment_list[fragment_count] = fragment end - return string.format('<%s>', table.concat(items, ', ')) -end + __lua_table_sort(fragment_list) ----@param self table -function __debug_fns.builder_fragment_set_mt.__tostring(self) - local items = {} ---@type string[] + local fragment_names = {} ---@type string[] - for fragment, fragment_index in pairs(self) do - items[fragment_index] = string.format('(%s -> %d)', - __id_name(fragment), fragment_index) + for i = 1, fragment_count do + fragment_names[i] = __id_name(fragment_list[i]) end - return string.format('{%s}', table.concat(items, ', ')) -end - ----@param self evolved.fragment[] -function __debug_fns.builder_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, ', ')) + return string.format('<%s>', table.concat(fragment_names, ', ')) end --- @@ -1298,29 +1186,11 @@ local function __chunk_with_fragment(chunk, fragment) return __new_chunk(chunk, fragment) end ----@param chunk? evolved.chunk ----@param fragment_list evolved.fragment[] ----@param fragment_count integer ----@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] - chunk = __chunk_with_fragment(chunk, fragment) - end - - return chunk -end - ---@param chunk? evolved.chunk ---@param components table ---@return evolved.chunk? ---@nodiscard -local function __chunk_with_component_map(chunk, components) +local function __chunk_with_components(chunk, components) for fragment in __lua_next, components do chunk = __chunk_with_fragment(chunk, fragment) end @@ -1390,36 +1260,6 @@ end --- --- ----@param chunk evolved.chunk ----@return evolved.chunk chunk -local function __chunk_pin(chunk) - local chunk_pin_count = __pinned_chunks[chunk] or 0 - - __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') - end - - __pinned_chunks[chunk] = chunk_pin_count > 1 and chunk_pin_count - 1 or nil - - return chunk -end - ---- ---- ---- ---- ---- - ---@param head_fragment evolved.fragment ---@param ... evolved.fragment tail_fragments ---@return evolved.chunk @@ -1438,32 +1278,10 @@ local function __chunk_fragments(head_fragment, ...) return chunk end ----@param fragment_list evolved.fragment[] ----@param fragment_count integer ----@return evolved.chunk? ----@nodiscard -local function __chunk_fragment_list(fragment_list, fragment_count) - if fragment_count == 0 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) - end - - return chunk -end - ---@param components table ---@return evolved.chunk? ---@nodiscard -local function __chunk_component_map(components) +local function __chunk_components(components) local root_fragment = __lua_next(components) if not root_fragment then @@ -1473,9 +1291,9 @@ local function __chunk_component_map(components) local chunk = __root_chunks[root_fragment] or __chunk_with_fragment(nil, root_fragment) - for child_fragment in __lua_next, components, root_fragment do - 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 @@ -1691,10 +1509,6 @@ local __defer_batch_destroy local __defer_spawn_entity local __defer_clone_entity -local __defer_spawn_entity_at -local __defer_spawn_entity_as -local __defer_spawn_entity_with - local __defer_call_hook --- @@ -1761,7 +1575,7 @@ local function __spawn_entity(entity, components) __error_fmt('spawn entity operations should be deferred') end - local chunk = __chunk_component_map(components) + local chunk = __chunk_components(components) if not chunk then return @@ -1875,7 +1689,7 @@ local function __clone_entity(entity, prefab, components) local prefab_chunk = __entity_chunks[prefab_index] local prefab_place = __entity_places[prefab_index] - local chunk = __chunk_with_component_map(prefab_chunk, components) + local chunk = __chunk_with_components(prefab_chunk, components) if not chunk then return @@ -2029,458 +1843,6 @@ local function __clone_entity(entity, prefab, components) 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_at(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_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 - - 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 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] - 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 - - 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 - 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 component_storage = chunk_component_storages[component_index] - - 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 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) - if __defer_depth <= 0 then - __error_fmt('spawn 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 chunk = __chunk_with_fragment_list(prefab_chunk, fragment_list, fragment_count) - - 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 prefab_chunk then - local prefab_component_count = prefab_chunk.__component_count - local prefab_component_storages = prefab_chunk.__component_storages - local prefab_component_fragments = prefab_chunk.__component_fragments - - if prefab_chunk.__has_setup_hooks then - for prefab_component_index = 1, prefab_component_count do - local fragment = prefab_component_fragments[prefab_component_index] - - ---@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 new_component = prefab_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_index = chunk_component_indices[fragment] - local component_storage = chunk_component_storages[component_index] - - 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 prefab_component_storage = prefab_component_storages[prefab_component_index] - local prefab_component = prefab_component_storage[prefab_place] - - local new_component = prefab_component - - if new_component == nil then - new_component = true - end - - local component_index = chunk_component_indices[fragment] - local component_storage = chunk_component_storages[component_index] - - 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] - 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 - - 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 - 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 component_storage = chunk_component_storages[component_index] - - 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 - - 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 - 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 component_storage = chunk_component_storages[component_index] - - 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 - --- --- --- @@ -3328,13 +2690,9 @@ local __defer_op = { spawn_entity = 9, clone_entity = 10, - spawn_entity_at = 11, - spawn_entity_as = 12, - spawn_entity_with = 13, + call_hook = 11, - call_hook = 14, - - __count = 14, + __count = 11, } ---@type table @@ -3900,177 +3258,6 @@ __defer_ops[__defer_op.clone_entity] = function(bytes, index) return 3 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 - 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 + 2] = entity - bytecode[length + 3] = prefab - 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_as] = 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] - - if __debug_mode then - if prefab then __debug_fns.validate_prefab(prefab) end - __debug_fns.validate_fragment_list(fragment_list, fragment_count) - 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) - 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 -end - ---@param hook fun(...) ---@param ... any hook arguments function __defer_call_hook(hook, ...) @@ -5217,85 +4404,103 @@ function __evolved_clone(prefab, components) return entity 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 - +---@param single evolved.component +---@param components? table +---@return evolved.entity +function __evolved_spawn_single(single, components) if not components then - components = __safe_tbls.__EMPTY_COMPONENT_LIST + components = {} 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) + __debug_fns.validate_component_map(components) + end + + do + ---@type evolved.default?, evolved.duplicate? + local single_default, single_duplicate = + components[__DEFAULT], components[__DUPLICATE] + + if single == nil then + single = single_default + end + + if single == nil and single_duplicate then + single = single_duplicate(single) + end + + if single == nil then + single = true + end 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 + components[entity] = single + __defer_spawn_entity(entity, components) + components[entity] = nil + else + __evolved_defer() + do + components[entity] = single + __spawn_entity(entity, components) + components[entity] = nil + end + __evolved_commit() 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 - +---@param prefab evolved.entity +---@param single evolved.component +---@param components? table +---@return evolved.entity +function __evolved_clone_single(prefab, single, components) if not components then - components = __safe_tbls.__EMPTY_COMPONENT_LIST + components = {} 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) + __debug_fns.validate_prefab(prefab) + __debug_fns.validate_component_map(components) + end + + do + ---@type evolved.default?, evolved.duplicate? + local single_default, single_duplicate = + components[__DEFAULT], components[__DUPLICATE] + + if single == nil then + single = single_default + end + + if single == nil and single_duplicate then + single = single_duplicate(single) + end + + if single == nil then + single = true + end end local entity = __acquire_id() if __defer_depth > 0 then - __defer_spawn_entity_as(entity, prefab, - fragments, fragment_count, - components, component_count) - return entity + components[entity] = single + __defer_clone_entity(entity, prefab, components) + components[entity] = nil + else + __evolved_defer() + do + components[entity] = single + __clone_entity(entity, prefab, components) + components[entity] = nil + end + __evolved_commit() end - __evolved_defer() - do - __spawn_entity_as(entity, prefab, - fragments, fragment_count, - components) - end - __evolved_commit() - return entity end @@ -5393,12 +4598,6 @@ function __evolved_chunk(fragment, ...) return chunk, chunk.__entity_list, chunk.__entity_count end ---- ---- ---- ---- ---- - ---@return boolean ---@nodiscard function __debug_fns.chunk_mt:is_alive() @@ -5517,38 +4716,15 @@ end ---@nodiscard function __evolved_builder() return __lua_setmetatable({ - __fragment_set = __lua_setmetatable({}, __debug_fns.builder_fragment_set_mt), - __fragment_list = __lua_setmetatable({}, __debug_fns.builder_fragment_list_mt), - __component_list = {}, - __component_count = 0, + __components = {}, }, __debug_fns.builder_mt) end ---- ---- ---- ---- ---- - ---@param fragment evolved.fragment ---@return boolean ---@nodiscard function __debug_fns.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 + return self.__components[fragment] ~= nil end ---@param ... evolved.fragment fragments @@ -5561,7 +4737,33 @@ function __debug_fns.builder_mt:has_all(...) 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 @@ -5574,7 +4776,33 @@ function __debug_fns.builder_mt:has_any(...) 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 @@ -5587,23 +4815,33 @@ function __debug_fns.builder_mt:get(...) 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 @@ -5632,26 +4870,7 @@ function __debug_fns.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 @@ -5665,44 +4884,42 @@ function __debug_fns.builder_mt:remove(...) 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 __debug_fns.builder_mt:clear() - self.__prefab = nil - self.__single = nil - self.__component_count = 0 + __lua_table_clear(self.__components) return self end @@ -5717,20 +4934,6 @@ function __debug_fns.builder_mt:name(name) return self:set(__NAME, name) end ----@param prefab evolved.entity ----@return evolved.builder builder -function __debug_fns.builder_mt:prefab(prefab) - self.__prefab = prefab - return self -end - ----@param single evolved.component ----@return evolved.builder builder -function __debug_fns.builder_mt:single(single) - self.__single = single == nil and true or single - return self -end - ---@param default evolved.component ---@return evolved.builder builder function __debug_fns.builder_mt:default(default) @@ -5858,60 +5061,144 @@ function __debug_fns.builder_mt:destroy_policy(destroy_policy) return self:set(__DESTROY_POLICY, destroy_policy) end ----@param no_clear? boolean ----@return evolved.entity entity -function __debug_fns.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 +---@return evolved.entity +function __debug_fns.builder_mt:spawn() + local components = self.__components if __debug_mode then - if prefab then __debug_fns.validate_prefab(prefab) end - __debug_fns.validate_fragment_list(fragment_list, component_count) + __debug_fns.validate_component_map(components) end local entity = __acquire_id() - if single ~= nil then - component_count = component_count + 1 - fragment_list[component_count] = entity - component_list[component_count] = single + if __defer_depth > 0 then + __defer_spawn_entity(entity, components) + else + __evolved_defer() + do + __spawn_entity(entity, components) + end + __evolved_commit() end - if not no_clear then - self:clear() + return entity +end + +---@param prefab evolved.entity +---@return evolved.entity +function __debug_fns.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_chunk = __chunk_fragment_list(fragment_list, component_count) + local entity = __acquire_id() 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) + __defer_clone_entity(entity, prefab, components) + else + __evolved_defer() + do + __clone_entity(entity, prefab, components) end - return entity + __evolved_commit() + end + + return entity +end + +---@param single evolved.component +---@return evolved.entity +function __debug_fns.builder_mt:spawn_single(single) + local components = self.__components + + if __debug_mode then + __debug_fns.validate_component_map(components) 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) + ---@type evolved.default?, evolved.duplicate? + local single_default, single_duplicate = + components[__DEFAULT], components[__DUPLICATE] + + if single == nil then + single = single_default + end + + if single == nil and single_duplicate then + single = single_duplicate(single) + end + + if single == nil then + single = true end end - __evolved_commit() + + local entity = __acquire_id() + + if __defer_depth > 0 then + components[entity] = single + __defer_spawn_entity(entity, components) + components[entity] = nil + else + __evolved_defer() + do + components[entity] = single + __spawn_entity(entity, components) + components[entity] = nil + end + __evolved_commit() + end + + return entity +end + +---@param prefab evolved.entity +---@param single evolved.component +---@return evolved.entity +function __debug_fns.builder_mt:clone_single(prefab, single) + local components = self.__components + + if __debug_mode then + __debug_fns.validate_prefab(prefab) + __debug_fns.validate_component_map(components) + end + + do + ---@type evolved.default?, evolved.duplicate? + local single_default, single_duplicate = + components[__DEFAULT], components[__DUPLICATE] + + if single == nil then + single = single_default + end + + if single == nil and single_duplicate then + single = single_duplicate(single) + end + + if single == nil then + single = true + end + end + + local entity = __acquire_id() + + if __defer_depth > 0 then + components[entity] = single + __defer_clone_entity(entity, prefab, components) + components[entity] = nil + else + __evolved_defer() + do + components[entity] = single + __clone_entity(entity, prefab, components) + components[entity] = nil + end + __evolved_commit() + end return entity end @@ -6061,6 +5348,7 @@ __evolved_set(__DUPLICATE, __ON_REMOVE, __update_fragment_duplicates) __evolved_set(__TAG, __NAME, 'TAG') __evolved_set(__NAME, __NAME, 'NAME') + __evolved_set(__DEFAULT, __NAME, 'DEFAULT') __evolved_set(__DUPLICATE, __NAME, 'DUPLICATE') @@ -6287,8 +5575,8 @@ evolved.process = __evolved_process evolved.spawn = __evolved_spawn evolved.clone = __evolved_clone -evolved.spawn_at = __evolved_spawn_at -evolved.spawn_as = __evolved_spawn_as +evolved.spawn_single = __evolved_spawn_single +evolved.clone_single = __evolved_clone_single evolved.debug_mode = __evolved_debug_mode evolved.collect_garbage = __evolved_collect_garbage