maestro refacto to grrom, getpositions actions transfered to Observer, changed to frustum, with subscription

This commit is contained in:
STEINNI
2026-06-14 10:16:56 +00:00
parent f3102d5fbc
commit c399f9ddb4
21 changed files with 760 additions and 185 deletions
+21 -1
View File
@@ -4,8 +4,28 @@ export const construct = (redisCnx) => {
export const methods = {
handleLifecycleEvent(msg) {
const srv = this.observerSrv
if(!srv) return
if(msg.eventType === 'onYourMarks') {
srv.onYourMarks()
return
}
if(msg.eventType === 'bigBang') {
srv.onBigBang()
}
},
dispatchArenaMessage(msg, chan) {
if(this.debug) console.log(`[${this.redisId}] Arena message (unhandled):`, msg.eventType, chan)
const observer = this.config.observer
if(!observer || !this.observerSrv) return(false)
if(this.matchesChan(chan, observer.lifecycle?.arenaChannel ?? 'arena:lifecycle')) {
this.handleLifecycleEvent(msg)
return(true)
}
return(false)
},
+2
View File
@@ -1,4 +1,5 @@
import { methods as utilities, construct as utilitiesConstruct } from './utilities.js'
import { methods as positions } from './positions.js'
import { dispatchMessage } from './dispatch.js'
export const afterLoginMethods = [
@@ -7,6 +8,7 @@ export const afterLoginMethods = [
export const meshActions = {
...utilities,
...positions,
}
export { dispatchMessage }
+280
View File
@@ -0,0 +1,280 @@
import { publishActionReply, parseSimTime } from '../../actionsHelper.js'
import { Frustum } from '../../frustum.js'
export const methods = {
/* Event-Rx:
{
"action": "GETAGENTPOSITION",
"reqid": "6az5e4r6a",
"payload": {
"agentId": "agent42",
"t": 12.5
}
}
Event-Tx:
{
"action": "GETAGENTPOSITION",
"success": true,
"reqid": "6az5e4r6a",
"payload": {
"agent": {
"id": "agent42",
"position": { "x": 1, "y": 2, "z": 3 },
"vector": { "x": 0, "y": 0, "z": 0 },
"since": 0,
"generation": 2,
"t": 12.5
}
}
}
*/
async action_GETAGENTPOSITION(action, payload, reqid, sender, roles) {
const replyOpts = {
action,
reqid,
sender,
replyChannel: this.config.observer.observerActionsReply,
}
if(!this.accessRights.canDo(roles, action)) {
publishActionReply(this, { ...replyOpts, reply: {
success: false,
err: 'Unauthorized action !',
} })
return
}
const reader = this.observerSrv.gpsStorageReader
if(!reader) {
publishActionReply(this, { ...replyOpts, reply: {
success: false,
err: 'GPS storage reader not ready',
} })
return
}
if(!this.observerSrv.isLive()) {
publishActionReply(this, { ...replyOpts, reply: {
success: false,
err: 'Simulation not live',
} })
return
}
const agentId = payload?.agentId
if(!agentId || typeof(agentId) !== 'string') {
publishActionReply(this, { ...replyOpts, reply: {
success: false,
err: 'Missing or invalid agentId',
} })
return
}
const at = parseSimTime(payload, () => this.observerSrv.now())
if(at === null) {
publishActionReply(this, { ...replyOpts, reply: {
success: false,
err: 'Invalid simulation time',
} })
return
}
const agent = await reader.getAgentPosition(agentId, at)
if(!agent) {
publishActionReply(this, { ...replyOpts, reply: {
success: false,
err: `Unknown agent: ${agentId}`,
} })
return
}
publishActionReply(this, { ...replyOpts, reply: {
success: true,
payload: { agent },
} })
},
/* Event-Rx:
{
"action": "GETAGENTSINFRUSTUM",
"reqid": "6az5e4r6a",
"payload": {
"planes": [
{ "nx": 1, "ny": 0, "nz": 0, "d": -10 },
{ "nx": -1, "ny": 0, "nz": 0, "d": 10 },
{ "nx": 0, "ny": 1, "nz": 0, "d": -10 },
{ "nx": 0, "ny": -1, "nz": 0, "d": 10 },
{ "nx": 0, "ny": 0, "nz": 1, "d": 0 },
{ "nx": 0, "ny": 0, "nz": -1, "d": 5 }
],
"t": 0
}
}
*/
async action_GETAGENTSINFRUSTUM(action, payload, reqid, sender, roles) {
const replyOpts = {
action,
reqid,
sender,
replyChannel: this.config.observer.observerActionsReply,
}
if(!this.accessRights.canDo(roles, action)) {
publishActionReply(this, { ...replyOpts, reply: {
success: false,
err: 'Unauthorized action !',
} })
return
}
const registry = this.observerSrv.requestorRegistry
if(!registry) {
publishActionReply(this, { ...replyOpts, reply: {
success: false,
err: 'Requestor registry not ready',
} })
return
}
if(!this.observerSrv.isLive()) {
publishActionReply(this, { ...replyOpts, reply: {
success: false,
err: 'Simulation not live',
} })
return
}
const frustum = Frustum.fromPlanes(payload?.planes)
if(!frustum) {
publishActionReply(this, { ...replyOpts, reply: {
success: false,
err: 'Missing or invalid frustum planes (expected 6)',
} })
return
}
const at = parseSimTime(payload, () => this.observerSrv.now())
if(at === null) {
publishActionReply(this, { ...replyOpts, reply: {
success: false,
err: 'Invalid simulation time',
} })
return
}
const result = await registry.evaluateOnce({ frustum, t: at })
if(!result.ok) {
publishActionReply(this, { ...replyOpts, reply: {
success: false,
err: result.err,
} })
return
}
publishActionReply(this, { ...replyOpts, reply: {
success: true,
payload: {
agents: result.agents,
t: result.t,
},
} })
},
/* Event-Rx:
{
"action": "SUBSCRIBEFRUSTUM",
"reqid": "6az5e4r6a",
"sender": "client-uuid",
"payload": {
"planes": [
{ "nx": 1, "ny": 0, "nz": 0, "d": -10 },
{ "nx": -1, "ny": 0, "nz": 0, "d": 10 },
{ "nx": 0, "ny": 1, "nz": 0, "d": -10 },
{ "nx": 0, "ny": -1, "nz": 0, "d": 10 },
{ "nx": 0, "ny": 0, "nz": 1, "d": 0 },
{ "nx": 0, "ny": 0, "nz": -1, "d": 5 }
],
"frequency": 800
}
}
Event-Tx:
{
"action": "SUBSCRIBEFRUSTUM",
"success": true,
"reqid": "6az5e4r6a",
"payload": {
"frequency": 900,
"agents": [ ... ],
"t": 12.5
}
}
Periodic push (no reqid):
{
"action": "GETAGENTSINFRUSTUM",
"success": true,
"sender": "observer",
"payload": { "agents": [ ... ], "t": 12.5 }
}
*/
async action_SUBSCRIBEFRUSTUM(action, payload, reqid, sender, roles) {
const replyOpts = {
action,
reqid,
sender,
replyChannel: this.config.observer.observerActionsReply,
}
if(!this.accessRights.canDo(roles, action)) {
publishActionReply(this, { ...replyOpts, reply: {
success: false,
err: 'Unauthorized action !',
} })
return
}
if(!sender || typeof(sender) !== 'string') {
publishActionReply(this, { ...replyOpts, reply: {
success: false,
err: 'Missing or invalid sender',
} })
return
}
const registry = this.observerSrv.requestorRegistry
if(!registry) {
publishActionReply(this, { ...replyOpts, reply: {
success: false,
err: 'Requestor registry not ready',
} })
return
}
if(!this.observerSrv.isLive()) {
publishActionReply(this, { ...replyOpts, reply: {
success: false,
err: 'Simulation not live',
} })
return
}
const result = await registry.subscribeFrustum(sender, {
planes: payload?.planes,
frequency: payload?.frequency,
})
if(!result.ok) {
publishActionReply(this, { ...replyOpts, reply: {
success: false,
err: result.err,
} })
return
}
publishActionReply(this, { ...replyOpts, reply: {
success: true,
payload: {
frequency: result.frequency,
agents: result.agents,
t: result.t,
},
} })
},
}