diff --git a/README.md b/README.md index 18eebe4..25682e5 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,8 @@ registry.is_alive -> entity -> (boolean) registry.destroy -> entity -> () registry.del -> entity -> entity... -> (entity) registry.set -> entity -> entity -> any -> (entity) -registry.get -> entity -> entity -> any -> (any) +registry.get -> entity -> entity... -> (any...) +registry.get_or -> entity -> entity -> any -> (any) registry.has -> entity -> entity -> (boolean) registry.has_all -> entity -> entity... -> (boolean) registry.has_any -> entity -> entity... -> (boolean) @@ -55,7 +56,8 @@ entity:is_alive -> (boolean) entity:destroy -> () entity:del -> entity... -> (entity) entity:set -> entity -> any -> (entity) -entity:get -> entity -> any -> (any) +entity:get -> entity... -> (any...) +entity:get_or -> entity -> any -> (any) entity:has -> entity -> (boolean) entity:has_all -> entity... -> (boolean) entity:has_any -> entity... -> (boolean) diff --git a/develop/untests/registry_untests.lua b/develop/untests/registry_untests.lua index 8190af5..bbcd65a 100644 --- a/develop/untests/registry_untests.lua +++ b/develop/untests/registry_untests.lua @@ -40,12 +40,76 @@ do local e = evo.registry.entity() assert(e == e:set(f1):set(f2):set(f3)) assert(e:has_all(f1, f2, f3)) - assert(e == e:del(f1)) + assert(e == e:del():del(f1)) assert(not e:has(f1) and e:has_all(f2, f3)) assert(e == e:del(f2, f3, f3)) assert(not e:has_any(f1, f2, f3)) 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 == e:set(f1, 1):set(f2, 2)) + + do + assert(nil == e:get()) + + local c1 = e:get(f1) + assert(c1 == 1) + + local c3 = e:get(f3) + assert(c3 == nil) + + local c4, c5 = e:get(f4, f5) + assert(c4 == nil and c5 == nil) + end + + do + local c1, c2 = e:get(f1, f2) + assert(c1 == 1 and c2 == 2) + end + + do + local c2, c1 = e:get(f2, f1) + assert(c1 == 1 and c2 == 2) + end + + do + local c3, c4, c1, c2 = e:get(f3, f4, f1, f2) + assert(c1 == 1 and c2 == 2 and c3 == nil and c4 == nil) + end + + assert(e == e:set(f3, 3):set(f4, 4)) + + do + local c4, c3, c2 = e:get(f4, f3, f2) + assert(c2 == 2 and c3 == 3 and c4 == 4) + end + + do + local c1, c2, c3, c4 = e:get(f1, f2, f3, f4) + assert(c1 == 1 and c2 == 2 and c3 == 3 and c4 == 4) + end + + do + local c5, c1, c2, c3, c4 = e:get(f5, f1, f2, f3, f4) + assert(c1 == 1 and c2 == 2 and c3 == 3 and c4 == 4 and c5 == nil) + end + + assert(e == e:set(f5, false)) + + do + local c5, c1, c2, c3, c4 = e:get(f5, f1, f2, f3, f4) + assert(c1 == 1 and c2 == 2 and c3 == 3 and c4 == 4 and c5 == false) + end +end + do local f1, f2 = evo.registry.entity(), @@ -94,28 +158,28 @@ do assert(not e:assign(f, 42)) assert(not e:has(f)) - assert(e:get(f) == nil) - assert(e:get(f, 42) == 42) + assert(e:get_or(f) == nil) + assert(e:get_or(f, 42) == 42) assert(e:insert(f, 84)) assert(e:has(f)) - assert(e:get(f) == 84) - assert(e:get(f, 42) == 84) + assert(e:get_or(f) == 84) + assert(e:get_or(f, 42) == 84) assert(not e:insert(f, 21)) assert(e:has(f)) - assert(e:get(f) == 84) - assert(e:get(f, 42) == 84) + assert(e:get_or(f) == 84) + assert(e:get_or(f, 42) == 84) assert(e:assign(f)) assert(e:has(f)) - assert(e:get(f) == true) - assert(e:get(f, 42) == true) + assert(e:get_or(f) == true) + assert(e:get_or(f, 42) == true) assert(e:assign(f, 21)) assert(e:has(f)) - assert(e:get(f) == 21) - assert(e:get(f, 42) == 21) + assert(e:get_or(f) == 21) + assert(e:get_or(f, 42) == 21) end do @@ -125,26 +189,26 @@ do local e = evo.registry.entity() assert(e == e:set(f, 42)) - assert(e:get(f) == 42) + assert(e:get_or(f) == 42) assert(e == e:set(f, 21)) - assert(e:get(f) == 21) + assert(e:get_or(f) == 21) end do local e = evo.registry.entity() assert(not e:assign(f, 42)) - assert(e:get(f) == nil) + assert(e:get_or(f) == nil) assert(e:insert(f, 42)) - assert(e:get(f) == 42) + assert(e:get_or(f) == 42) assert(e:assign(f, 21)) - assert(e:get(f) == 21) + assert(e:get_or(f) == 21) assert(not e:insert(f, 42)) - assert(e:get(f) == 21) + assert(e:get_or(f) == 21) end end @@ -305,8 +369,8 @@ for _ = 1, 100 do if e1.__chunk ~= nil then for f, _ in pairs(e1.__chunk.__components) do - assert(e1:get(f) == f.__guid) - assert(e2:get(f) == f.__guid) + assert(e1:get_or(f) == f.__guid) + assert(e2:get_or(f) == f.__guid) end end end diff --git a/evolved/registry.lua b/evolved/registry.lua index 844a7bb..5e3d148 100644 --- a/evolved/registry.lua +++ b/evolved/registry.lua @@ -345,19 +345,58 @@ function registry.set(entity, fragment, component) return entity end +---@param entity evolved.entity +---@param ... evolved.entity fragments +---@return any ... components +---@nodiscard +function registry.get(entity, ...) + local components = entity.__chunk and entity.__chunk.__components + if components == nil then return end + + local fragment_count = select('#', ...) + if fragment_count == 0 then return end + + local index_in_chunk = entity.__index_in_chunk + + if fragment_count == 1 then + local f1 = ... + local cs1 = components[f1] + return cs1 and cs1[index_in_chunk] + end + + if fragment_count == 2 then + local f1, f2 = ... + local cs1, cs2 = components[f1], components[f2] + return cs1 and cs1[index_in_chunk], cs2 and cs2[index_in_chunk] + end + + if fragment_count == 3 then + local f1, f2, f3 = ... + local cs1, cs2, cs3 = components[f1], components[f2], components[f3] + return cs1 and cs1[index_in_chunk], cs2 and cs2[index_in_chunk], cs3 and cs3[index_in_chunk] + end + + do + local f1, f2, f3 = ... + local cs1, cs2, cs3 = components[f1], components[f2], components[f3] + return cs1 and cs1[index_in_chunk], cs2 and cs2[index_in_chunk], cs3 and cs3[index_in_chunk], + registry.get(entity, select(4, ...)) + end +end + ---@param entity evolved.entity ---@param fragment evolved.entity ---@param default any ---@return any ---@nodiscard -function registry.get(entity, fragment, default) - local chunk_components = entity.__chunk and entity.__chunk.__components[fragment] +function registry.get_or(entity, fragment, default) + local components = entity.__chunk and entity.__chunk.__components[fragment] - if chunk_components == nil then + if components == nil then return default end - return chunk_components[entity.__index_in_chunk] + return components[entity.__index_in_chunk] end ---@param entity evolved.entity @@ -402,8 +441,8 @@ function registry.assign(entity, fragment, component) local new_chunk = __chunk_with_fragment(old_chunk, fragment) if old_chunk == new_chunk then - local chunk_components = new_chunk.__components[fragment] - chunk_components[entity.__index_in_chunk] = component + local components = new_chunk.__components[fragment] + components[entity.__index_in_chunk] = component return true end @@ -680,6 +719,7 @@ evolved_entity_mt.destroy = registry.destroy evolved_entity_mt.del = registry.del evolved_entity_mt.set = registry.set evolved_entity_mt.get = registry.get +evolved_entity_mt.get_or = registry.get_or evolved_entity_mt.has = registry.has evolved_entity_mt.has_all = registry.has_all evolved_entity_mt.has_any = registry.has_any