diff --git a/README.md b/README.md index a7204f9..c93b7bc 100644 --- a/README.md +++ b/README.md @@ -420,17 +420,19 @@ You should try to avoid structural changes, especially in performance-critical c #### Spawning Entities ```lua ----@param components? table +---@param component_table? table +---@param component_mapper? fun(chunk: evolved.chunk, place: integer) ---@return evolved.entity -function evolved.spawn(components) end +function evolved.spawn(component_table, component_mapper) end ---@param prefab evolved.entity ----@param components? table +---@param component_table? table +---@param component_mapper? fun(chunk: evolved.chunk, place: integer) ---@return evolved.entity -function evolved.clone(prefab, components) end +function evolved.clone(prefab, component_table, component_mapper) end ``` -The [`evolved.spawn`](#evolvedspawn) function allows you to spawn an entity with all the necessary fragments. It takes a table of components as an argument, where the keys are fragments and the values are components. By the way, you don't need to create this `components` table every time; consider using a predefined table for maximum performance. +The [`evolved.spawn`](#evolvedspawn) function allows you to spawn an entity with all the necessary fragments. It takes a table of components as an argument, where the keys are fragments and the values are components. By the way, you don't need to create this `component_table` every time; consider using a predefined table for maximum performance. You can also use the [`evolved.clone`](#evolvedclone) function to clone an existing entity. This is useful for creating entities with the same fragments as an existing entity but with different components. @@ -1268,22 +1270,22 @@ local MOVEMENT_SYSTEM = evolved.builder() -- -- -do - local entity_list, entity_count = evolved.builder() - :set(POSITION_X) - :set(POSITION_Y) - :set(VELOCITY_X) - :set(VELOCITY_Y) - :multi_build(10000) +evolved.builder() + :set(POSITION_X) + :set(POSITION_Y) + :set(VELOCITY_X) + :set(VELOCITY_Y) + :multi_spawn(10000, function(chunk, b_place, e_place) + local position_xs, position_ys = chunk:components(POSITION_X, POSITION_Y) + local velocity_xs, velocity_ys = chunk:components(VELOCITY_X, VELOCITY_Y) - for i = 1, entity_count do - local entity = entity_list[i] - evolved.set(entity, POSITION_X, math.random(0, 640)) - evolved.set(entity, POSITION_Y, math.random(0, 480)) - evolved.set(entity, VELOCITY_X, math.random(-100, 100)) - evolved.set(entity, VELOCITY_Y, math.random(-100, 100)) - end -end + for place = b_place, e_place do + position_xs[place] = math.random(0, 640) + position_ys[place] = math.random(0, 480) + velocity_xs[place] = math.random(-100, 100) + velocity_ys[place] = math.random(-100, 100) + end + end) -- -- @@ -1309,6 +1311,9 @@ system :: id component :: any storage :: component[] +component_table :: +component_mapper :: {chunk, integer, integer} + default :: component duplicate :: {component -> component} @@ -1387,11 +1392,11 @@ depth :: integer commit :: boolean cancel :: boolean -spawn :: ? -> entity -multi_spawn :: integer, ? -> entity[], integer +spawn :: component_table?, component_mapper? -> entity +multi_spawn :: integer, component_table?, component_mapper? -> entity[], integer -clone :: entity, ? -> entity -multi_clone :: integer, entity, ? -> entity[], integer +clone :: entity, component_table?, component_mapper? -> entity +multi_clone :: integer, entity, component_table?, component_mapper? -> entity[], integer alive :: entity -> boolean alive_all :: entity... -> boolean @@ -1405,7 +1410,7 @@ has :: entity, fragment -> boolean has_all :: entity, fragment... -> boolean has_any :: entity, fragment... -> boolean -get :: entity, fragment... -> component... +get :: entity, fragment... -> component... set :: entity, fragment, component -> () remove :: entity, fragment... -> () @@ -1453,14 +1458,14 @@ chunk_mt:components :: fragment... -> storage... ``` builder :: builder -builder_mt:build :: entity? -> entity -builder_mt:multi_build :: integer, entity? -> entity[], integer +builder_mt:build :: entity?, component_mapper? -> entity +builder_mt:multi_build :: integer, entity?, component_mapper? -> entity[], integer -builder_mt:spawn :: entity -builder_mt:multi_spawn :: integer -> entity[], integer +builder_mt:spawn :: component_mapper? -> entity +builder_mt:multi_spawn :: integer, component_mapper? -> entity[], integer -builder_mt:clone :: entity -> entity -builder_mt:multi_clone :: integer, entity -> entity[], integer +builder_mt:clone :: entity, component_mapper? -> entity +builder_mt:multi_clone :: integer, entity, component_mapper? -> entity[], integer builder_mt:has :: fragment -> boolean builder_mt:has_all :: fragment... -> boolean @@ -1696,28 +1701,31 @@ function evolved.cancel() end ### `evolved.spawn` ```lua ----@param components? table +---@param component_table? evolved.component_table +---@param component_mapper? evolved.component_mapper ---@return evolved.entity entity -function evolved.spawn(components) end +function evolved.spawn(component_table, component_mapper) end ``` ### `evolved.multi_spawn` ```lua ---@param entity_count integer ----@param components? table +---@param component_table? evolved.component_table +---@param component_mapper? evolved.component_mapper ---@return evolved.entity[] entity_list ---@return integer entity_count -function evolved.multi_spawn(entity_count, components) end +function evolved.multi_spawn(entity_count, component_table, component_mapper) end ``` ### `evolved.clone` ```lua ---@param prefab evolved.entity ----@param components? table +---@param component_table? evolved.component_table +---@param component_mapper? evolved.component_mapper ---@return evolved.entity entity -function evolved.clone(prefab, components) end +function evolved.clone(prefab, component_table, component_mapper) end ``` ### `evolved.multi_clone` @@ -1725,10 +1733,11 @@ function evolved.clone(prefab, components) end ```lua ---@param entity_count integer ---@param prefab evolved.entity ----@param components? table +---@param component_table? evolved.component_table +---@param component_mapper? evolved.component_mapper ---@return evolved.entity[] entity_list ---@return integer entity_count -function evolved.multi_clone(entity_count, prefab, components) end +function evolved.multi_clone(entity_count, prefab, component_table, component_mapper) end ``` ### `evolved.alive` @@ -2045,8 +2054,9 @@ function evolved.builder() end ```lua ---@param prefab? evolved.entity +---@param component_mapper? evolved.component_mapper ---@return evolved.entity entity -function evolved.builder_mt:build(prefab) end +function evolved.builder_mt:build(prefab, component_mapper) end ``` ### `evolved.builder_mt:multi_build` @@ -2054,33 +2064,37 @@ function evolved.builder_mt:build(prefab) end ```lua ---@param entity_count integer ---@param prefab? evolved.entity +---@param component_mapper? evolved.component_mapper ---@return evolved.entity[] entity_list ---@return integer entity_count -function evolved.builder_mt:multi_build(entity_count, prefab) end +function evolved.builder_mt:multi_build(entity_count, prefab, component_mapper) end ``` #### `evolved.builder_mt:spawn` ```lua +---@param component_mapper? evolved.component_mapper ---@return evolved.entity entity -function evolved.builder_mt:spawn() end +function evolved.builder_mt:spawn(component_mapper) end ``` #### `evolved.builder_mt:multi_spawn` ```lua ---@param entity_count integer +---@param component_mapper? evolved.component_mapper ---@return evolved.entity[] entity_list ---@return integer entity_count -function evolved.builder_mt:multi_spawn(entity_count) end +function evolved.builder_mt:multi_spawn(entity_count, component_mapper) end ``` #### `evolved.builder_mt:clone` ```lua ---@param prefab evolved.entity +---@param component_mapper? evolved.component_mapper ---@return evolved.entity entity -function evolved.builder_mt:clone(prefab) end +function evolved.builder_mt:clone(prefab, component_mapper) end ``` #### `evolved.builder_mt:multi_clone` @@ -2088,9 +2102,10 @@ function evolved.builder_mt:clone(prefab) end ```lua ---@param entity_count integer ---@param prefab evolved.entity +---@param component_mapper? evolved.component_mapper ---@return evolved.entity[] entity_list ---@return integer entity_count -function evolved.builder_mt:multi_clone(entity_count, prefab) end +function evolved.builder_mt:multi_clone(entity_count, prefab, component_mapper) end ``` #### `evolved.builder_mt:has` diff --git a/develop/ROADMAP.md b/develop/ROADMAP.md index 668acf4..5b53895 100644 --- a/develop/ROADMAP.md +++ b/develop/ROADMAP.md @@ -15,7 +15,8 @@ - Having a light version of the gargabe collector can be useful for some use-cases - We can shrink the table pool tables on garbage collection if they are too large - Should we sort chunk children by fragment id? +- Basic default component value as true looks awful, should we use something else? ## Known Issues -- Errors in hooks or rellocs/compmoves are cannot be handled properly right now +- Errors in hooks or rellocs/compmoves/mappers are cannot be handled properly right now diff --git a/develop/all.lua b/develop/all.lua index 9615cde..7e01a14 100644 --- a/develop/all.lua +++ b/develop/all.lua @@ -5,6 +5,7 @@ require 'develop.testing.depth_tests' require 'develop.testing.destroy_tests' require 'develop.testing.locate_tests' require 'develop.testing.main_tests' +require 'develop.testing.mappers_tests' require 'develop.testing.multi_spawn_tests' require 'develop.testing.name_tests' require 'develop.testing.process_with_tests' diff --git a/develop/testing/mappers_tests.lua b/develop/testing/mappers_tests.lua new file mode 100644 index 0000000..1e84950 --- /dev/null +++ b/develop/testing/mappers_tests.lua @@ -0,0 +1,242 @@ +local evo = require 'evolved' + +do + local f1, f2 = evo.id(2) + + local e1 = evo.spawn({ [f1] = 1, [f2] = 2 }, function(c, p) + local f1s, f2s = c:components(f1, f2) + f1s[p] = f1s[p] * 2 + f2s[p] = f2s[p] * 3 + end) + + local e2 = evo.spawn({ [f1] = 1, [f2] = 2 }, function(c, p) + local f1s, f2s = c:components(f1, f2) + f1s[p] = f1s[p] + 10 + f2s[p] = f2s[p] + 20 + end) + + assert(evo.has(e1, f1) and evo.get(e1, f1) == 2) + assert(evo.has(e1, f2) and evo.get(e1, f2) == 6) + assert(evo.has(e2, f1) and evo.get(e2, f1) == 11) + assert(evo.has(e2, f2) and evo.get(e2, f2) == 22) + + local e11 = evo.clone(e1, nil, function(c, p) + local f1s, f2s = c:components(f1, f2) + f1s[p] = f1s[p] * 3 + f2s[p] = f2s[p] * 4 + end) + + local e22 = evo.clone(e2, nil, function(c, p) + local f1s, f2s = c:components(f1, f2) + f1s[p] = f1s[p] + 30 + f2s[p] = f2s[p] + 40 + end) + + assert(evo.has(e11, f1) and evo.get(e11, f1) == 6) + assert(evo.has(e11, f2) and evo.get(e11, f2) == 24) + assert(evo.has(e22, f1) and evo.get(e22, f1) == 41) + assert(evo.has(e22, f2) and evo.get(e22, f2) == 62) +end + +do + local f1, f2 = evo.id(2) + + evo.defer() + + local e1 = evo.spawn({ [f1] = 1, [f2] = 2 }, function(c, p) + local f1s, f2s = c:components(f1, f2) + f1s[p] = f1s[p] * 2 + f2s[p] = f2s[p] * 3 + end) + + local e2 = evo.spawn({ [f1] = 1, [f2] = 2 }, function(c, p) + local f1s, f2s = c:components(f1, f2) + f1s[p] = f1s[p] + 10 + f2s[p] = f2s[p] + 20 + end) + + assert(not evo.has(e1, f1) and evo.get(e1, f1) == nil) + assert(not evo.has(e1, f2) and evo.get(e1, f2) == nil) + assert(not evo.has(e2, f1) and evo.get(e2, f1) == nil) + assert(not evo.has(e2, f2) and evo.get(e2, f2) == nil) + + evo.commit() + + assert(evo.has(e1, f1) and evo.get(e1, f1) == 2) + assert(evo.has(e1, f2) and evo.get(e1, f2) == 6) + assert(evo.has(e2, f1) and evo.get(e2, f1) == 11) + assert(evo.has(e2, f2) and evo.get(e2, f2) == 22) + + evo.defer() + + local e11 = evo.clone(e1, nil, function(c, p) + local f1s, f2s = c:components(f1, f2) + f1s[p] = f1s[p] * 3 + f2s[p] = f2s[p] * 4 + end) + + local e22 = evo.clone(e2, nil, function(c, p) + local f1s, f2s = c:components(f1, f2) + f1s[p] = f1s[p] + 30 + f2s[p] = f2s[p] + 40 + end) + + assert(not evo.has(e11, f1) and evo.get(e11, f1) == nil) + assert(not evo.has(e11, f2) and evo.get(e11, f2) == nil) + assert(not evo.has(e22, f1) and evo.get(e22, f1) == nil) + assert(not evo.has(e22, f2) and evo.get(e22, f2) == nil) + + evo.commit() + + assert(evo.has(e11, f1) and evo.get(e11, f1) == 6) + assert(evo.has(e11, f2) and evo.get(e11, f2) == 24) + assert(evo.has(e22, f1) and evo.get(e22, f1) == 41) + assert(evo.has(e22, f2) and evo.get(e22, f2) == 62) +end + +do + local f1, f2 = evo.id(2) + + local es, ec = evo.multi_spawn(10, { [f1] = 1, [f2] = 2 }, function(c, b, e) + local f1s, f2s = c:components(f1, f2) + for p = b, e do + f1s[p] = f1s[p] * 2 + f2s[p] = f2s[p] * 3 + end + end) + + for i = 1, ec do + local e = es[i] + assert(evo.has(e, f1) and evo.get(e, f1) == 2) + assert(evo.has(e, f2) and evo.get(e, f2) == 6) + end + + local es2, ec2 = evo.multi_clone(10, es[1], nil, function(c, b, e) + local f1s, f2s = c:components(f1, f2) + for p = b, e do + f1s[p] = f1s[p] + 10 + f2s[p] = f2s[p] + 20 + end + end) + + for i = 1, ec2 do + local e = es2[i] + assert(evo.has(e, f1) and evo.get(e, f1) == 12) + assert(evo.has(e, f2) and evo.get(e, f2) == 26) + end +end + +do + local f1, f2 = evo.id(2) + + evo.defer() + + local es, ec = evo.multi_spawn(10, { [f1] = 1, [f2] = 2 }, function(c, b, e) + local f1s, f2s = c:components(f1, f2) + for p = b, e do + f1s[p] = f1s[p] * 2 + f2s[p] = f2s[p] * 3 + end + end) + + for i = 1, ec do + local e = es[i] + 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 + + evo.commit() + + for i = 1, ec do + local e = es[i] + assert(evo.has(e, f1) and evo.get(e, f1) == 2) + assert(evo.has(e, f2) and evo.get(e, f2) == 6) + end + + evo.defer() + + local es2, ec2 = evo.multi_clone(10, es[1], nil, function(c, b, e) + local f1s, f2s = c:components(f1, f2) + for p = b, e do + f1s[p] = f1s[p] + 10 + f2s[p] = f2s[p] + 20 + end + end) + + for i = 1, ec2 do + local e = es2[i] + 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 + + evo.commit() + + for i = 1, ec2 do + local e = es2[i] + assert(evo.has(e, f1) and evo.get(e, f1) == 12) + assert(evo.has(e, f2) and evo.get(e, f2) == 26) + end +end + +do + local f1, f2 = evo.id(2) + + local e1 = evo.builder():set(f1, 1):set(f2, 2):build(nil, function(c, p) + local f1s, f2s = c:components(f1, f2) + f1s[p] = f1s[p] * 2 + f2s[p] = f2s[p] * 3 + end) + + assert(evo.has(e1, f1) and evo.get(e1, f1) == 2) + assert(evo.has(e1, f2) and evo.get(e1, f2) == 6) + + local e2 = evo.builder():build(e1, function(c, p) + local f1s, f2s = c:components(f1, f2) + f1s[p] = f1s[p] + 10 + f2s[p] = f2s[p] + 20 + end) + + assert(evo.has(e2, f1) and evo.get(e2, f1) == 12) + assert(evo.has(e2, f2) and evo.get(e2, f2) == 26) + + local e3 = evo.builder():set(f2, 3):build(e1, function(c, p) + local f1s, f2s = c:components(f1, f2) + f1s[p] = f1s[p] + 10 + f2s[p] = f2s[p] + 20 + end) + + assert(evo.has(e3, f1) and evo.get(e3, f1) == 12) + assert(evo.has(e3, f2) and evo.get(e3, f2) == 23) +end + +do + local f1, f2 = evo.id(2) + + local es, ec = evo.builder():set(f1, 1):set(f2, 2):multi_build(10, nil, function(c, b, e) + local f1s, f2s = c:components(f1, f2) + for p = b, e do + f1s[p] = f1s[p] * 2 + f2s[p] = f2s[p] * 3 + end + end) + + for i = 1, ec do + local e = es[i] + assert(evo.has(e, f1) and evo.get(e, f1) == 2) + assert(evo.has(e, f2) and evo.get(e, f2) == 6) + end + + local es2, ec2 = evo.builder():multi_build(10, es[1], function(c, b, e) + local f1s, f2s = c:components(f1, f2) + for p = b, e do + f1s[p] = f1s[p] + 10 + f2s[p] = f2s[p] + 20 + end + end) + + for i = 1, ec2 do + local e = es2[i] + assert(evo.has(e, f1) and evo.get(e, f1) == 12) + assert(evo.has(e, f2) and evo.get(e, f2) == 26) + end +end diff --git a/evolved.lua b/evolved.lua index a71f741..d69b4d2 100644 --- a/evolved.lua +++ b/evolved.lua @@ -37,6 +37,9 @@ local evolved = { ---@alias evolved.component any ---@alias evolved.storage evolved.component[] +---@alias evolved.component_table table +---@alias evolved.component_mapper fun(chunk: evolved.chunk, b_place: integer, e_place: integer) + ---@alias evolved.default evolved.component ---@alias evolved.duplicate fun(component: evolved.component): evolved.component @@ -198,7 +201,7 @@ __chunk_mt.__index = __chunk_mt ---@class evolved.builder ---@field package __chunk? evolved.chunk ----@field package __components table +---@field package __component_table evolved.component_table local __builder_mt = {} __builder_mt.__index = __builder_mt @@ -682,13 +685,11 @@ local __table_pool_tag = { system_list = 3, each_state = 4, execute_state = 5, - entity_set = 6, - entity_list = 7, - fragment_set = 8, - fragment_list = 9, - component_map = 10, - component_list = 11, - __count = 11, + entity_list = 6, + fragment_set = 7, + fragment_list = 8, + component_table = 9, + __count = 9, } ---@class (exact) evolved.table_pool @@ -1017,21 +1018,6 @@ local __safe_tbls = { __newindex = function() __error_fmt 'attempt to modify empty fragment set' end }) --[[@as table]], - __EMPTY_FRAGMENT_LIST = __lua_setmetatable({}, { - __tostring = function() return 'empty fragment list' end, - __newindex = function() __error_fmt 'attempt to modify empty fragment list' end - }) --[=[@as evolved.fragment[]]=], - - __EMPTY_COMPONENT_MAP = __lua_setmetatable({}, { - __tostring = function() return 'empty component map' end, - __newindex = function() __error_fmt 'attempt to modify empty component map' end - }) --[[@as table]], - - __EMPTY_COMPONENT_LIST = __lua_setmetatable({}, { - __tostring = function() return 'empty component list' end, - __newindex = function() __error_fmt 'attempt to modify empty component list' end - }) --[=[@as evolved.component[]]=], - __EMPTY_COMPONENT_STORAGE = __lua_setmetatable({}, { __tostring = function() return 'empty component storage' end, __newindex = function() __error_fmt 'attempt to modify empty component storage' end @@ -1906,7 +1892,7 @@ function __chunk_with_fragment(chunk, fragment) end ---@param chunk? evolved.chunk ----@param components table +---@param components evolved.component_table ---@return evolved.chunk? ---@nodiscard function __chunk_with_components(chunk, components) @@ -2063,7 +2049,7 @@ function __chunk_fragments(head_fragment, ...) return chunk end ----@param components table +---@param components evolved.component_table ---@return evolved.chunk? ---@nodiscard function __chunk_components(components) @@ -2313,14 +2299,15 @@ end ---@param chunk? evolved.chunk ---@param entity evolved.entity ----@param components table -function __spawn_entity(chunk, entity, components) +---@param component_table? evolved.component_table +---@param component_mapper? evolved.component_mapper +function __spawn_entity(chunk, entity, component_table, component_mapper) if __defer_depth <= 0 then __error_fmt('spawn entity operations should be deferred') end if not chunk or chunk.__unreachable_or_collected then - chunk = __chunk_components(components) + chunk = component_table and __chunk_components(component_table) end while chunk and chunk.__has_required_fragments do @@ -2369,7 +2356,7 @@ function __spawn_entity(chunk, entity, components) local component_fragment = chunk_component_fragments[component_index] local component_duplicate = chunk_component_duplicates[component_index] - local ini_component = components[component_fragment] + local ini_component = component_table and component_table[component_fragment] if ini_component == nil then ini_component = chunk_component_defaults[component_index] @@ -2392,6 +2379,10 @@ function __spawn_entity(chunk, entity, components) end end + if component_mapper then + component_mapper(chunk, place, place) + end + if chunk.__has_insert_hooks then local chunk_fragment_list = chunk.__fragment_list local chunk_fragment_count = chunk.__fragment_count @@ -2435,14 +2426,15 @@ end ---@param chunk? evolved.chunk ---@param entity_list evolved.entity[] ---@param entity_count integer ----@param components table -function __multi_spawn_entity(chunk, entity_list, entity_count, components) +---@param component_table? evolved.component_table +---@param component_mapper? evolved.component_mapper +function __multi_spawn_entity(chunk, entity_list, entity_count, component_table, component_mapper) if __defer_depth <= 0 then __error_fmt('spawn entity operations should be deferred') end if not chunk or chunk.__unreachable_or_collected then - chunk = __chunk_components(components) + chunk = component_table and __chunk_components(component_table) end while chunk and chunk.__has_required_fragments do @@ -2498,7 +2490,7 @@ function __multi_spawn_entity(chunk, entity_list, entity_count, components) local component_fragment = chunk_component_fragments[component_index] local component_duplicate = chunk_component_duplicates[component_index] - local ini_component = components[component_fragment] + local ini_component = component_table and component_table[component_fragment] if ini_component == nil then ini_component = chunk_component_defaults[component_index] @@ -2525,6 +2517,10 @@ function __multi_spawn_entity(chunk, entity_list, entity_count, components) end end + if component_mapper then + component_mapper(chunk, b_place, e_place) + end + if chunk.__has_insert_hooks then local chunk_fragment_list = chunk.__fragment_list local chunk_fragment_count = chunk.__fragment_count @@ -2575,8 +2571,9 @@ end ---@param prefab evolved.entity ---@param entity evolved.entity ----@param components table -function __clone_entity(prefab, entity, components) +---@param component_table? evolved.component_table +---@param component_mapper? evolved.component_mapper +function __clone_entity(prefab, entity, component_table, component_mapper) if __defer_depth <= 0 then __error_fmt('clone entity operations should be deferred') end @@ -2592,12 +2589,12 @@ function __clone_entity(prefab, entity, components) end if not prefab_chunk or not prefab_chunk.__without_unique_fragments then - return __spawn_entity(nil, entity, components) + return __spawn_entity(nil, entity, component_table, component_mapper) end - local chunk = __chunk_with_components( - prefab_chunk.__without_unique_fragments, - components) + local chunk = component_table + and __chunk_with_components(prefab_chunk.__without_unique_fragments, component_table) + or prefab_chunk.__without_unique_fragments while chunk and chunk.__has_required_fragments do local required_chunk = chunk.__with_required_fragments @@ -2648,7 +2645,7 @@ function __clone_entity(prefab, entity, components) local component_fragment = chunk_component_fragments[component_index] local component_duplicate = chunk_component_duplicates[component_index] - local ini_component = components[component_fragment] + local ini_component = component_table and component_table[component_fragment] if ini_component == nil then if chunk == prefab_chunk then @@ -2681,6 +2678,10 @@ function __clone_entity(prefab, entity, components) end end + if component_mapper then + component_mapper(chunk, place, place) + end + if chunk.__has_insert_hooks then local chunk_fragment_list = chunk.__fragment_list local chunk_fragment_count = chunk.__fragment_count @@ -2724,8 +2725,9 @@ end ---@param prefab evolved.entity ---@param entity_list evolved.entity[] ---@param entity_count integer ----@param components table -function __multi_clone_entity(prefab, entity_list, entity_count, components) +---@param component_table? evolved.component_table +---@param component_mapper? evolved.component_mapper +function __multi_clone_entity(prefab, entity_list, entity_count, component_table, component_mapper) if __defer_depth <= 0 then __error_fmt('clone entity operations should be deferred') end @@ -2741,12 +2743,12 @@ function __multi_clone_entity(prefab, entity_list, entity_count, components) end if not prefab_chunk or not prefab_chunk.__without_unique_fragments then - return __multi_spawn_entity(nil, entity_list, entity_count, components) + return __multi_spawn_entity(nil, entity_list, entity_count, component_table, component_mapper) end - local chunk = __chunk_with_components( - prefab_chunk.__without_unique_fragments, - components) + local chunk = component_table + and __chunk_with_components(prefab_chunk.__without_unique_fragments, component_table) + or prefab_chunk.__without_unique_fragments while chunk and chunk.__has_required_fragments do local required_chunk = chunk.__with_required_fragments @@ -2804,7 +2806,7 @@ function __multi_clone_entity(prefab, entity_list, entity_count, components) local component_fragment = chunk_component_fragments[component_index] local component_duplicate = chunk_component_duplicates[component_index] - local ini_component = components[component_fragment] + local ini_component = component_table and component_table[component_fragment] if ini_component == nil then if chunk == prefab_chunk then @@ -2841,6 +2843,10 @@ function __multi_clone_entity(prefab, entity_list, entity_count, components) end end + if component_mapper then + component_mapper(chunk, b_place, e_place) + end + if chunk.__has_insert_hooks then local chunk_fragment_list = chunk.__fragment_list local chunk_fragment_count = chunk.__fragment_count @@ -3995,13 +4001,18 @@ end ---@param chunk? evolved.chunk ---@param entity evolved.entity ----@param component_map table -function __defer_spawn_entity(chunk, entity, component_map) - ---@type table - local component_map_dup = __acquire_table(__table_pool_tag.component_map) +---@param component_table? evolved.component_table +---@param component_mapper? evolved.component_mapper +function __defer_spawn_entity(chunk, entity, component_table, component_mapper) + ---@type evolved.component_table? + local component_table2 - for fragment, component in __lua_next, component_map do - component_map_dup[fragment] = component + if component_table then + component_table2 = __acquire_table(__table_pool_tag.component_table) + + for fragment, component in __lua_next, component_table do + component_table2[fragment] = component + end end local length = __defer_length @@ -4010,43 +4021,53 @@ function __defer_spawn_entity(chunk, entity, component_map) bytecode[length + 1] = __defer_op.spawn_entity bytecode[length + 2] = chunk bytecode[length + 3] = entity - bytecode[length + 4] = component_map_dup + bytecode[length + 4] = component_table2 + bytecode[length + 5] = component_mapper - __defer_length = length + 4 + __defer_length = length + 5 end __defer_ops[__defer_op.spawn_entity] = function(bytes, index) local chunk = bytes[index + 0] local entity = bytes[index + 1] - local component_map_dup = bytes[index + 2] + local component_table2 = bytes[index + 2] + local component_mapper = bytes[index + 3] __evolved_defer() do - __spawn_entity(chunk, entity, component_map_dup) - __release_table(__table_pool_tag.component_map, component_map_dup) + __spawn_entity(chunk, entity, component_table2, component_mapper) + + if component_table2 then + __release_table(__table_pool_tag.component_table, component_table2) + end end __evolved_commit() - return 3 + return 4 end ---@param chunk? evolved.chunk ---@param entity_list evolved.entity[] ---@param entity_count integer ----@param component_map table -function __defer_multi_spawn_entity(chunk, entity_list, entity_count, component_map) +---@param component_table? evolved.component_table +---@param component_mapper? evolved.component_mapper +function __defer_multi_spawn_entity(chunk, entity_list, entity_count, component_table, component_mapper) ---@type evolved.entity[] - local entity_list_dup = __acquire_table(__table_pool_tag.entity_list) + local entity_list2 = __acquire_table(__table_pool_tag.entity_list) __lua_table_move( entity_list, 1, entity_count, - 1, entity_list_dup) + 1, entity_list2) - ---@type table - local component_map_dup = __acquire_table(__table_pool_tag.component_map) + ---@type evolved.component_table? + local component_table2 - for fragment, component in __lua_next, component_map do - component_map_dup[fragment] = component + if component_table then + component_table2 = __acquire_table(__table_pool_tag.component_table) + + for fragment, component in __lua_next, component_table do + component_table2[fragment] = component + end end local length = __defer_length @@ -4055,38 +4076,51 @@ function __defer_multi_spawn_entity(chunk, entity_list, entity_count, component_ bytecode[length + 1] = __defer_op.multi_spawn_entity bytecode[length + 2] = chunk bytecode[length + 3] = entity_count - bytecode[length + 4] = entity_list_dup - bytecode[length + 5] = component_map_dup + bytecode[length + 4] = entity_list2 + bytecode[length + 5] = component_table2 + bytecode[length + 6] = component_mapper - __defer_length = length + 5 + __defer_length = length + 6 end __defer_ops[__defer_op.multi_spawn_entity] = function(bytes, index) local chunk = bytes[index + 0] local entity_count = bytes[index + 1] - local entity_list_dup = bytes[index + 2] - local component_map_dup = bytes[index + 3] + local entity_list2 = bytes[index + 2] + local component_table2 = bytes[index + 3] + local component_mapper = bytes[index + 4] __evolved_defer() do - __multi_spawn_entity(chunk, entity_list_dup, entity_count, component_map_dup) - __release_table(__table_pool_tag.entity_list, entity_list_dup) - __release_table(__table_pool_tag.component_map, component_map_dup) + __multi_spawn_entity(chunk, entity_list2, entity_count, component_table2, component_mapper) + + if entity_list2 then + __release_table(__table_pool_tag.entity_list, entity_list2) + end + + if component_table2 then + __release_table(__table_pool_tag.component_table, component_table2) + end end __evolved_commit() - return 4 + return 5 end ---@param prefab evolved.entity ---@param entity evolved.entity ----@param component_map table -function __defer_clone_entity(prefab, entity, component_map) - ---@type table - local component_map_dup = __acquire_table(__table_pool_tag.component_map) +---@param component_table? evolved.component_table +---@param component_mapper? evolved.component_mapper +function __defer_clone_entity(prefab, entity, component_table, component_mapper) + ---@type evolved.component_table? + local component_table2 - for fragment, component in __lua_next, component_map do - component_map_dup[fragment] = component + if component_table then + component_table2 = __acquire_table(__table_pool_tag.component_table) + + for fragment, component in __lua_next, component_table do + component_table2[fragment] = component + end end local length = __defer_length @@ -4095,43 +4129,53 @@ function __defer_clone_entity(prefab, entity, component_map) bytecode[length + 1] = __defer_op.clone_entity bytecode[length + 2] = prefab bytecode[length + 3] = entity - bytecode[length + 4] = component_map_dup + bytecode[length + 4] = component_table2 + bytecode[length + 5] = component_mapper - __defer_length = length + 4 + __defer_length = length + 5 end __defer_ops[__defer_op.clone_entity] = function(bytes, index) local prefab = bytes[index + 0] local entity = bytes[index + 1] - local component_map_dup = bytes[index + 2] + local component_table2 = bytes[index + 2] + local component_mapper = bytes[index + 3] __evolved_defer() do - __clone_entity(prefab, entity, component_map_dup) - __release_table(__table_pool_tag.component_map, component_map_dup) + __clone_entity(prefab, entity, component_table2, component_mapper) + + if component_table2 then + __release_table(__table_pool_tag.component_table, component_table2) + end end __evolved_commit() - return 3 + return 4 end ---@param prefab evolved.entity ---@param entity_list evolved.entity[] ---@param entity_count integer ----@param component_map table -function __defer_multi_clone_entity(prefab, entity_list, entity_count, component_map) +---@param component_table? evolved.component_table +---@param component_mapper? evolved.component_mapper +function __defer_multi_clone_entity(prefab, entity_list, entity_count, component_table, component_mapper) ---@type evolved.entity[] - local entity_list_dup = __acquire_table(__table_pool_tag.entity_list) + local entity_list2 = __acquire_table(__table_pool_tag.entity_list) __lua_table_move( entity_list, 1, entity_count, - 1, entity_list_dup) + 1, entity_list2) - ---@type table - local component_map_dup = __acquire_table(__table_pool_tag.component_map) + ---@type evolved.component_table? + local component_table2 - for fragment, component in __lua_next, component_map do - component_map_dup[fragment] = component + if component_table then + component_table2 = __acquire_table(__table_pool_tag.component_table) + + for fragment, component in __lua_next, component_table do + component_table2[fragment] = component + end end local length = __defer_length @@ -4140,27 +4184,35 @@ function __defer_multi_clone_entity(prefab, entity_list, entity_count, component bytecode[length + 1] = __defer_op.multi_clone_entity bytecode[length + 2] = prefab bytecode[length + 3] = entity_count - bytecode[length + 4] = entity_list_dup - bytecode[length + 5] = component_map_dup + bytecode[length + 4] = entity_list2 + bytecode[length + 5] = component_table2 + bytecode[length + 6] = component_mapper - __defer_length = length + 5 + __defer_length = length + 6 end __defer_ops[__defer_op.multi_clone_entity] = function(bytes, index) local prefab = bytes[index + 0] local entity_count = bytes[index + 1] - local entity_list_dup = bytes[index + 2] - local component_map_dup = bytes[index + 3] + local entity_list2 = bytes[index + 2] + local component_table2 = bytes[index + 3] + local component_mapper = bytes[index + 4] __evolved_defer() do - __multi_clone_entity(prefab, entity_list_dup, entity_count, component_map_dup) - __release_table(__table_pool_tag.entity_list, entity_list_dup) - __release_table(__table_pool_tag.component_map, component_map_dup) + __multi_clone_entity(prefab, entity_list2, entity_count, component_table2, component_mapper) + + if entity_list2 then + __release_table(__table_pool_tag.entity_list, entity_list2) + end + + if component_table2 then + __release_table(__table_pool_tag.component_table, component_table2) + end end __evolved_commit() - return 4 + return 5 end --- @@ -4479,28 +4531,33 @@ function __evolved_cancel() return __evolved_commit() end ----@param components? table +---@param component_table? evolved.component_table +---@param component_mapper? evolved.component_mapper ---@return evolved.entity entity -function __evolved_spawn(components) - components = components or __safe_tbls.__EMPTY_COMPONENT_MAP - +function __evolved_spawn(component_table, component_mapper) if __debug_mode then - for fragment in __lua_next, components do - if not __evolved_alive(fragment) then - __error_fmt('the fragment (%s) is not alive and cannot be used', - __id_name(fragment)) + if component_table then + for fragment in __lua_next, component_table do + if not __evolved_alive(fragment) then + __error_fmt('the fragment (%s) is not alive and cannot be used', + __id_name(fragment)) + end end end end local entity = __acquire_id() + if not component_table or not __lua_next(component_table) then + return entity + end + if __defer_depth > 0 then - __defer_spawn_entity(nil, entity, components) + __defer_spawn_entity(nil, entity, component_table, component_mapper) else __evolved_defer() do - __spawn_entity(nil, entity, components) + __spawn_entity(nil, entity, component_table, component_mapper) end __evolved_commit() end @@ -4509,21 +4566,22 @@ function __evolved_spawn(components) end ---@param entity_count integer ----@param components? table +---@param component_table? evolved.component_table +---@param component_mapper? evolved.component_mapper ---@return evolved.entity[] entity_list ---@return integer entity_count -function __evolved_multi_spawn(entity_count, components) +function __evolved_multi_spawn(entity_count, component_table, component_mapper) if entity_count <= 0 then return {}, 0 end - components = components or __safe_tbls.__EMPTY_COMPONENT_MAP - if __debug_mode then - for fragment in __lua_next, components do - if not __evolved_alive(fragment) then - __error_fmt('the fragment (%s) is not alive and cannot be used', - __id_name(fragment)) + if component_table then + for fragment in __lua_next, component_table do + if not __evolved_alive(fragment) then + __error_fmt('the fragment (%s) is not alive and cannot be used', + __id_name(fragment)) + end end end end @@ -4534,12 +4592,16 @@ function __evolved_multi_spawn(entity_count, components) entity_list[entity_index] = __acquire_id() end + if not component_table or not __lua_next(component_table) then + return entity_list, entity_count + end + if __defer_depth > 0 then - __defer_multi_spawn_entity(nil, entity_list, entity_count, components) + __defer_multi_spawn_entity(nil, entity_list, entity_count, component_table, component_mapper) else __evolved_defer() do - __multi_spawn_entity(nil, entity_list, entity_count, components) + __multi_spawn_entity(nil, entity_list, entity_count, component_table, component_mapper) end __evolved_commit() end @@ -4548,21 +4610,22 @@ function __evolved_multi_spawn(entity_count, components) end ---@param prefab evolved.entity ----@param components? table +---@param component_table? evolved.component_table +---@param component_mapper? evolved.component_mapper ---@return evolved.entity entity -function __evolved_clone(prefab, components) - components = components or __safe_tbls.__EMPTY_COMPONENT_MAP - +function __evolved_clone(prefab, component_table, component_mapper) if __debug_mode then if not __evolved_alive(prefab) then __error_fmt('the prefab (%s) is not alive and cannot be used', __id_name(prefab)) end - for fragment in __lua_next, components do - if not __evolved_alive(fragment) then - __error_fmt('the fragment (%s) is not alive and cannot be used', - __id_name(fragment)) + if component_table then + for fragment in __lua_next, component_table do + if not __evolved_alive(fragment) then + __error_fmt('the fragment (%s) is not alive and cannot be used', + __id_name(fragment)) + end end end end @@ -4570,11 +4633,11 @@ function __evolved_clone(prefab, components) local entity = __acquire_id() if __defer_depth > 0 then - __defer_clone_entity(prefab, entity, components) + __defer_clone_entity(prefab, entity, component_table, component_mapper) else __evolved_defer() do - __clone_entity(prefab, entity, components) + __clone_entity(prefab, entity, component_table, component_mapper) end __evolved_commit() end @@ -4584,26 +4647,27 @@ end ---@param entity_count integer ---@param prefab evolved.entity ----@param components? table +---@param component_table? evolved.component_table +---@param component_mapper? evolved.component_mapper ---@return evolved.entity[] entity_list ---@return integer entity_count -function __evolved_multi_clone(entity_count, prefab, components) +function __evolved_multi_clone(entity_count, prefab, component_table, component_mapper) if entity_count <= 0 then return {}, 0 end - components = components or __safe_tbls.__EMPTY_COMPONENT_MAP - if __debug_mode then if not __evolved_alive(prefab) then __error_fmt('the prefab (%s) is not alive and cannot be used', __id_name(prefab)) end - for fragment in __lua_next, components do - if not __evolved_alive(fragment) then - __error_fmt('the fragment (%s) is not alive and cannot be used', - __id_name(fragment)) + if component_table then + for fragment in __lua_next, component_table do + if not __evolved_alive(fragment) then + __error_fmt('the fragment (%s) is not alive and cannot be used', + __id_name(fragment)) + end end end end @@ -4615,11 +4679,11 @@ function __evolved_multi_clone(entity_count, prefab, components) end if __defer_depth > 0 then - __defer_multi_clone_entity(prefab, entity_list, entity_count, components) + __defer_multi_clone_entity(prefab, entity_list, entity_count, component_table, component_mapper) else __evolved_defer() do - __multi_clone_entity(prefab, entity_list, entity_count, components) + __multi_clone_entity(prefab, entity_list, entity_count, component_table, component_mapper) end __evolved_commit() end @@ -5976,7 +6040,7 @@ end ---@nodiscard function __evolved_builder() return __lua_setmetatable({ - __components = {}, + __component_table = {}, }, __builder_mt) end @@ -5984,7 +6048,7 @@ function __builder_mt:__tostring() local fragment_list = {} ---@type evolved.fragment[] local fragment_count = 0 ---@type integer - for fragment in __lua_next, self.__components do + for fragment in __lua_next, self.__component_table do fragment_count = fragment_count + 1 fragment_list[fragment_count] = fragment end @@ -6001,49 +6065,58 @@ function __builder_mt:__tostring() end ---@param prefab? evolved.entity +---@param component_mapper? evolved.component_mapper ---@return evolved.entity entity -function __builder_mt:build(prefab) +function __builder_mt:build(prefab, component_mapper) if prefab then - return self:clone(prefab) + return self:clone(prefab, component_mapper) else - return self:spawn() + return self:spawn(component_mapper) end end ---@param entity_count integer ---@param prefab? evolved.entity +---@param component_mapper? evolved.component_mapper ---@return evolved.entity[] entity_list ---@return integer entity_count -function __builder_mt:multi_build(entity_count, prefab) +function __builder_mt:multi_build(entity_count, prefab, component_mapper) if prefab then - return self:multi_clone(entity_count, prefab) + return self:multi_clone(entity_count, prefab, component_mapper) else - return self:multi_spawn(entity_count) + return self:multi_spawn(entity_count, component_mapper) end end +---@param component_mapper? evolved.component_mapper ---@return evolved.entity entity -function __builder_mt:spawn() +function __builder_mt:spawn(component_mapper) local chunk = self.__chunk - local components = self.__components + local component_table = self.__component_table if __debug_mode then - for fragment in __lua_next, components do - if not __evolved_alive(fragment) then - __error_fmt('the fragment (%s) is not alive and cannot be used', - __id_name(fragment)) + if component_table then + for fragment in __lua_next, component_table do + if not __evolved_alive(fragment) then + __error_fmt('the fragment (%s) is not alive and cannot be used', + __id_name(fragment)) + end end end end local entity = __acquire_id() + if not component_table or not __lua_next(component_table) then + return entity + end + if __defer_depth > 0 then - __defer_spawn_entity(chunk, entity, components) + __defer_spawn_entity(chunk, entity, component_table, component_mapper) else __evolved_defer() do - __spawn_entity(chunk, entity, components) + __spawn_entity(chunk, entity, component_table, component_mapper) end __evolved_commit() end @@ -6052,21 +6125,24 @@ function __builder_mt:spawn() end ---@param entity_count integer +---@param component_mapper? evolved.component_mapper ---@return evolved.entity[] entity_list ---@return integer entity_count -function __builder_mt:multi_spawn(entity_count) +function __builder_mt:multi_spawn(entity_count, component_mapper) if entity_count <= 0 then return {}, 0 end local chunk = self.__chunk - local components = self.__components + local component_table = self.__component_table if __debug_mode then - for fragment in __lua_next, components do - if not __evolved_alive(fragment) then - __error_fmt('the fragment (%s) is not alive and cannot be used', - __id_name(fragment)) + if component_table then + for fragment in __lua_next, component_table do + if not __evolved_alive(fragment) then + __error_fmt('the fragment (%s) is not alive and cannot be used', + __id_name(fragment)) + end end end end @@ -6077,12 +6153,16 @@ function __builder_mt:multi_spawn(entity_count) entity_list[entity_index] = __acquire_id() end + if not component_table or not __lua_next(component_table) then + return entity_list, entity_count + end + if __defer_depth > 0 then - __defer_multi_spawn_entity(chunk, entity_list, entity_count, components) + __defer_multi_spawn_entity(chunk, entity_list, entity_count, component_table, component_mapper) else __evolved_defer() do - __multi_spawn_entity(chunk, entity_list, entity_count, components) + __multi_spawn_entity(chunk, entity_list, entity_count, component_table, component_mapper) end __evolved_commit() end @@ -6091,9 +6171,10 @@ function __builder_mt:multi_spawn(entity_count) end ---@param prefab evolved.entity +---@param component_mapper? evolved.component_mapper ---@return evolved.entity entity -function __builder_mt:clone(prefab) - local components = self.__components +function __builder_mt:clone(prefab, component_mapper) + local component_table = self.__component_table if __debug_mode then if not __evolved_alive(prefab) then @@ -6101,10 +6182,12 @@ function __builder_mt:clone(prefab) __id_name(prefab)) end - for fragment in __lua_next, components do - if not __evolved_alive(fragment) then - __error_fmt('the fragment (%s) is not alive and cannot be used', - __id_name(fragment)) + if component_table then + for fragment in __lua_next, component_table do + if not __evolved_alive(fragment) then + __error_fmt('the fragment (%s) is not alive and cannot be used', + __id_name(fragment)) + end end end end @@ -6112,11 +6195,11 @@ function __builder_mt:clone(prefab) local entity = __acquire_id() if __defer_depth > 0 then - __defer_clone_entity(prefab, entity, components) + __defer_clone_entity(prefab, entity, component_table, component_mapper) else __evolved_defer() do - __clone_entity(prefab, entity, components) + __clone_entity(prefab, entity, component_table, component_mapper) end __evolved_commit() end @@ -6126,14 +6209,15 @@ end ---@param entity_count integer ---@param prefab evolved.entity +---@param component_mapper? evolved.component_mapper ---@return evolved.entity[] entity_list ---@return integer entity_count -function __builder_mt:multi_clone(entity_count, prefab) +function __builder_mt:multi_clone(entity_count, prefab, component_mapper) if entity_count <= 0 then return {}, 0 end - local components = self.__components + local component_table = self.__component_table if __debug_mode then if not __evolved_alive(prefab) then @@ -6141,10 +6225,12 @@ function __builder_mt:multi_clone(entity_count, prefab) __id_name(prefab)) end - for fragment in __lua_next, components do - if not __evolved_alive(fragment) then - __error_fmt('the fragment (%s) is not alive and cannot be used', - __id_name(fragment)) + if component_table then + for fragment in __lua_next, component_table do + if not __evolved_alive(fragment) then + __error_fmt('the fragment (%s) is not alive and cannot be used', + __id_name(fragment)) + end end end end @@ -6156,11 +6242,11 @@ function __builder_mt:multi_clone(entity_count, prefab) end if __defer_depth > 0 then - __defer_multi_clone_entity(prefab, entity_list, entity_count, components) + __defer_multi_clone_entity(prefab, entity_list, entity_count, component_table, component_mapper) else __evolved_defer() do - __multi_clone_entity(prefab, entity_list, entity_count, components) + __multi_clone_entity(prefab, entity_list, entity_count, component_table, component_mapper) end __evolved_commit() end @@ -6217,7 +6303,7 @@ function __builder_mt:get(...) return end - local cs = self.__components + local cs = self.__component_table if fragment_count == 1 then local f1 = ... @@ -6260,7 +6346,7 @@ function __builder_mt:set(fragment, component) end local new_chunk = __chunk_with_fragment(self.__chunk, fragment) - local components = self.__components + local component_table = self.__component_table if new_chunk.__has_setup_hooks then ---@type evolved.default?, evolved.duplicate? @@ -6272,12 +6358,12 @@ function __builder_mt:set(fragment, 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 - components[fragment] = new_component + component_table[fragment] = new_component else local new_component = component if new_component == nil then new_component = true end - components[fragment] = new_component + component_table[fragment] = new_component end self.__chunk = new_chunk @@ -6294,12 +6380,12 @@ function __builder_mt:remove(...) end local new_chunk = self.__chunk - local components = self.__components + local component_table = self.__component_table for fragment_index = 1, fragment_count do ---@type evolved.fragment local fragment = __lua_select(fragment_index, ...) - new_chunk, components[fragment] = __chunk_without_fragment(new_chunk, fragment), nil + new_chunk, component_table[fragment] = __chunk_without_fragment(new_chunk, fragment), nil end self.__chunk = new_chunk @@ -6309,7 +6395,7 @@ end ---@return evolved.builder builder function __builder_mt:clear() self.__chunk = nil - __lua_table_clear(self.__components) + __lua_table_clear(self.__component_table) return self end diff --git a/example/main.lua b/example/main.lua index a7ac0c6..84abfec 100644 --- a/example/main.lua +++ b/example/main.lua @@ -52,25 +52,28 @@ evolved.builder() :name('SYSTEMS.STARTUP') :group(STAGES.ON_SETUP) :prologue(function() - local screen_width, screen_height = love.graphics.getDimensions() + evolved.multi_clone(500, PREFABS.CIRCLE, nil, function(chunk, b_place, e_place) + local screen_width, screen_height = love.graphics.getDimensions() - local circle_list, circle_count = evolved.multi_clone(100, PREFABS.CIRCLE) + ---@type number[], number[] + local position_xs, position_ys = chunk:components( + FRAGMENTS.POSITION_X, FRAGMENTS.POSITION_Y) - for i = 1, circle_count do - local circle = circle_list[i] + ---@type number[], number[] + local velocity_xs, velocity_ys = chunk:components( + FRAGMENTS.VELOCITY_X, FRAGMENTS.VELOCITY_Y) - local px = math.random() * screen_width - local py = math.random() * screen_height + for i = b_place, e_place do + local px = math.random() * screen_width + local py = math.random() * screen_height - local vx = math.random(-100, 100) - local vy = math.random(-100, 100) + local vx = math.random(-100, 100) + local vy = math.random(-100, 100) - evolved.set(circle, FRAGMENTS.POSITION_X, px) - evolved.set(circle, FRAGMENTS.POSITION_Y, py) - - evolved.set(circle, FRAGMENTS.VELOCITY_X, vx) - evolved.set(circle, FRAGMENTS.VELOCITY_Y, vy) - end + position_xs[i], position_ys[i] = px, py + velocity_xs[i], velocity_ys[i] = vx, vy + end + end) end):build() evolved.builder() @@ -124,7 +127,7 @@ evolved.builder() for i = 1, entity_count do local x, y = position_xs[i], position_ys[i] - love.graphics.circle('fill', x, y, 10) + love.graphics.circle('fill', x, y, 5) end end):build()