83 lines
2.3 KiB
JavaScript
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))
|
|
}
|
|
|
|
}
|