General Actions to handlers Refacto
This commit is contained in:
@@ -1,32 +0,0 @@
|
||||
|
||||
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) {
|
||||
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)
|
||||
},
|
||||
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
|
||||
export function dispatchMessage(redisCnx, msg, chan) {
|
||||
if(typeof(redisCnx.dispatchArenaMessage) !== 'function') return
|
||||
redisCnx.dispatchArenaMessage(msg, chan)
|
||||
}
|
||||
@@ -1,12 +1,17 @@
|
||||
import { methods as arenaMethods, construct as arenaConstruct } from './arenaHandlers.js'
|
||||
import { dispatchMessage } from './dispatch.js'
|
||||
import { assembleHandlers, createDispatchMessage } from '../../../bus/assembleMesh.js'
|
||||
import * as lifecycle from './lifecycle.js'
|
||||
|
||||
export const afterLoginMethods = [
|
||||
arenaConstruct,
|
||||
]
|
||||
const { actionHandlers, eventHandlers, afterLogin } = assembleHandlers([lifecycle])
|
||||
|
||||
export const meshActions = {
|
||||
...arenaMethods,
|
||||
}
|
||||
export { actionHandlers, afterLogin }
|
||||
|
||||
export { dispatchMessage }
|
||||
export const dispatchMessage = createDispatchMessage({
|
||||
eventHandlers,
|
||||
actionRules(redisCnx) {
|
||||
const observer = redisCnx.config.observer ?? {}
|
||||
const arenaChannel = observer.bus?.arena?.actionsChannel
|
||||
return({
|
||||
channels: arenaChannel ? [arenaChannel] : [],
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
export const eventHandlers = {
|
||||
'arena:lifecycle': {
|
||||
onYourMarks(msg, chan) {
|
||||
this.observerSrv?.onYourMarks()
|
||||
},
|
||||
bigBang(msg, chan) {
|
||||
this.observerSrv?.onBigBang()
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
|
||||
export function dispatchMessage(redisCnx, msg, chan) {
|
||||
const observer = redisCnx.config.observer
|
||||
if(!observer?.observerActionsChannel) return
|
||||
|
||||
const actionsChan = redisCnx.fullChan(observer.observerActionsChannel)
|
||||
if(chan != actionsChan) return
|
||||
|
||||
const action = msg.action
|
||||
if(!action || typeof(action) !== 'string') {
|
||||
console.warn(`[${redisCnx.redisId}] Ignoring message without action on ${chan}`)
|
||||
return
|
||||
}
|
||||
|
||||
const handler = redisCnx['action_'+action]
|
||||
if(typeof(handler) != 'function') {
|
||||
if(redisCnx.debug) console.warn(`[${redisCnx.redisId}] Unknown action ${action} on ${chan}`)
|
||||
return
|
||||
}
|
||||
|
||||
const payload = ('payload' in msg) ? msg.payload : null
|
||||
const reqid = ('reqid' in msg) ? msg.reqid.substr(0, 50) : null
|
||||
const sender = msg.sender || null
|
||||
const roles = Array.isArray(msg.roles) ? msg.roles : ['*']
|
||||
|
||||
if(redisCnx.debug) console.log(`[${redisCnx.redisId}] Dispatching action ${action} from ${sender}`)
|
||||
handler.call(redisCnx, action, payload, reqid, sender, roles)
|
||||
}
|
||||
@@ -1,14 +1,17 @@
|
||||
import { methods as utilities, construct as utilitiesConstruct } from './utilities.js'
|
||||
import { methods as positions } from './positions.js'
|
||||
import { dispatchMessage } from './dispatch.js'
|
||||
import { assembleHandlers, createDispatchMessage } from '../../../bus/assembleMesh.js'
|
||||
import * as positions from './positions.js'
|
||||
import * as utilities from './utilities.js'
|
||||
|
||||
export const afterLoginMethods = [
|
||||
utilitiesConstruct,
|
||||
]
|
||||
const { actionHandlers, eventHandlers, afterLogin } = assembleHandlers([positions, utilities])
|
||||
|
||||
export const meshActions = {
|
||||
...utilities,
|
||||
...positions,
|
||||
}
|
||||
export { actionHandlers, afterLogin }
|
||||
|
||||
export { dispatchMessage }
|
||||
export const dispatchMessage = createDispatchMessage({
|
||||
eventHandlers,
|
||||
actionRules(redisCnx) {
|
||||
const observer = redisCnx.config.observer ?? {}
|
||||
return({
|
||||
channels: [observer.observerActionsChannel].filter(Boolean),
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,257 +1,93 @@
|
||||
import { publishActionReply, parseSimTime } from '../../actionsHelper.js'
|
||||
import { replyToAction } from '../../../bus/publishActionReply.js'
|
||||
import { parseSimTime } from '../../actionsHelper.js'
|
||||
import { Frustum } from '../../frustum.js'
|
||||
|
||||
export const methods = {
|
||||
export const actions = {
|
||||
|
||||
/* 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',
|
||||
} })
|
||||
replyToAction(this, { action, reqid, sender, success: false, err: 'GPS storage reader not ready' })
|
||||
return
|
||||
}
|
||||
|
||||
if(!this.observerSrv.isLive()) {
|
||||
publishActionReply(this, { ...replyOpts, reply: {
|
||||
success: false,
|
||||
err: 'Simulation not live',
|
||||
} })
|
||||
replyToAction(this, { action, reqid, sender, 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',
|
||||
} })
|
||||
replyToAction(this, { action, reqid, sender, 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',
|
||||
} })
|
||||
replyToAction(this, { action, reqid, sender, 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}`,
|
||||
} })
|
||||
replyToAction(this, { action, reqid, sender, success: false, err: `Unknown agent: ${agentId}` })
|
||||
return
|
||||
}
|
||||
|
||||
publishActionReply(this, { ...replyOpts, reply: {
|
||||
success: true,
|
||||
payload: { agent },
|
||||
} })
|
||||
replyToAction(this, { action, reqid, sender, 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',
|
||||
} })
|
||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Requestor registry not ready' })
|
||||
return
|
||||
}
|
||||
|
||||
if(!this.observerSrv.isLive()) {
|
||||
publishActionReply(this, { ...replyOpts, reply: {
|
||||
success: false,
|
||||
err: 'Simulation not live',
|
||||
} })
|
||||
replyToAction(this, { action, reqid, sender, 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)',
|
||||
} })
|
||||
replyToAction(this, { action, reqid, sender, 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',
|
||||
} })
|
||||
replyToAction(this, { action, reqid, sender, 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,
|
||||
} })
|
||||
replyToAction(this, { action, reqid, sender, success: false, err: result.err })
|
||||
return
|
||||
}
|
||||
|
||||
publishActionReply(this, { ...replyOpts, reply: {
|
||||
replyToAction(this, {
|
||||
action,
|
||||
reqid,
|
||||
sender,
|
||||
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',
|
||||
} })
|
||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Requestor registry not ready' })
|
||||
return
|
||||
}
|
||||
|
||||
if(!this.observerSrv.isLive()) {
|
||||
publishActionReply(this, { ...replyOpts, reply: {
|
||||
success: false,
|
||||
err: 'Simulation not live',
|
||||
} })
|
||||
replyToAction(this, { action, reqid, sender, success: false, err: 'Simulation not live' })
|
||||
return
|
||||
}
|
||||
|
||||
@@ -260,21 +96,21 @@ export const methods = {
|
||||
frequency: payload?.frequency,
|
||||
})
|
||||
if(!result.ok) {
|
||||
publishActionReply(this, { ...replyOpts, reply: {
|
||||
success: false,
|
||||
err: result.err,
|
||||
} })
|
||||
replyToAction(this, { action, reqid, sender, success: false, err: result.err })
|
||||
return
|
||||
}
|
||||
|
||||
publishActionReply(this, { ...replyOpts, reply: {
|
||||
replyToAction(this, {
|
||||
action,
|
||||
reqid,
|
||||
sender,
|
||||
success: true,
|
||||
payload: {
|
||||
frequency: result.frequency,
|
||||
agents: result.agents,
|
||||
t: result.t,
|
||||
},
|
||||
} })
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
@@ -1,48 +1,20 @@
|
||||
import { publishActionReply } from '../../actionsHelper.js'
|
||||
import { replyToAction } from '../../../bus/publishActionReply.js'
|
||||
|
||||
export const construct = (redisCnx) => {
|
||||
}
|
||||
|
||||
export const methods = {
|
||||
export const actions = {
|
||||
|
||||
async action_RELOADCONFIG(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
|
||||
}
|
||||
this.reloadAccessRights()
|
||||
publishActionReply(this, { ...replyOpts, reply: {
|
||||
success: true,
|
||||
} })
|
||||
replyToAction(this, { action, reqid, sender, success: true })
|
||||
},
|
||||
|
||||
async action_GETCONFIG(action, payload, reqid, sender, roles) {
|
||||
const replyOpts = {
|
||||
replyToAction(this, {
|
||||
action,
|
||||
reqid,
|
||||
sender,
|
||||
replyChannel: this.config.observer.observerActionsReply,
|
||||
}
|
||||
if(!this.accessRights.canDo(roles, action)) {
|
||||
publishActionReply(this, { ...replyOpts, reply: {
|
||||
success: false,
|
||||
err: 'Unauthorized action !',
|
||||
} })
|
||||
return
|
||||
}
|
||||
publishActionReply(this, { ...replyOpts, reply: {
|
||||
success: true,
|
||||
payload: this.getAccessRights(),
|
||||
} })
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user