mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-14 12:10:23 +07:00
first builders impl (without optimization yet)
This commit is contained in:
21
README.md
21
README.md
@@ -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)
|
||||
|
||||
@@ -2453,3 +2453,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
|
||||
|
||||
261
evolved.lua
261
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
|
||||
@@ -2756,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