Merge branch 'feature/mappers' into dev

This commit is contained in:
BlackMATov
2026-01-18 19:30:08 +07:00
6 changed files with 601 additions and 253 deletions
+60 -45
View File
@@ -420,17 +420,19 @@ You should try to avoid structural changes, especially in performance-critical c
#### Spawning Entities #### Spawning Entities
```lua ```lua
---@param components? table<evolved.fragment, evolved.component> ---@param component_table? table<evolved.fragment, evolved.component>
---@param component_mapper? fun(chunk: evolved.chunk, place: integer)
---@return evolved.entity ---@return evolved.entity
function evolved.spawn(components) end function evolved.spawn(component_table, component_mapper) end
---@param prefab evolved.entity ---@param prefab evolved.entity
---@param components? table<evolved.fragment, evolved.component> ---@param component_table? table<evolved.fragment, evolved.component>
---@param component_mapper? fun(chunk: evolved.chunk, place: integer)
---@return evolved.entity ---@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. 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 evolved.builder()
local entity_list, entity_count = evolved.builder() :set(POSITION_X)
:set(POSITION_X) :set(POSITION_Y)
:set(POSITION_Y) :set(VELOCITY_X)
:set(VELOCITY_X) :set(VELOCITY_Y)
:set(VELOCITY_Y) :multi_spawn(10000, function(chunk, b_place, e_place)
:multi_build(10000) 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 for place = b_place, e_place do
local entity = entity_list[i] position_xs[place] = math.random(0, 640)
evolved.set(entity, POSITION_X, math.random(0, 640)) position_ys[place] = math.random(0, 480)
evolved.set(entity, POSITION_Y, math.random(0, 480)) velocity_xs[place] = math.random(-100, 100)
evolved.set(entity, VELOCITY_X, math.random(-100, 100)) velocity_ys[place] = math.random(-100, 100)
evolved.set(entity, VELOCITY_Y, math.random(-100, 100)) end
end end)
end
-- --
-- --
@@ -1309,6 +1311,9 @@ system :: id
component :: any component :: any
storage :: component[] storage :: component[]
component_table :: <fragment, component>
component_mapper :: {chunk, integer, integer}
default :: component default :: component
duplicate :: {component -> component} duplicate :: {component -> component}
@@ -1387,11 +1392,11 @@ depth :: integer
commit :: boolean commit :: boolean
cancel :: boolean cancel :: boolean
spawn :: <fragment, component>? -> entity spawn :: component_table?, component_mapper? -> entity
multi_spawn :: integer, <fragment, component>? -> entity[], integer multi_spawn :: integer, component_table?, component_mapper? -> entity[], integer
clone :: entity, <fragment, component>? -> entity clone :: entity, component_table?, component_mapper? -> entity
multi_clone :: integer, entity, <fragment, component>? -> entity[], integer multi_clone :: integer, entity, component_table?, component_mapper? -> entity[], integer
alive :: entity -> boolean alive :: entity -> boolean
alive_all :: entity... -> boolean alive_all :: entity... -> boolean
@@ -1405,7 +1410,7 @@ has :: entity, fragment -> boolean
has_all :: entity, fragment... -> boolean has_all :: entity, fragment... -> boolean
has_any :: entity, fragment... -> boolean has_any :: entity, fragment... -> boolean
get :: entity, fragment... -> component... get :: entity, fragment... -> component...
set :: entity, fragment, component -> () set :: entity, fragment, component -> ()
remove :: entity, fragment... -> () remove :: entity, fragment... -> ()
@@ -1453,14 +1458,14 @@ chunk_mt:components :: fragment... -> storage...
``` ```
builder :: builder builder :: builder
builder_mt:build :: entity? -> entity builder_mt:build :: entity?, component_mapper? -> entity
builder_mt:multi_build :: integer, entity? -> entity[], integer builder_mt:multi_build :: integer, entity?, component_mapper? -> entity[], integer
builder_mt:spawn :: entity builder_mt:spawn :: component_mapper? -> entity
builder_mt:multi_spawn :: integer -> entity[], integer builder_mt:multi_spawn :: integer, component_mapper? -> entity[], integer
builder_mt:clone :: entity -> entity builder_mt:clone :: entity, component_mapper? -> entity
builder_mt:multi_clone :: integer, entity -> entity[], integer builder_mt:multi_clone :: integer, entity, component_mapper? -> entity[], integer
builder_mt:has :: fragment -> boolean builder_mt:has :: fragment -> boolean
builder_mt:has_all :: fragment... -> boolean builder_mt:has_all :: fragment... -> boolean
@@ -1696,28 +1701,31 @@ function evolved.cancel() end
### `evolved.spawn` ### `evolved.spawn`
```lua ```lua
---@param components? table<evolved.fragment, evolved.component> ---@param component_table? evolved.component_table
---@param component_mapper? evolved.component_mapper
---@return evolved.entity entity ---@return evolved.entity entity
function evolved.spawn(components) end function evolved.spawn(component_table, component_mapper) end
``` ```
### `evolved.multi_spawn` ### `evolved.multi_spawn`
```lua ```lua
---@param entity_count integer ---@param entity_count integer
---@param components? table<evolved.fragment, evolved.component> ---@param component_table? evolved.component_table
---@param component_mapper? evolved.component_mapper
---@return evolved.entity[] entity_list ---@return evolved.entity[] entity_list
---@return integer entity_count ---@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` ### `evolved.clone`
```lua ```lua
---@param prefab evolved.entity ---@param prefab evolved.entity
---@param components? table<evolved.fragment, evolved.component> ---@param component_table? evolved.component_table
---@param component_mapper? evolved.component_mapper
---@return evolved.entity entity ---@return evolved.entity entity
function evolved.clone(prefab, components) end function evolved.clone(prefab, component_table, component_mapper) end
``` ```
### `evolved.multi_clone` ### `evolved.multi_clone`
@@ -1725,10 +1733,11 @@ function evolved.clone(prefab, components) end
```lua ```lua
---@param entity_count integer ---@param entity_count integer
---@param prefab evolved.entity ---@param prefab evolved.entity
---@param components? table<evolved.fragment, evolved.component> ---@param component_table? evolved.component_table
---@param component_mapper? evolved.component_mapper
---@return evolved.entity[] entity_list ---@return evolved.entity[] entity_list
---@return integer entity_count ---@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` ### `evolved.alive`
@@ -2045,8 +2054,9 @@ function evolved.builder() end
```lua ```lua
---@param prefab? evolved.entity ---@param prefab? evolved.entity
---@param component_mapper? evolved.component_mapper
---@return evolved.entity entity ---@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` ### `evolved.builder_mt:multi_build`
@@ -2054,33 +2064,37 @@ function evolved.builder_mt:build(prefab) end
```lua ```lua
---@param entity_count integer ---@param entity_count integer
---@param prefab? evolved.entity ---@param prefab? evolved.entity
---@param component_mapper? evolved.component_mapper
---@return evolved.entity[] entity_list ---@return evolved.entity[] entity_list
---@return integer entity_count ---@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` #### `evolved.builder_mt:spawn`
```lua ```lua
---@param component_mapper? evolved.component_mapper
---@return evolved.entity entity ---@return evolved.entity entity
function evolved.builder_mt:spawn() end function evolved.builder_mt:spawn(component_mapper) end
``` ```
#### `evolved.builder_mt:multi_spawn` #### `evolved.builder_mt:multi_spawn`
```lua ```lua
---@param entity_count integer ---@param entity_count integer
---@param component_mapper? evolved.component_mapper
---@return evolved.entity[] entity_list ---@return evolved.entity[] entity_list
---@return integer entity_count ---@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` #### `evolved.builder_mt:clone`
```lua ```lua
---@param prefab evolved.entity ---@param prefab evolved.entity
---@param component_mapper? evolved.component_mapper
---@return evolved.entity entity ---@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` #### `evolved.builder_mt:multi_clone`
@@ -2088,9 +2102,10 @@ function evolved.builder_mt:clone(prefab) end
```lua ```lua
---@param entity_count integer ---@param entity_count integer
---@param prefab evolved.entity ---@param prefab evolved.entity
---@param component_mapper? evolved.component_mapper
---@return evolved.entity[] entity_list ---@return evolved.entity[] entity_list
---@return integer entity_count ---@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` #### `evolved.builder_mt:has`
+2 -1
View File
@@ -15,7 +15,8 @@
- Having a light version of the gargabe collector can be useful for some use-cases - 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 - We can shrink the table pool tables on garbage collection if they are too large
- Should we sort chunk children by fragment id? - Should we sort chunk children by fragment id?
- Basic default component value as true looks awful, should we use something else?
## Known Issues ## 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
+1
View File
@@ -5,6 +5,7 @@ require 'develop.testing.depth_tests'
require 'develop.testing.destroy_tests' require 'develop.testing.destroy_tests'
require 'develop.testing.locate_tests' require 'develop.testing.locate_tests'
require 'develop.testing.main_tests' require 'develop.testing.main_tests'
require 'develop.testing.mappers_tests'
require 'develop.testing.multi_spawn_tests' require 'develop.testing.multi_spawn_tests'
require 'develop.testing.name_tests' require 'develop.testing.name_tests'
require 'develop.testing.process_with_tests' require 'develop.testing.process_with_tests'
+242
View File
@@ -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
+278 -192
View File
@@ -37,6 +37,9 @@ local evolved = {
---@alias evolved.component any ---@alias evolved.component any
---@alias evolved.storage evolved.component[] ---@alias evolved.storage evolved.component[]
---@alias evolved.component_table table<evolved.fragment, evolved.component>
---@alias evolved.component_mapper fun(chunk: evolved.chunk, b_place: integer, e_place: integer)
---@alias evolved.default evolved.component ---@alias evolved.default evolved.component
---@alias evolved.duplicate fun(component: evolved.component): evolved.component ---@alias evolved.duplicate fun(component: evolved.component): evolved.component
@@ -198,7 +201,7 @@ __chunk_mt.__index = __chunk_mt
---@class evolved.builder ---@class evolved.builder
---@field package __chunk? evolved.chunk ---@field package __chunk? evolved.chunk
---@field package __components table<evolved.fragment, evolved.component> ---@field package __component_table evolved.component_table
local __builder_mt = {} local __builder_mt = {}
__builder_mt.__index = __builder_mt __builder_mt.__index = __builder_mt
@@ -682,13 +685,11 @@ local __table_pool_tag = {
system_list = 3, system_list = 3,
each_state = 4, each_state = 4,
execute_state = 5, execute_state = 5,
entity_set = 6, entity_list = 6,
entity_list = 7, fragment_set = 7,
fragment_set = 8, fragment_list = 8,
fragment_list = 9, component_table = 9,
component_map = 10, __count = 9,
component_list = 11,
__count = 11,
} }
---@class (exact) evolved.table_pool ---@class (exact) evolved.table_pool
@@ -1017,21 +1018,6 @@ local __safe_tbls = {
__newindex = function() __error_fmt 'attempt to modify empty fragment set' end __newindex = function() __error_fmt 'attempt to modify empty fragment set' end
}) --[[@as table<evolved.fragment, integer>]], }) --[[@as table<evolved.fragment, integer>]],
__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<evolved.fragment, evolved.component>]],
__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({}, { __EMPTY_COMPONENT_STORAGE = __lua_setmetatable({}, {
__tostring = function() return 'empty component storage' end, __tostring = function() return 'empty component storage' end,
__newindex = function() __error_fmt 'attempt to modify 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 end
---@param chunk? evolved.chunk ---@param chunk? evolved.chunk
---@param components table<evolved.fragment, evolved.component> ---@param components evolved.component_table
---@return evolved.chunk? ---@return evolved.chunk?
---@nodiscard ---@nodiscard
function __chunk_with_components(chunk, components) function __chunk_with_components(chunk, components)
@@ -2063,7 +2049,7 @@ function __chunk_fragments(head_fragment, ...)
return chunk return chunk
end end
---@param components table<evolved.fragment, evolved.component> ---@param components evolved.component_table
---@return evolved.chunk? ---@return evolved.chunk?
---@nodiscard ---@nodiscard
function __chunk_components(components) function __chunk_components(components)
@@ -2313,14 +2299,15 @@ end
---@param chunk? evolved.chunk ---@param chunk? evolved.chunk
---@param entity evolved.entity ---@param entity evolved.entity
---@param components table<evolved.fragment, evolved.component> ---@param component_table? evolved.component_table
function __spawn_entity(chunk, entity, components) ---@param component_mapper? evolved.component_mapper
function __spawn_entity(chunk, entity, component_table, component_mapper)
if __defer_depth <= 0 then if __defer_depth <= 0 then
__error_fmt('spawn entity operations should be deferred') __error_fmt('spawn entity operations should be deferred')
end end
if not chunk or chunk.__unreachable_or_collected then if not chunk or chunk.__unreachable_or_collected then
chunk = __chunk_components(components) chunk = component_table and __chunk_components(component_table)
end end
while chunk and chunk.__has_required_fragments do 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_fragment = chunk_component_fragments[component_index]
local component_duplicate = chunk_component_duplicates[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 ini_component == nil then
ini_component = chunk_component_defaults[component_index] ini_component = chunk_component_defaults[component_index]
@@ -2392,6 +2379,10 @@ function __spawn_entity(chunk, entity, components)
end end
end end
if component_mapper then
component_mapper(chunk, place, place)
end
if chunk.__has_insert_hooks then if chunk.__has_insert_hooks then
local chunk_fragment_list = chunk.__fragment_list local chunk_fragment_list = chunk.__fragment_list
local chunk_fragment_count = chunk.__fragment_count local chunk_fragment_count = chunk.__fragment_count
@@ -2435,14 +2426,15 @@ end
---@param chunk? evolved.chunk ---@param chunk? evolved.chunk
---@param entity_list evolved.entity[] ---@param entity_list evolved.entity[]
---@param entity_count integer ---@param entity_count integer
---@param components table<evolved.fragment, evolved.component> ---@param component_table? evolved.component_table
function __multi_spawn_entity(chunk, entity_list, entity_count, components) ---@param component_mapper? evolved.component_mapper
function __multi_spawn_entity(chunk, entity_list, entity_count, component_table, component_mapper)
if __defer_depth <= 0 then if __defer_depth <= 0 then
__error_fmt('spawn entity operations should be deferred') __error_fmt('spawn entity operations should be deferred')
end end
if not chunk or chunk.__unreachable_or_collected then if not chunk or chunk.__unreachable_or_collected then
chunk = __chunk_components(components) chunk = component_table and __chunk_components(component_table)
end end
while chunk and chunk.__has_required_fragments do 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_fragment = chunk_component_fragments[component_index]
local component_duplicate = chunk_component_duplicates[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 ini_component == nil then
ini_component = chunk_component_defaults[component_index] ini_component = chunk_component_defaults[component_index]
@@ -2525,6 +2517,10 @@ function __multi_spawn_entity(chunk, entity_list, entity_count, components)
end end
end end
if component_mapper then
component_mapper(chunk, b_place, e_place)
end
if chunk.__has_insert_hooks then if chunk.__has_insert_hooks then
local chunk_fragment_list = chunk.__fragment_list local chunk_fragment_list = chunk.__fragment_list
local chunk_fragment_count = chunk.__fragment_count local chunk_fragment_count = chunk.__fragment_count
@@ -2575,8 +2571,9 @@ end
---@param prefab evolved.entity ---@param prefab evolved.entity
---@param entity evolved.entity ---@param entity evolved.entity
---@param components table<evolved.fragment, evolved.component> ---@param component_table? evolved.component_table
function __clone_entity(prefab, entity, components) ---@param component_mapper? evolved.component_mapper
function __clone_entity(prefab, entity, component_table, component_mapper)
if __defer_depth <= 0 then if __defer_depth <= 0 then
__error_fmt('clone entity operations should be deferred') __error_fmt('clone entity operations should be deferred')
end end
@@ -2592,12 +2589,12 @@ function __clone_entity(prefab, entity, components)
end end
if not prefab_chunk or not prefab_chunk.__without_unique_fragments then 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 end
local chunk = __chunk_with_components( local chunk = component_table
prefab_chunk.__without_unique_fragments, and __chunk_with_components(prefab_chunk.__without_unique_fragments, component_table)
components) or prefab_chunk.__without_unique_fragments
while chunk and chunk.__has_required_fragments do while chunk and chunk.__has_required_fragments do
local required_chunk = chunk.__with_required_fragments 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_fragment = chunk_component_fragments[component_index]
local component_duplicate = chunk_component_duplicates[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 ini_component == nil then
if chunk == prefab_chunk then if chunk == prefab_chunk then
@@ -2681,6 +2678,10 @@ function __clone_entity(prefab, entity, components)
end end
end end
if component_mapper then
component_mapper(chunk, place, place)
end
if chunk.__has_insert_hooks then if chunk.__has_insert_hooks then
local chunk_fragment_list = chunk.__fragment_list local chunk_fragment_list = chunk.__fragment_list
local chunk_fragment_count = chunk.__fragment_count local chunk_fragment_count = chunk.__fragment_count
@@ -2724,8 +2725,9 @@ end
---@param prefab evolved.entity ---@param prefab evolved.entity
---@param entity_list evolved.entity[] ---@param entity_list evolved.entity[]
---@param entity_count integer ---@param entity_count integer
---@param components table<evolved.fragment, evolved.component> ---@param component_table? evolved.component_table
function __multi_clone_entity(prefab, entity_list, entity_count, components) ---@param component_mapper? evolved.component_mapper
function __multi_clone_entity(prefab, entity_list, entity_count, component_table, component_mapper)
if __defer_depth <= 0 then if __defer_depth <= 0 then
__error_fmt('clone entity operations should be deferred') __error_fmt('clone entity operations should be deferred')
end end
@@ -2741,12 +2743,12 @@ function __multi_clone_entity(prefab, entity_list, entity_count, components)
end end
if not prefab_chunk or not prefab_chunk.__without_unique_fragments then 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 end
local chunk = __chunk_with_components( local chunk = component_table
prefab_chunk.__without_unique_fragments, and __chunk_with_components(prefab_chunk.__without_unique_fragments, component_table)
components) or prefab_chunk.__without_unique_fragments
while chunk and chunk.__has_required_fragments do while chunk and chunk.__has_required_fragments do
local required_chunk = chunk.__with_required_fragments 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_fragment = chunk_component_fragments[component_index]
local component_duplicate = chunk_component_duplicates[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 ini_component == nil then
if chunk == prefab_chunk then if chunk == prefab_chunk then
@@ -2841,6 +2843,10 @@ function __multi_clone_entity(prefab, entity_list, entity_count, components)
end end
end end
if component_mapper then
component_mapper(chunk, b_place, e_place)
end
if chunk.__has_insert_hooks then if chunk.__has_insert_hooks then
local chunk_fragment_list = chunk.__fragment_list local chunk_fragment_list = chunk.__fragment_list
local chunk_fragment_count = chunk.__fragment_count local chunk_fragment_count = chunk.__fragment_count
@@ -3995,13 +4001,18 @@ end
---@param chunk? evolved.chunk ---@param chunk? evolved.chunk
---@param entity evolved.entity ---@param entity evolved.entity
---@param component_map table<evolved.fragment, evolved.component> ---@param component_table? evolved.component_table
function __defer_spawn_entity(chunk, entity, component_map) ---@param component_mapper? evolved.component_mapper
---@type table<evolved.fragment, evolved.component> function __defer_spawn_entity(chunk, entity, component_table, component_mapper)
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 if component_table then
component_map_dup[fragment] = component component_table2 = __acquire_table(__table_pool_tag.component_table)
for fragment, component in __lua_next, component_table do
component_table2[fragment] = component
end
end end
local length = __defer_length 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 + 1] = __defer_op.spawn_entity
bytecode[length + 2] = chunk bytecode[length + 2] = chunk
bytecode[length + 3] = entity 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 end
__defer_ops[__defer_op.spawn_entity] = function(bytes, index) __defer_ops[__defer_op.spawn_entity] = function(bytes, index)
local chunk = bytes[index + 0] local chunk = bytes[index + 0]
local entity = bytes[index + 1] 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() __evolved_defer()
do do
__spawn_entity(chunk, entity, component_map_dup) __spawn_entity(chunk, entity, component_table2, component_mapper)
__release_table(__table_pool_tag.component_map, component_map_dup)
if component_table2 then
__release_table(__table_pool_tag.component_table, component_table2)
end
end end
__evolved_commit() __evolved_commit()
return 3 return 4
end end
---@param chunk? evolved.chunk ---@param chunk? evolved.chunk
---@param entity_list evolved.entity[] ---@param entity_list evolved.entity[]
---@param entity_count integer ---@param entity_count integer
---@param component_map table<evolved.fragment, evolved.component> ---@param component_table? evolved.component_table
function __defer_multi_spawn_entity(chunk, entity_list, entity_count, component_map) ---@param component_mapper? evolved.component_mapper
function __defer_multi_spawn_entity(chunk, entity_list, entity_count, component_table, component_mapper)
---@type evolved.entity[] ---@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( __lua_table_move(
entity_list, 1, entity_count, entity_list, 1, entity_count,
1, entity_list_dup) 1, entity_list2)
---@type table<evolved.fragment, evolved.component> ---@type evolved.component_table?
local component_map_dup = __acquire_table(__table_pool_tag.component_map) local component_table2
for fragment, component in __lua_next, component_map do if component_table then
component_map_dup[fragment] = component component_table2 = __acquire_table(__table_pool_tag.component_table)
for fragment, component in __lua_next, component_table do
component_table2[fragment] = component
end
end end
local length = __defer_length 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 + 1] = __defer_op.multi_spawn_entity
bytecode[length + 2] = chunk bytecode[length + 2] = chunk
bytecode[length + 3] = entity_count bytecode[length + 3] = entity_count
bytecode[length + 4] = entity_list_dup bytecode[length + 4] = entity_list2
bytecode[length + 5] = component_map_dup bytecode[length + 5] = component_table2
bytecode[length + 6] = component_mapper
__defer_length = length + 5 __defer_length = length + 6
end end
__defer_ops[__defer_op.multi_spawn_entity] = function(bytes, index) __defer_ops[__defer_op.multi_spawn_entity] = function(bytes, index)
local chunk = bytes[index + 0] local chunk = bytes[index + 0]
local entity_count = bytes[index + 1] local entity_count = bytes[index + 1]
local entity_list_dup = bytes[index + 2] local entity_list2 = bytes[index + 2]
local component_map_dup = bytes[index + 3] local component_table2 = bytes[index + 3]
local component_mapper = bytes[index + 4]
__evolved_defer() __evolved_defer()
do do
__multi_spawn_entity(chunk, entity_list_dup, entity_count, component_map_dup) __multi_spawn_entity(chunk, entity_list2, entity_count, component_table2, component_mapper)
__release_table(__table_pool_tag.entity_list, entity_list_dup)
__release_table(__table_pool_tag.component_map, component_map_dup) 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 end
__evolved_commit() __evolved_commit()
return 4 return 5
end end
---@param prefab evolved.entity ---@param prefab evolved.entity
---@param entity evolved.entity ---@param entity evolved.entity
---@param component_map table<evolved.fragment, evolved.component> ---@param component_table? evolved.component_table
function __defer_clone_entity(prefab, entity, component_map) ---@param component_mapper? evolved.component_mapper
---@type table<evolved.fragment, evolved.component> function __defer_clone_entity(prefab, entity, component_table, component_mapper)
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 if component_table then
component_map_dup[fragment] = component component_table2 = __acquire_table(__table_pool_tag.component_table)
for fragment, component in __lua_next, component_table do
component_table2[fragment] = component
end
end end
local length = __defer_length 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 + 1] = __defer_op.clone_entity
bytecode[length + 2] = prefab bytecode[length + 2] = prefab
bytecode[length + 3] = entity 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 end
__defer_ops[__defer_op.clone_entity] = function(bytes, index) __defer_ops[__defer_op.clone_entity] = function(bytes, index)
local prefab = bytes[index + 0] local prefab = bytes[index + 0]
local entity = bytes[index + 1] 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() __evolved_defer()
do do
__clone_entity(prefab, entity, component_map_dup) __clone_entity(prefab, entity, component_table2, component_mapper)
__release_table(__table_pool_tag.component_map, component_map_dup)
if component_table2 then
__release_table(__table_pool_tag.component_table, component_table2)
end
end end
__evolved_commit() __evolved_commit()
return 3 return 4
end end
---@param prefab evolved.entity ---@param prefab evolved.entity
---@param entity_list evolved.entity[] ---@param entity_list evolved.entity[]
---@param entity_count integer ---@param entity_count integer
---@param component_map table<evolved.fragment, evolved.component> ---@param component_table? evolved.component_table
function __defer_multi_clone_entity(prefab, entity_list, entity_count, component_map) ---@param component_mapper? evolved.component_mapper
function __defer_multi_clone_entity(prefab, entity_list, entity_count, component_table, component_mapper)
---@type evolved.entity[] ---@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( __lua_table_move(
entity_list, 1, entity_count, entity_list, 1, entity_count,
1, entity_list_dup) 1, entity_list2)
---@type table<evolved.fragment, evolved.component> ---@type evolved.component_table?
local component_map_dup = __acquire_table(__table_pool_tag.component_map) local component_table2
for fragment, component in __lua_next, component_map do if component_table then
component_map_dup[fragment] = component component_table2 = __acquire_table(__table_pool_tag.component_table)
for fragment, component in __lua_next, component_table do
component_table2[fragment] = component
end
end end
local length = __defer_length 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 + 1] = __defer_op.multi_clone_entity
bytecode[length + 2] = prefab bytecode[length + 2] = prefab
bytecode[length + 3] = entity_count bytecode[length + 3] = entity_count
bytecode[length + 4] = entity_list_dup bytecode[length + 4] = entity_list2
bytecode[length + 5] = component_map_dup bytecode[length + 5] = component_table2
bytecode[length + 6] = component_mapper
__defer_length = length + 5 __defer_length = length + 6
end end
__defer_ops[__defer_op.multi_clone_entity] = function(bytes, index) __defer_ops[__defer_op.multi_clone_entity] = function(bytes, index)
local prefab = bytes[index + 0] local prefab = bytes[index + 0]
local entity_count = bytes[index + 1] local entity_count = bytes[index + 1]
local entity_list_dup = bytes[index + 2] local entity_list2 = bytes[index + 2]
local component_map_dup = bytes[index + 3] local component_table2 = bytes[index + 3]
local component_mapper = bytes[index + 4]
__evolved_defer() __evolved_defer()
do do
__multi_clone_entity(prefab, entity_list_dup, entity_count, component_map_dup) __multi_clone_entity(prefab, entity_list2, entity_count, component_table2, component_mapper)
__release_table(__table_pool_tag.entity_list, entity_list_dup)
__release_table(__table_pool_tag.component_map, component_map_dup) 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 end
__evolved_commit() __evolved_commit()
return 4 return 5
end end
--- ---
@@ -4479,28 +4531,33 @@ function __evolved_cancel()
return __evolved_commit() return __evolved_commit()
end end
---@param components? table<evolved.fragment, evolved.component> ---@param component_table? evolved.component_table
---@param component_mapper? evolved.component_mapper
---@return evolved.entity entity ---@return evolved.entity entity
function __evolved_spawn(components) function __evolved_spawn(component_table, component_mapper)
components = components or __safe_tbls.__EMPTY_COMPONENT_MAP
if __debug_mode then if __debug_mode then
for fragment in __lua_next, components do if component_table then
if not __evolved_alive(fragment) then for fragment in __lua_next, component_table do
__error_fmt('the fragment (%s) is not alive and cannot be used', if not __evolved_alive(fragment) then
__id_name(fragment)) __error_fmt('the fragment (%s) is not alive and cannot be used',
__id_name(fragment))
end
end end
end end
end end
local entity = __acquire_id() local entity = __acquire_id()
if not component_table or not __lua_next(component_table) then
return entity
end
if __defer_depth > 0 then if __defer_depth > 0 then
__defer_spawn_entity(nil, entity, components) __defer_spawn_entity(nil, entity, component_table, component_mapper)
else else
__evolved_defer() __evolved_defer()
do do
__spawn_entity(nil, entity, components) __spawn_entity(nil, entity, component_table, component_mapper)
end end
__evolved_commit() __evolved_commit()
end end
@@ -4509,21 +4566,22 @@ function __evolved_spawn(components)
end end
---@param entity_count integer ---@param entity_count integer
---@param components? table<evolved.fragment, evolved.component> ---@param component_table? evolved.component_table
---@param component_mapper? evolved.component_mapper
---@return evolved.entity[] entity_list ---@return evolved.entity[] entity_list
---@return integer entity_count ---@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 if entity_count <= 0 then
return {}, 0 return {}, 0
end end
components = components or __safe_tbls.__EMPTY_COMPONENT_MAP
if __debug_mode then if __debug_mode then
for fragment in __lua_next, components do if component_table then
if not __evolved_alive(fragment) then for fragment in __lua_next, component_table do
__error_fmt('the fragment (%s) is not alive and cannot be used', if not __evolved_alive(fragment) then
__id_name(fragment)) __error_fmt('the fragment (%s) is not alive and cannot be used',
__id_name(fragment))
end
end end
end end
end end
@@ -4534,12 +4592,16 @@ function __evolved_multi_spawn(entity_count, components)
entity_list[entity_index] = __acquire_id() entity_list[entity_index] = __acquire_id()
end end
if not component_table or not __lua_next(component_table) then
return entity_list, entity_count
end
if __defer_depth > 0 then 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 else
__evolved_defer() __evolved_defer()
do do
__multi_spawn_entity(nil, entity_list, entity_count, components) __multi_spawn_entity(nil, entity_list, entity_count, component_table, component_mapper)
end end
__evolved_commit() __evolved_commit()
end end
@@ -4548,21 +4610,22 @@ function __evolved_multi_spawn(entity_count, components)
end end
---@param prefab evolved.entity ---@param prefab evolved.entity
---@param components? table<evolved.fragment, evolved.component> ---@param component_table? evolved.component_table
---@param component_mapper? evolved.component_mapper
---@return evolved.entity entity ---@return evolved.entity entity
function __evolved_clone(prefab, components) function __evolved_clone(prefab, component_table, component_mapper)
components = components or __safe_tbls.__EMPTY_COMPONENT_MAP
if __debug_mode then if __debug_mode then
if not __evolved_alive(prefab) then if not __evolved_alive(prefab) then
__error_fmt('the prefab (%s) is not alive and cannot be used', __error_fmt('the prefab (%s) is not alive and cannot be used',
__id_name(prefab)) __id_name(prefab))
end end
for fragment in __lua_next, components do if component_table then
if not __evolved_alive(fragment) then for fragment in __lua_next, component_table do
__error_fmt('the fragment (%s) is not alive and cannot be used', if not __evolved_alive(fragment) then
__id_name(fragment)) __error_fmt('the fragment (%s) is not alive and cannot be used',
__id_name(fragment))
end
end end
end end
end end
@@ -4570,11 +4633,11 @@ function __evolved_clone(prefab, components)
local entity = __acquire_id() local entity = __acquire_id()
if __defer_depth > 0 then if __defer_depth > 0 then
__defer_clone_entity(prefab, entity, components) __defer_clone_entity(prefab, entity, component_table, component_mapper)
else else
__evolved_defer() __evolved_defer()
do do
__clone_entity(prefab, entity, components) __clone_entity(prefab, entity, component_table, component_mapper)
end end
__evolved_commit() __evolved_commit()
end end
@@ -4584,26 +4647,27 @@ end
---@param entity_count integer ---@param entity_count integer
---@param prefab evolved.entity ---@param prefab evolved.entity
---@param components? table<evolved.fragment, evolved.component> ---@param component_table? evolved.component_table
---@param component_mapper? evolved.component_mapper
---@return evolved.entity[] entity_list ---@return evolved.entity[] entity_list
---@return integer entity_count ---@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 if entity_count <= 0 then
return {}, 0 return {}, 0
end end
components = components or __safe_tbls.__EMPTY_COMPONENT_MAP
if __debug_mode then if __debug_mode then
if not __evolved_alive(prefab) then if not __evolved_alive(prefab) then
__error_fmt('the prefab (%s) is not alive and cannot be used', __error_fmt('the prefab (%s) is not alive and cannot be used',
__id_name(prefab)) __id_name(prefab))
end end
for fragment in __lua_next, components do if component_table then
if not __evolved_alive(fragment) then for fragment in __lua_next, component_table do
__error_fmt('the fragment (%s) is not alive and cannot be used', if not __evolved_alive(fragment) then
__id_name(fragment)) __error_fmt('the fragment (%s) is not alive and cannot be used',
__id_name(fragment))
end
end end
end end
end end
@@ -4615,11 +4679,11 @@ function __evolved_multi_clone(entity_count, prefab, components)
end end
if __defer_depth > 0 then 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 else
__evolved_defer() __evolved_defer()
do do
__multi_clone_entity(prefab, entity_list, entity_count, components) __multi_clone_entity(prefab, entity_list, entity_count, component_table, component_mapper)
end end
__evolved_commit() __evolved_commit()
end end
@@ -5976,7 +6040,7 @@ end
---@nodiscard ---@nodiscard
function __evolved_builder() function __evolved_builder()
return __lua_setmetatable({ return __lua_setmetatable({
__components = {}, __component_table = {},
}, __builder_mt) }, __builder_mt)
end end
@@ -5984,7 +6048,7 @@ function __builder_mt:__tostring()
local fragment_list = {} ---@type evolved.fragment[] local fragment_list = {} ---@type evolved.fragment[]
local fragment_count = 0 ---@type integer 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_count = fragment_count + 1
fragment_list[fragment_count] = fragment fragment_list[fragment_count] = fragment
end end
@@ -6001,49 +6065,58 @@ function __builder_mt:__tostring()
end end
---@param prefab? evolved.entity ---@param prefab? evolved.entity
---@param component_mapper? evolved.component_mapper
---@return evolved.entity entity ---@return evolved.entity entity
function __builder_mt:build(prefab) function __builder_mt:build(prefab, component_mapper)
if prefab then if prefab then
return self:clone(prefab) return self:clone(prefab, component_mapper)
else else
return self:spawn() return self:spawn(component_mapper)
end end
end end
---@param entity_count integer ---@param entity_count integer
---@param prefab? evolved.entity ---@param prefab? evolved.entity
---@param component_mapper? evolved.component_mapper
---@return evolved.entity[] entity_list ---@return evolved.entity[] entity_list
---@return integer entity_count ---@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 if prefab then
return self:multi_clone(entity_count, prefab) return self:multi_clone(entity_count, prefab, component_mapper)
else else
return self:multi_spawn(entity_count) return self:multi_spawn(entity_count, component_mapper)
end end
end end
---@param component_mapper? evolved.component_mapper
---@return evolved.entity entity ---@return evolved.entity entity
function __builder_mt:spawn() function __builder_mt:spawn(component_mapper)
local chunk = self.__chunk local chunk = self.__chunk
local components = self.__components local component_table = self.__component_table
if __debug_mode then if __debug_mode then
for fragment in __lua_next, components do if component_table then
if not __evolved_alive(fragment) then for fragment in __lua_next, component_table do
__error_fmt('the fragment (%s) is not alive and cannot be used', if not __evolved_alive(fragment) then
__id_name(fragment)) __error_fmt('the fragment (%s) is not alive and cannot be used',
__id_name(fragment))
end
end end
end end
end end
local entity = __acquire_id() local entity = __acquire_id()
if not component_table or not __lua_next(component_table) then
return entity
end
if __defer_depth > 0 then if __defer_depth > 0 then
__defer_spawn_entity(chunk, entity, components) __defer_spawn_entity(chunk, entity, component_table, component_mapper)
else else
__evolved_defer() __evolved_defer()
do do
__spawn_entity(chunk, entity, components) __spawn_entity(chunk, entity, component_table, component_mapper)
end end
__evolved_commit() __evolved_commit()
end end
@@ -6052,21 +6125,24 @@ function __builder_mt:spawn()
end end
---@param entity_count integer ---@param entity_count integer
---@param component_mapper? evolved.component_mapper
---@return evolved.entity[] entity_list ---@return evolved.entity[] entity_list
---@return integer entity_count ---@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 if entity_count <= 0 then
return {}, 0 return {}, 0
end end
local chunk = self.__chunk local chunk = self.__chunk
local components = self.__components local component_table = self.__component_table
if __debug_mode then if __debug_mode then
for fragment in __lua_next, components do if component_table then
if not __evolved_alive(fragment) then for fragment in __lua_next, component_table do
__error_fmt('the fragment (%s) is not alive and cannot be used', if not __evolved_alive(fragment) then
__id_name(fragment)) __error_fmt('the fragment (%s) is not alive and cannot be used',
__id_name(fragment))
end
end end
end end
end end
@@ -6077,12 +6153,16 @@ function __builder_mt:multi_spawn(entity_count)
entity_list[entity_index] = __acquire_id() entity_list[entity_index] = __acquire_id()
end end
if not component_table or not __lua_next(component_table) then
return entity_list, entity_count
end
if __defer_depth > 0 then 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 else
__evolved_defer() __evolved_defer()
do do
__multi_spawn_entity(chunk, entity_list, entity_count, components) __multi_spawn_entity(chunk, entity_list, entity_count, component_table, component_mapper)
end end
__evolved_commit() __evolved_commit()
end end
@@ -6091,9 +6171,10 @@ function __builder_mt:multi_spawn(entity_count)
end end
---@param prefab evolved.entity ---@param prefab evolved.entity
---@param component_mapper? evolved.component_mapper
---@return evolved.entity entity ---@return evolved.entity entity
function __builder_mt:clone(prefab) function __builder_mt:clone(prefab, component_mapper)
local components = self.__components local component_table = self.__component_table
if __debug_mode then if __debug_mode then
if not __evolved_alive(prefab) then if not __evolved_alive(prefab) then
@@ -6101,10 +6182,12 @@ function __builder_mt:clone(prefab)
__id_name(prefab)) __id_name(prefab))
end end
for fragment in __lua_next, components do if component_table then
if not __evolved_alive(fragment) then for fragment in __lua_next, component_table do
__error_fmt('the fragment (%s) is not alive and cannot be used', if not __evolved_alive(fragment) then
__id_name(fragment)) __error_fmt('the fragment (%s) is not alive and cannot be used',
__id_name(fragment))
end
end end
end end
end end
@@ -6112,11 +6195,11 @@ function __builder_mt:clone(prefab)
local entity = __acquire_id() local entity = __acquire_id()
if __defer_depth > 0 then if __defer_depth > 0 then
__defer_clone_entity(prefab, entity, components) __defer_clone_entity(prefab, entity, component_table, component_mapper)
else else
__evolved_defer() __evolved_defer()
do do
__clone_entity(prefab, entity, components) __clone_entity(prefab, entity, component_table, component_mapper)
end end
__evolved_commit() __evolved_commit()
end end
@@ -6126,14 +6209,15 @@ end
---@param entity_count integer ---@param entity_count integer
---@param prefab evolved.entity ---@param prefab evolved.entity
---@param component_mapper? evolved.component_mapper
---@return evolved.entity[] entity_list ---@return evolved.entity[] entity_list
---@return integer entity_count ---@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 if entity_count <= 0 then
return {}, 0 return {}, 0
end end
local components = self.__components local component_table = self.__component_table
if __debug_mode then if __debug_mode then
if not __evolved_alive(prefab) then if not __evolved_alive(prefab) then
@@ -6141,10 +6225,12 @@ function __builder_mt:multi_clone(entity_count, prefab)
__id_name(prefab)) __id_name(prefab))
end end
for fragment in __lua_next, components do if component_table then
if not __evolved_alive(fragment) then for fragment in __lua_next, component_table do
__error_fmt('the fragment (%s) is not alive and cannot be used', if not __evolved_alive(fragment) then
__id_name(fragment)) __error_fmt('the fragment (%s) is not alive and cannot be used',
__id_name(fragment))
end
end end
end end
end end
@@ -6156,11 +6242,11 @@ function __builder_mt:multi_clone(entity_count, prefab)
end end
if __defer_depth > 0 then 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 else
__evolved_defer() __evolved_defer()
do do
__multi_clone_entity(prefab, entity_list, entity_count, components) __multi_clone_entity(prefab, entity_list, entity_count, component_table, component_mapper)
end end
__evolved_commit() __evolved_commit()
end end
@@ -6217,7 +6303,7 @@ function __builder_mt:get(...)
return return
end end
local cs = self.__components local cs = self.__component_table
if fragment_count == 1 then if fragment_count == 1 then
local f1 = ... local f1 = ...
@@ -6260,7 +6346,7 @@ function __builder_mt:set(fragment, component)
end end
local new_chunk = __chunk_with_fragment(self.__chunk, fragment) 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 if new_chunk.__has_setup_hooks then
---@type evolved.default?, evolved.duplicate? ---@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 and fragment_duplicate then new_component = fragment_duplicate(new_component) end
if new_component == nil then new_component = true end if new_component == nil then new_component = true end
components[fragment] = new_component component_table[fragment] = new_component
else else
local new_component = component local new_component = component
if new_component == nil then new_component = true end if new_component == nil then new_component = true end
components[fragment] = new_component component_table[fragment] = new_component
end end
self.__chunk = new_chunk self.__chunk = new_chunk
@@ -6294,12 +6380,12 @@ function __builder_mt:remove(...)
end end
local new_chunk = self.__chunk local new_chunk = self.__chunk
local components = self.__components local component_table = self.__component_table
for fragment_index = 1, fragment_count do for fragment_index = 1, fragment_count do
---@type evolved.fragment ---@type evolved.fragment
local fragment = __lua_select(fragment_index, ...) 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 end
self.__chunk = new_chunk self.__chunk = new_chunk
@@ -6309,7 +6395,7 @@ end
---@return evolved.builder builder ---@return evolved.builder builder
function __builder_mt:clear() function __builder_mt:clear()
self.__chunk = nil self.__chunk = nil
__lua_table_clear(self.__components) __lua_table_clear(self.__component_table)
return self return self
end end
+18 -15
View File
@@ -52,25 +52,28 @@ evolved.builder()
:name('SYSTEMS.STARTUP') :name('SYSTEMS.STARTUP')
:group(STAGES.ON_SETUP) :group(STAGES.ON_SETUP)
:prologue(function() :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 ---@type number[], number[]
local circle = circle_list[i] local velocity_xs, velocity_ys = chunk:components(
FRAGMENTS.VELOCITY_X, FRAGMENTS.VELOCITY_Y)
local px = math.random() * screen_width for i = b_place, e_place do
local py = math.random() * screen_height local px = math.random() * screen_width
local py = math.random() * screen_height
local vx = math.random(-100, 100) local vx = math.random(-100, 100)
local vy = math.random(-100, 100) local vy = math.random(-100, 100)
evolved.set(circle, FRAGMENTS.POSITION_X, px) position_xs[i], position_ys[i] = px, py
evolved.set(circle, FRAGMENTS.POSITION_Y, py) velocity_xs[i], velocity_ys[i] = vx, vy
end
evolved.set(circle, FRAGMENTS.VELOCITY_X, vx) end)
evolved.set(circle, FRAGMENTS.VELOCITY_Y, vy)
end
end):build() end):build()
evolved.builder() evolved.builder()
@@ -124,7 +127,7 @@ evolved.builder()
for i = 1, entity_count do for i = 1, entity_count do
local x, y = position_xs[i], position_ys[i] 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
end):build() end):build()