phaser4-rex-plugins
Version:
553 lines (454 loc) • 15.4 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.rexstatemanagerplugin = factory());
})(this, (function () { 'use strict';
var EventEmitterMethods = {
setEventEmitter(eventEmitter, EventEmitterClass) {
if (EventEmitterClass === undefined) {
EventEmitterClass = Phaser.Events.EventEmitter; // Use built-in EventEmitter class by default
}
this._privateEE = (eventEmitter === true) || (eventEmitter === undefined);
this._eventEmitter = (this._privateEE) ? (new EventEmitterClass()) : eventEmitter;
return this;
},
destroyEventEmitter() {
if (this._eventEmitter && this._privateEE) {
this._eventEmitter.shutdown();
}
return this;
},
getEventEmitter() {
return this._eventEmitter;
},
on() {
if (this._eventEmitter) {
this._eventEmitter.on.apply(this._eventEmitter, arguments);
}
return this;
},
once() {
if (this._eventEmitter) {
this._eventEmitter.once.apply(this._eventEmitter, arguments);
}
return this;
},
off() {
if (this._eventEmitter) {
this._eventEmitter.off.apply(this._eventEmitter, arguments);
}
return this;
},
emit(event) {
if (this._eventEmitter && event) {
this._eventEmitter.emit.apply(this._eventEmitter, arguments);
}
return this;
},
addListener() {
if (this._eventEmitter) {
this._eventEmitter.addListener.apply(this._eventEmitter, arguments);
}
return this;
},
removeListener() {
if (this._eventEmitter) {
this._eventEmitter.removeListener.apply(this._eventEmitter, arguments);
}
return this;
},
removeAllListeners() {
if (this._eventEmitter) {
this._eventEmitter.removeAllListeners.apply(this._eventEmitter, arguments);
}
return this;
},
listenerCount() {
if (this._eventEmitter) {
return this._eventEmitter.listenerCount.apply(this._eventEmitter, arguments);
}
return 0;
},
listeners() {
if (this._eventEmitter) {
return this._eventEmitter.listeners.apply(this._eventEmitter, arguments);
}
return [];
},
eventNames() {
if (this._eventEmitter) {
return this._eventEmitter.eventNames.apply(this._eventEmitter, arguments);
}
return [];
},
};
var GetValue = function (source, key, defaultValue) {
if (!source || typeof source === 'number') {
return defaultValue;
}
if (typeof (key) === 'string') {
if (source.hasOwnProperty(key)) {
return source[key];
}
if (key.indexOf('.') !== -1) {
key = key.split('.');
} else {
return defaultValue;
}
}
var keys = key;
var parent = source;
var value = defaultValue;
// Use for loop here so we can break early
for (var i = 0; i < keys.length; i++) {
key = keys[i];
if (parent.hasOwnProperty(key)) {
// Yes it has a key property, let's carry on down
value = parent[key];
parent = value;
}
else {
// Can't go any further, so reset to default
value = defaultValue;
break;
}
}
return value;
};
class StateManagerBase {
constructor(config) {
this._states = {};
this._stateLock = false;
this.enable = true;
this._start = undefined;
this._state = undefined;
this._prevState = undefined;
// Event emitter
var eventEmitter = GetValue(config, 'eventEmitter', undefined);
var EventEmitterClass = GetValue(config, 'EventEmitterClass', undefined);
this.setEventEmitter(eventEmitter, EventEmitterClass);
}
shutdown() {
this.destroyEventEmitter();
}
destroy() {
this.shutdown();
}
toJSON() {
return {
curState: this.state,
prevState: this.prevState,
enable: this.enable,
start: this._start
};
}
setEnable(e) {
if (e === undefined) {
e = true;
}
this.enable = e;
return this;
}
toggleEnable() {
this.setEnable(!this.enable);
return this;
}
getState(name) {
return this._states[name];
}
addState(name, state) {
if (typeof (name) !== 'string') {
state = name;
name = state.name;
}
this._states[name] = state;
return this;
}
addStates(states) {
if (Array.isArray(states)) {
for (var i = 0, cnt = states.length; i < cnt; i++) {
this.addState(states[i]);
}
} else {
for (var name in states) {
this.addState(name, states[name]);
}
}
return this;
}
removeState(name) {
if (this._states.hasOwnProperty(name)) {
delete this._states[name];
}
return this;
}
removeAllStates() {
for (var name in this._states) {
delete this._states[name];
}
return this;
}
set state(newState) {
if (!this.enable || this._stateLock) {
return;
}
if (this._state === newState) {
return;
}
this._prevState = this._state;
this._state = newState;
this._stateLock = true; // Lock state
this.emit('statechange', this);
if (this._prevState != null) {
var state = this.getState(this._prevState);
if (state && state.exit) {
state.exit(this);
}
this.emit(`exit_${this._prevState}`, this);
}
this._stateLock = false;
if (this._state != null) {
var state = this.getState(this._state);
if (state && state.enter) {
state.enter(this);
}
this.emit(`enter_${this._state}`, this);
}
}
get state() {
return this._state;
}
get prevState() {
return this._prevState;
}
get stateList() {
return Object.keys(this._states);
}
start(state) {
this._start = state;
this._prevState = undefined;
this._state = state; // Won't fire statechange events
return this;
}
goto(nextState) {
if (nextState != null) {
this.state = nextState;
}
return this;
}
next() {
var state = this.getState(this.state);
if (!state || !state.next) {
return this;
}
var nextState;
if (typeof (state.next) === 'string') {
nextState = state.next;
} else {
nextState = state.next(this);
}
this.goto(nextState);
return this;
}
runMethod(methodName, a1, a2, a3, a4, a5) {
var state = this.getState(this.state);
if (!state) {
return undefined;
}
var fn = state[methodName];
if (!fn) {
return undefined;
}
// Copy from eventemitter3
var len = arguments.length;
switch (len) {
case 1: return fn(this);
case 2: return fn(this, a1);
case 3: return fn(this, a1, a2);
case 4: return fn(this, a1, a2, a3);
case 5: return fn(this, a1, a2, a3, a4);
case 6: return fn(this, a1, a2, a3, a4, a5);
}
var args = Array.prototype.slice.call(arguments);
args[0] = this;
return fn.apply(undefined, args);
}
}
Object.assign(
StateManagerBase.prototype,
EventEmitterMethods
);
var HasListener = function (eventEmitter, eventName, fn, context, once) {
if (once === undefined) {
once = false;
}
var listeners = eventEmitter._events[eventName];
if (!listeners) {
return false;
}
for (var i = 0, cnt = listeners.length; i < cnt; i++) {
var listener = listeners[i];
if ((listener.fn === fn) &&
(listener.context === context) &&
(listener.once === once)
) {
return true;
}
}
return false;
};
class StateManager extends StateManagerBase {
constructor(config) {
super(config);
this._scene = GetValue(config, 'scene', undefined);
}
shutdown() {
this.stopUpdate();
this.stopPreUpdate();
this.stopPostUpdate();
this._scene = undefined;
super.shutdown();
}
getScene() {
return this._scene;
}
update(time, delta) {
this.runMethod('update', time, delta);
}
preupdate(time, delta) {
this.runMethod('preupdate', time, delta);
}
postupdate(time, delta) {
this.runMethod('postupdate', time, delta);
}
startUpdate(scene) {
if (!scene) {
scene = this._scene;
}
var eventEmitter = scene.sys.events;
if (HasListener(eventEmitter, 'update', this.update, this)) {
return this;
}
this._scene = scene;
eventEmitter.on('update', this.update, this);
return this;
}
stopUpdate() {
if (!this._scene) {
return this;
}
this._scene.sys.events.off('update', this.update, this);
return this;
}
startPreUpdate(scene) {
if (!scene) {
scene = this._scene;
}
var eventEmitter = scene.sys.events;
if (HasListener(eventEmitter, 'preupdate', this.preupdate, this)) {
return this;
}
this._scene = scene;
eventEmitter.on('preupdate', this.preupdate, this);
return this;
}
stopOreUpdate() {
if (!this._scene) {
return this;
}
this._scene.sys.events.off('preupdate', this.preupdate, this);
return this;
}
startPostUpdate(scene) {
if (!scene) {
scene = this._scene;
}
var eventEmitter = scene.sys.events;
if (HasListener(eventEmitter, 'postupdate', this.postupdate, this)) {
return this;
}
this._scene = scene;
eventEmitter.on('postupdate', this.postupdate, this);
return this;
}
stopPostUpdate() {
if (!this._scene) {
return this;
}
this._scene.sys.events.off('postupdate', this.postupdate, this);
return this;
}
}
var IsInValidKey = function (keys) {
return (keys == null) || (keys === '') || (keys.length === 0);
};
var GetEntry = function (target, keys, defaultEntry) {
var entry = target;
if (IsInValidKey(keys)) ; else {
if (typeof (keys) === 'string') {
keys = keys.split('.');
}
var key;
for (var i = 0, cnt = keys.length; i < cnt; i++) {
key = keys[i];
if ((entry[key] == null) || (typeof (entry[key]) !== 'object')) {
var newEntry;
if (i === cnt - 1) {
if (defaultEntry === undefined) {
newEntry = {};
} else {
newEntry = defaultEntry;
}
} else {
newEntry = {};
}
entry[key] = newEntry;
}
entry = entry[key];
}
}
return entry;
};
var SetValue = function (target, keys, value, delimiter) {
if (delimiter === undefined) {
delimiter = '.';
}
// no object
if (typeof (target) !== 'object') {
return;
}
// invalid key
else if (IsInValidKey(keys)) {
// don't erase target
if (value == null) {
return;
}
// set target to another object
else if (typeof (value) === 'object') {
target = value;
}
} else {
if (typeof (keys) === 'string') {
keys = keys.split(delimiter);
}
var lastKey = keys.pop();
var entry = GetEntry(target, keys);
entry[lastKey] = value;
}
return target;
};
class StateManagerPlugin extends Phaser.Plugins.BasePlugin {
constructor(pluginManager) {
super(pluginManager);
}
start() {
var eventEmitter = this.game.events;
eventEmitter.on('destroy', this.destroy, this);
}
add(config) {
return new StateManager(config);
}
}
SetValue(window, 'RexPlugins.StateManager', StateManager);
return StateManagerPlugin;
}));