import { positionAt } from '../GPS/actions/arena/worldline.js' export class GpsStorageReader { constructor(systemCnx, gpsStorage, debug = false) { this.cnx = systemCnx this.gpsStorage = gpsStorage this.debug = debug } agentHashKey(agentId) { return(this.gpsStorage.agentHashKey.replace(/\[UID\]/g, agentId)) } #parseHashField(raw) { if(raw == null) return(null) if(typeof(raw) === 'object') return(raw) try { return(JSON.parse(raw)) } catch { return(null) } } #segmentToAgent(segment) { if(!segment?.id) return(null) if(!this.#isVector(segment.position) || !this.#isVector(segment.vector)) return(null) return({ id: segment.id, position: { ...segment.position }, vector: { ...segment.vector }, since: segment.since ?? 0, generation: segment.generation ?? 0, }) } #isVector(v) { return( v && typeof(v) === 'object' && typeof(v.x) === 'number' && typeof(v.y) === 'number' && typeof(v.z) === 'number' ) } buildAgentSnapshot(agent, at) { return({ id: agent.id, position: positionAt(agent, at), vector: { ...agent.vector }, since: agent.since, generation: agent.generation ?? 0, t: at, }) } async loadSegment(agentId) { const raw = await this.cnx.redisHget(this.agentHashKey(agentId), 'segment') return(this.#parseHashField(raw)) } async listAgentIds() { return(await this.cnx.redisSmembers(this.gpsStorage.agentsIndexKey)) } async loadAllAgents() { const ids = await this.listAgentIds() const agents = new Map() for(const id of ids) { const segment = await this.loadSegment(id) const agent = this.#segmentToAgent(segment) if(agent) agents.set(id, agent) } return(agents) } async getAgentPosition(agentId, at) { const segment = await this.loadSegment(agentId) const agent = this.#segmentToAgent(segment) if(!agent) return(null) return(this.buildAgentSnapshot(agent, at)) } }