Fix types

This commit is contained in:
Ukendio 2024-06-15 20:03:12 +02:00
parent c3d745a88b
commit 1344398ffe

View file

@ -252,7 +252,7 @@ local function moveEntity(entityIndex: EntityIndex, entityId: i53, record: Recor
record.row = destinationRow record.row = destinationRow
end end
local function hash(arr): string | number local function hash(arr): string
return table.concat(arr, "_") return table.concat(arr, "_")
end end
@ -262,10 +262,10 @@ local function ensureComponentRecord(
componentId: number, componentId: number,
i: number i: number
): ArchetypeMap ): ArchetypeMap
local archetypesMap = componentIndex[componentId] local archetypesMap = componentIndex[componentId]
if not archetypesMap then if not archetypesMap then
archetypesMap = { size = 0, cache = {} } archetypesMap = ({ size = 0, cache = {} } :: any) :: ArchetypeMap
componentIndex[componentId] = archetypesMap componentIndex[componentId] = archetypesMap
end end
@ -490,7 +490,7 @@ local function findArchetypeWith(world: World, node: Archetype, componentId: i53
-- them each time would be expensive. Instead this insertion sort can find the insertion -- them each time would be expensive. Instead this insertion sort can find the insertion
-- point in the types array. -- point in the types array.
local destinationType = table.clone(node.types) local destinationType = table.clone(node.types) :: { i53 }
local at = findInsert(types, componentId) local at = findInsert(types, componentId)
if at == -1 then if at == -1 then
-- If it finds a duplicate, it just means it is the same archetype so it can return it -- If it finds a duplicate, it just means it is the same archetype so it can return it
@ -575,7 +575,7 @@ local function archetypeTraverseRemove(world: World, componentId: i53, from: Arc
local remove = edge.remove local remove = edge.remove
if not remove then if not remove then
local to = table.clone(from.types) local to = table.clone(from.types) :: { i53 }
local at = table.find(to, componentId) local at = table.find(to, componentId)
if not at then if not at then
return from return from
@ -615,7 +615,7 @@ local function get(record: Record, componentId: i24)
return archetype.columns[archetypeRecord][record.row] return archetype.columns[archetypeRecord][record.row]
end end
function World.get(world: World, entityId: i53, a: i53, b: i53?, c: i53?, d: i53?, e: i53?) function World.get(world: World, entityId: i53, a: i53, b: i53?, c: i53?, d: i53?, e: i53?): any
local id = entityId local id = entityId
local record = world.entityIndex.sparse[id] local record = world.entityIndex.sparse[id]
if not record then if not record then
@ -658,14 +658,15 @@ function World.query(world: World, ...): Query
error("Missing components") error("Missing components")
end end
local compatibleArchetypes = {} type CompatibleArchetype = { archetype: Archetype, indices: { number } }
local compatibleArchetypes = {} :: { CompatibleArchetype }
local length = 0 local length = 0
local components = { ... } local components = { ... }
local archetypes = world.archetypes local archetypes = world.archetypes
local queryLength = #components local queryLength = #components
local firstArchetypeMap local firstArchetypeMap: ArchetypeMap
local componentIndex = world.componentIndex local componentIndex = world.componentIndex
for _, componentId in components do for _, componentId in components do
@ -707,7 +708,8 @@ function World.query(world: World, ...): Query
} }
end end
local lastArchetype, compatibleArchetype = next(compatibleArchetypes) local lastArchetype, compatibleArchetype: CompatibleArchetype = next(compatibleArchetypes :: any)
if not lastArchetype then if not lastArchetype then
return EmptyQuery return EmptyQuery
end end
@ -715,51 +717,24 @@ function World.query(world: World, ...): Query
local preparedQuery = {} local preparedQuery = {}
preparedQuery.__index = preparedQuery preparedQuery.__index = preparedQuery
function preparedQuery:without(...)
local withoutComponents = { ... }
for i = #compatibleArchetypes, 1, -1 do
local archetype = compatibleArchetypes[i].archetype
local records = archetype.records
local shouldRemove = false
for _, componentId in withoutComponents do
if records[componentId] then
shouldRemove = true
break
end
end
if shouldRemove then
table.remove(compatibleArchetypes, i)
end
end
lastArchetype, compatibleArchetype = next(compatibleArchetypes)
if not lastArchetype then
return EmptyQuery
end
return self
end
local lastRow local lastRow
local queryOutput = {} local queryOutput = {}
function preparedQuery:__iter() function preparedQuery:__iter()
return function() return function()
local archetype = compatibleArchetype.archetype local archetype = compatibleArchetype.archetype
local row: number = next(archetype.entities, lastRow) :: number local row: number = next(archetype.entities, lastRow)
while row == nil do while row == nil do
lastArchetype, compatibleArchetype = next(compatibleArchetypes, lastArchetype) lastArchetype, compatibleArchetype = next(compatibleArchetypes, lastArchetype)
if lastArchetype == nil then if lastArchetype == nil then
return return
end end
archetype = compatibleArchetype.archetype archetype = compatibleArchetype.archetype
row = next(archetype.entities, row) :: number row = next(archetype.entities, row)
end end
lastRow = row lastRow = row
local entityId = archetype.entities[row :: number] local entityId = archetype.entities[row]
local columns = archetype.columns local columns = archetype.columns
local tr = compatibleArchetype.indices local tr = compatibleArchetype.indices
@ -811,22 +786,49 @@ function World.query(world: World, ...): Query
queryOutput[i] = columns[tr[i]][row] queryOutput[i] = columns[tr[i]][row]
end end
return entityId, unpack(queryOutput, 1, queryLength) return entityId, unpack(queryOutput :: any, 1, queryLength)
end end
end end
function preparedQuery:without(...)
local withoutComponents = { ... }
for i = #compatibleArchetypes, 1, -1 do
local archetype = compatibleArchetypes[i].archetype
local records = archetype.records
local shouldRemove = false
for _, componentId in withoutComponents do
if records[componentId] then
shouldRemove = true
break
end
end
if shouldRemove then
table.remove(compatibleArchetypes, i)
end
end
lastArchetype, compatibleArchetype = next(compatibleArchetypes :: any)
if not lastArchetype then
return EmptyQuery
end
return self
end
return setmetatable({}, preparedQuery) :: any return setmetatable({}, preparedQuery) :: any
end end
function World.__iter(world: World): () -> (number?, unknown?) function World.__iter(world: World): () -> any
local dense = world.entityIndex.dense local dense = world.entityIndex.dense
local sparse = world.entityIndex.sparse local sparse = world.entityIndex.sparse
local last local last
return function() return function()
local lastEntity, entityId = next(dense, last) local lastEntity: number?, entityId: number = next(dense, last)
if not lastEntity then if not lastEntity then
return return
end end
last = lastEntity last = lastEntity