mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-14 12:10:23 +07:00
primary/secondary pair iterators
This commit is contained in:
12
README.md
12
README.md
@@ -53,6 +53,7 @@
|
||||
- [Aliases](#aliases)
|
||||
- [Predefs](#predefs)
|
||||
- [Functions](#functions)
|
||||
- [Relations](#relations)
|
||||
- [Classes](#classes)
|
||||
- [Chunk](#chunk)
|
||||
- [Builder](#builder)
|
||||
@@ -1114,6 +1115,17 @@ debug_mode :: boolean -> ()
|
||||
collect_garbage :: ()
|
||||
```
|
||||
|
||||
### Relations
|
||||
|
||||
primary :: entity, fragment, integer? -> fragment?, component?
|
||||
secondary :: entity, fragment, integer? -> fragment?, component?
|
||||
|
||||
primaries :: entity, fragment -> {primaries_state? -> fragment?, component?}, primaries_state?
|
||||
secondaries :: entity, fragment -> {secondaries_state? -> fragment?, component?}, secondaries_state?
|
||||
|
||||
primary_count :: entity, fragment -> integer
|
||||
secondary_count :: entity, fragment -> integer
|
||||
|
||||
### Classes
|
||||
|
||||
#### Chunk
|
||||
|
||||
@@ -6,20 +6,20 @@ require 'develop.testing.pairs_tests'
|
||||
require 'develop.testing.requires_fragment_tests'
|
||||
require 'develop.testing.system_as_query_tests'
|
||||
|
||||
require 'develop.unbench'
|
||||
require 'develop.usbench'
|
||||
-- require 'develop.unbench'
|
||||
-- require 'develop.usbench'
|
||||
|
||||
local basics = require 'develop.basics'
|
||||
-- local basics = require 'develop.basics'
|
||||
|
||||
print '----------------------------------------'
|
||||
basics.describe_fuzz 'develop.fuzzing.destroy_fuzz'
|
||||
print '----------------------------------------'
|
||||
basics.describe_fuzz 'develop.fuzzing.batch_destroy_fuzz'
|
||||
print '----------------------------------------'
|
||||
basics.describe_fuzz 'develop.fuzzing.explicit_fuzz'
|
||||
print '----------------------------------------'
|
||||
basics.describe_fuzz 'develop.fuzzing.pack_unpack_fuzz'
|
||||
print '----------------------------------------'
|
||||
basics.describe_fuzz 'develop.fuzzing.requires_fuzz'
|
||||
print '----------------------------------------'
|
||||
basics.describe_fuzz 'develop.fuzzing.unique_fuzz'
|
||||
-- print '----------------------------------------'
|
||||
-- basics.describe_fuzz 'develop.fuzzing.destroy_fuzz'
|
||||
-- print '----------------------------------------'
|
||||
-- basics.describe_fuzz 'develop.fuzzing.batch_destroy_fuzz'
|
||||
-- print '----------------------------------------'
|
||||
-- basics.describe_fuzz 'develop.fuzzing.explicit_fuzz'
|
||||
-- print '----------------------------------------'
|
||||
-- basics.describe_fuzz 'develop.fuzzing.pack_unpack_fuzz'
|
||||
-- print '----------------------------------------'
|
||||
-- basics.describe_fuzz 'develop.fuzzing.requires_fuzz'
|
||||
-- print '----------------------------------------'
|
||||
-- basics.describe_fuzz 'develop.fuzzing.unique_fuzz'
|
||||
|
||||
@@ -635,6 +635,210 @@ do
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local p1, p2, s1, s2 = evo.id(4)
|
||||
|
||||
---@param o evolved.entity
|
||||
---@param s evolved.fragment
|
||||
---@return evolved.fragment[], evolved.component[], number
|
||||
local function collect_primaries(o, s)
|
||||
local fragments, components, count = {}, {}, 0
|
||||
|
||||
for f, c in evo.primaries(o, s) do
|
||||
count = count + 1
|
||||
|
||||
fragments[count] = f
|
||||
components[count] = c
|
||||
|
||||
do
|
||||
local ff, cc = evo.primary(o, s, count)
|
||||
assert(ff == f and cc == c)
|
||||
end
|
||||
end
|
||||
|
||||
assert(evo.primary_count(o, s) == count)
|
||||
return fragments, components, count
|
||||
end
|
||||
|
||||
---@param o evolved.entity
|
||||
---@param p evolved.fragment
|
||||
---@return evolved.fragment[], evolved.component[], number
|
||||
local function collect_secondaries(o, p)
|
||||
local fragments, components, count = {}, {}, 0
|
||||
|
||||
for f, c in evo.secondaries(o, p) do
|
||||
count = count + 1
|
||||
fragments[count] = f
|
||||
components[count] = c
|
||||
end
|
||||
|
||||
return fragments, components, count
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.builder()
|
||||
:set(evo.pair(p1, s1), 42)
|
||||
:spawn()
|
||||
|
||||
assert(evo.primary(e, s1) == p1)
|
||||
assert(evo.primary(e, s2) == nil)
|
||||
|
||||
assert(evo.secondary(e, p1) == s1)
|
||||
assert(evo.secondary(e, p2) == nil)
|
||||
|
||||
assert(evo.primary_count(e, s1) == 1)
|
||||
assert(evo.primary_count(e, s2) == 0)
|
||||
assert(evo.secondary_count(e, p1) == 1)
|
||||
assert(evo.secondary_count(e, p2) == 0)
|
||||
|
||||
do
|
||||
local p_list, c_list, count = collect_primaries(e, s1)
|
||||
assert(#p_list == 1 and #c_list == 1 and count == 1)
|
||||
assert(p_list[1] == p1 and c_list[1] == 42)
|
||||
end
|
||||
|
||||
do
|
||||
local p_list, c_list, count = collect_primaries(e, s2)
|
||||
assert(#p_list == 0 and #c_list == 0 and count == 0)
|
||||
end
|
||||
|
||||
do
|
||||
local s_list, c_list, count = collect_secondaries(e, p1)
|
||||
assert(#s_list == 1 and #c_list == 1 and count == 1)
|
||||
assert(s_list[1] == s1 and c_list[1] == 42)
|
||||
end
|
||||
|
||||
do
|
||||
local s_list, c_list, count = collect_secondaries(e, p2)
|
||||
assert(#s_list == 0 and #c_list == 0 and count == 0)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.builder()
|
||||
:set(evo.pair(p1, s1), 42)
|
||||
:set(evo.pair(p1, s2), 84)
|
||||
:set(evo.pair(p2, s1), 21)
|
||||
:set(evo.pair(p2, s2), 63)
|
||||
:spawn()
|
||||
|
||||
do
|
||||
assert(evo.primary_count(e, s1) == 2)
|
||||
assert(evo.primary_count(e, s2) == 2)
|
||||
assert(evo.secondary_count(e, p1) == 2)
|
||||
assert(evo.secondary_count(e, p2) == 2)
|
||||
end
|
||||
|
||||
do
|
||||
local pp, cc = evo.primary(e, s1)
|
||||
assert(pp == p1 and cc == 42)
|
||||
|
||||
pp, cc = evo.primary(e, s1, 1)
|
||||
assert(pp == p1 and cc == 42)
|
||||
|
||||
pp, cc = evo.primary(e, s1, 2)
|
||||
assert(pp == p2 and cc == 21)
|
||||
|
||||
pp, cc = evo.primary(e, s1, 3)
|
||||
assert(pp == nil and cc == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local pp, cc = evo.primary(e, s2)
|
||||
assert(pp == p1 and cc == 84)
|
||||
|
||||
pp, cc = evo.primary(e, s2, 1)
|
||||
assert(pp == p1 and cc == 84)
|
||||
|
||||
pp, cc = evo.primary(e, s2, 2)
|
||||
assert(pp == p2 and cc == 63)
|
||||
|
||||
pp, cc = evo.primary(e, s2, 3)
|
||||
assert(pp == nil and cc == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local pp, cc = evo.secondary(e, p1)
|
||||
assert(pp == s1 and cc == 42)
|
||||
|
||||
pp, cc = evo.secondary(e, p1, 1)
|
||||
assert(pp == s1 and cc == 42)
|
||||
|
||||
pp, cc = evo.secondary(e, p1, 2)
|
||||
assert(pp == s2 and cc == 84)
|
||||
|
||||
pp, cc = evo.secondary(e, p1, 3)
|
||||
assert(pp == nil and cc == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local pp, cc = evo.secondary(e, p2)
|
||||
assert(pp == s1 and cc == 21)
|
||||
|
||||
pp, cc = evo.secondary(e, p2, 1)
|
||||
assert(pp == s1 and cc == 21)
|
||||
|
||||
pp, cc = evo.secondary(e, p2, 2)
|
||||
assert(pp == s2 and cc == 63)
|
||||
|
||||
pp, cc = evo.secondary(e, p2, 3)
|
||||
assert(pp == nil and cc == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local p_list, c_list, count = collect_primaries(e, s1)
|
||||
assert(#p_list == 2 and #c_list == 2 and count == 2)
|
||||
assert(p_list[1] == p1 and c_list[1] == 42)
|
||||
assert(p_list[2] == p2 and c_list[2] == 21)
|
||||
end
|
||||
|
||||
do
|
||||
local p_list, c_list, count = collect_primaries(e, s2)
|
||||
assert(#p_list == 2 and #c_list == 2 and count == 2)
|
||||
assert(p_list[1] == p1 and c_list[1] == 84)
|
||||
assert(p_list[2] == p2 and c_list[2] == 63)
|
||||
end
|
||||
|
||||
do
|
||||
local s_list, c_list, count = collect_secondaries(e, p1)
|
||||
assert(#s_list == 2 and #c_list == 2 and count == 2)
|
||||
assert(s_list[1] == s1 and c_list[1] == 42)
|
||||
assert(s_list[2] == s2 and c_list[2] == 84)
|
||||
end
|
||||
|
||||
do
|
||||
local s_list, c_list, count = collect_secondaries(e, p2)
|
||||
assert(#s_list == 2 and #c_list == 2 and count == 2)
|
||||
assert(s_list[1] == s1 and c_list[1] == 21)
|
||||
assert(s_list[2] == s2 and c_list[2] == 63)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local p, s = evo.id(2)
|
||||
|
||||
local e = evo.id()
|
||||
|
||||
assert(not evo.primary(e, s))
|
||||
assert(not evo.primary(e, s, 1))
|
||||
assert(not evo.primary(e, s, 2))
|
||||
assert(not evo.primary(e, s, -1))
|
||||
assert(not evo.primary(e, s, -2))
|
||||
|
||||
assert(not evo.secondary(e, p))
|
||||
assert(not evo.secondary(e, p, 1))
|
||||
assert(not evo.secondary(e, p, 2))
|
||||
assert(not evo.secondary(e, p, -1))
|
||||
assert(not evo.secondary(e, p, -2))
|
||||
|
||||
assert(evo.primary_count(e, s) == 0)
|
||||
assert(evo.secondary_count(e, p) == 0)
|
||||
|
||||
assert(evo.primaries(e, s)() == nil)
|
||||
assert(evo.secondaries(e, p)() == nil)
|
||||
end
|
||||
|
||||
-- TODO:
|
||||
-- How should required fragments work with pairs?
|
||||
-- How can we set defaults for paired fragments?
|
||||
|
||||
516
evolved.lua
516
evolved.lua
@@ -82,6 +82,20 @@ local evolved = {
|
||||
---@field package [3] integer chunk_stack_size
|
||||
---@field package [4] table<evolved.fragment, integer>? exclude_set
|
||||
|
||||
---@class (exact) evolved.primaries_state
|
||||
---@field package [1] integer structural_changes
|
||||
---@field package [2] evolved.chunk entity_chunk
|
||||
---@field package [3] integer entity_place
|
||||
---@field package [4] evolved.fragment secondary_fragment
|
||||
---@field package [5] integer secondary_pair_index
|
||||
|
||||
---@class (exact) evolved.secondaries_state
|
||||
---@field package [1] integer structural_changes
|
||||
---@field package [2] evolved.chunk entity_chunk
|
||||
---@field package [3] integer entity_place
|
||||
---@field package [4] evolved.fragment primary_fragment
|
||||
---@field package [5] integer primary_pair_index
|
||||
|
||||
---@alias evolved.each_iterator fun(
|
||||
--- state: evolved.each_state?):
|
||||
--- evolved.fragment?, evolved.component?
|
||||
@@ -90,6 +104,14 @@ local evolved = {
|
||||
--- state: evolved.execute_state?):
|
||||
--- evolved.chunk?, evolved.entity[]?, integer?
|
||||
|
||||
---@alias evolved.primaries_iterator fun(
|
||||
--- state: evolved.primaries_state?):
|
||||
--- evolved.fragment?, evolved.component?
|
||||
|
||||
---@alias evolved.secondaries_iterator fun(
|
||||
--- state: evolved.secondaries_state?):
|
||||
--- evolved.fragment?, evolved.component?
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
@@ -433,13 +455,15 @@ 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,
|
||||
primaries_state = 6,
|
||||
secondaries_state = 7,
|
||||
entity_set = 8,
|
||||
entity_list = 9,
|
||||
fragment_set = 10,
|
||||
fragment_list = 11,
|
||||
component_map = 12,
|
||||
component_list = 13,
|
||||
__count = 13,
|
||||
}
|
||||
|
||||
---@class (exact) evolved.table_pool
|
||||
@@ -731,90 +755,6 @@ end
|
||||
---
|
||||
---
|
||||
|
||||
---@type evolved.each_iterator
|
||||
local function __each_iterator(each_state)
|
||||
if not each_state then return end
|
||||
|
||||
local structural_changes = each_state[1]
|
||||
local entity_chunk = each_state[2]
|
||||
local entity_place = each_state[3]
|
||||
local chunk_fragment_index = each_state[4]
|
||||
|
||||
if structural_changes ~= __structural_changes then
|
||||
__error_fmt('structural changes are prohibited during iteration')
|
||||
end
|
||||
|
||||
local chunk_fragment_list = entity_chunk.__fragment_list
|
||||
local chunk_fragment_count = entity_chunk.__fragment_count
|
||||
local chunk_component_indices = entity_chunk.__component_indices
|
||||
local chunk_component_storages = entity_chunk.__component_storages
|
||||
|
||||
if chunk_fragment_index <= chunk_fragment_count then
|
||||
each_state[4] = chunk_fragment_index + 1
|
||||
local fragment = chunk_fragment_list[chunk_fragment_index]
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
return fragment, component_storage and component_storage[entity_place]
|
||||
end
|
||||
|
||||
__release_table(__table_pool_tag.each_state, each_state, true)
|
||||
end
|
||||
|
||||
---@type evolved.execute_iterator
|
||||
local function __execute_iterator(execute_state)
|
||||
if not execute_state then return end
|
||||
|
||||
local structural_changes = execute_state[1]
|
||||
local chunk_stack = execute_state[2]
|
||||
local chunk_stack_size = execute_state[3]
|
||||
local exclude_set = execute_state[4]
|
||||
|
||||
if structural_changes ~= __structural_changes then
|
||||
__error_fmt('structural changes are prohibited during iteration')
|
||||
end
|
||||
|
||||
while chunk_stack_size > 0 do
|
||||
local chunk = chunk_stack[chunk_stack_size]
|
||||
|
||||
chunk_stack[chunk_stack_size] = nil
|
||||
chunk_stack_size = chunk_stack_size - 1
|
||||
|
||||
local chunk_child_list = chunk.__child_list
|
||||
local chunk_child_count = chunk.__child_count
|
||||
|
||||
for i = 1, chunk_child_count do
|
||||
local chunk_child = chunk_child_list[i]
|
||||
local chunk_child_fragment = chunk_child.__fragment
|
||||
|
||||
local is_chunk_child_matched =
|
||||
(not chunk_child.__has_explicit_major) and
|
||||
(not exclude_set or not exclude_set[chunk_child_fragment])
|
||||
|
||||
if is_chunk_child_matched then
|
||||
chunk_stack_size = chunk_stack_size + 1
|
||||
chunk_stack[chunk_stack_size] = chunk_child
|
||||
end
|
||||
end
|
||||
|
||||
local chunk_entity_list = chunk.__entity_list
|
||||
local chunk_entity_count = chunk.__entity_count
|
||||
|
||||
if chunk_entity_count > 0 then
|
||||
execute_state[3] = chunk_stack_size
|
||||
return chunk, chunk_entity_list, chunk_entity_count
|
||||
end
|
||||
end
|
||||
|
||||
__release_table(__table_pool_tag.chunk_list, chunk_stack, true)
|
||||
__release_table(__table_pool_tag.execute_state, execute_state, true)
|
||||
end
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
local __ANY = __acquire_id()
|
||||
|
||||
local __TAG = __acquire_id()
|
||||
@@ -941,6 +881,15 @@ local __evolved_process
|
||||
local __evolved_debug_mode
|
||||
local __evolved_collect_garbage
|
||||
|
||||
local __evolved_primary
|
||||
local __evolved_secondary
|
||||
|
||||
local __evolved_primaries
|
||||
local __evolved_secondaries
|
||||
|
||||
local __evolved_primary_count
|
||||
local __evolved_secondary_count
|
||||
|
||||
local __evolved_chunk
|
||||
local __evolved_builder
|
||||
|
||||
@@ -1097,6 +1046,158 @@ end
|
||||
---
|
||||
---
|
||||
|
||||
local __iterator_fns = {}
|
||||
|
||||
---@type evolved.each_iterator
|
||||
function __iterator_fns.__each_iterator(each_state)
|
||||
if not each_state then return end
|
||||
|
||||
local structural_changes = each_state[1]
|
||||
local entity_chunk = each_state[2]
|
||||
local entity_place = each_state[3]
|
||||
local chunk_fragment_index = each_state[4]
|
||||
|
||||
if structural_changes ~= __structural_changes then
|
||||
__error_fmt('structural changes are prohibited during iteration')
|
||||
end
|
||||
|
||||
local chunk_fragment_list = entity_chunk.__fragment_list
|
||||
local chunk_fragment_count = entity_chunk.__fragment_count
|
||||
local chunk_component_indices = entity_chunk.__component_indices
|
||||
local chunk_component_storages = entity_chunk.__component_storages
|
||||
|
||||
if chunk_fragment_index <= chunk_fragment_count then
|
||||
each_state[4] = chunk_fragment_index + 1
|
||||
local fragment = chunk_fragment_list[chunk_fragment_index]
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
return fragment, component_storage and component_storage[entity_place]
|
||||
end
|
||||
|
||||
__release_table(__table_pool_tag.each_state, each_state, true)
|
||||
end
|
||||
|
||||
---@type evolved.execute_iterator
|
||||
function __iterator_fns.__execute_iterator(execute_state)
|
||||
if not execute_state then return end
|
||||
|
||||
local structural_changes = execute_state[1]
|
||||
local chunk_stack = execute_state[2]
|
||||
local chunk_stack_size = execute_state[3]
|
||||
local exclude_set = execute_state[4]
|
||||
|
||||
if structural_changes ~= __structural_changes then
|
||||
__error_fmt('structural changes are prohibited during iteration')
|
||||
end
|
||||
|
||||
while chunk_stack_size > 0 do
|
||||
local chunk = chunk_stack[chunk_stack_size]
|
||||
|
||||
chunk_stack[chunk_stack_size] = nil
|
||||
chunk_stack_size = chunk_stack_size - 1
|
||||
|
||||
local chunk_child_list = chunk.__child_list
|
||||
local chunk_child_count = chunk.__child_count
|
||||
|
||||
for i = 1, chunk_child_count do
|
||||
local chunk_child = chunk_child_list[i]
|
||||
local chunk_child_fragment = chunk_child.__fragment
|
||||
|
||||
local is_chunk_child_matched =
|
||||
(not chunk_child.__has_explicit_major) and
|
||||
(not exclude_set or not exclude_set[chunk_child_fragment])
|
||||
|
||||
if is_chunk_child_matched then
|
||||
chunk_stack_size = chunk_stack_size + 1
|
||||
chunk_stack[chunk_stack_size] = chunk_child
|
||||
end
|
||||
end
|
||||
|
||||
local chunk_entity_list = chunk.__entity_list
|
||||
local chunk_entity_count = chunk.__entity_count
|
||||
|
||||
if chunk_entity_count > 0 then
|
||||
execute_state[3] = chunk_stack_size
|
||||
return chunk, chunk_entity_list, chunk_entity_count
|
||||
end
|
||||
end
|
||||
|
||||
__release_table(__table_pool_tag.chunk_list, chunk_stack, true)
|
||||
__release_table(__table_pool_tag.execute_state, execute_state, true)
|
||||
end
|
||||
|
||||
---@type evolved.primaries_iterator
|
||||
function __iterator_fns.__primaries_iterator(primaries_state)
|
||||
if not primaries_state then return end
|
||||
|
||||
local structural_changes = primaries_state[1]
|
||||
local entity_chunk = primaries_state[2]
|
||||
local entity_place = primaries_state[3]
|
||||
local secondary_fragment = primaries_state[4]
|
||||
local secondary_pair_index = primaries_state[5]
|
||||
|
||||
if structural_changes ~= __structural_changes then
|
||||
__error_fmt('structural changes are prohibited during iteration')
|
||||
end
|
||||
|
||||
local secondary_pairs = entity_chunk.__secondaries[secondary_fragment]
|
||||
local secondary_pair_list = secondary_pairs and secondary_pairs.__item_list
|
||||
local secondary_pair_count = secondary_pairs and secondary_pairs.__item_count or 0
|
||||
|
||||
if secondary_pair_index <= secondary_pair_count then
|
||||
primaries_state[5] = secondary_pair_index + 1
|
||||
local secondary_pair = secondary_pair_list[secondary_pair_index]
|
||||
|
||||
local primary, _ = __evolved_unpair(secondary_pair)
|
||||
|
||||
local component_index = entity_chunk.__component_indices[secondary_pair]
|
||||
local component_storage = entity_chunk.__component_storages[component_index]
|
||||
|
||||
return primary, component_storage and component_storage[entity_place]
|
||||
end
|
||||
|
||||
__release_table(__table_pool_tag.primaries_state, primaries_state, true)
|
||||
end
|
||||
|
||||
---@type evolved.secondaries_iterator
|
||||
function __iterator_fns.__secondaries_iterator(secondaries_state)
|
||||
if not secondaries_state then return end
|
||||
|
||||
local structural_changes = secondaries_state[1]
|
||||
local entity_chunk = secondaries_state[2]
|
||||
local entity_place = secondaries_state[3]
|
||||
local primary_fragment = secondaries_state[4]
|
||||
local primary_pair_index = secondaries_state[5]
|
||||
|
||||
if structural_changes ~= __structural_changes then
|
||||
__error_fmt('structural changes are prohibited during iteration')
|
||||
end
|
||||
|
||||
local primary_pairs = entity_chunk.__primaries[primary_fragment]
|
||||
local primary_pair_list = primary_pairs and primary_pairs.__item_list
|
||||
local primary_pair_count = primary_pairs and primary_pairs.__item_count or 0
|
||||
|
||||
if primary_pair_index <= primary_pair_count then
|
||||
secondaries_state[5] = primary_pair_index + 1
|
||||
local primary_pair = primary_pair_list[primary_pair_index]
|
||||
|
||||
local _, secondary = __evolved_unpair(primary_pair)
|
||||
|
||||
local component_index = entity_chunk.__component_indices[primary_pair]
|
||||
local component_storage = entity_chunk.__component_storages[component_index]
|
||||
|
||||
return secondary, component_storage and component_storage[entity_place]
|
||||
end
|
||||
|
||||
__release_table(__table_pool_tag.secondaries_state, secondaries_state, true)
|
||||
end
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
local __new_chunk
|
||||
local __update_chunk_tags
|
||||
local __update_chunk_flags
|
||||
@@ -1776,7 +1877,9 @@ local function __chunk_has_fragment(chunk, fragment)
|
||||
return false
|
||||
end
|
||||
|
||||
return chunk.__secondaries[secondary] ~= nil
|
||||
local secondaries = chunk.__secondaries[secondary]
|
||||
|
||||
return secondaries and secondaries.__item_count > 0
|
||||
elseif secondary_index == any_index then
|
||||
local primary = __freelist_ids[primary_index]
|
||||
|
||||
@@ -1785,7 +1888,9 @@ local function __chunk_has_fragment(chunk, fragment)
|
||||
return false
|
||||
end
|
||||
|
||||
return chunk.__primaries[primary] ~= nil
|
||||
local primaries = chunk.__primaries[primary]
|
||||
|
||||
return primaries and primaries.__item_count > 0
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5421,7 +5526,7 @@ function __evolved_each(entity)
|
||||
local entity_index = entity % 0x100000
|
||||
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
return __each_iterator
|
||||
return __iterator_fns.__each_iterator
|
||||
end
|
||||
|
||||
local entity_chunks = __entity_chunks
|
||||
@@ -5431,7 +5536,7 @@ function __evolved_each(entity)
|
||||
local place = entity_places[entity_index]
|
||||
|
||||
if not chunk then
|
||||
return __each_iterator
|
||||
return __iterator_fns.__each_iterator
|
||||
end
|
||||
|
||||
---@type evolved.each_state
|
||||
@@ -5442,7 +5547,7 @@ function __evolved_each(entity)
|
||||
each_state[3] = place
|
||||
each_state[4] = 1
|
||||
|
||||
return __each_iterator, each_state
|
||||
return __iterator_fns.__each_iterator, each_state
|
||||
end
|
||||
|
||||
---@param query evolved.query
|
||||
@@ -5453,7 +5558,7 @@ function __evolved_execute(query)
|
||||
local query_index = query % 0x100000
|
||||
|
||||
if __freelist_ids[query_index] ~= query then
|
||||
return __execute_iterator
|
||||
return __iterator_fns.__execute_iterator
|
||||
end
|
||||
|
||||
---@type evolved.chunk[]
|
||||
@@ -5536,7 +5641,7 @@ function __evolved_execute(query)
|
||||
execute_state[3] = chunk_stack_size
|
||||
execute_state[4] = query_exclude_set
|
||||
|
||||
return __execute_iterator, execute_state
|
||||
return __iterator_fns.__execute_iterator, execute_state
|
||||
end
|
||||
|
||||
---@param ... evolved.system systems
|
||||
@@ -5631,6 +5736,212 @@ end
|
||||
---
|
||||
---
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param secondary evolved.fragment
|
||||
---@param index? integer
|
||||
---@return evolved.fragment? primary
|
||||
---@return evolved.component? component
|
||||
---@nodiscard
|
||||
function __evolved_primary(entity, secondary, index)
|
||||
index = index or 1
|
||||
|
||||
if __is_pair(entity) then
|
||||
-- pairs are always empty
|
||||
return
|
||||
end
|
||||
|
||||
local entity_index = entity % 2 ^ 20
|
||||
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
return
|
||||
end
|
||||
|
||||
local chunk = __entity_chunks[entity_index]
|
||||
local place = __entity_places[entity_index]
|
||||
|
||||
local secondary_pairs = chunk and chunk.__secondaries[secondary]
|
||||
local secondary_pair_list = secondary_pairs and secondary_pairs.__item_list
|
||||
local secondary_pair_count = secondary_pairs and secondary_pairs.__item_count or 0
|
||||
|
||||
if index < 1 or index > secondary_pair_count then
|
||||
return
|
||||
end
|
||||
|
||||
local secondary_pair = secondary_pair_list[index]
|
||||
local primary, _ = __evolved_unpair(secondary_pair)
|
||||
|
||||
local component_index = chunk.__component_indices[secondary_pair]
|
||||
local component_storage = chunk.__component_storages[component_index]
|
||||
|
||||
return primary, component_storage and component_storage[place]
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param primary evolved.fragment
|
||||
---@param index? integer
|
||||
---@return evolved.fragment? secondary
|
||||
---@return evolved.component? component
|
||||
---@nodiscard
|
||||
function __evolved_secondary(entity, primary, index)
|
||||
index = index or 1
|
||||
|
||||
if __is_pair(entity) then
|
||||
-- pairs are always empty
|
||||
return
|
||||
end
|
||||
|
||||
local entity_index = entity % 2 ^ 20
|
||||
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
return
|
||||
end
|
||||
|
||||
local chunk = __entity_chunks[entity_index]
|
||||
local place = __entity_places[entity_index]
|
||||
|
||||
local primary_pairs = chunk and chunk.__primaries[primary]
|
||||
local primary_pair_list = primary_pairs and primary_pairs.__item_list
|
||||
local primary_pair_count = primary_pairs and primary_pairs.__item_count or 0
|
||||
|
||||
if index < 1 or index > primary_pair_count then
|
||||
return
|
||||
end
|
||||
|
||||
local primary_pair = primary_pair_list[index]
|
||||
local _, secondary = __evolved_unpair(primary_pair)
|
||||
|
||||
local component_index = chunk.__component_indices[primary_pair]
|
||||
local component_storage = chunk.__component_storages[component_index]
|
||||
|
||||
return secondary, component_storage and component_storage[place]
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param secondary evolved.fragment
|
||||
---@return evolved.primaries_iterator iterator
|
||||
---@return evolved.primaries_state? iterator_state
|
||||
---@nodiscard
|
||||
function __evolved_primaries(entity, secondary)
|
||||
if __is_pair(entity) then
|
||||
-- pairs are always empty
|
||||
return __iterator_fns.__primaries_iterator
|
||||
end
|
||||
|
||||
local entity_index = entity % 2 ^ 20
|
||||
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
return __iterator_fns.__primaries_iterator
|
||||
end
|
||||
|
||||
local chunk = __entity_chunks[entity_index]
|
||||
local place = __entity_places[entity_index]
|
||||
|
||||
local secondaries = chunk and chunk.__secondaries[secondary]
|
||||
|
||||
if not secondaries then
|
||||
return __iterator_fns.__primaries_iterator
|
||||
end
|
||||
|
||||
---@type evolved.primaries_state
|
||||
local primaries_state = __acquire_table(__table_pool_tag.primaries_state)
|
||||
|
||||
primaries_state[1] = __structural_changes
|
||||
primaries_state[2] = chunk
|
||||
primaries_state[3] = place
|
||||
primaries_state[4] = secondary
|
||||
primaries_state[5] = 1
|
||||
|
||||
return __iterator_fns.__primaries_iterator, primaries_state
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param primary evolved.fragment
|
||||
---@return evolved.secondaries_iterator iterator
|
||||
---@return evolved.secondaries_state? iterator_state
|
||||
---@nodiscard
|
||||
function __evolved_secondaries(entity, primary)
|
||||
if __is_pair(entity) then
|
||||
-- pairs are always empty
|
||||
return __iterator_fns.__secondaries_iterator
|
||||
end
|
||||
|
||||
local entity_index = entity % 2 ^ 20
|
||||
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
return __iterator_fns.__secondaries_iterator
|
||||
end
|
||||
|
||||
local chunk = __entity_chunks[entity_index]
|
||||
local place = __entity_places[entity_index]
|
||||
|
||||
local primaries = chunk and chunk.__primaries[primary]
|
||||
|
||||
if not primaries then
|
||||
return __iterator_fns.__secondaries_iterator
|
||||
end
|
||||
|
||||
---@type evolved.secondaries_state
|
||||
local secondaries_state = __acquire_table(__table_pool_tag.secondaries_state)
|
||||
|
||||
secondaries_state[1] = __structural_changes
|
||||
secondaries_state[2] = chunk
|
||||
secondaries_state[3] = place
|
||||
secondaries_state[4] = primary
|
||||
secondaries_state[5] = 1
|
||||
|
||||
return __iterator_fns.__secondaries_iterator, secondaries_state
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param secondary evolved.fragment
|
||||
---@return integer
|
||||
---@nodiscard
|
||||
function __evolved_primary_count(entity, secondary)
|
||||
if __is_pair(entity) then
|
||||
-- pairs are always empty
|
||||
return 0
|
||||
end
|
||||
|
||||
local entity_index = entity % 2 ^ 20
|
||||
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
return 0
|
||||
end
|
||||
|
||||
local chunk = __entity_chunks[entity_index]
|
||||
|
||||
local secondary_pairs = chunk and chunk.__secondaries[secondary]
|
||||
return secondary_pairs and secondary_pairs.__item_count or 0
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param primary evolved.fragment
|
||||
---@return integer
|
||||
---@nodiscard
|
||||
function __evolved_secondary_count(entity, primary)
|
||||
if __is_pair(entity) then
|
||||
-- pairs are always empty
|
||||
return 0
|
||||
end
|
||||
|
||||
local entity_index = entity % 2 ^ 20
|
||||
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
return 0
|
||||
end
|
||||
|
||||
local chunk = __entity_chunks[entity_index]
|
||||
|
||||
local primary_pairs = chunk and chunk.__primaries[primary]
|
||||
return primary_pairs and primary_pairs.__item_count or 0
|
||||
end
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
---@param fragment evolved.fragment
|
||||
---@param ... evolved.fragment fragments
|
||||
---@return evolved.chunk chunk
|
||||
@@ -6557,6 +6868,15 @@ evolved.batch_destroy = __evolved_batch_destroy
|
||||
evolved.each = __evolved_each
|
||||
evolved.execute = __evolved_execute
|
||||
|
||||
evolved.primary = __evolved_primary
|
||||
evolved.secondary = __evolved_secondary
|
||||
|
||||
evolved.primaries = __evolved_primaries
|
||||
evolved.secondaries = __evolved_secondaries
|
||||
|
||||
evolved.primary_count = __evolved_primary_count
|
||||
evolved.secondary_count = __evolved_secondary_count
|
||||
|
||||
evolved.process = __evolved_process
|
||||
|
||||
evolved.debug_mode = __evolved_debug_mode
|
||||
|
||||
Reference in New Issue
Block a user