phaser4-rex-plugins
Version:
219 lines (180 loc) • 7.54 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.rexdatamonitorplugin = factory());
})(this, (function () { 'use strict';
var GetPropertyPath = function (parentPath, property) {
return (parentPath === '') ? property : `${parentPath}.${property}`;
};
var EmitEvents = function (eventEmitter, op, parentPath, property, value, prevValue) {
var propertyPath = GetPropertyPath(parentPath, property);
eventEmitter.emit(`${op}-${propertyPath}`, value, prevValue);
var parentPath = (parentPath === '') ? '*' : `${parentPath}.*`;
eventEmitter.emit(`${op}-${parentPath}`, property, value, prevValue);
eventEmitter.emit(`${op}`, propertyPath, value, prevValue);
};
var EmitAddKeyEvents = function (eventEmitter, eventName, parentPath, property, value) {
EmitEvents(eventEmitter, eventName, parentPath, property, value, undefined);
};
var EmitSetValueEvents = function (eventEmitter, eventName, parentPath, property, value, prevValue) {
EmitEvents(eventEmitter, eventName, parentPath, property, value, prevValue);
};
var EmitDeleteKeyEvents = function (eventEmitter, eventName, parentPath, property) {
EmitEvents(eventEmitter, eventName, parentPath, property, undefined, undefined);
};
var IsPlainObject = function (obj)
{
// Not plain objects:
// - Any object or value whose internal [[Class]] property is not "[object Object]"
// - DOM nodes
// - window
if (typeof(obj) !== 'object' || obj.nodeType || obj === obj.window)
{
return false;
}
// Support: Firefox <20
// The try/catch suppresses exceptions thrown when attempting to access
// the "constructor" property of certain host objects, ie. |window.location|
// https://bugzilla.mozilla.org/show_bug.cgi?id=814622
try
{
if (obj.constructor && !({}).hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf'))
{
return false;
}
}
catch (e)
{
return false;
}
// If the function hasn't returned already, we're confident that
// |obj| is a plain object, created by {} or constructed with new Object
return true;
};
var AddMonitor = function (data, eventEmitter, eventNames, parentPath, subKey) {
if (subKey) {
parentPath = GetPropertyPath(parentPath, subKey);
}
var monitor;
if (Array.isArray(data)) {
monitor = AddArrayMonitor(data, eventEmitter, eventNames, parentPath);
} else {
monitor = AddDictionaryMonitor(data, eventEmitter, eventNames, parentPath);
}
for (var property in data) {
var value = data[property];
if (!IsPlainObject(value)) {
// Number or string
EmitAddKeyEvents(eventEmitter, eventNames.addKey, parentPath, property, value);
} else {
// Dictionary or array
EmitAddKeyEvents(eventEmitter, eventNames.addKey, parentPath, property, value);
// Replace value by monitor
value = AddMonitor(value, eventEmitter, eventNames, parentPath, property);
Reflect.set(data, property, value);
}
}
return monitor;
};
var ProcessSetTargetAction = function (
target, property, value,
eventEmitter, eventNames, parentPath
) {
var prevValue, eventName, fireEventCallback;
if (!Reflect.has(target, property)) {
// Add new key
prevValue = undefined;
eventName = eventNames.addKey;
fireEventCallback = EmitAddKeyEvents;
} else {
// Set key
prevValue = Reflect.get(target, property);
eventName = eventNames.setKey;
fireEventCallback = EmitSetValueEvents;
}
if (!IsPlainObject(value)) {
// Number or string
Reflect.set(target, property, value);
fireEventCallback(eventEmitter, eventName, parentPath, property, value, prevValue);
} else {
// Dictionary or array
fireEventCallback(eventEmitter, eventName, parentPath, property, value, prevValue);
value = AddMonitor(value, eventEmitter, eventNames, parentPath, property);
Reflect.set(target, property, value);
}
};
var AddDictionaryMonitor = function (data, eventEmitter, eventNames, parentPath) {
return new Proxy(data, {
set(target, property, value) {
ProcessSetTargetAction(
target, property, value,
eventEmitter, eventNames, parentPath
);
return true;
},
deleteProperty(target, property) {
if (Reflect.has(target, property)) {
Reflect.deleteProperty(target, property);
EmitDeleteKeyEvents(eventEmitter, eventNames.deleteKey, parentPath, property);
}
return true;
}
});
};
var AddArrayMonitor = function (data, eventEmitter, eventNames, parentPath) {
return new Proxy(data, {
set(target, property, value) {
if (property === 'length') { // Skip length property
return true;
}
ProcessSetTargetAction(
target, property, value,
eventEmitter, eventNames, parentPath
);
return true;
},
deleteProperty(target, property) {
Reflect.deleteProperty(target, property);
target.splice(property, 1);
EmitDeleteKeyEvents(eventEmitter, eventNames.deleteKey, parentPath, property);
return true;
}
});
};
var AddDataMonitor = function ({
data = {},
eventEmitter,
eventNames,
parentPath = '',
}) {
if (!eventNames) {
eventNames = {};
} else {
eventNames = { ...eventNames };
}
if (!eventNames.hasOwnProperty('addKey')) {
eventNames.addKey = 'add';
}
if (!eventNames.hasOwnProperty('setKey')) {
eventNames.setKey = 'set';
}
if (!eventNames.hasOwnProperty('deleteKey')) {
eventNames.deleteKey = 'del';
}
var proxyData = AddMonitor(data, eventEmitter, eventNames, parentPath);
return proxyData;
};
class DataMonitorPlugin extends Phaser.Plugins.BasePlugin {
constructor(pluginManager) {
super(pluginManager);
}
start() {
var eventEmitter = this.game.events;
eventEmitter.on('destroy', this.destroy, this);
}
add(config) {
return AddDataMonitor(config);
}
}
return DataMonitorPlugin;
}));