mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-16 14:11:16 +07:00
Merge branch 'feature/builders' into feature/benches
This commit is contained in:
27
README.md
27
README.md
@@ -26,13 +26,13 @@ TAG :: fragment
|
||||
DEFAULT :: fragment
|
||||
CONSTRUCT :: fragment
|
||||
|
||||
INCLUDES :: fragment
|
||||
EXCLUDES :: fragment
|
||||
|
||||
ON_SET :: fragment
|
||||
ON_ASSIGN :: fragment
|
||||
ON_INSERT :: fragment
|
||||
ON_REMOVE :: fragment
|
||||
|
||||
INCLUDE_LIST :: fragment
|
||||
EXCLUDE_LIST :: fragment
|
||||
```
|
||||
|
||||
## Functions
|
||||
@@ -75,4 +75,25 @@ each :: entity -> {each_state? -> fragment?, component?}, each_state?
|
||||
execute :: query -> {execute_state? -> chunk?, entity[]?}, execute_state?
|
||||
```
|
||||
|
||||
```
|
||||
entity :: entity_builder
|
||||
entity_builder:set :: fragment, any... -> entity_builder
|
||||
entity_builder:build :: entity
|
||||
```
|
||||
|
||||
```
|
||||
fragment :: fragment_builder
|
||||
fragment_builder:tag :: fragment_builder
|
||||
fragment_builder:default :: component -> fragment_builder
|
||||
fragment_builder:construct :: {any... -> component} -> fragment_builder
|
||||
fragment_builder:build :: fragment
|
||||
```
|
||||
|
||||
```
|
||||
query :: query_builder
|
||||
query_builder:include :: fragment... -> query_builder
|
||||
query_builder:exclude :: fragment... -> query_builder
|
||||
query_builder:build :: query
|
||||
```
|
||||
|
||||
## [License (MIT)](./LICENSE.md)
|
||||
|
||||
@@ -332,12 +332,11 @@ do
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4, f5 = evo.id(5)
|
||||
evo.set(f1, evo.CONSTRUCT, function(_, _, a, b) return a - b end)
|
||||
evo.set(f2, evo.CONSTRUCT, function(_, _, c) return c end)
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
evo.set(f1, evo.CONSTRUCT, function(a, b) return a - b end)
|
||||
evo.set(f2, evo.CONSTRUCT, function(c) return c end)
|
||||
evo.set(f3, evo.CONSTRUCT, function() return nil end)
|
||||
evo.set(f4, evo.CONSTRUCT, function() return false end)
|
||||
evo.set(f5, evo.CONSTRUCT, function(e) return e end)
|
||||
|
||||
local e = evo.id()
|
||||
|
||||
@@ -345,25 +344,21 @@ do
|
||||
evo.insert(e, f2, false)
|
||||
evo.insert(e, f3, 43)
|
||||
evo.insert(e, f4, 43)
|
||||
evo.insert(e, f5)
|
||||
|
||||
assert(evo.get(e, f1) == 42)
|
||||
assert(evo.get(e, f2) == false)
|
||||
assert(evo.get(e, f3) == true)
|
||||
assert(evo.get(e, f4) == false)
|
||||
assert(evo.get(e, f5) == e)
|
||||
|
||||
evo.assign(e, f1, 42, 2)
|
||||
evo.assign(e, f2, true)
|
||||
evo.assign(e, f3, 43)
|
||||
evo.assign(e, f4, 43)
|
||||
evo.assign(e, f5, 43)
|
||||
|
||||
assert(evo.get(e, f1) == 40)
|
||||
assert(evo.get(e, f2) == true)
|
||||
assert(evo.get(e, f3) == true)
|
||||
assert(evo.get(e, f4) == false)
|
||||
assert(evo.get(e, f5) == e)
|
||||
end
|
||||
|
||||
do
|
||||
@@ -827,7 +822,7 @@ do
|
||||
assert(evo.insert(e5, f4, 53))
|
||||
|
||||
local q = evo.id()
|
||||
evo.insert(q, evo.INCLUDE_LIST, f1, f2)
|
||||
evo.insert(q, evo.INCLUDES, f1, f2)
|
||||
|
||||
assert(evo.batch_assign(q, f1, 60) == 3)
|
||||
|
||||
@@ -887,7 +882,7 @@ do
|
||||
assert(evo.insert(e5, f4, 53))
|
||||
|
||||
local q = evo.id()
|
||||
evo.insert(q, evo.INCLUDE_LIST, f1, f2)
|
||||
evo.insert(q, evo.INCLUDES, f1, f2)
|
||||
|
||||
assert(evo.batch_assign(q, f1, 60) == 3)
|
||||
|
||||
@@ -945,7 +940,7 @@ do
|
||||
assert(evo.insert(e5, f4, 53))
|
||||
|
||||
local q = evo.id()
|
||||
evo.insert(q, evo.INCLUDE_LIST, f1, f2)
|
||||
evo.insert(q, evo.INCLUDES, f1, f2)
|
||||
|
||||
assert(evo.batch_clear(q) == 3)
|
||||
|
||||
@@ -1015,7 +1010,7 @@ do
|
||||
assert(evo.insert(e5, f4, 53))
|
||||
|
||||
local q = evo.id()
|
||||
evo.insert(q, evo.INCLUDE_LIST, f1, f2)
|
||||
evo.insert(q, evo.INCLUDES, f1, f2)
|
||||
|
||||
assert(evo.batch_clear(q) == 3)
|
||||
assert(entity_sum == e2 * 2 + e3 * 3 + e4 * 4)
|
||||
@@ -1063,7 +1058,7 @@ do
|
||||
assert(evo.insert(e5, f4, 53))
|
||||
|
||||
local q = evo.id()
|
||||
evo.insert(q, evo.INCLUDE_LIST, f1, f2)
|
||||
evo.insert(q, evo.INCLUDES, f1, f2)
|
||||
|
||||
assert(evo.batch_destroy(q) == 3)
|
||||
|
||||
@@ -1133,7 +1128,7 @@ do
|
||||
assert(evo.insert(e5, f4, 53))
|
||||
|
||||
local q = evo.id()
|
||||
evo.insert(q, evo.INCLUDE_LIST, f1, f2)
|
||||
evo.insert(q, evo.INCLUDES, f1, f2)
|
||||
|
||||
assert(evo.batch_destroy(q) == 3)
|
||||
assert(entity_sum == e2 * 2 + e3 * 3 + e4 * 4)
|
||||
@@ -1181,7 +1176,7 @@ do
|
||||
assert(evo.insert(e5, f4, 53))
|
||||
|
||||
local q = evo.id()
|
||||
evo.insert(q, evo.INCLUDE_LIST, f1, f2)
|
||||
evo.insert(q, evo.INCLUDES, f1, f2)
|
||||
|
||||
assert(evo.batch_remove(q, f2, f3) == 3)
|
||||
|
||||
@@ -1254,7 +1249,7 @@ do
|
||||
assert(evo.insert(e5, f4, 53))
|
||||
|
||||
local q = evo.id()
|
||||
evo.insert(q, evo.INCLUDE_LIST, f1, f2)
|
||||
evo.insert(q, evo.INCLUDES, f1, f2)
|
||||
|
||||
assert(evo.batch_remove(q, f2, f3) == 3)
|
||||
assert(entity_sum == e2 + e3 * 2 + e4 * 2)
|
||||
@@ -1290,7 +1285,7 @@ do
|
||||
assert(evo.insert(e4, f4, 50))
|
||||
|
||||
local q = evo.id()
|
||||
evo.insert(q, evo.INCLUDE_LIST, f2)
|
||||
evo.insert(q, evo.INCLUDES, f2)
|
||||
|
||||
assert(evo.batch_insert(q, f1, 60) == 1)
|
||||
|
||||
@@ -1335,7 +1330,7 @@ do
|
||||
assert(evo.insert(e4, f4, 50))
|
||||
|
||||
local q = evo.id()
|
||||
evo.insert(q, evo.INCLUDE_LIST, f2)
|
||||
evo.insert(q, evo.INCLUDES, f2)
|
||||
|
||||
entity_sum = 0
|
||||
component_sum = 0
|
||||
@@ -1378,7 +1373,7 @@ do
|
||||
assert(evo.insert(e4, f4, 50))
|
||||
|
||||
local q = evo.id()
|
||||
evo.insert(q, evo.INCLUDE_LIST, f2)
|
||||
evo.insert(q, evo.INCLUDES, f2)
|
||||
|
||||
assert(evo.batch_set(q, f1, 60) == 3)
|
||||
|
||||
@@ -1423,7 +1418,7 @@ do
|
||||
assert(evo.insert(e4, f4, 50))
|
||||
|
||||
local q = evo.id()
|
||||
evo.insert(q, evo.INCLUDE_LIST, f2)
|
||||
evo.insert(q, evo.INCLUDES, f2)
|
||||
|
||||
entity_sum = 0
|
||||
component_sum = 0
|
||||
@@ -1816,12 +1811,12 @@ do
|
||||
do
|
||||
do
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1)
|
||||
evo.set(q, evo.INCLUDES, f1)
|
||||
evo.batch_destroy(q)
|
||||
end
|
||||
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1, f2)
|
||||
evo.set(q, evo.INCLUDES, f1, f2)
|
||||
|
||||
do
|
||||
local e = evo.id()
|
||||
@@ -1866,12 +1861,12 @@ do
|
||||
do
|
||||
do
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1)
|
||||
evo.set(q, evo.INCLUDES, f1)
|
||||
evo.batch_destroy(q)
|
||||
end
|
||||
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1, f2)
|
||||
evo.set(q, evo.INCLUDES, f1, f2)
|
||||
|
||||
do
|
||||
local e1 = evo.id()
|
||||
@@ -1913,12 +1908,12 @@ do
|
||||
do
|
||||
do
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1)
|
||||
evo.set(q, evo.INCLUDES, f1)
|
||||
evo.batch_destroy(q)
|
||||
end
|
||||
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1, f2)
|
||||
evo.set(q, evo.INCLUDES, f1, f2)
|
||||
|
||||
do
|
||||
local e1 = evo.id()
|
||||
@@ -1964,12 +1959,12 @@ do
|
||||
do
|
||||
do
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1)
|
||||
evo.set(q, evo.INCLUDES, f1)
|
||||
evo.batch_destroy(q)
|
||||
end
|
||||
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1, f2)
|
||||
evo.set(q, evo.INCLUDES, f1, f2)
|
||||
|
||||
do
|
||||
local e1 = evo.id()
|
||||
@@ -2009,12 +2004,12 @@ do
|
||||
do
|
||||
do
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1)
|
||||
evo.set(q, evo.INCLUDES, f1)
|
||||
evo.batch_destroy(q)
|
||||
end
|
||||
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1, f2)
|
||||
evo.set(q, evo.INCLUDES, f1, f2)
|
||||
|
||||
do
|
||||
local e1 = evo.id()
|
||||
@@ -2056,7 +2051,7 @@ do
|
||||
local f1, f2 = evo.id(2)
|
||||
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1)
|
||||
evo.set(q, evo.INCLUDES, f1)
|
||||
|
||||
local e1 = evo.id()
|
||||
assert(evo.insert(e1, f1, 41))
|
||||
@@ -2092,7 +2087,7 @@ do
|
||||
local f1, f2 = evo.id(2)
|
||||
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1)
|
||||
evo.set(q, evo.INCLUDES, f1)
|
||||
|
||||
local e1 = evo.id()
|
||||
assert(evo.insert(e1, f1, 41))
|
||||
@@ -2128,7 +2123,7 @@ do
|
||||
local f1, f2 = evo.id(2)
|
||||
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1)
|
||||
evo.set(q, evo.INCLUDES, f1)
|
||||
|
||||
local e1 = evo.id()
|
||||
assert(evo.insert(e1, f1, 41))
|
||||
@@ -2164,7 +2159,7 @@ do
|
||||
local f1 = evo.id(1)
|
||||
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1)
|
||||
evo.set(q, evo.INCLUDES, f1)
|
||||
|
||||
local e1 = evo.id()
|
||||
assert(evo.insert(e1, f1, 41))
|
||||
@@ -2187,7 +2182,7 @@ do
|
||||
local f1 = evo.id(1)
|
||||
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1)
|
||||
evo.set(q, evo.INCLUDES, f1)
|
||||
|
||||
local e1 = evo.id()
|
||||
assert(evo.insert(e1, f1, 41))
|
||||
@@ -2212,7 +2207,7 @@ do
|
||||
local f1 = evo.id(1)
|
||||
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1)
|
||||
evo.set(q, evo.INCLUDES, f1)
|
||||
|
||||
local e1 = evo.id()
|
||||
assert(evo.insert(e1, f1, 41))
|
||||
@@ -2237,8 +2232,8 @@ do
|
||||
local f1, f2 = evo.id(2)
|
||||
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1)
|
||||
evo.set(q, evo.INCLUDE_LIST, f2)
|
||||
evo.set(q, evo.INCLUDES, f1)
|
||||
evo.set(q, evo.INCLUDES, f2)
|
||||
|
||||
local e1 = evo.id()
|
||||
assert(evo.insert(e1, f1, 41))
|
||||
@@ -2254,7 +2249,7 @@ do
|
||||
assert(entities and entities[1] == e2)
|
||||
end
|
||||
|
||||
evo.set(q, evo.INCLUDE_LIST)
|
||||
evo.set(q, evo.INCLUDES)
|
||||
|
||||
do
|
||||
local iter, state = evo.execute(q)
|
||||
@@ -2269,7 +2264,7 @@ do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1)
|
||||
evo.set(q, evo.INCLUDES, f1)
|
||||
|
||||
local e1 = evo.id()
|
||||
assert(evo.insert(e1, f1, 41))
|
||||
@@ -2297,10 +2292,10 @@ do
|
||||
local f1, f2 = evo.id(2)
|
||||
|
||||
local q = evo.id()
|
||||
evo.set(q, evo.INCLUDE_LIST, f1)
|
||||
evo.set(q, evo.INCLUDES, f1)
|
||||
|
||||
evo.set(q, evo.EXCLUDE_LIST, f1)
|
||||
evo.set(q, evo.EXCLUDE_LIST, f2)
|
||||
evo.set(q, evo.EXCLUDES, f1)
|
||||
evo.set(q, evo.EXCLUDES, f2)
|
||||
|
||||
local e1 = evo.id()
|
||||
assert(evo.insert(e1, f1, 41))
|
||||
@@ -2320,7 +2315,7 @@ do
|
||||
assert(not entities)
|
||||
end
|
||||
|
||||
evo.set(q, evo.EXCLUDE_LIST)
|
||||
evo.set(q, evo.EXCLUDES)
|
||||
|
||||
do
|
||||
local iter, state = evo.execute(q)
|
||||
@@ -2356,7 +2351,7 @@ do
|
||||
assert(not chunk and not entities)
|
||||
end
|
||||
|
||||
evo.set(q, evo.EXCLUDE_LIST, f2)
|
||||
evo.set(q, evo.EXCLUDES, f2)
|
||||
|
||||
do
|
||||
local iter, state = evo.execute(q)
|
||||
@@ -2364,7 +2359,7 @@ do
|
||||
assert(not chunk and not entities)
|
||||
end
|
||||
|
||||
evo.set(q, evo.INCLUDE_LIST, f1)
|
||||
evo.set(q, evo.INCLUDES, f1)
|
||||
|
||||
do
|
||||
local iter, state = evo.execute(q)
|
||||
@@ -2459,3 +2454,61 @@ do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1 = evo.fragment():default(41):build()
|
||||
local f2 = evo.fragment():construct(function() return 42 end):build()
|
||||
local f3 = evo.fragment():tag():build()
|
||||
|
||||
local e0 = evo.entity():build()
|
||||
assert(not evo.has_any(e0, f1, f2, f3))
|
||||
|
||||
local e1 = evo.entity():set(f1):build()
|
||||
assert(evo.has(e1, f1))
|
||||
assert(evo.get(e1, f1) == 41)
|
||||
|
||||
local e2 = evo.entity():set(f1):set(f2):build()
|
||||
assert(evo.has(e2, f1) and evo.has(e2, f2))
|
||||
assert(evo.get(e2, f1) == 41 and evo.get(e2, f2) == 42)
|
||||
|
||||
local e3 = evo.entity():set(f1):set(f2):set(f3):build()
|
||||
assert(evo.has(e3, f1) and evo.has(e3, f2) and evo.has(e3, f3))
|
||||
assert(evo.get(e3, f1) == 41 and evo.get(e3, f2) == 42 and evo.get(e3, f3) == nil)
|
||||
|
||||
---@param q evolved.query
|
||||
---@return evolved.entity[]
|
||||
local function collect_entities(q)
|
||||
local entities = {}
|
||||
for _, es in evo.execute(q) do
|
||||
for _, e in ipairs(es) do
|
||||
entities[#entities + 1] = e
|
||||
end
|
||||
end
|
||||
return entities
|
||||
end
|
||||
|
||||
local q1 = evo.query():include(f1):build()
|
||||
local q2 = evo.query():include(f1, f2):build()
|
||||
local q3 = evo.query():include(f1):include(f2):exclude(f3):build()
|
||||
|
||||
do
|
||||
local entities = collect_entities(q1)
|
||||
assert(#entities == 3)
|
||||
assert(entities[1] == e1)
|
||||
assert(entities[2] == e2)
|
||||
assert(entities[3] == e3)
|
||||
end
|
||||
|
||||
do
|
||||
local entities = collect_entities(q2)
|
||||
assert(#entities == 2)
|
||||
assert(entities[1] == e2)
|
||||
assert(entities[2] == e3)
|
||||
end
|
||||
|
||||
do
|
||||
local entities = collect_entities(q3)
|
||||
assert(#entities == 1)
|
||||
assert(entities[1] == e2)
|
||||
end
|
||||
end
|
||||
|
||||
439
evolved.lua
439
evolved.lua
@@ -219,9 +219,10 @@ local __TABLE_POOL_TAG__CHUNK_LIST = 2
|
||||
local __TABLE_POOL_TAG__EACH_STATE = 3
|
||||
local __TABLE_POOL_TAG__EXECUTE_STATE = 4
|
||||
local __TABLE_POOL_TAG__FRAGMENT_LIST = 5
|
||||
local __TABLE_POOL_TAG__COMPONENT_LIST = 6
|
||||
|
||||
---@type table<evolved.table_pool_tag, table[]>
|
||||
local __tagged_table_pools = __table_new(5, 0)
|
||||
local __tagged_table_pools = __table_new(6, 0)
|
||||
|
||||
---@param tag evolved.table_pool_tag
|
||||
---@param narray integer
|
||||
@@ -339,13 +340,39 @@ evolved.TAG = __acquire_id()
|
||||
evolved.DEFAULT = __acquire_id()
|
||||
evolved.CONSTRUCT = __acquire_id()
|
||||
|
||||
evolved.INCLUDES = __acquire_id()
|
||||
evolved.EXCLUDES = __acquire_id()
|
||||
|
||||
evolved.ON_SET = __acquire_id()
|
||||
evolved.ON_ASSIGN = __acquire_id()
|
||||
evolved.ON_INSERT = __acquire_id()
|
||||
evolved.ON_REMOVE = __acquire_id()
|
||||
|
||||
evolved.INCLUDE_LIST = __acquire_id()
|
||||
evolved.EXCLUDE_LIST = __acquire_id()
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
local __INCLUDE_SET = __acquire_id()
|
||||
local __EXCLUDE_SET = __acquire_id()
|
||||
local __SORTED_INCLUDE_LIST = __acquire_id()
|
||||
local __SORTED_EXCLUDE_LIST = __acquire_id()
|
||||
|
||||
---@type table<evolved.fragment, boolean>
|
||||
local __EMPTY_FRAGMENT_SET = setmetatable({}, {
|
||||
__newindex = function() error('attempt to modify empty fragment set') end
|
||||
})
|
||||
|
||||
---@type evolved.fragment[]
|
||||
local __EMPTY_FRAGMENT_LIST = setmetatable({}, {
|
||||
__newindex = function() error('attempt to modify empty fragment list') end
|
||||
})
|
||||
|
||||
---@type evolved.component[]
|
||||
local __EMPTY_COMPONENT_STORAGE = setmetatable({}, {
|
||||
__newindex = function() error('attempt to modify empty component storage') end
|
||||
})
|
||||
|
||||
---
|
||||
---
|
||||
@@ -353,17 +380,15 @@ evolved.EXCLUDE_LIST = __acquire_id()
|
||||
---
|
||||
---
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param fragment evolved.fragment
|
||||
---@param ... any component arguments
|
||||
---@return evolved.component
|
||||
local function __component_construct(entity, fragment, ...)
|
||||
local function __component_construct(fragment, ...)
|
||||
local default, construct = evolved.get(fragment, evolved.DEFAULT, evolved.CONSTRUCT)
|
||||
|
||||
local component = ...
|
||||
|
||||
if construct ~= nil then
|
||||
component = construct(entity, fragment, ...)
|
||||
component = construct(...)
|
||||
end
|
||||
|
||||
if component == nil then
|
||||
@@ -842,7 +867,7 @@ local function __chunk_assign(chunk, fragment, ...)
|
||||
for place = 1, chunk_size do
|
||||
local entity = chunk_entities[place]
|
||||
local old_component = component_storage[place]
|
||||
local new_component = __component_construct(entity, fragment, ...)
|
||||
local new_component = __component_construct(fragment, ...)
|
||||
component_storage[place] = new_component
|
||||
__fragment_call_set_and_assign_hooks(entity, fragment, new_component, old_component)
|
||||
end
|
||||
@@ -872,8 +897,7 @@ local function __chunk_assign(chunk, fragment, ...)
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
if chunk.__has_defaults_or_constructs and __fragment_has_default_or_construct(fragment) then
|
||||
for place = 1, chunk_size do
|
||||
local entity = chunk_entities[place]
|
||||
local new_component = __component_construct(entity, fragment, ...)
|
||||
local new_component = __component_construct(fragment, ...)
|
||||
component_storage[place] = new_component
|
||||
end
|
||||
else
|
||||
@@ -948,7 +972,7 @@ local function __chunk_insert(chunk, fragment, ...)
|
||||
if chunk.__has_defaults_or_constructs and __fragment_has_default_or_construct(fragment) then
|
||||
for new_place = new_size + 1, new_size + old_size do
|
||||
local entity = new_entities[new_place]
|
||||
local new_component = __component_construct(entity, fragment, ...)
|
||||
local new_component = __component_construct(fragment, ...)
|
||||
new_component_storage[new_place] = new_component
|
||||
__fragment_call_set_and_insert_hooks(entity, fragment, new_component)
|
||||
end
|
||||
@@ -977,8 +1001,7 @@ local function __chunk_insert(chunk, fragment, ...)
|
||||
local new_component_storage = new_component_storages[new_component_index]
|
||||
if chunk.__has_defaults_or_constructs and __fragment_has_default_or_construct(fragment) then
|
||||
for new_place = new_size + 1, new_size + old_size do
|
||||
local entity = new_entities[new_place]
|
||||
local new_component = __component_construct(entity, fragment, ...)
|
||||
local new_component = __component_construct(fragment, ...)
|
||||
new_component_storage[new_place] = new_component
|
||||
end
|
||||
else
|
||||
@@ -1824,7 +1847,7 @@ function evolved.set(entity, fragment, ...)
|
||||
local old_component = old_component_storage[old_place]
|
||||
|
||||
if old_chunk.__has_defaults_or_constructs then
|
||||
local new_component = __component_construct(entity, fragment, ...)
|
||||
local new_component = __component_construct(fragment, ...)
|
||||
|
||||
old_component_storage[old_place] = new_component
|
||||
|
||||
@@ -1866,7 +1889,7 @@ function evolved.set(entity, fragment, ...)
|
||||
local new_component_storage = new_component_storages[new_component_index]
|
||||
|
||||
if new_chunk.__has_defaults_or_constructs then
|
||||
local new_component = __component_construct(entity, fragment, ...)
|
||||
local new_component = __component_construct(fragment, ...)
|
||||
|
||||
new_component_storage[new_place] = new_component
|
||||
|
||||
@@ -1951,7 +1974,7 @@ function evolved.assign(entity, fragment, ...)
|
||||
local old_component = component_storage[place]
|
||||
|
||||
if chunk.__has_defaults_or_constructs then
|
||||
local new_component = __component_construct(entity, fragment, ...)
|
||||
local new_component = __component_construct(fragment, ...)
|
||||
|
||||
component_storage[place] = new_component
|
||||
|
||||
@@ -2020,7 +2043,7 @@ function evolved.insert(entity, fragment, ...)
|
||||
local new_component_storage = new_component_storages[new_component_index]
|
||||
|
||||
if new_chunk.__has_defaults_or_constructs then
|
||||
local new_component = __component_construct(entity, fragment, ...)
|
||||
local new_component = __component_construct(fragment, ...)
|
||||
|
||||
new_component_storage[new_place] = new_component
|
||||
|
||||
@@ -2448,18 +2471,20 @@ end
|
||||
---
|
||||
---
|
||||
|
||||
local __INCLUDE_SET = __acquire_id()
|
||||
local __EXCLUDE_SET = __acquire_id()
|
||||
local __SORTED_INCLUDE_LIST = __acquire_id()
|
||||
local __SORTED_EXCLUDE_LIST = __acquire_id()
|
||||
|
||||
evolved.set(evolved.TAG, evolved.TAG)
|
||||
|
||||
---@param ... evolved.fragment
|
||||
evolved.set(evolved.INCLUDE_LIST, evolved.CONSTRUCT, function(_, _, ...)
|
||||
local include_list = {}
|
||||
evolved.set(evolved.INCLUDES, evolved.CONSTRUCT, function(...)
|
||||
local fragment_count = select('#', ...)
|
||||
|
||||
for i = 1, select('#', ...) do
|
||||
if fragment_count == 0 then
|
||||
return __table_new(0, 0)
|
||||
end
|
||||
|
||||
---@type evolved.fragment[]
|
||||
local include_list = __table_new(fragment_count, 0)
|
||||
|
||||
for i = 1, fragment_count do
|
||||
include_list[i] = select(i, ...)
|
||||
end
|
||||
|
||||
@@ -2467,14 +2492,24 @@ evolved.set(evolved.INCLUDE_LIST, evolved.CONSTRUCT, function(_, _, ...)
|
||||
end)
|
||||
|
||||
---@param query evolved.query
|
||||
---@param include_list evolved.entity[]
|
||||
evolved.set(evolved.INCLUDE_LIST, evolved.ON_SET, function(query, _, include_list)
|
||||
---@type table<evolved.fragment, boolean>, evolved.fragment[]
|
||||
local include_set, sorted_include_list = {}, {}
|
||||
---@param include_list evolved.fragment[]
|
||||
evolved.set(evolved.INCLUDES, evolved.ON_SET, function(query, _, include_list)
|
||||
local include_list_size = #include_list
|
||||
|
||||
for _, f in ipairs(include_list) do
|
||||
include_set[f] = true
|
||||
sorted_include_list[#sorted_include_list + 1] = f
|
||||
---@type table<evolved.fragment, boolean>
|
||||
local include_set = __table_new(0, include_list_size)
|
||||
|
||||
for i = 1, include_list_size do
|
||||
include_set[include_list[i]] = true
|
||||
end
|
||||
|
||||
---@type evolved.fragment[]
|
||||
local sorted_include_list = __table_new(include_list_size, 0)
|
||||
local sorted_include_list_size = 0
|
||||
|
||||
for f, _ in pairs(include_set) do
|
||||
sorted_include_list[sorted_include_list_size + 1] = f
|
||||
sorted_include_list_size = sorted_include_list_size + 1
|
||||
end
|
||||
|
||||
table.sort(sorted_include_list)
|
||||
@@ -2483,15 +2518,22 @@ evolved.set(evolved.INCLUDE_LIST, evolved.ON_SET, function(query, _, include_lis
|
||||
evolved.set(query, __SORTED_INCLUDE_LIST, sorted_include_list)
|
||||
end)
|
||||
|
||||
evolved.set(evolved.INCLUDE_LIST, evolved.ON_REMOVE, function(query)
|
||||
evolved.set(evolved.INCLUDES, evolved.ON_REMOVE, function(query)
|
||||
evolved.remove(query, __INCLUDE_SET, __SORTED_INCLUDE_LIST)
|
||||
end)
|
||||
|
||||
---@param ... evolved.fragment
|
||||
evolved.set(evolved.EXCLUDE_LIST, evolved.CONSTRUCT, function(_, _, ...)
|
||||
local exclude_list = {}
|
||||
evolved.set(evolved.EXCLUDES, evolved.CONSTRUCT, function(...)
|
||||
local fragment_count = select('#', ...)
|
||||
|
||||
for i = 1, select('#', ...) do
|
||||
if fragment_count == 0 then
|
||||
return __table_new(0, 0)
|
||||
end
|
||||
|
||||
---@type evolved.fragment[]
|
||||
local exclude_list = __table_new(fragment_count, 0)
|
||||
|
||||
for i = 1, fragment_count do
|
||||
exclude_list[i] = select(i, ...)
|
||||
end
|
||||
|
||||
@@ -2499,14 +2541,24 @@ evolved.set(evolved.EXCLUDE_LIST, evolved.CONSTRUCT, function(_, _, ...)
|
||||
end)
|
||||
|
||||
---@param query evolved.query
|
||||
---@param exclude_list evolved.entity[]
|
||||
evolved.set(evolved.EXCLUDE_LIST, evolved.ON_SET, function(query, _, exclude_list)
|
||||
---@type table<evolved.fragment, boolean>, evolved.fragment[]
|
||||
local exclude_set, sorted_exclude_list = {}, {}
|
||||
---@param exclude_list evolved.fragment[]
|
||||
evolved.set(evolved.EXCLUDES, evolved.ON_SET, function(query, _, exclude_list)
|
||||
local exclude_list_size = #exclude_list
|
||||
|
||||
for _, f in ipairs(exclude_list) do
|
||||
exclude_set[f] = true
|
||||
sorted_exclude_list[#sorted_exclude_list + 1] = f
|
||||
---@type table<evolved.fragment, boolean>
|
||||
local exclude_set = __table_new(0, exclude_list_size)
|
||||
|
||||
for i = 1, exclude_list_size do
|
||||
exclude_set[exclude_list[i]] = true
|
||||
end
|
||||
|
||||
---@type evolved.fragment[]
|
||||
local sorted_exclude_list = __table_new(exclude_list_size, 0)
|
||||
local sorted_exclude_list_size = 0
|
||||
|
||||
for f, _ in pairs(exclude_set) do
|
||||
sorted_exclude_list[sorted_exclude_list_size + 1] = f
|
||||
sorted_exclude_list_size = sorted_exclude_list_size + 1
|
||||
end
|
||||
|
||||
table.sort(sorted_exclude_list)
|
||||
@@ -2515,7 +2567,7 @@ evolved.set(evolved.EXCLUDE_LIST, evolved.ON_SET, function(query, _, exclude_lis
|
||||
evolved.set(query, __SORTED_EXCLUDE_LIST, sorted_exclude_list)
|
||||
end)
|
||||
|
||||
evolved.set(evolved.EXCLUDE_LIST, evolved.ON_REMOVE, function(query)
|
||||
evolved.set(evolved.EXCLUDES, evolved.ON_REMOVE, function(query)
|
||||
evolved.remove(query, __EXCLUDE_SET, __SORTED_EXCLUDE_LIST)
|
||||
end)
|
||||
|
||||
@@ -2525,27 +2577,6 @@ end)
|
||||
---
|
||||
---
|
||||
|
||||
---@type table<evolved.fragment, boolean>
|
||||
local __EMPTY_FRAGMENT_SET = setmetatable({}, {
|
||||
__newindex = function() error('attempt to modify empty fragment set') end
|
||||
})
|
||||
|
||||
---@type evolved.fragment[]
|
||||
local __EMPTY_FRAGMENT_LIST = setmetatable({}, {
|
||||
__newindex = function() error('attempt to modify empty fragment list') end
|
||||
})
|
||||
|
||||
---@type evolved.component[]
|
||||
local __EMPTY_COMPONENT_STORAGE = setmetatable({}, {
|
||||
__newindex = function() error('attempt to modify empty component storage') end
|
||||
})
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
---@param ... evolved.fragment fragments
|
||||
---@return evolved.chunk?, evolved.entity[]?
|
||||
function evolved.chunk(...)
|
||||
@@ -2603,39 +2634,39 @@ function evolved.select(chunk, ...)
|
||||
local indices = chunk.__component_indices
|
||||
local storages = chunk.__component_storages
|
||||
|
||||
local EMPTY_COMPONENT_STORAGE = __EMPTY_COMPONENT_STORAGE
|
||||
local empty_component_storage = __EMPTY_COMPONENT_STORAGE
|
||||
|
||||
if fragment_count == 1 then
|
||||
local f1 = ...
|
||||
local i1 = indices[f1]
|
||||
return
|
||||
i1 and storages[i1] or EMPTY_COMPONENT_STORAGE
|
||||
i1 and storages[i1] or empty_component_storage
|
||||
end
|
||||
|
||||
if fragment_count == 2 then
|
||||
local f1, f2 = ...
|
||||
local i1, i2 = indices[f1], indices[f2]
|
||||
return
|
||||
i1 and storages[i1] or EMPTY_COMPONENT_STORAGE,
|
||||
i2 and storages[i2] or EMPTY_COMPONENT_STORAGE
|
||||
i1 and storages[i1] or empty_component_storage,
|
||||
i2 and storages[i2] or empty_component_storage
|
||||
end
|
||||
|
||||
if fragment_count == 3 then
|
||||
local f1, f2, f3 = ...
|
||||
local i1, i2, i3 = indices[f1], indices[f2], indices[f3]
|
||||
return
|
||||
i1 and storages[i1] or EMPTY_COMPONENT_STORAGE,
|
||||
i2 and storages[i2] or EMPTY_COMPONENT_STORAGE,
|
||||
i3 and storages[i3] or EMPTY_COMPONENT_STORAGE
|
||||
i1 and storages[i1] or empty_component_storage,
|
||||
i2 and storages[i2] or empty_component_storage,
|
||||
i3 and storages[i3] or empty_component_storage
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = ...
|
||||
local i1, i2, i3 = indices[f1], indices[f2], indices[f3]
|
||||
return
|
||||
i1 and storages[i1] or EMPTY_COMPONENT_STORAGE,
|
||||
i2 and storages[i2] or EMPTY_COMPONENT_STORAGE,
|
||||
i3 and storages[i3] or EMPTY_COMPONENT_STORAGE,
|
||||
i1 and storages[i1] or empty_component_storage,
|
||||
i2 and storages[i2] or empty_component_storage,
|
||||
i3 and storages[i3] or empty_component_storage,
|
||||
evolved.select(chunk, select(4, ...))
|
||||
end
|
||||
end
|
||||
@@ -2726,4 +2757,262 @@ end
|
||||
---
|
||||
---
|
||||
|
||||
---@class (exact) evolved.__entity_builder
|
||||
---@field package __fragment_list? evolved.fragment[]
|
||||
---@field package __component_list? evolved.component[]
|
||||
|
||||
---@class evolved.entity_builder : evolved.__entity_builder
|
||||
local evolved_entity_builder = {}
|
||||
evolved_entity_builder.__index = evolved_entity_builder
|
||||
|
||||
---@return evolved.entity_builder
|
||||
---@nodiscard
|
||||
function evolved.entity()
|
||||
---@type evolved.__entity_builder
|
||||
local builder = {
|
||||
__fragment_list = nil,
|
||||
__component_list = nil,
|
||||
}
|
||||
---@cast builder evolved.entity_builder
|
||||
return setmetatable(builder, evolved_entity_builder)
|
||||
end
|
||||
|
||||
---@param fragment evolved.fragment
|
||||
---@param ... any component arguments
|
||||
---@return evolved.entity_builder
|
||||
function evolved_entity_builder:set(fragment, ...)
|
||||
local component = __component_construct(fragment, ...)
|
||||
|
||||
local fragment_list = self.__fragment_list
|
||||
local component_list = self.__component_list
|
||||
|
||||
if not fragment_list then
|
||||
fragment_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, 8, 0)
|
||||
self.__fragment_list = fragment_list
|
||||
end
|
||||
|
||||
if not component_list then
|
||||
component_list = __acquire_table(__TABLE_POOL_TAG__COMPONENT_LIST, 8, 0)
|
||||
self.__component_list = component_list
|
||||
end
|
||||
|
||||
fragment_list[#fragment_list + 1] = fragment
|
||||
component_list[#component_list + 1] = component
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
---@return evolved.entity
|
||||
function evolved_entity_builder:build()
|
||||
local fragment_list = self.__fragment_list
|
||||
local component_list = self.__component_list
|
||||
|
||||
self.__fragment_list = nil
|
||||
self.__component_list = nil
|
||||
|
||||
local entity = evolved.id()
|
||||
|
||||
if fragment_list and component_list then
|
||||
for i = 1, #fragment_list do
|
||||
local fragment = fragment_list[i]
|
||||
local component = component_list[i]
|
||||
evolved.set(entity, fragment, component)
|
||||
end
|
||||
end
|
||||
|
||||
if fragment_list then
|
||||
__release_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragment_list)
|
||||
end
|
||||
|
||||
if component_list then
|
||||
__release_table(__TABLE_POOL_TAG__COMPONENT_LIST, component_list)
|
||||
end
|
||||
|
||||
return entity
|
||||
end
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
---@class (evact) evolved.__fragment_builder
|
||||
---@field package __tag boolean
|
||||
---@field package __default? evolved.component
|
||||
---@field package __construct? fun(...): evolved.component
|
||||
|
||||
---@class evolved.fragment_builder : evolved.__fragment_builder
|
||||
local evolved_fragment_builder = {}
|
||||
evolved_fragment_builder.__index = evolved_fragment_builder
|
||||
|
||||
---@return evolved.fragment_builder
|
||||
---@nodiscard
|
||||
function evolved.fragment()
|
||||
---@type evolved.__fragment_builder
|
||||
local builder = {
|
||||
__tag = false,
|
||||
__default = nil,
|
||||
__construct = nil,
|
||||
}
|
||||
---@cast builder evolved.fragment_builder
|
||||
return setmetatable(builder, evolved_fragment_builder)
|
||||
end
|
||||
|
||||
---@return evolved.fragment_builder
|
||||
function evolved_fragment_builder:tag()
|
||||
self.__tag = true
|
||||
return self
|
||||
end
|
||||
|
||||
---@param default evolved.component
|
||||
---@return evolved.fragment_builder
|
||||
function evolved_fragment_builder:default(default)
|
||||
self.__default = default
|
||||
return self
|
||||
end
|
||||
|
||||
---@param construct fun(...): evolved.component
|
||||
---@return evolved.fragment_builder
|
||||
function evolved_fragment_builder:construct(construct)
|
||||
self.__construct = construct
|
||||
return self
|
||||
end
|
||||
|
||||
---@return evolved.fragment
|
||||
function evolved_fragment_builder:build()
|
||||
local tag = self.__tag
|
||||
local default = self.__default
|
||||
local construct = self.__construct
|
||||
|
||||
self.__tag = false
|
||||
self.__default = nil
|
||||
self.__construct = nil
|
||||
|
||||
local fragment = evolved.id()
|
||||
|
||||
if tag then
|
||||
evolved.set(fragment, evolved.TAG, tag)
|
||||
end
|
||||
|
||||
if default ~= nil then
|
||||
evolved.set(fragment, evolved.DEFAULT, default)
|
||||
end
|
||||
|
||||
if construct ~= nil then
|
||||
evolved.set(fragment, evolved.CONSTRUCT, construct)
|
||||
end
|
||||
|
||||
return fragment
|
||||
end
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
---@class (exact) evolved.__query_builder
|
||||
---@field package __include_list? evolved.fragment[]
|
||||
---@field package __exclude_list? evolved.fragment[]
|
||||
|
||||
---@class evolved.query_builder : evolved.__query_builder
|
||||
local evolved_query_builder = {}
|
||||
evolved_query_builder.__index = evolved_query_builder
|
||||
|
||||
---@return evolved.query_builder
|
||||
---@nodiscard
|
||||
function evolved.query()
|
||||
---@type evolved.__query_builder
|
||||
local builder = {
|
||||
__include_list = nil,
|
||||
__exclude_list = nil,
|
||||
}
|
||||
---@cast builder evolved.query_builder
|
||||
return setmetatable(builder, evolved_query_builder)
|
||||
end
|
||||
|
||||
---@param ... evolved.fragment fragments
|
||||
---@return evolved.query_builder
|
||||
function evolved_query_builder:include(...)
|
||||
local fragment_count = select('#', ...)
|
||||
|
||||
if fragment_count == 0 then
|
||||
return self
|
||||
end
|
||||
|
||||
local include_list = self.__include_list
|
||||
|
||||
if not include_list then
|
||||
include_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, 8, 0)
|
||||
self.__include_list = include_list
|
||||
end
|
||||
|
||||
local include_list_size = #include_list
|
||||
|
||||
for i = 1, fragment_count do
|
||||
local fragment = select(i, ...)
|
||||
include_list[include_list_size + 1] = fragment
|
||||
include_list_size = include_list_size + 1
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
---@param ... evolved.fragment fragments
|
||||
---@return evolved.query_builder
|
||||
function evolved_query_builder:exclude(...)
|
||||
local fragment_count = select('#', ...)
|
||||
|
||||
if fragment_count == 0 then
|
||||
return self
|
||||
end
|
||||
|
||||
local exclude_list = self.__exclude_list
|
||||
|
||||
if not exclude_list then
|
||||
exclude_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, 8, 0)
|
||||
self.__exclude_list = exclude_list
|
||||
end
|
||||
|
||||
local exclude_list_size = #exclude_list
|
||||
|
||||
for i = 1, fragment_count do
|
||||
local fragment = select(i, ...)
|
||||
exclude_list[exclude_list_size + 1] = fragment
|
||||
exclude_list_size = exclude_list_size + 1
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
---@return evolved.query
|
||||
function evolved_query_builder:build()
|
||||
local include_list = self.__include_list
|
||||
local exclude_list = self.__exclude_list
|
||||
|
||||
self.__include_list = nil
|
||||
self.__exclude_list = nil
|
||||
|
||||
local query = evolved.id()
|
||||
|
||||
if include_list then
|
||||
evolved.insert(query, evolved.INCLUDES, __table_unpack(include_list))
|
||||
__release_table(__TABLE_POOL_TAG__FRAGMENT_LIST, include_list)
|
||||
end
|
||||
|
||||
if exclude_list then
|
||||
evolved.insert(query, evolved.EXCLUDES, __table_unpack(exclude_list))
|
||||
__release_table(__TABLE_POOL_TAG__FRAGMENT_LIST, exclude_list)
|
||||
end
|
||||
|
||||
return query
|
||||
end
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
---
|
||||
|
||||
return evolved
|
||||
|
||||
Reference in New Issue
Block a user