From 3175d5e94c8e51baf39f076c1379df7523ade2f7 Mon Sep 17 00:00:00 2001 From: Ukendio Date: Sun, 11 Aug 2024 15:03:05 +0200 Subject: [PATCH] Add back multret ;C --- src/init.luau | 77 ++++++++++++++++++++++++++++++++++++++++++++++--- test/tests.luau | 16 ++++++++++ 2 files changed, 89 insertions(+), 4 deletions(-) diff --git a/src/init.luau b/src/init.luau index bbed609..645dc9f 100644 --- a/src/init.luau +++ b/src/init.luau @@ -364,7 +364,55 @@ local function world_parent(world: World, entity: i53) return world_target(world, entity, EcsChildOf) end -local function world_get(world: World, entity: i53, id: i53) +local world_get: (world: World, entityId: i53, a: i53, b: i53?, c: i53?, d: i53?, e: i53?) -> (...any) +do + -- Keeping the function as small as possible to enable inlining + local records + local columns + local row + + local function fetch(id) + local tr = records[id] + + if not tr then + return nil + end + + return columns[tr.column][row] + end + + function world_get(world: World, entity: i53, a: i53, b: i53?, c: i53?, d: i53?, e: i53?): ...any + local record = world.entityIndex.sparse[entity] + if not record then + return nil + end + + local archetype = record.archetype + if not archetype then + return nil + end + + records = archetype.records + columns = archetype.columns + row = record.row + + local va = fetch(a) + + if not b then + return va + elseif not c then + return va, fetch(b) + elseif not d then + return va, fetch(b), fetch(c) + elseif not e then + return va, fetch(b), fetch(c), fetch(d) + else + error("args exceeded") + end + end +end + +local function world_get_one_inline(world: World, entity: i53, id: i53) local record = world.entityIndex.sparse[entity] if not record then return nil @@ -379,11 +427,10 @@ local function world_get(world: World, entity: i53, id: i53) if not tr then return nil end - return archetype.columns[tr.column][record.row] end -local function world_has(world: World, entity: i53, id: i53): boolean +local function world_has_one_inline(world: World, entity: i53, id: i53): boolean local record = world.entityIndex.sparse[entity] if not record then return false @@ -397,6 +444,28 @@ local function world_has(world: World, entity: i53, id: i53): boolean return archetype.records[id] ~= nil end +local function world_has(world: World, entity: number, ...: i53): boolean + local record = world.entityIndex.sparse[entity] + if not record then + return false + end + + local archetype = record.archetype + if not archetype then + return false + end + + local records = archetype.records + + for i = 1, select("#", ...) do + if not records[select(i, ...)] then + return false + end + end + + return true +end + local function archetype_ensure(world: World, types, prev): Archetype if #types < 1 then return world.ROOT_ARCHETYPE @@ -467,7 +536,7 @@ local function archetype_traverse_add(world: World, id: i53, from: Archetype): A end local function invoke_hook(world: World, hook_id: number, id: i53, entity: i53, data: any?) - local hook = world_get(world, id, hook_id) + local hook = world_get_one_inline(world, id, hook_id) if hook then hook(entity, data) end diff --git a/test/tests.luau b/test/tests.luau index 9575b10..40672af 100644 --- a/test/tests.luau +++ b/test/tests.luau @@ -698,6 +698,22 @@ TEST("world:has()", function() CHECK(world:has(e, Tag)) end + + do CASE "should return false when missing one tag" + local world = jecs.World.new() + + local A = world:component() + local B = world:component() + local C = world:component() + local D = world:component() + + local e = world:entity() + world:add(e, A) + world:add(e, C) + world:add(e, D) + + CHECK(world:has(e, A, B, C, D) == false) + end end) TEST("world:component()", function()