diff --git a/benches/visual/query.bench.lua b/benches/visual/query.bench.lua index 57eddaa..3d00783 100644 --- a/benches/visual/query.bench.lua +++ b/benches/visual/query.bench.lua @@ -7,7 +7,7 @@ local Matter = require(ReplicatedStorage.DevPackages["_Index"]["matter-ecs_matte local ecr = require(ReplicatedStorage.DevPackages["_Index"]["centau_ecr@0.8.0"].ecr) local newWorld = Matter.World.new() -local jecs = require(ReplicatedStorage.Shim) +local jecs = require(ReplicatedStorage.Lib) local mirror = require(ReplicatedStorage.mirror) local mcs = mirror.World.new() local ecs = jecs.World.new() diff --git a/lib/init.lua b/lib/init.lua index cfde17f..9cf8926 100644 --- a/lib/init.lua +++ b/lib/init.lua @@ -654,63 +654,13 @@ export type Query = typeof(EmptyQuery) type CompatibleArchetype = { archetype: Archetype, indices: { number } } -function World.query(world: World, ...): Query - -- breaking? - if (...) == nil then - error("Missing components") - end +local function PreparedQuery( + compatibleArchetypes: { CompatibleArchetype } , components: { i53 }) - local compatibleArchetypes: { CompatibleArchetype } = {} - local length = 0 - - local components = { ... } - local archetypes = world.archetypes local queryLength = #components - - local firstArchetypeMap: ArchetypeMap - local componentIndex = world.componentIndex - - for _, componentId in components do - local map = componentIndex[componentId] - if not map then - return EmptyQuery - end - - if firstArchetypeMap == nil or map.size < firstArchetypeMap.size then - firstArchetypeMap = map - end - end - - for id in firstArchetypeMap.cache do - local archetype = archetypes[id] - local archetypeRecords = archetype.records - - local indices = {} - local skip = false - - for i, componentId in components do - local index = archetypeRecords[componentId] - if not index then - skip = true - break - end - -- index should be index.offset - indices[i] = index - end - - if skip then - continue - end - - length += 1 - compatibleArchetypes[length] = { - archetype = archetype, - indices = indices, - } - end - + local lastArchetype = 1 - local compatibleArchetype: CompatibleArchetype = compatibleArchetypes[lastArchetype] + local compatibleArchetype: CompatibleArchetype = compatibleArchetypes[lastArchetype] if not compatibleArchetype then return EmptyQuery @@ -792,7 +742,7 @@ function World.query(world: World, ...): Query queryOutput[i] = columns[tr[i]][row] end - return entityId, unpack(queryOutput :: any, 1, queryLength) + return entityId, unpack(queryOutput, 1, queryLength) end function preparedQuery:__iter() @@ -822,7 +772,7 @@ function World.query(world: World, ...): Query end end - lastArchetype, compatibleArchetype = next(compatibleArchetypes :: any) + lastArchetype, compatibleArchetype = next(compatibleArchetypes) if not lastArchetype then return EmptyQuery end @@ -833,6 +783,63 @@ function World.query(world: World, ...): Query return setmetatable({}, preparedQuery) :: any end +function World.query(world: World, ...): Query + -- breaking? + if (...) == nil then + error("Missing components") + end + + local compatibleArchetypes: { CompatibleArchetype } = {} + local length = 0 + + local components = { ... } :: any + local archetypes = world.archetypes + + local firstArchetypeMap: ArchetypeMap + local componentIndex = world.componentIndex + + for _, componentId in components do + local map = componentIndex[componentId] + if not map then + return EmptyQuery + end + + if firstArchetypeMap == nil or map.size < firstArchetypeMap.size then + firstArchetypeMap = map + end + end + + for id in firstArchetypeMap.cache do + local archetype = archetypes[id] + local archetypeRecords = archetype.records + + local indices = {} + local skip = false + + for i, componentId in components do + local index = archetypeRecords[componentId] + if not index then + skip = true + break + end + -- index should be index.offset + indices[i] = index + end + + if skip then + continue + end + + length += 1 + compatibleArchetypes[length] = { + archetype = archetype, + indices = indices, + } + end + + return PreparedQuery(compatibleArchetypes, components) +end + function World.__iter(world: World): () -> any local dense = world.entityIndex.dense local sparse = world.entityIndex.sparse