Fix types for iter

This commit is contained in:
Ukendio 2024-08-12 22:43:46 +02:00
parent d4d5af1211
commit 0b9d9530b9

View file

@ -177,55 +177,56 @@ local function entity_index_new_id(entityIndex: EntityIndex, index: i24): i53
return id return id
end end
local function archetype_move(entityIndex: EntityIndex, to: Archetype, local function archetype_move(entity_index: EntityIndex, to: Archetype,
destinationRow: i24, from: Archetype, sourceRow: i24) dst_row: i24, from: Archetype, src_row: i24)
local columns = from.columns local src_columns = from.columns
local sourceEntities = from.entities local dst_columns = to.columns
local destinationEntities = to.entities local dst_entities = to.entities
local destinationColumns = to.columns local src_entities = from.entities
local records = to.records
local last = #src_entities
local types = from.types local types = from.types
local last = #sourceEntities local records = to.records
for i, column in columns do for i, column in src_columns do
-- Retrieves the new column index from the source archetype's record from each component -- Retrieves the new column index from the source archetype's record from each component
-- We have to do this because the columns are tightly packed and indexes may not correspond to each other. -- We have to do this because the columns are tightly packed and indexes may not correspond to each other.
local tr = records[types[i]] local tr = records[types[i]]
-- Sometimes target column may not exist, e.g. when you remove a component. -- Sometimes target column may not exist, e.g. when you remove a component.
if tr then if tr then
destinationColumns[tr.column][destinationRow] = column[sourceRow] dst_columns[tr.column][dst_row] = column[src_row]
end end
-- If the entity is the last row in the archetype then swapping it would be meaningless. -- If the entity is the last row in the archetype then swapping it would be meaningless.
if sourceRow ~= last then if src_row ~= last then
-- Swap rempves columns to ensure there are no holes in the archetype. -- Swap rempves columns to ensure there are no holes in the archetype.
column[sourceRow] = column[last] column[src_row] = column[last]
end end
column[last] = nil column[last] = nil
end end
local sparse = entityIndex.sparse local sparse = entity_index.sparse
local movedAway = #sourceEntities local moved = #src_entities
-- Move the entity from the source to the destination archetype. -- Move the entity from the source to the destination archetype.
-- Because we have swapped columns we now have to update the records -- Because we have swapped columns we now have to update the records
-- corresponding to the entities' rows that were swapped. -- corresponding to the entities' rows that were swapped.
local e1 = sourceEntities[sourceRow] local e1 = src_entities[src_row]
local e2 = sourceEntities[movedAway] local e2 = src_entities[moved]
if sourceRow ~= movedAway then if src_row ~= moved then
sourceEntities[sourceRow] = e2 src_entities[src_row] = e2
end end
sourceEntities[movedAway] = nil :: any src_entities[moved] = nil :: any
destinationEntities[destinationRow] = e1 dst_entities[dst_row] = e1
local record1 = sparse[e1] local record1 = sparse[e1]
local record2 = sparse[e2] local record2 = sparse[e2]
record1.row = destinationRow record1.row = dst_row
record2.row = sourceRow record2.row = src_row
end end
local function archetype_append(entity: number, archetype: Archetype): number local function archetype_append(entity: number, archetype: Archetype): number
@ -259,14 +260,14 @@ local function id_record_ensure(
componentIndex: ComponentIndex, componentIndex: ComponentIndex,
componentId: number componentId: number
): ArchetypeMap ): ArchetypeMap
local archetypesMap = componentIndex[componentId] local idr = componentIndex[componentId]
if not archetypesMap then if not idr then
archetypesMap = ({ size = 0, cache = {} } :: any) :: ArchetypeMap idr = ({ size = 0, cache = {} } :: any) :: ArchetypeMap
componentIndex[componentId] = archetypesMap componentIndex[componentId] = idr
end end
return archetypesMap return idr
end end
local function ECS_ID_IS_WILDCARD(e: i53): boolean local function ECS_ID_IS_WILDCARD(e: i53): boolean
@ -725,13 +726,13 @@ end
type CompatibleArchetype = { archetype: Archetype, indices: { number } } type CompatibleArchetype = { archetype: Archetype, indices: { number } }
local noop: Item = function() local function noop()
return nil :: any
end end
local Arm = function(self, ...) local function Arm(query, ...)
return self return query
end end
local world_query local world_query
do do
local empty_list = {} local empty_list = {}
@ -1275,7 +1276,7 @@ type Item = () -> (number, ...any)
export type Entity<T = nil> = number & {__DO_NOT_USE_OR_YOU_WILL_BE_FIRED: T } export type Entity<T = nil> = number & {__DO_NOT_USE_OR_YOU_WILL_BE_FIRED: T }
type Iter<T...> = () -> () -> (Entity, T...) type Iter<T...> = (query: Query<T...>) -> () -> (Entity, T...)
type Query<T...> = typeof(setmetatable({}, { type Query<T...> = typeof(setmetatable({}, {
__iter = (nil :: any) :: Iter<T...> __iter = (nil :: any) :: Iter<T...>
@ -1298,18 +1299,21 @@ export type World = {
nextEntityId: number, nextEntityId: number,
ROOT_ARCHETYPE: Archetype, ROOT_ARCHETYPE: Archetype,
} & { } & {
target: (world: World, entity: Entity, relation: Entity) -> Entity, target: (World, entity: Entity, relation: Entity) -> Entity,
parent: (world: World, entity: Entity) -> Entity, parent: (World, entity: Entity) -> Entity,
entity: (world: World) -> Entity, entity: (World) -> Entity,
clear: (world: World, entity: Entity) -> (), clear: (World, entity: Entity) -> (),
delete: (world: World, entity: Entity) -> (), delete: (World, entity: Entity) -> (),
component: <T>(world: World) -> Entity<T>, component: <T>(World) -> Entity<T>,
get: <T>(world: World, entity: Entity, id: Entity<T>) -> T, get: (<T>(World, entity: Entity, id: Entity<T>) -> T)
has: (world: World, entity: Entity, id: Entity) -> boolean, & (<A, B>(World, id: Entity, Entity<A>, Entity<B>) -> (A, B))
add: (world: World, entity: Entity, id: Entity) -> (), & (<A, B, C>(World, id: Entity, Entity<A>, Entity<B>, Entity<C>) -> (A, B, C))
set: <T>(world: World, entity: Entity, & <A, B, C, D>(World, id: Entity, Entity<A>, Entity<B>, Entity<C>, Entity<D>) -> (A, B, C, D),
has: (World, entity: Entity, ...Entity) -> boolean,
add: (World, entity: Entity, id: Entity) -> (),
set: <T>(World, entity: Entity,
id: Entity<T>, data: T) -> (), id: Entity<T>, data: T) -> (),
remove: (world: World, entity: Entity, id: Entity) -> (), remove: (World, entity: Entity, id: Entity) -> (),
query: query:
(<A>(World, Entity<A>) -> Query<A>) (<A>(World, Entity<A>) -> Query<A>)
& (<A, B>(World, Entity<A>, Entity<B>) -> Query<A, B>) & (<A, B>(World, Entity<A>, Entity<B>) -> Query<A, B>)
@ -1327,7 +1331,7 @@ export type World = {
} }
return { return {
World = World , World = World :: { new: () -> World },
OnAdd = EcsOnAdd :: Entity, OnAdd = EcsOnAdd :: Entity,
OnRemove = EcsOnRemove :: Entity, OnRemove = EcsOnRemove :: Entity,
@ -1344,6 +1348,7 @@ return {
ECS_ID = ECS_ENTITY_T_LO, ECS_ID = ECS_ENTITY_T_LO,
ECS_GENERATION_INC = ECS_GENERATION_INC, ECS_GENERATION_INC = ECS_GENERATION_INC,
ECS_GENERATION = ECS_GENERATION, ECS_GENERATION = ECS_GENERATION,
ECS_ID_IS_WILDCARD = ECS_ID_IS_WILDCARD,
IS_PAIR = ECS_IS_PAIR, IS_PAIR = ECS_IS_PAIR,
pair_first = ecs_pair_first, pair_first = ecs_pair_first,