Files
P42_godDaemons/Observer/gpsStorageReader.js
T

83 lines
2.3 KiB
JavaScript

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))
}
}