mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-13 19:48:00 +07:00
multi fragments removing
This commit is contained in:
@@ -34,8 +34,8 @@ registry.has -> entity -> entity -> (boolean)
|
||||
registry.has_all -> entity -> entity... -> (boolean)
|
||||
registry.has_any -> entity -> entity... -> (boolean)
|
||||
registry.assign -> entity -> entity -> any -> ()
|
||||
registry.insert -> entity -> entity -> any -> ()
|
||||
registry.remove -> entity -> entity -> ()
|
||||
registry.insert -> entity -> entity -> any -> (boolean)
|
||||
registry.remove -> entity -> entity... -> (boolean)
|
||||
registry.query -> entity -> entity... -> (query)
|
||||
registry.execute -> query -> (() -> (chunk?))
|
||||
registry.chunk -> entity -> entity... -> (chunk)
|
||||
@@ -55,8 +55,8 @@ entity:has -> entity -> (boolean)
|
||||
entity:has_all -> entity... -> (boolean)
|
||||
entity:has_any -> entity... -> (boolean)
|
||||
entity:assign -> entity -> any -> ()
|
||||
entity:insert -> entity -> any -> ()
|
||||
entity:remove -> entity -> ()
|
||||
entity:insert -> entity -> any -> (boolean)
|
||||
entity:remove -> entity... -> (boolean)
|
||||
```
|
||||
|
||||
### Instance `query`
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
- [ ] add blocklist of fragments for queries
|
||||
- [ ] add checks of prohibited changes while querying
|
||||
- [ ] add check inserts and removes after destroying entity
|
||||
- [ ] add multi remove fragments function from entities
|
||||
- [x] add multi remove fragments function from entities
|
||||
- [ ] add multi get fragments function from entities
|
||||
- [ ] add multi entity creation function
|
||||
- [ ] cache matched chunks in queries
|
||||
- [x] cache transitions between chunks
|
||||
- [x] chunk's children should be stored in an array instead of a table
|
||||
@@ -2,26 +2,53 @@
|
||||
local evo = require 'evolved.evolved'
|
||||
|
||||
do
|
||||
local f1, f2 = evo.registry.entity(), evo.registry.entity()
|
||||
local f1, f2, f3 =
|
||||
evo.registry.entity(),
|
||||
evo.registry.entity(),
|
||||
evo.registry.entity()
|
||||
|
||||
local e = evo.registry.entity()
|
||||
assert(e.__chunk == nil)
|
||||
|
||||
e:insert(f1)
|
||||
assert(e:insert(f1))
|
||||
assert(e:has(f1))
|
||||
assert(not e:has(f2))
|
||||
|
||||
e:insert(f2)
|
||||
assert(e:insert(f2))
|
||||
assert(e:has(f1))
|
||||
assert(e:has(f2))
|
||||
|
||||
e:remove(f1)
|
||||
assert(e:remove(f1))
|
||||
assert(not e:has(f1))
|
||||
assert(e:has(f2))
|
||||
|
||||
e:remove(f2)
|
||||
assert(e:remove(f2))
|
||||
assert(not e:has(f1))
|
||||
assert(not e:has(f2))
|
||||
|
||||
assert(e:insert(f3))
|
||||
assert(not e:remove(f2))
|
||||
assert(not e:remove())
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4, f5 =
|
||||
evo.registry.entity(),
|
||||
evo.registry.entity(),
|
||||
evo.registry.entity(),
|
||||
evo.registry.entity(),
|
||||
evo.registry.entity()
|
||||
|
||||
local e = evo.registry.entity()
|
||||
|
||||
assert(e:insert(f1, f1:guid()))
|
||||
assert(e:insert(f2, f2:guid()))
|
||||
assert(e:insert(f3, f3:guid()))
|
||||
assert(e:insert(f4, f4:guid()))
|
||||
|
||||
assert(e:remove(f1, f2, f5))
|
||||
|
||||
assert(e.__chunk == evo.registry.chunk(f3, f4))
|
||||
end
|
||||
|
||||
do
|
||||
@@ -36,15 +63,14 @@ do
|
||||
assert(e:get_or(f) == nil)
|
||||
assert(e:get_or(f, 42) == 42)
|
||||
|
||||
e:insert(f, 84)
|
||||
assert(e:insert(f, 84))
|
||||
|
||||
assert(e:get(f) == 84)
|
||||
assert(e:get_or(f) == 84)
|
||||
assert(e:get_or(f, 42) == 84)
|
||||
|
||||
if not os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") then
|
||||
assert(not pcall(e.insert, e, f, 42))
|
||||
end
|
||||
assert(not e:insert(f, 42))
|
||||
assert(e:get(f) == 42)
|
||||
|
||||
e:assign(f)
|
||||
assert(e:get(f) == true)
|
||||
@@ -102,7 +128,7 @@ end
|
||||
|
||||
for _ = 1, 100 do
|
||||
local insert_fragments = {} ---@type evolved.entity[]
|
||||
local insert_fragment_count = math.random(1, 10)
|
||||
local insert_fragment_count = math.random(0, 10)
|
||||
|
||||
for _ = 1, insert_fragment_count do
|
||||
local fragment = evo.registry.entity()
|
||||
@@ -110,7 +136,7 @@ for _ = 1, 100 do
|
||||
end
|
||||
|
||||
local remove_fragments = {} ---@type evolved.entity[]
|
||||
local remove_fragment_count = math.random(1, insert_fragment_count)
|
||||
local remove_fragment_count = math.random(0, insert_fragment_count)
|
||||
|
||||
for _ = 1, remove_fragment_count do
|
||||
local fragment = insert_fragments[math.random(1, #insert_fragments)]
|
||||
|
||||
@@ -334,7 +334,8 @@ end
|
||||
---@return boolean
|
||||
---@nodiscard
|
||||
function registry.has(entity, fragment)
|
||||
return entity.__chunk ~= nil and __chunk_has_fragment(entity.__chunk, fragment)
|
||||
if entity.__chunk == nil then return false end
|
||||
return __chunk_has_fragment(entity.__chunk, fragment)
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
@@ -373,6 +374,7 @@ end
|
||||
---@param entity evolved.entity
|
||||
---@param fragment evolved.entity
|
||||
---@param component any
|
||||
---@return boolean is_inserted
|
||||
function registry.insert(entity, fragment, component)
|
||||
component = component == nil and true or component
|
||||
|
||||
@@ -380,62 +382,71 @@ function registry.insert(entity, fragment, component)
|
||||
local new_chunk = __chunk_with_fragment(old_chunk, fragment)
|
||||
|
||||
if old_chunk == new_chunk then
|
||||
error(string.format('entity %s already has fragment %s', entity, fragment), 2)
|
||||
local chunk_components = new_chunk.__components[fragment]
|
||||
chunk_components[entity.__index_in_chunk] = component
|
||||
return false
|
||||
end
|
||||
|
||||
local old_index_in_chunk = entity.__index_in_chunk
|
||||
local new_index_in_chunk = new_chunk and #new_chunk.__entities + 1 or 0
|
||||
local new_index_in_chunk = #new_chunk.__entities + 1
|
||||
|
||||
if new_chunk ~= nil then
|
||||
new_chunk.__entities[new_index_in_chunk] = entity
|
||||
new_chunk.__components[fragment][new_index_in_chunk] = component
|
||||
|
||||
if old_chunk ~= nil then
|
||||
for old_f, old_cs in pairs(old_chunk.__components) do
|
||||
local new_cs = new_chunk.__components[old_f]
|
||||
new_cs[new_index_in_chunk] = old_cs[old_index_in_chunk]
|
||||
end
|
||||
end
|
||||
end
|
||||
new_chunk.__entities[new_index_in_chunk] = entity
|
||||
new_chunk.__components[fragment][new_index_in_chunk] = component
|
||||
|
||||
if old_chunk ~= nil then
|
||||
for old_f, old_cs in pairs(old_chunk.__components) do
|
||||
local new_cs = new_chunk.__components[old_f]
|
||||
new_cs[new_index_in_chunk] = old_cs[old_index_in_chunk]
|
||||
end
|
||||
|
||||
__detach_entity(entity)
|
||||
end
|
||||
|
||||
entity.__chunk = new_chunk
|
||||
entity.__index_in_chunk = new_index_in_chunk
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param fragment evolved.entity
|
||||
function registry.remove(entity, fragment)
|
||||
---@param ... evolved.entity fragments
|
||||
---@return boolean is_removed
|
||||
function registry.remove(entity, ...)
|
||||
local old_chunk = entity.__chunk
|
||||
local new_chunk = __chunk_without_fragment(old_chunk, fragment)
|
||||
local new_chunk = entity.__chunk
|
||||
|
||||
for i = 1, select('#', ...) do
|
||||
local fragment = select(i, ...)
|
||||
new_chunk = __chunk_without_fragment(new_chunk, fragment)
|
||||
end
|
||||
|
||||
if old_chunk == new_chunk then
|
||||
error(string.format('entity %s does not have fragment %s', entity, fragment), 2)
|
||||
return false
|
||||
end
|
||||
|
||||
if new_chunk == nil then
|
||||
__detach_entity(entity)
|
||||
return true
|
||||
end
|
||||
|
||||
local old_index_in_chunk = entity.__index_in_chunk
|
||||
local new_index_in_chunk = new_chunk and #new_chunk.__entities + 1 or 0
|
||||
local new_index_in_chunk = #new_chunk.__entities + 1
|
||||
|
||||
if new_chunk ~= nil then
|
||||
new_chunk.__entities[new_index_in_chunk] = entity
|
||||
|
||||
if old_chunk ~= nil then
|
||||
for new_f, new_cs in pairs(new_chunk.__components) do
|
||||
local old_cs = old_chunk.__components[new_f]
|
||||
new_cs[new_index_in_chunk] = old_cs[old_index_in_chunk]
|
||||
end
|
||||
end
|
||||
end
|
||||
new_chunk.__entities[new_index_in_chunk] = entity
|
||||
|
||||
if old_chunk ~= nil then
|
||||
for new_f, new_cs in pairs(new_chunk.__components) do
|
||||
local old_cs = old_chunk.__components[new_f]
|
||||
new_cs[new_index_in_chunk] = old_cs[old_index_in_chunk]
|
||||
end
|
||||
|
||||
__detach_entity(entity)
|
||||
end
|
||||
|
||||
entity.__chunk = new_chunk
|
||||
entity.__index_in_chunk = new_index_in_chunk
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
---@param fragment evolved.entity
|
||||
|
||||
Reference in New Issue
Block a user