phaser4-rex-plugins
Version:
398 lines (335 loc) • 10.6 kB
JavaScript
import EventEmitterMethods from '../../../utils/eventemitter/StandAloneEventEmitterMethods.js';
import GetValue from '../../../utils/object/GetValue.js';
import CSVParser from 'papaparse/papaparse.min.js';
import InstMem from './InstMem.js';
import CmdHandlers from './commands/CmdHandlers.js';
import { WaitComplete } from '../../../utils/promise/WaitEvent.js';
import Timer from './timer/DefaultTimer.js';
class CSVScenarioLogic {
constructor(parent, config) {
if (parent === undefined) {
parent = {};
}
this.parent = parent;
// Event emitter
this.setEventEmitter(GetValue(config, 'eventEmitter', undefined));
this.timer = this.createTimer(parent, config);
this._timeScale = 1;
this.instMem = new InstMem(this);
this.cmdHandlers = new CmdHandlers(this);
this.resetFromJSON(config);
this.boot(parent, config);
}
// Override
boot(parent, config) {
return this;
}
// Override
createTimer(parent, config) {
return new Timer(parent);
}
resetFromJSON(o) {
this._inRunCmdLoop = false;
this.isRunning = GetValue(o, 'state', false);
this.isPaused = GetValue(o, 'pause', false);
this.waitEvent = GetValue(o, 'wait', undefined);
this.scope = GetValue(o, 'scope', undefined);
this.timeUnit = GetValue(o, 'timeUnit', 0);
this.cmdPrefix = GetValue(o, 'prefix', DEFAULT_PREFIX);
this.argsConvert = GetValue(o, 'argsConvert', true);
this.argsConvertScope = GetValue(o, 'argsConvertScope', undefined);
this.cmdHandlers.resetFromJSON(GetValue(o, 'handlers', undefined));
this.instMem.resetFromJSON(GetValue(o, 'instMem', undefined));
this.delimiter = GetValue(o, 'delimiter', ',');
this.translateCommandNameCallback = GetValue(o, 'translateCommandNameCallback', undefined);
return this;
}
toJSON() {
return {
state: this.isRunning,
pause: this.isPaused,
wait: this.waitEvent,
scope: this.scope,
timeUnit: this.timeUnit,
prefix: this.cmdPrefix,
argsConvert: this.argsConvert,
argsConvertScope: this.argsConvertScope,
handlers: this.cmdHandlers.toJSON(),
instMem: this.instMem.toJSON(),
delimiter: this.delimiter
};
}
shutdown() {
if (!this.parent) {
return
}
this.destroyEventEmitter();
this.clear();
this.timer.destroy();
this.parent = undefined;
}
destroy() {
this.shutdown();
}
load(strCmd, scope, config) {
this.clear();
this.timeUnit = GetValue(config, 'timeUnit', this.timeUnit);
if (typeof (this.timeUnit) === 'string') {
this.timeUnit = TIMEUNITMODE[this.timeUnit];
}
this.cmdPrefix = GetValue(config, 'prefix', this.cmdPrefix);
if (typeof (this.cmdPrefix) === 'string') {
this.cmdPrefix = new RegExp(this.cmdPrefix);
}
this.argsConvert = GetValue(config, 'argsConvert', this.argsConvert);
this.argsConvertScope = GetValue(config, 'argsConvertScope', this.argsConvertScope);
this.scope = scope;
this.delimiter = GetValue(config, 'delimiter', this.delimiter);
this.translateCommandNameCallback = GetValue(config, 'translateCommandNameCallback', this.translateCommandNameCallback);
this.append(strCmd);
return this;
}
clear() {
this.stop();
this.instMem.resetFromJSON();
this.cmdHandlers.resetFromJSON();
}
start(config) {
this.stop();
var label = GetValue(config, 'label', '');
this.offset = GetValue(config, 'offset', 0);
if (this.isDebugMode) {
this.log('Start at Label: ' + label);
}
var result = this.goto(label);
if (!result) {
return false;
}
this.isRunning = true;
this.runNextCmd();
return true;
}
play(config) {
this.start(config);
return this;
}
playPromise(config) {
var promise = WaitComplete(this);
this.start(config);
return promise;
}
getIndex(label) {
var index = this.getCmdHandler('label').getIndex(label);
if (index == null) {
this.error(`Label: ${label} is not found`);
}
return index;
}
goto(label) {
var index;
if (typeof (label) === 'string') {
index = this.getIndex(label);
} else {
index = label;
}
if (index == null) {
return false;
}
this.instMem.setNextIndex(index);
return true;
}
get timeScale() {
return this._timeScale;
}
set timeScale(value) {
this._timeScale = value;
this.timer.setTimeScale(value);
}
setTimeScale(timeScale) {
this.timeScale = timeScale;
return this;
}
wait(eventName) {
this.waitEvent = eventName;
if (typeof (eventName) === 'number') {
var delay = eventName;
if (this.timeUnit === 1) {
delay *= 1000;
}
var self = this;
this.timer.start(
delay,
function () { self.continue(eventName); }
);
} else {
this.emit(`wait.${eventName}`, this);
}
this.emit('wait', eventName, this);
return this;
}
stop() {
if (!this.isRunning) {
return this;
}
this.isRunning = false;
this.isPaused = false;
// clear wait event
this.waitEvent = undefined;
this.timer.stop();
return this;
}
complete() {
this.emit('complete', this.scope, this);
this.stop();
return this;
}
append(csvString) {
var arr = CSVParser.parse(csvString, {
delimiter: this.delimiter
}).data;
this.parse(arr);
return this;
}
pause() {
if (!this.isRunning) {
return this;
}
if (this.isPaused) {
return this;
}
this.isPaused = true;
this.timer.pause();
return this;
}
resume() {
if (!this.isRunning) {
return this;
}
if (!this.isPaused) {
return this;
}
this.isPaused = false;
this.timer.resume();
return this;
}
continue(eventName) {
if ((!this.isRunning) ||
this.isPaused ||
(this.waitEvent === undefined)) {
return this;
}
if ((eventName === true) || (eventName === this.waitEvent)) {
this.waitEvent = undefined;
this.runNextCmd();
}
return this;
}
get lastLabel() {
return this.cmdHandlers.cmds.label.lastLabel;
}
get previousLabel() {
return this.cmdHandlers.cmds.label.prevLabel;
}
get lastCustomCommandName() {
return this.cmdHandlers.cmds['-'].lastMethodName;
}
getCmdHandler(name) {
if (typeof (name) !== 'string') {
name = name[0];
}
return this.cmdHandlers.get(name);
}
parse(arr) {
var item, name, prefix = this.cmdPrefix;
for (var i = 0, len = arr.length; i < len; i++) {
item = arr[i];
name = item[0];
if (name === '-') {
this.appendCustomCommand(item);
} else if (!isNaN(name)) {
var time = parseFloat(name);
if (time > 0) {
// insert 'wait' command
this.appendCommand(['wait', time]);
}
this.appendCustomCommand(item);
} else if (prefix.test(name)) {
var innerMatch = name.match(prefix);
item[0] = innerMatch[1].toLowerCase();
var isValid = this.appendCommand(item);
if (!isValid) {
this.error(`Line ${i}: ${JSON.stringify(item)} is not a valid command`);
}
} else {
// insert 'wait' command
this.appendCommand(['wait', name]);
item[0] = '-';
this.appendCommand(item);
}
}
return this;
}
appendCommand(inst) {
var handler = this.getCmdHandler(inst);
if (handler == null) {
return false;
}
inst = handler.parse(inst, this.instMem.length);
if (inst) {
this.instMem.append(inst);
}
return true;
}
appendCustomCommand(inst) {
inst[0] = '-';
if (this.translateCommandNameCallback) {
inst[1] = this.translateCommandNameCallback(inst[1]);
}
return this.appendCommand(inst);
}
runNextCmd() {
if (this._inRunCmdLoop) { // prevent re-entry
return;
}
var instMem = this.instMem;
var inst;
this._inRunCmdLoop = true;
while (
this.isRunning &&
(!this.isPaused) &&
(this.waitEvent === undefined)
) {
inst = instMem.get();
instMem.setNextIndex();
if (inst == null) {
this.complete();
break;
}
this.getCmdHandler(inst).run(inst);
}
this._inRunCmdLoop = false;
return this;
}
log(msg) {
this.emit('log', msg, this.scope, this);
return this;
}
get isDebugMode() {
return (this.listenerCount('log') > 0);
}
error(msg) {
this.emit('error', msg, this.scope, this);
return this;
}
}
Object.assign(
CSVScenarioLogic.prototype,
EventEmitterMethods
);
const TIMEUNITMODE = {
ms: 0,
s: 1,
sec: 1
};
const DEFAULT_PREFIX = /^#([a-zA-Z]+)/;
export default CSVScenarioLogic;