UNPKG

mmir-lib

Version:

MMIR (Mobile Multimodal Interaction and Relay) library

145 lines (135 loc) 4.16 kB
/** * This is a Worker script that is used as "threaded queue" for managing SCION event execution: * * New events for SCION are queued in order to allow raising new events from within SCION-event-processing. * * <p> * This "threaded queue" receives messages from the "WebWorker environment engine" of * {@link mmir.dialogEngine} - see {@link mmir.state.StateEngineFactory.StateEngineWebWorkerImpl}. * * <p> * The message / work flow is as follows: * <ul> * <li>on receiving <code>queueJob</code>: add new event-job to the queue</li> * <li>on receiving <code>finishedJob</code>: * <li>if queue is empty: does nothing</li> * <li>if queue is not empty: take next job from queue and send it as a <code>processNextJob</code> message to SCION</li> * </li> * </ul> * * @module workers/scion-queue */ if(typeof self === 'undefined' && typeof process !== 'undefined'){ require('./nodeWorkerThreadsInit'); } /** * A JobQueue is an Array with additional property JobQueue.readyForJob {Boolean} * * @private * @interface * @name JobQueue * @augments Array * @property {Boolean} readyForJob flag that indicates if queue is ready for the next job. * * @see ~Job * @see Array */ /** * the Job object, describing jobs on a JobQueue * * @private * @interface * @name Job * @property {Number | String} [engineId] the engine's ID for which this job should be queued * @property {String} [event] OPTIONAL the event name (must be present for command "queueJob") * @property {any} [eventData] OPTIONAL event data * * @see ~JobQueue */ /** * dictionary of <code>jobId -> JobQueue</code> * * @private * @type {PlainObject} * * @see ~JobQueue */ var queues = {}; /** * Handler for received messages. * * @function * @name onmessage * @param {Object} evt the message object with<br> * @param {"finishedJob" | "queueJob" | "destroyQueue"} evt.data.command the message type / name (e.g. <tt>finishedJob</tt>)<br> * @param {Number | String} evt.data.engineId Number the engine's ID for which this job should be queued * @param {module:workers/scion-queue~Job} [evt.data.job] the job object (e.g. in case of command <tt>queueJob</tt> the job that will be queued) * * @public * @memberOf module:workers/scion-queue# */ self.onmessage = function(evt){ var data = evt.data; var queue = getQueue(data.engineId, data.command !== 'destroyQueue'); switch(data.command){ case 'finishedJob': queue.readyForJob = true; distributeJobs(queue); break; case 'queueJob': queue.push(data.job); distributeJobs(queue); break; case 'destroyQueue': delete queues[data.engineId]; break; default: console.warn('ScionQueueWorker: received unknown message ', evt); } }; /** * HELPER get queue for an engine (ID) * * @function * @private * * @param {Number | String} engineId the engine ID * @param {Boolean} [isCreate] if TRUE, the queue will be created if it does not exist yet * @return {module:workers/scion-queue~JobQuee} the queue for the engineId (if isCreate is FALSE, and no queue exits for the engineId, it will return UNDEFINED) */ function getQueue(engineId, isCreate){ var queue; if(queues[engineId]){ queue = queues[engineId]; } else if(isCreate){ queue = new Array(); queue.readyForJob = true; queues[engineId] = queue; } return queue; } /** * Handler for sending messages. * * <p> * In case of <code>finishedJob</code>: * take next job for the engine-queue and send it to SCION, i.e. post a message <tt>e</tt> with <br> * * {String} event.data.command = <tt>processNextJob</tt><br> * {Object} event.data.job the job object (that was added before to the queue with command / message <tt>queueJob</tt> * * * @function * @public * @param {module:workers/scion-queue~JobQueue} queue the job queue */ function distributeJobs(queue){ if(queue.readyForJob && queue.length > 0){ readyForJob = false; var job = queue.shift(); self.postMessage({ command: 'processNextJob', job: job }); } };