Fix upvalues conflict in nested queries

This commit is contained in:
Ukendio 2024-08-03 04:49:45 +02:00
parent 3e639db371
commit e5634b10b2

View file

@ -721,6 +721,9 @@ end
local Arm = function(self: Query, ...)
return self
end
local world_query
do
local EmptyQuery: Query = {
__iter = function(): Item
return noop
@ -734,7 +737,13 @@ local EmptyQuery: Query = {
setmetatable(EmptyQuery, EmptyQuery)
local function world_query(world, ...)
local function world_query_replace_values(row, columns, ...)
for i, column in columns do
column[row] = select(i, ...)
end
end
function world_query(world, ...)
-- breaking
if (...) == nil then
error("Missing components")
@ -743,34 +752,34 @@ local function world_query(world, ...)
local compatible_archetypes = {}
local length = 0
local components = { ... } :: any
local ids = { ... }
local A, B, C, D, E, F, G, H, I = ...
local a, b, c, d, e, f, g, h
local archetypes = world.archetypes
local firstArchetypeMap: ArchetypeMap
local idr: ArchetypeMap
local componentIndex = world.componentIndex
for _, componentId in components do
local map = componentIndex[componentId]
for _, id in ids do
local map = componentIndex[id]
if not map then
return EmptyQuery
end
if firstArchetypeMap == nil or map.size < firstArchetypeMap.size then
firstArchetypeMap = map
if idr == nil or map.size < idr.size then
idr = map
end
end
for id in firstArchetypeMap.cache do
local compatibleArchetype = archetypes[id]
local archetypeRecords = compatibleArchetype.records
for archetype_id in idr.cache do
local compatibleArchetype = archetypes[archetype_id]
local tr = compatibleArchetype.records
local skip = false
for i, componentId in components do
local index = archetypeRecords[componentId]
for i, id in ids do
local index = tr[id]
if not index then
skip = true
break
@ -785,12 +794,9 @@ local function world_query(world, ...)
compatible_archetypes[length] = compatibleArchetype
end
local init = false
local drain = false
local ids = components
local world_query_iter_next
if length == 0 then
return EmptyQuery
end
local lastArchetype = 1
local archetype
@ -799,7 +805,8 @@ local function world_query(world, ...)
local i
local queryOutput
local function world_query_iter_create()
local world_query_iter_next
if not B then
function world_query_iter_next(): any
local entityId = entities[i]
@ -983,8 +990,9 @@ local function world_query(world, ...)
return entityId, unpack(queryOutput)
end
end
end
local init = false
local drain = false
local function query_init(query)
if init and drain then
@ -1054,7 +1062,7 @@ local function world_query(world, ...)
return true
end
local function world_query_without(self, ...)
local function world_query_without(query, ...)
local withoutComponents = { ... }
for i = #compatible_archetypes, 1, -1 do
local archetype = compatible_archetypes[i]
@ -1074,16 +1082,15 @@ local function world_query(world, ...)
compatible_archetypes[i] = compatible_archetypes[last]
end
compatible_archetypes[last] = nil
length -= 1
end
end
return self
if length == 0 then
return EmptyQuery
end
local function world_query_replace_values(row, columns, ...)
for i, column in columns do
column[row] = select(i, ...)
end
return query
end
local function world_query_replace(query, fn: (...any) -> (...any))
@ -1130,14 +1137,14 @@ local function world_query(world, ...)
end
local function world_query_with(query, ...)
local ids = { ... }
local with = { ... }
for i = #compatible_archetypes, 1, -1 do
local archetype = compatible_archetypes[i]
local records = archetype.records
local tr = archetype.records
local shouldRemove = false
for _, id in ids do
if not records[id] then
for _, id in with do
if not tr[id] then
shouldRemove = true
break
end
@ -1149,11 +1156,12 @@ local function world_query(world, ...)
compatible_archetypes[i] = compatible_archetypes[last]
end
compatible_archetypes[last] = nil
length -= 1
end
end
query_init(query)
if length == 0 then
return EmptyQuery
end
return query
end
@ -1177,15 +1185,11 @@ local function world_query(world, ...)
return world_query_iter_next
end
local function world_query_next()
local function world_query_next(world)
if not drain then
error("Did you forget to call query:drain()?")
end
return world_query_iter_next()
end
if #compatible_archetypes == 0 then
return EmptyQuery
return world_query_iter_next(world)
end
local it = {
@ -1200,19 +1204,13 @@ local function world_query(world, ...)
setmetatable(it, it)
drain = false
init = false
ids = components
world_query_iter_create()
return it
end
end
type WorldIterator = (() -> (i53, { [unknown]: unknown? })) & (() -> ()) & (() -> i53)
-- __nominal_type_dont_use could not be any or T as it causes a type error
-- or produces a union
export type Entity<T = any> = number & { __nominal_type_dont_use: T }
export type Entity<T = any> = number & { __DO_NOT_USE_OR_YOU_WILL_BE_FIRED: T }
export type Pair = number
export type QueryShim<T...> = typeof(setmetatable({