diff --git a/init.luau b/init.luau index e53d366..8395a5b 100644 --- a/init.luau +++ b/init.luau @@ -35,8 +35,7 @@ export type Archetype = { type: string, entities: { number }, columns: { Column }, - records: { number }, - counts: { number }, + records: { ArchetypeRecord }, } & GraphNode export type Record = { @@ -45,9 +44,13 @@ export type Record = { dense: i24, } +type ArchetypeRecord = { + count: number, + column: number, +} + type IdRecord = { - columns: { number }, - counts: { number }, + cache: { ArchetypeRecord }, flags: number, size: number, hooks: { @@ -299,7 +302,7 @@ local function archetype_move(entity_index: EntityIndex, to: Archetype, dst_row: -- Sometimes target column may not exist, e.g. when you remove a component. if tr then - dst_columns[tr][dst_row] = column[src_row] + dst_columns[tr.column][dst_row] = column[src_row] end -- If the entity is the last row in the archetype then swapping it would be meaningless. @@ -340,17 +343,17 @@ local function archetype_append(entity: number, archetype: Archetype): number return length end -local function new_entity(entity: i53, record: Record, archetype: Archetype): Record - local row = archetype_append(entity, archetype) +local function new_entity(entityId: i53, record: Record, archetype: Archetype): Record + local row = archetype_append(entityId, archetype) record.archetype = archetype record.row = row return record end -local function entity_move(entity_index: EntityIndex, entity: i53, record: Record, to: Archetype) +local function entity_move(entity_index: EntityIndex, entityId: i53, record: Record, to: Archetype) local sourceRow = record.row local from = record.archetype - local dst_row = archetype_append(entity, to) + local dst_row = archetype_append(entityId, to) archetype_move(entity_index, to, dst_row, from, sourceRow) record.archetype = to record.row = dst_row @@ -360,14 +363,14 @@ local function hash(arr: { number }): string return table.concat(arr, "_") end -local function fetch(id, records: { number }, columns: { Column }, row: number): any +local function fetch(id, records: { ArchetypeRecord }, columns: { Column }, row: number): any local tr = records[id] if not tr then return nil end - return columns[tr][row] + return columns[tr.column][row] end local function world_get(world: World, entity: i53, a: i53, b: i53?, c: i53?, d: i53?, e: i53?): ...any @@ -415,7 +418,7 @@ local function world_get_one_inline(world: World, entity: i53, id: i53): any if not tr then return nil end - return archetype.columns[tr][record.row] + return archetype.columns[tr.column][record.row] end local function world_has_one_inline(world: World, entity: number, id: i53): boolean @@ -473,19 +476,17 @@ local function world_target(world: World, entity: i53, relation: i24, index: num return nil end - local archetype_id = archetype.id - local count = idr.counts[archetype.id] - if not count then + local tr = idr.cache[archetype.id] + if not tr then return nil end + local count = tr.count if nth >= count then nth = nth + count + 1 end - local tr = idr.columns[archetype_id] - - nth = archetype.types[nth + tr] + nth = archetype.types[nth + tr.column] if not nth then return nil @@ -540,8 +541,7 @@ local function id_record_ensure(world: World, id: number): IdRecord idr = { size = 0, - columns = {}, - counts = {}, + cache = {}, flags = flags, hooks = { on_add = on_add, @@ -558,26 +558,19 @@ end local function archetype_append_to_records( idr: IdRecord, - archetype: Archetype, + archetype_id: number, + records: Map, id: number, index: number ) - local archetype_id = archetype.id - local archetype_records = archetype.records - local archetype_counts = archetype.counts - local idr_columns = idr.columns - local idr_counts = idr.counts - local tr = idr_columns[archetype_id] + local tr = idr.cache[archetype_id] if not tr then - idr_columns[archetype_id] = index - idr_counts[archetype_id] = 1 - - archetype_records[id] = index - archetype_counts[id] = 1 + tr = { column = index, count = 1 } + idr.cache[archetype_id] = tr + idr.size += 1 + records[id] = tr else - local max_count = idr_counts[archetype_id] + 1 - idr_counts[archetype_id] = max_count - archetype_counts[id] = max_count + tr.count += 1 end end @@ -588,15 +581,13 @@ local function archetype_create(world: World, id_types: { i24 }, ty, prev: i53?) local length = #id_types local columns = (table.create(length) :: any) :: { Column } - local records: { number } = {} - local counts: {number} = {} + local records: { ArchetypeRecord } = {} local archetype: Archetype = { columns = columns, entities = {}, id = archetype_id, records = records, - counts = counts, type = ty, types = id_types, @@ -607,7 +598,7 @@ local function archetype_create(world: World, id_types: { i24 }, ty, prev: i53?) for i, componentId in id_types do local idr = id_record_ensure(world, componentId) - archetype_append_to_records(idr, archetype, componentId, i) + archetype_append_to_records(idr, archetype_id, records, componentId, i) if ECS_IS_PAIR(componentId) then local relation = ecs_pair_first(world, componentId) @@ -615,11 +606,11 @@ local function archetype_create(world: World, id_types: { i24 }, ty, prev: i53?) local r = ECS_PAIR(relation, EcsWildcard) local idr_r = id_record_ensure(world, r) - archetype_append_to_records(idr_r, archetype, r, i) + archetype_append_to_records(idr_r, archetype_id, records, r, i) local t = ECS_PAIR(EcsWildcard, object) local idr_t = id_record_ensure(world, t) - archetype_append_to_records(idr_t, archetype, t, i) + archetype_append_to_records(idr_t, archetype_id, records, t, i) end if bit32.band(idr.flags, ECS_ID_IS_TAG) == 0 then @@ -799,6 +790,10 @@ local function archetype_traverse_remove(world: World, id: i53, from: Archetype) return to :: Archetype end +local function invoke_hook(action, entity, data) + action(entity, data) +end + local function world_add(world: World, entity: i53, id: i53): () local entity_index = world.entity_index local record = entity_index_try_get_fast(entity_index, entity) @@ -843,7 +838,7 @@ local function world_set(world: World, entity: i53, id: i53, data: unknown): () -- If the archetypes are the same it can avoid moving the entity -- and just set the data directly. local tr = to.records[id] - local column = from.columns[tr] + local column = from.columns[tr.column] column[record.row] = data local on_set = idr_hooks.on_set if on_set then @@ -869,7 +864,7 @@ local function world_set(world: World, entity: i53, id: i53, data: unknown): () end local tr = to.records[id] - local column = to.columns[tr] + local column = to.columns[tr.column] column[record.row] = data @@ -950,7 +945,6 @@ local function archetype_delete(world: World, archetype: Archetype, row: number, record_to_move.row = row end - delete = entities[row] entities[row] = move end @@ -1066,8 +1060,7 @@ local function archetype_destroy(world: World, archetype: Archetype) for id in records do local idr = component_index[id] - idr.columns[archetype_id] = nil :: any - idr.counts[archetype_id] = nil + idr.cache[archetype_id] = nil :: any idr.size -= 1 records[id] = nil :: any if idr.size == 0 then @@ -1125,7 +1118,7 @@ do if idr then local flags = idr.flags if bit32.band(flags, ECS_ID_DELETE) ~= 0 then - for archetype_id in idr.columns do + for archetype_id in idr.cache do local idr_archetype = archetypes[archetype_id] local entities = idr_archetype.entities @@ -1137,7 +1130,7 @@ do archetype_destroy(world, idr_archetype) end else - for archetype_id in idr.columns do + for archetype_id in idr.cache do local idr_archetype = archetypes[archetype_id] local entities = idr_archetype.entities local n = #entities @@ -1154,7 +1147,7 @@ do local dense_array = entity_index.dense_array if idr_t then - for archetype_id in idr_t.columns do + for archetype_id in idr_t.cache do local children = {} local idr_t_archetype = archetypes[archetype_id] @@ -1274,55 +1267,55 @@ local function query_iter_init(query: QueryInner): () -> (number, ...any) local e: Column, f: Column, g: Column, h: Column if not B then - a = columns[records[A]] + a = columns[records[A].column] elseif not C then - a = columns[records[A]] - b = columns[records[B]] + a = columns[records[A].column] + b = columns[records[B].column] elseif not D then - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] elseif not E then - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] elseif not F then - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] - e = columns[records[E]] + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] + e = columns[records[E].column] elseif not G then - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] - e = columns[records[E]] - f = columns[records[F]] + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] + e = columns[records[E].column] + f = columns[records[F].column] elseif not H then - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] - e = columns[records[E]] - f = columns[records[F]] - g = columns[records[G]] + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] + e = columns[records[E].column] + f = columns[records[F].column] + g = columns[records[G].column] elseif not I then - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] - e = columns[records[E]] - f = columns[records[F]] - g = columns[records[G]] - h = columns[records[H]] + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] + e = columns[records[E].column] + f = columns[records[F].column] + g = columns[records[G].column] + h = columns[records[H].column] end if not B then function world_query_iter_next(): any - local entity = entities[i] - while entity == nil do + local entityId = entities[i] + while entityId == nil do lastArchetype += 1 archetype = compatible_archetypes[lastArchetype] if not archetype then @@ -1334,21 +1327,21 @@ local function query_iter_init(query: QueryInner): () -> (number, ...any) if i == 0 then continue end - entity = entities[i] + entityId = entities[i] columns = archetype.columns records = archetype.records - a = columns[records[A]] + a = columns[records[A].column] end local row = i i -= 1 - return entity, a[row] + return entityId, a[row] end elseif not C then function world_query_iter_next(): any - local entity = entities[i] - while entity == nil do + local entityId = entities[i] + while entityId == nil do lastArchetype += 1 archetype = compatible_archetypes[lastArchetype] if not archetype then @@ -1360,22 +1353,22 @@ local function query_iter_init(query: QueryInner): () -> (number, ...any) if i == 0 then continue end - entity = entities[i] + entityId = entities[i] columns = archetype.columns records = archetype.records - a = columns[records[A]] - b = columns[records[B]] + a = columns[records[A].column] + b = columns[records[B].column] end local row = i i -= 1 - return entity, a[row], b[row] + return entityId, a[row], b[row] end elseif not D then function world_query_iter_next(): any - local entity = entities[i] - while entity == nil do + local entityId = entities[i] + while entityId == nil do lastArchetype += 1 archetype = compatible_archetypes[lastArchetype] if not archetype then @@ -1387,23 +1380,23 @@ local function query_iter_init(query: QueryInner): () -> (number, ...any) if i == 0 then continue end - entity = entities[i] + entityId = entities[i] columns = archetype.columns records = archetype.records - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] end local row = i i -= 1 - return entity, a[row], b[row], c[row] + return entityId, a[row], b[row], c[row] end elseif not E then function world_query_iter_next(): any - local entity = entities[i] - while entity == nil do + local entityId = entities[i] + while entityId == nil do lastArchetype += 1 archetype = compatible_archetypes[lastArchetype] if not archetype then @@ -1415,151 +1408,25 @@ local function query_iter_init(query: QueryInner): () -> (number, ...any) if i == 0 then continue end - entity = entities[i] + entityId = entities[i] columns = archetype.columns records = archetype.records - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] end local row = i i -= 1 - return entity, a[row], b[row], c[row], d[row] - end - elseif not F then - function world_query_iter_next(): any - local entity = entities[i] - while entity == nil do - lastArchetype += 1 - archetype = compatible_archetypes[lastArchetype] - if not archetype then - return nil - end - - entities = archetype.entities - i = #entities - if i == 0 then - continue - end - entity = entities[i] - columns = archetype.columns - records = archetype.records - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] - e = columns[records[E]] - end - - local row = i - i -= 1 - - return entity, a[row], b[row], c[row], d[row], e[row] - end - elseif not G then - function world_query_iter_next(): any - local entity = entities[i] - while entity == nil do - lastArchetype += 1 - archetype = compatible_archetypes[lastArchetype] - if not archetype then - return nil - end - - entities = archetype.entities - i = #entities - if i == 0 then - continue - end - entity = entities[i] - columns = archetype.columns - records = archetype.records - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] - e = columns[records[E]] - f = columns[records[F]] - end - - local row = i - i -= 1 - - return entity, a[row], b[row], c[row], d[row], e[row], f[row] - end - elseif not H then - function world_query_iter_next(): any - local entity = entities[i] - while entity == nil do - lastArchetype += 1 - archetype = compatible_archetypes[lastArchetype] - if not archetype then - return nil - end - - entities = archetype.entities - i = #entities - if i == 0 then - continue - end - entity = entities[i] - columns = archetype.columns - records = archetype.records - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] - e = columns[records[E]] - f = columns[records[F]] - g = columns[records[G]] - end - - local row = i - i -= 1 - - return entity, a[row], b[row], c[row], d[row], e[row], f[row], g[row] - end - elseif not I then - function world_query_iter_next(): any - local entity = entities[i] - while entity == nil do - lastArchetype += 1 - archetype = compatible_archetypes[lastArchetype] - if not archetype then - return nil - end - - entities = archetype.entities - i = #entities - if i == 0 then - continue - end - entity = entities[i] - columns = archetype.columns - records = archetype.records - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] - e = columns[records[E]] - f = columns[records[F]] - g = columns[records[G]] - h = columns[records[H]] - end - - local row = i - i -= 1 - - return entity, a[row], b[row], c[row], d[row], e[row], f[row], g[row], h[row] + return entityId, a[row], b[row], c[row], d[row] end else - local output = {} + local queryOutput = {} function world_query_iter_next(): any - local entity = entities[i] - while entity == nil do + local entityId = entities[i] + while entityId == nil do lastArchetype += 1 archetype = compatible_archetypes[lastArchetype] if not archetype then @@ -1571,19 +1438,61 @@ local function query_iter_init(query: QueryInner): () -> (number, ...any) if i == 0 then continue end - entity = entities[i] + entityId = entities[i] columns = archetype.columns records = archetype.records + + if not F then + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] + e = columns[records[E].column] + elseif not G then + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] + e = columns[records[E].column] + f = columns[records[F].column] + elseif not H then + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] + e = columns[records[E].column] + f = columns[records[F].column] + g = columns[records[G].column] + elseif not I then + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] + e = columns[records[E].column] + f = columns[records[F].column] + g = columns[records[G].column] + h = columns[records[H].column] + end end local row = i i -= 1 - for j, id in ids do - output[j] = columns[records[id]][row] + if not F then + return entityId, a[row], b[row], c[row], d[row], e[row] + elseif not G then + return entityId, a[row], b[row], c[row], d[row], e[row], f[row] + elseif not H then + return entityId, a[row], b[row], c[row], d[row], e[row], f[row], g[row] + elseif not I then + return entityId, a[row], b[row], c[row], d[row], e[row], f[row], g[row], h[row] end - return entity, unpack(output) + for j, id in ids do + queryOutput[j] = columns[records[id].column][row] + end + + return entityId, unpack(queryOutput) end end @@ -1688,7 +1597,7 @@ local function query_cached(query: QueryInner) local entities: { number } local i: number local archetype: Archetype - local records: { number } + local records: { ArchetypeRecord } local archetypes = query.compatible_archetypes local world = query.world :: { observable: Observable } @@ -1745,49 +1654,49 @@ local function query_cached(query: QueryInner) records = archetype.records columns = archetype.columns if not B then - a = columns[records[A]] + a = columns[records[A].column] elseif not C then - a = columns[records[A]] - b = columns[records[B]] + a = columns[records[A].column] + b = columns[records[B].column] elseif not D then - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] elseif not E then - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] elseif not F then - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] - e = columns[records[E]] + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] + e = columns[records[E].column] elseif not G then - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] - e = columns[records[E]] - f = columns[records[F]] + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] + e = columns[records[E].column] + f = columns[records[F].column] elseif not H then - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] - e = columns[records[E]] - f = columns[records[F]] - g = columns[records[G]] + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] + e = columns[records[E].column] + f = columns[records[F].column] + g = columns[records[G].column] elseif not I then - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] - e = columns[records[E]] - f = columns[records[F]] - g = columns[records[G]] - h = columns[records[H]] + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] + e = columns[records[E].column] + f = columns[records[F].column] + g = columns[records[G].column] + h = columns[records[H].column] end return world_query_iter_next @@ -1795,8 +1704,8 @@ local function query_cached(query: QueryInner) if not B then function world_query_iter_next(): any - local entity = entities[i] - while entity == nil do + local entityId = entities[i] + while entityId == nil do lastArchetype += 1 archetype = compatible_archetypes[lastArchetype] if not archetype then @@ -1808,21 +1717,21 @@ local function query_cached(query: QueryInner) if i == 0 then continue end - entity = entities[i] + entityId = entities[i] columns = archetype.columns records = archetype.records - a = columns[records[A]] + a = columns[records[A].column] end local row = i i -= 1 - return entity, a[row] + return entityId, a[row] end elseif not C then function world_query_iter_next(): any - local entity = entities[i] - while entity == nil do + local entityId = entities[i] + while entityId == nil do lastArchetype += 1 archetype = compatible_archetypes[lastArchetype] if not archetype then @@ -1834,22 +1743,22 @@ local function query_cached(query: QueryInner) if i == 0 then continue end - entity = entities[i] + entityId = entities[i] columns = archetype.columns records = archetype.records - a = columns[records[A]] - b = columns[records[B]] + a = columns[records[A].column] + b = columns[records[B].column] end local row = i i -= 1 - return entity, a[row], b[row] + return entityId, a[row], b[row] end elseif not D then function world_query_iter_next(): any - local entity = entities[i] - while entity == nil do + local entityId = entities[i] + while entityId == nil do lastArchetype += 1 archetype = compatible_archetypes[lastArchetype] if not archetype then @@ -1861,23 +1770,23 @@ local function query_cached(query: QueryInner) if i == 0 then continue end - entity = entities[i] + entityId = entities[i] columns = archetype.columns records = archetype.records - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] end local row = i i -= 1 - return entity, a[row], b[row], c[row] + return entityId, a[row], b[row], c[row] end elseif not E then function world_query_iter_next(): any - local entity = entities[i] - while entity == nil do + local entityId = entities[i] + while entityId == nil do lastArchetype += 1 archetype = compatible_archetypes[lastArchetype] if not archetype then @@ -1889,151 +1798,25 @@ local function query_cached(query: QueryInner) if i == 0 then continue end - entity = entities[i] + entityId = entities[i] columns = archetype.columns records = archetype.records - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] end local row = i i -= 1 - return entity, a[row], b[row], c[row], d[row] - end - elseif not F then - function world_query_iter_next(): any - local entity = entities[i] - while entity == nil do - lastArchetype += 1 - archetype = compatible_archetypes[lastArchetype] - if not archetype then - return nil - end - - entities = archetype.entities - i = #entities - if i == 0 then - continue - end - entity = entities[i] - columns = archetype.columns - records = archetype.records - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] - e = columns[records[E]] - end - - local row = i - i -= 1 - - return entity, a[row], b[row], c[row], d[row], e[row] - end - elseif not G then - function world_query_iter_next(): any - local entity = entities[i] - while entity == nil do - lastArchetype += 1 - archetype = compatible_archetypes[lastArchetype] - if not archetype then - return nil - end - - entities = archetype.entities - i = #entities - if i == 0 then - continue - end - entity = entities[i] - columns = archetype.columns - records = archetype.records - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] - e = columns[records[E]] - f = columns[records[F]] - end - - local row = i - i -= 1 - - return entity, a[row], b[row], c[row], d[row], e[row], f[row] - end - elseif not H then - function world_query_iter_next(): any - local entity = entities[i] - while entity == nil do - lastArchetype += 1 - archetype = compatible_archetypes[lastArchetype] - if not archetype then - return nil - end - - entities = archetype.entities - i = #entities - if i == 0 then - continue - end - entity = entities[i] - columns = archetype.columns - records = archetype.records - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] - e = columns[records[E]] - f = columns[records[F]] - g = columns[records[G]] - end - - local row = i - i -= 1 - - return entity, a[row], b[row], c[row], d[row], e[row], f[row], g[row] - end - elseif not I then - function world_query_iter_next(): any - local entity = entities[i] - while entity == nil do - lastArchetype += 1 - archetype = compatible_archetypes[lastArchetype] - if not archetype then - return nil - end - - entities = archetype.entities - i = #entities - if i == 0 then - continue - end - entity = entities[i] - columns = archetype.columns - records = archetype.records - a = columns[records[A]] - b = columns[records[B]] - c = columns[records[C]] - d = columns[records[D]] - e = columns[records[E]] - f = columns[records[F]] - g = columns[records[G]] - h = columns[records[H]] - end - - local row = i - i -= 1 - - return entity, a[row], b[row], c[row], d[row], e[row], f[row], g[row], h[row] + return entityId, a[row], b[row], c[row], d[row] end else local queryOutput = {} function world_query_iter_next(): any - local entity = entities[i] - while entity == nil do + local entityId = entities[i] + while entityId == nil do lastArchetype += 1 archetype = compatible_archetypes[lastArchetype] if not archetype then @@ -2045,29 +1828,61 @@ local function query_cached(query: QueryInner) if i == 0 then continue end - entity = entities[i] + entityId = entities[i] columns = archetype.columns records = archetype.records + + if not F then + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] + e = columns[records[E].column] + elseif not G then + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] + e = columns[records[E].column] + f = columns[records[F].column] + elseif not H then + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] + e = columns[records[E].column] + f = columns[records[F].column] + g = columns[records[G].column] + elseif not I then + a = columns[records[A].column] + b = columns[records[B].column] + c = columns[records[C].column] + d = columns[records[D].column] + e = columns[records[E].column] + f = columns[records[F].column] + g = columns[records[G].column] + h = columns[records[H].column] + end end local row = i i -= 1 if not F then - return entity, a[row], b[row], c[row], d[row], e[row] + return entityId, a[row], b[row], c[row], d[row], e[row] elseif not G then - return entity, a[row], b[row], c[row], d[row], e[row], f[row] + return entityId, a[row], b[row], c[row], d[row], e[row], f[row] elseif not H then - return entity, a[row], b[row], c[row], d[row], e[row], f[row], g[row] + return entityId, a[row], b[row], c[row], d[row], e[row], f[row], g[row] elseif not I then - return entity, a[row], b[row], c[row], d[row], e[row], f[row], g[row], h[row] + return entityId, a[row], b[row], c[row], d[row], e[row], f[row], g[row], h[row] end for j, id in ids do - queryOutput[j] = columns[records[id]][row] + queryOutput[j] = columns[records[id].column][row] end - return entity, unpack(queryOutput) + return entityId, unpack(queryOutput) end end @@ -2120,7 +1935,7 @@ local function world_query(world: World, ...) return q end - for archetype_id in idr.columns do + for archetype_id in idr.cache do local compatibleArchetype = archetypes[archetype_id] if #compatibleArchetype.entities == 0 then continue @@ -2154,9 +1969,9 @@ local function world_each(world: World, id): () -> () return NOOP end - local idr_columns = idr.columns + local idr_cache = idr.cache local archetypes = world.archetypes - local archetype_id = next(idr_columns, nil) :: number + local archetype_id = next(idr_cache, nil) :: number local archetype = archetypes[archetype_id] if not archetype then return NOOP @@ -2168,7 +1983,7 @@ local function world_each(world: World, id): () -> () return function(): any local entity = entities[row] while not entity do - archetype_id = next(idr_columns, archetype_id) :: number + archetype_id = next(idr_cache, archetype_id) :: number if not archetype_id then return end diff --git a/pesde.toml b/pesde.toml index 67a7bc4..94d42bd 100644 --- a/pesde.toml +++ b/pesde.toml @@ -11,7 +11,7 @@ includes = [ license = "MIT" name = "marked/jecs" repository = "https://git.devmarked.win/marked/jecs-pesde" -version = "0.5.5" +version = "0.5.4" [indices] default = "https://github.com/pesde-pkg/index"