mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-14 20:11:27 +07:00
system processing with topological sorting (without optimizations yet)
This commit is contained in:
@@ -91,6 +91,8 @@ select :: chunk, fragment... -> component[]...
|
||||
|
||||
each :: entity -> {each_state? -> fragment?, component?}, each_state?
|
||||
execute :: query -> {execute_state? -> chunk?, entity[]?, integer?}, execute_state?
|
||||
|
||||
process :: phase... -> ()
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
121
evolved.lua
121
evolved.lua
@@ -431,6 +431,11 @@ local __EXCLUDE_SET = __acquire_id()
|
||||
local __SORTED_INCLUDE_LIST = __acquire_id()
|
||||
local __SORTED_EXCLUDE_LIST = __acquire_id()
|
||||
|
||||
---@type table
|
||||
local __EMPTY_TABLE = setmetatable({}, {
|
||||
__newindex = function() error('attempt to modify empty table') end
|
||||
})
|
||||
|
||||
---@type table<evolved.fragment, boolean>
|
||||
local __EMPTY_FRAGMENT_SET = setmetatable({}, {
|
||||
__newindex = function() error('attempt to modify empty fragment set') end
|
||||
@@ -2594,6 +2599,108 @@ end
|
||||
---
|
||||
---
|
||||
|
||||
---@param system evolved.system
|
||||
local function __system_process(system)
|
||||
---@type evolved.query?, evolved.process?, evolved.execute?
|
||||
local query, process, execute = evolved.get(system,
|
||||
evolved.QUERY, evolved.PROCESS, evolved.EXECUTE)
|
||||
|
||||
if process then
|
||||
local success, result = pcall(process)
|
||||
|
||||
if not success then
|
||||
error(string.format('system processing failed: %s', result), 2)
|
||||
end
|
||||
end
|
||||
|
||||
if query and execute then
|
||||
evolved.defer()
|
||||
do
|
||||
for chunk, entities, entity_count in evolved.execute(query) do
|
||||
local success, result = pcall(execute, chunk, entities, entity_count)
|
||||
|
||||
if not success then
|
||||
evolved.commit()
|
||||
error(string.format('system execution failed: %s', result), 2)
|
||||
end
|
||||
end
|
||||
end
|
||||
evolved.commit()
|
||||
end
|
||||
end
|
||||
|
||||
---@param phase evolved.phase
|
||||
local function __phase_process(phase)
|
||||
local phase_system_set = __phase_system_sets[phase]
|
||||
|
||||
if not phase_system_set then
|
||||
return
|
||||
end
|
||||
|
||||
---@type evolved.system[]
|
||||
local topological_sorting_stack = {}
|
||||
local topological_sorting_stack_size = 0
|
||||
|
||||
for system in pairs(phase_system_set) do
|
||||
topological_sorting_stack_size = topological_sorting_stack_size + 1
|
||||
topological_sorting_stack[topological_sorting_stack_size] = system
|
||||
end
|
||||
|
||||
---@type evolved.system[]
|
||||
local processing_system_list = {}
|
||||
local processing_system_list_size = 0
|
||||
|
||||
---@type table<evolved.system, integer>
|
||||
local topological_sorting_marks = {}
|
||||
|
||||
while topological_sorting_stack_size > 0 do
|
||||
local system = topological_sorting_stack[topological_sorting_stack_size]
|
||||
|
||||
local system_mark = topological_sorting_marks[system]
|
||||
|
||||
if not system_mark then
|
||||
topological_sorting_marks[system] = 1
|
||||
|
||||
local system_dependency_set = __system_after_sets[system] or __EMPTY_TABLE
|
||||
|
||||
for system_dependency in pairs(system_dependency_set) do
|
||||
local system_dependency_mark = topological_sorting_marks[system_dependency]
|
||||
|
||||
if not system_dependency_mark then
|
||||
topological_sorting_stack_size = topological_sorting_stack_size + 1
|
||||
topological_sorting_stack[topological_sorting_stack_size] = system_dependency
|
||||
elseif system_dependency_mark == 1 then
|
||||
error('cyclic dependency detected', 2)
|
||||
elseif system_dependency_mark == 2 then
|
||||
-- nothing, dependency has already been placed
|
||||
end
|
||||
end
|
||||
elseif system_mark == 1 then
|
||||
topological_sorting_marks[system] = 2
|
||||
|
||||
processing_system_list_size = processing_system_list_size + 1
|
||||
processing_system_list[processing_system_list_size] = system
|
||||
|
||||
topological_sorting_stack[topological_sorting_stack_size] = nil
|
||||
topological_sorting_stack_size = topological_sorting_stack_size - 1
|
||||
elseif system_mark == 2 then
|
||||
topological_sorting_stack[topological_sorting_stack_size] = nil
|
||||
topological_sorting_stack_size = topological_sorting_stack_size - 1
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, processing_system_list_size do
|
||||
local system = processing_system_list[i]
|
||||
__system_process(system)
|
||||
end
|
||||
end
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
---@enum evolved.defer_op
|
||||
local __defer_op = {
|
||||
set = 1,
|
||||
@@ -5554,6 +5661,20 @@ function evolved.execute(query)
|
||||
return __execute_iterator, execute_state
|
||||
end
|
||||
|
||||
---@param ... evolved.phase phases
|
||||
function evolved.process(...)
|
||||
local phase_count = select('#', ...)
|
||||
|
||||
if phase_count == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
for i = 1, phase_count do
|
||||
local phase = select(i, ...)
|
||||
__phase_process(phase)
|
||||
end
|
||||
end
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user