systems can be queries themselves

This commit is contained in:
BlackMATov
2025-05-26 17:37:40 +07:00
parent 5ae0e77f20
commit 3a64bac8e2
4 changed files with 166 additions and 9 deletions

View File

@@ -671,6 +671,29 @@ The [`evolved.process`](#evolvedprocess) function is used to process systems. It
function evolved.process(...) end
```
If you don't specify a query for the system, the system itself will be treated as a query. This means the system can contain `evolved.INCLUDES` and `evolved.EXCLUDES` fragments, and it will be processed according to them. This is useful for creating systems with unique queries that don't need to be reused in other systems.
```lua
local evolved = require 'evolved'
local health = evolved.id()
local system = evolved.builder()
:include(health)
:execute(function(chunk, entity_list, entity_count)
local health_components = chunk:components(health)
for i = 1, entity_count do
print(i)
health_components[i] = math.max(
health_components[i] - 1,
0)
end
end):spawn()
evolved.process(system)
```
To group systems together, you can use the [`evolved.GROUP`](#evolvedgroup) fragment. Systems with a specified group will be processed when you call the [`evolved.process`](#evolvedprocess) function with this group. For example, you can group all physics systems together and process them in one [`evolved.process`](#evolvedprocess) call.
```lua
@@ -1125,6 +1148,10 @@ builder_mt:destruction_policy :: id -> builder
# Changelog
## vX.X.X-dev
- Systems can be queries themselves
## v1.0.0
- Initial release

View File

@@ -1,6 +1,9 @@
require 'develop.example'
require 'develop.unbench'
require 'develop.untests'
require 'develop.testing.system_as_query_tests'
require 'develop.unbench'
require 'develop.usbench'
local basics = require 'develop.basics'

View File

@@ -0,0 +1,128 @@
local evo = require 'evolved'
do
local f1, f2, f3 = evo.id(3)
local q1e3 = evo.builder():include(f1):exclude(f3):spawn()
local q2e3 = evo.builder():include(f2):exclude(f3):spawn()
local e1 = evo.builder():set(f1, 1):spawn()
local e12 = evo.builder():set(f1, 11):set(f2, 12):spawn()
local e2 = evo.builder():set(f2, 2):spawn()
local e23 = evo.builder():set(f2, 23):set(f3, 3):spawn()
local c1 = evo.chunk(f1)
local c12 = evo.chunk(f1, f2)
local c2 = evo.chunk(f2)
do
local _, entity_list, entity_count = evo.chunk(f2, f3)
assert(entity_count == 1 and entity_list[1] == e23)
end
do
local entity_sum = 0
local s = evo.builder()
:query(q1e3)
:execute(function(chunk, entity_list, entity_count)
for i = 1, entity_count do
entity_sum = entity_sum + entity_list[i]
end
if chunk == c1 then
assert(entity_count == 1)
assert(entity_list[1] == e1)
elseif chunk == c12 then
assert(entity_count == 1)
assert(entity_list[1] == e12)
else
assert(false, "Unexpected chunk: " .. tostring(chunk))
end
end):spawn()
evo.process(s)
assert(entity_sum == e1 + e12)
end
do
local entity_sum = 0
local s = evo.builder()
:query(q2e3)
:execute(function(chunk, entity_list, entity_count)
for i = 1, entity_count do
entity_sum = entity_sum + entity_list[i]
end
if chunk == c12 then
assert(entity_count == 1)
assert(entity_list[1] == e12)
elseif chunk == c2 then
assert(entity_count == 1)
assert(entity_list[1] == e2)
else
assert(false, "Unexpected chunk: " .. tostring(chunk))
end
end):spawn()
evo.process(s)
assert(entity_sum == e12 + e2)
end
do
local entity_sum = 0
local s = evo.builder()
:include(f1)
:exclude(f3)
:execute(function(chunk, entity_list, entity_count)
for i = 1, entity_count do
entity_sum = entity_sum + entity_list[i]
end
if chunk == c1 then
assert(entity_count == 1)
assert(entity_list[1] == e1)
elseif chunk == c12 then
assert(entity_count == 1)
assert(entity_list[1] == e12)
else
assert(false, "Unexpected chunk: " .. tostring(chunk))
end
end):spawn()
evo.process(s)
assert(entity_sum == e1 + e12)
end
do
local entity_sum = 0
local s = evo.builder()
:include(f2)
:exclude(f3)
:execute(function(chunk, entity_list, entity_count)
for i = 1, entity_count do
entity_sum = entity_sum + entity_list[i]
end
if chunk == c12 then
assert(entity_count == 1)
assert(entity_list[1] == e12)
elseif chunk == c2 then
assert(entity_count == 1)
assert(entity_list[1] == e2)
else
assert(false, "Unexpected chunk: " .. tostring(chunk))
end
end):spawn()
evo.process(s)
assert(entity_sum == e12 + e2)
end
end

View File

@@ -2727,6 +2727,7 @@ end
---@param system evolved.system
local function __system_process(system)
---@type evolved.query?, evolved.execute?, evolved.prologue?, evolved.epilogue?
local query, execute, prologue, epilogue = __evolved_get(system,
__QUERY, __EXECUTE, __PROLOGUE, __EPILOGUE)
@@ -2738,10 +2739,9 @@ local function __system_process(system)
end
end
if query and execute then
if execute then
__evolved_defer()
do
for chunk, entity_list, entity_count in __evolved_execute(query) do
for chunk, entity_list, entity_count in __evolved_execute(query or system) do
local success, result = __lua_pcall(execute, chunk, entity_list, entity_count)
if not success then
@@ -2749,7 +2749,6 @@ local function __system_process(system)
__error_fmt('system execution failed: %s', result)
end
end
end
__evolved_commit()
end