import { AccesRights } from '../accesRights.js' import { GpsStorageReader } from './gpsStorageReader.js' import { RequestorRegistry } from './requestorRegistry.js' import { publishActionReply } from './actionsHelper.js' import { SimState } from '../GPS/simulationState.js' export class observerServer { constructor(configHelper, allRediscnx, debug) { this.configHelper = configHelper this.observerConfig = configHelper.config this.allRediscnx = allRediscnx this.debug = debug this.accessRights = new AccesRights(this.observerConfig, debug) this.arenaCnx = null this.arenaCnxs = [] this.systemCnx = null this.gpsStorageReader = null this.requestorRegistry = null this.state = SimState.IDLE this.bigBangEpoch = null } getObserverSettings() { const observer = this.observerConfig.observer ?? {} return({ senderId: observer.senderId ?? 'observer', scanIntervalMs: observer.scanIntervalMs ?? 300, lifecycle: { arenaChannel: observer.lifecycle?.arenaChannel ?? 'arena:lifecycle', godsReadyChannel: observer.lifecycle?.godsReadyChannel ?? 'arena:gods:ready', }, }) } getGpsStorageSettings() { const gps = this.observerConfig.gps ?? {} return(gps.GPSstorage ?? null) } initGpsStorageReader() { const gpsStorage = this.getGpsStorageSettings() if(gpsStorage && this.systemCnx) { this.gpsStorageReader = new GpsStorageReader(this.systemCnx, gpsStorage, this.debug) this.initRequestorRegistry() } } initRequestorRegistry() { if(!this.gpsStorageReader || this.requestorRegistry) return const { scanIntervalMs } = this.getObserverSettings() this.requestorRegistry = new RequestorRegistry( this.gpsStorageReader, () => this.now(), scanIntervalMs, (sender, payload) => this.publishFrustumUpdate(sender, payload), this.debug ) } publishFrustumUpdate(sender, payload) { if(!this.systemCnx || !sender) return const observer = this.observerConfig.observer ?? {} publishActionReply(this.systemCnx, { action: 'GETAGENTSINFRUSTUM', sender, replyChannel: observer.observerActionsReply ?? 'system:replies:[UID]', reply: { success: true, payload, }, }) } isLive() { return(this.state === SimState.LIVE) } simNow() { if(this.bigBangEpoch === null) return(null) return((performance.now() - this.bigBangEpoch) / 1000) } now() { if(this.isLive()) return(this.simNow()) return(null) } onYourMarks() { this.state = SimState.PREPARE this.bigBangEpoch = null this.requestorRegistry?.clear() } onBigBang() { this.bigBangEpoch = performance.now() this.state = SimState.LIVE } wireSystemConnexion(cnx) { cnx.observerSrv = this cnx.accessRights = this.accessRights cnx.reloadAccessRights = () => this.reloadAccessRights() cnx.getAccessRights = () => this.getAccessRights() if(!this.systemCnx || cnx.redisConfig.role === 'primary') { this.systemCnx = cnx this.initGpsStorageReader() } } wireArenaConnexion(cnx) { cnx.observerSrv = this this.arenaCnxs.push(cnx) if(!this.arenaCnx || cnx.redisConfig.role === 'primary') { this.arenaCnx = cnx } } async reloadAccessRights() { await this.configHelper.refreshAccessRights() this.observerConfig.accessRights = this.configHelper.config.accessRights this.accessRights.refreshAccessRights(this.observerConfig) } getAccessRights() { return(this.observerConfig.accessRights) } }