--!strict --!optimize 2 local jecs = require("../../jecs") type Entity = jecs.Entity export type Identity = typeof(setmetatable( {}, {} :: { __call: (any, key: unknown) -> (Entity, Cleaner), __index: { reference: (key: unknown) -> (Entity, Cleaner), find: (key: unknown) -> (Entity?, Cleaner?), }, } )) type Cleaner = () -> () local ref_cache: { [jecs.World]: Identity } = {} local function construct(world: jecs.World, skip_cache: boolean?): Identity if not skip_cache then local hit = ref_cache[world] if hit then return hit end end local lookup: { [unknown]: Entity } = {} local cleaner_cache: { [unknown]: Cleaner } = {} local function serve_cleaner(key: unknown): () -> () local hit = cleaner_cache[key] if hit then return hit end local function cleaner() lookup[key] = nil cleaner_cache[key] = nil end cleaner_cache[key] = cleaner return cleaner end local function ref(key: unknown): (Entity, Cleaner) local entity = lookup[key] if not entity then entity = world:entity() lookup[key] = entity end return entity, serve_cleaner(key) end local function find(key: unknown): (Entity?, Cleaner?) local entity = lookup[key] if not entity then return nil, nil end return entity, serve_cleaner(key) end local function call(_, key: unknown): (Entity, Cleaner) return ref(key) end local self = setmetatable({}, { __call = call, __index = { reference = ref, find = find, }, }) if not skip_cache then ref_cache[world] = self end return self end return construct