forked from sent/waves
482 lines
19 KiB
JavaScript
482 lines
19 KiB
JavaScript
var GroupHoldr;
|
|
(function (GroupHoldr_1) {
|
|
"use strict";
|
|
/**
|
|
* A general utility to keep Arrays and/or Objects by key names within a
|
|
* container so they can be referenced automatically by those keys. Automation
|
|
* is made easier by more abstraction, such as by automatically generated add,
|
|
* remove, etc. methods.
|
|
*/
|
|
var GroupHoldr = (function () {
|
|
/**
|
|
* @param {IGroupHoldrSettings} settings
|
|
*/
|
|
function GroupHoldr(settings) {
|
|
if (typeof settings === "undefined") {
|
|
throw new Error("No settings object given to GroupHoldr.");
|
|
}
|
|
if (typeof settings.groupNames === "undefined") {
|
|
throw new Error("No groupNames given to GroupHoldr.");
|
|
}
|
|
if (typeof settings.groupTypes === "undefined") {
|
|
throw new Error("No groupTypes given to GroupHoldr.");
|
|
}
|
|
// These functions containers are filled in setGroupNames
|
|
this.functions = {
|
|
"setGroup": {},
|
|
"getGroup": {},
|
|
"set": {},
|
|
"get": {},
|
|
"add": {},
|
|
"delete": {}
|
|
};
|
|
this.setGroupNames(settings.groupNames, settings.groupTypes);
|
|
}
|
|
/* Simple gets
|
|
*/
|
|
/**
|
|
* @return {Object} The Object with Object<Function>s for each action
|
|
* available on groups.
|
|
*/
|
|
GroupHoldr.prototype.getFunctions = function () {
|
|
return this.functions;
|
|
};
|
|
/**
|
|
* @return {Object} The Object storing each of the internal groups.
|
|
*/
|
|
GroupHoldr.prototype.getGroups = function () {
|
|
return this.groups;
|
|
};
|
|
/**
|
|
* @param {String} name
|
|
* @return {Mixed} The group of the given name.
|
|
*/
|
|
GroupHoldr.prototype.getGroup = function (name) {
|
|
return this.groups[name];
|
|
};
|
|
/**
|
|
* @return {String[]} An Array containing each of the group names.
|
|
*/
|
|
GroupHoldr.prototype.getGroupNames = function () {
|
|
return this.groupNames;
|
|
};
|
|
/* Group/ordering manipulators
|
|
*/
|
|
/**
|
|
* Switches a value from one group to another, regardless of group types.
|
|
*
|
|
* @param {Mixed} value The value being moved from one group to another.
|
|
* @param {String} groupNameOld The name of the group to move out of.
|
|
* @param {String} groupNameNew The name of the group to move into.
|
|
* @param {Mixed} [keyOld] What key the value used to be under (required if
|
|
* the old group is an Object).
|
|
* @param {Mixed} [keyNew] Optionally, what key the value will now be under
|
|
* (required if the new group is an Object).
|
|
*/
|
|
GroupHoldr.prototype.switchMemberGroup = function (value, groupNameOld, groupNameNew, keyOld, keyNew) {
|
|
var groupOld = this.groups[groupNameOld];
|
|
if (groupOld.constructor === Array) {
|
|
this.functions.delete[groupNameOld](value, keyOld);
|
|
}
|
|
else {
|
|
this.functions.delete[groupNameOld](keyOld);
|
|
}
|
|
this.functions.add[groupNameNew](value, keyNew);
|
|
};
|
|
/**
|
|
* Calls a function for each group, with that group as the first argument.
|
|
* Extra arguments may be passed in an array after scope and func, as in
|
|
* Function.apply's standard.
|
|
*
|
|
* @param {Mixed} scope An optional scope to call this from (if falsy,
|
|
* defaults to this).
|
|
* @param {Function} func A function to apply to each group.
|
|
* @param {Array} [args] An optional array of arguments to pass to the
|
|
* function after each group.
|
|
*/
|
|
GroupHoldr.prototype.applyAll = function (scope, func, args) {
|
|
if (args === void 0) { args = undefined; }
|
|
var i;
|
|
if (!args) {
|
|
args = [undefined];
|
|
}
|
|
else {
|
|
args.unshift(undefined);
|
|
}
|
|
if (!scope) {
|
|
scope = this;
|
|
}
|
|
for (i = this.groupNames.length - 1; i >= 0; i -= 1) {
|
|
args[0] = this.groups[this.groupNames[i]];
|
|
func.apply(scope, args);
|
|
}
|
|
args.shift();
|
|
};
|
|
/**
|
|
* Calls a function for each member of each group. Extra arguments may be
|
|
* passed in an array after scope and func, as in Function.apply's standard.
|
|
*
|
|
* @param {Mixed} scope An optional scope to call this from (if falsy,
|
|
* defaults to this).
|
|
* @param {Function} func A function to apply to each group.
|
|
* @param {Array} [args] An optional array of arguments to pass to the
|
|
* function after each group.
|
|
*/
|
|
GroupHoldr.prototype.applyOnAll = function (scope, func, args) {
|
|
if (args === void 0) { args = undefined; }
|
|
var group, i, j;
|
|
if (!args) {
|
|
args = [undefined];
|
|
}
|
|
else {
|
|
args.unshift(undefined);
|
|
}
|
|
if (!scope) {
|
|
scope = this;
|
|
}
|
|
for (i = this.groupNames.length - 1; i >= 0; i -= 1) {
|
|
group = this.groups[this.groupNames[i]];
|
|
if (group instanceof Array) {
|
|
for (j = 0; j < group.length; j += 1) {
|
|
args[0] = group[j];
|
|
func.apply(scope, args);
|
|
}
|
|
}
|
|
else {
|
|
for (j in group) {
|
|
if (group.hasOwnProperty(j)) {
|
|
args[0] = group[j];
|
|
func.apply(scope, args);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
/**
|
|
* Calls a function for each group, with that group as the first argument.
|
|
* Extra arguments may be passed after scope and func natively, as in
|
|
* Function.call's standard.
|
|
*
|
|
* @param {Mixed} [scope] An optional scope to call this from (if falsy,
|
|
* defaults to this).
|
|
* @param {Function} func A function to apply to each group.
|
|
*/
|
|
GroupHoldr.prototype.callAll = function (scope, func) {
|
|
var args = Array.prototype.slice.call(arguments, 1), i;
|
|
if (!scope) {
|
|
scope = this;
|
|
}
|
|
for (i = this.groupNames.length - 1; i >= 0; i -= 1) {
|
|
args[0] = this.groups[this.groupNames[i]];
|
|
func.apply(scope, args);
|
|
}
|
|
};
|
|
/**
|
|
* Calls a function for each member of each group. Extra arguments may be
|
|
* passed after scope and func natively, as in Function.call's standard.
|
|
*
|
|
* @param {Mixed} [scope] An optional scope to call this from (if falsy,
|
|
* defaults to this).
|
|
* @param {Function} func A function to apply to each group member.
|
|
*/
|
|
GroupHoldr.prototype.callOnAll = function (scope, func) {
|
|
var args = Array.prototype.slice.call(arguments, 1), group, i, j;
|
|
if (!scope) {
|
|
scope = this;
|
|
}
|
|
for (i = this.groupNames.length - 1; i >= 0; i -= 1) {
|
|
group = this.groups[this.groupNames[i]];
|
|
if (group instanceof Array) {
|
|
for (j = 0; j < group.length; j += 1) {
|
|
args[0] = group[j];
|
|
func.apply(scope, args);
|
|
}
|
|
}
|
|
else {
|
|
for (j in group) {
|
|
if (group.hasOwnProperty(j)) {
|
|
args[0] = group[j];
|
|
func.apply(scope, args);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
/**
|
|
* Clears each Array by setting its length to 0.
|
|
*/
|
|
GroupHoldr.prototype.clearArrays = function () {
|
|
var group, i;
|
|
for (i = this.groupNames.length - 1; i >= 0; i -= 1) {
|
|
group = this.groups[this.groupNames[i]];
|
|
if (group instanceof Array) {
|
|
group.length = 0;
|
|
}
|
|
}
|
|
};
|
|
/* Core setup logic
|
|
*/
|
|
/**
|
|
* Meaty function to reset, given an array of names an object of types
|
|
* Any pre-existing functions are cleared, and new ones are added as
|
|
* member objects and to {functions}.
|
|
*
|
|
* @param {String[]} names An array of names of groupings to be made
|
|
* @param {Mixed} types An associative array of the function types of
|
|
* the names given in names. This may also be taken
|
|
* in as a String, to be converted to an Object.
|
|
*/
|
|
GroupHoldr.prototype.setGroupNames = function (names, types) {
|
|
var scope = this, typeFunc, typeName;
|
|
if (!(names instanceof Array)) {
|
|
throw new Error("groupNames is not an Array");
|
|
}
|
|
// If there already were group names, clear them
|
|
if (this.groupNames) {
|
|
this.clearFunctions();
|
|
}
|
|
// Reset the group types and type names, to be filled next
|
|
this.groupNames = names;
|
|
this.groupTypes = {};
|
|
this.groupTypeNames = {};
|
|
// If groupTypes is an object, set custom group types for everything
|
|
if (types.constructor === Object) {
|
|
this.groupNames.forEach(function (name) {
|
|
scope.groupTypes[name] = scope.getTypeFunction(types[name]);
|
|
scope.groupTypeNames[name] = scope.getTypeName(types[name]);
|
|
});
|
|
}
|
|
else {
|
|
// Otherwise assume everything uses the same one, such as from a String
|
|
typeFunc = this.getTypeFunction(types);
|
|
typeName = this.getTypeName(types);
|
|
this.groupNames.forEach(function (name) {
|
|
scope.groupTypes[name] = typeFunc;
|
|
scope.groupTypeNames[name] = typeName;
|
|
});
|
|
}
|
|
// Create the containers, and set the modifying functions
|
|
this.setGroups();
|
|
this.setFunctions();
|
|
};
|
|
/**
|
|
* Removes any pre-existing "set", "get", etc. functions.
|
|
*/
|
|
GroupHoldr.prototype.clearFunctions = function () {
|
|
this.groupNames.forEach(function (name) {
|
|
// Delete member variable functions
|
|
delete this["set" + name + "Group"];
|
|
delete this["get" + name + "Group"];
|
|
delete this["set" + name];
|
|
delete this["get" + name];
|
|
delete this["add" + name];
|
|
delete this["delete" + name];
|
|
// Delete functions under .functions by making each type a new {}
|
|
this.functions.setGroup = {};
|
|
this.functions.getGroup = {};
|
|
this.functions.set = {};
|
|
this.functions.get = {};
|
|
this.functions.add = {};
|
|
this.functions.delete = {};
|
|
});
|
|
};
|
|
/**
|
|
* Resets groups to an empty object, and fills it with a new groupType for
|
|
* each name in groupNames
|
|
*/
|
|
GroupHoldr.prototype.setGroups = function () {
|
|
var scope = this;
|
|
this.groups = {};
|
|
this.groupNames.forEach(function (name) {
|
|
scope.groups[name] = new scope.groupTypes[name]();
|
|
});
|
|
};
|
|
/**
|
|
* Calls the function setters for each name in groupNames
|
|
* @remarks Those are: createFunction<XYZ>: "Set", "Get", "Add", "Del"
|
|
*/
|
|
GroupHoldr.prototype.setFunctions = function () {
|
|
var groupName, i;
|
|
for (i = 0; i < this.groupNames.length; i += 1) {
|
|
groupName = this.groupNames[i];
|
|
this.createFunctionSetGroup(groupName);
|
|
this.createFunctionGetGroup(groupName);
|
|
this.createFunctionSet(groupName);
|
|
this.createFunctionGet(groupName);
|
|
this.createFunctionAdd(groupName);
|
|
this.createFunctionDelete(groupName);
|
|
}
|
|
};
|
|
/* Function generators
|
|
*/
|
|
/**
|
|
* Creates a setGroup function under this and functions.setGroup.
|
|
*
|
|
* @param {String} name The name of the group, from groupNames.
|
|
*/
|
|
GroupHoldr.prototype.createFunctionSetGroup = function (name) {
|
|
var scope = this;
|
|
/**
|
|
* Sets the value of the group referenced by the name.
|
|
*
|
|
* @param {Mixed} value The new value for the group, which should be
|
|
* the same type as the group (Array or Object).
|
|
*/
|
|
this.functions.setGroup[name] = this["set" + name + "Group"] = function (value) {
|
|
scope.groups[name] = value;
|
|
};
|
|
};
|
|
/**
|
|
* Creates a getGroup function under this and functions.getGroup.
|
|
*
|
|
* @param {String} name The name of the group, from groupNames.
|
|
*/
|
|
GroupHoldr.prototype.createFunctionGetGroup = function (name) {
|
|
var scope = this;
|
|
/**
|
|
* @param {String} key The String key that references the group.
|
|
* @return {Mixed} The group referenced by the given key.
|
|
*/
|
|
this.functions.getGroup[name] = this["get" + name + "Group"] = function () {
|
|
return scope.groups[name];
|
|
};
|
|
};
|
|
/**
|
|
* Creates a set function under this and functions.set.
|
|
*
|
|
* @param {String} name The name of the group, from groupNames.
|
|
*/
|
|
GroupHoldr.prototype.createFunctionSet = function (name) {
|
|
/**
|
|
* Sets a value contained within the group.
|
|
*
|
|
* @param {Mixed} key The key referencing the value to obtain. This
|
|
* should be a Number if the group is an Array, or
|
|
* a String if the group is an Object.
|
|
* @param {Mixed} value
|
|
*/
|
|
this.functions.set[name] = this["set" + name] = function (key, value) {
|
|
if (value === void 0) { value = undefined; }
|
|
this.groups[name][key] = value;
|
|
};
|
|
};
|
|
/**
|
|
* Creates a get<type> function under this and functions.get
|
|
*
|
|
* @param {String} name The name of the group, from groupNames
|
|
*/
|
|
GroupHoldr.prototype.createFunctionGet = function (name) {
|
|
/**
|
|
* Gets the value within a group referenced by the given key.
|
|
*
|
|
* @param {Mixed} key The key referencing the value to obtain. This
|
|
* should be a Number if the group is an Array, or
|
|
* a String if the group is an Object.
|
|
* @return {Mixed} value
|
|
*/
|
|
this.functions.get[name] = this["get" + name] = function (key) {
|
|
return this.groups[name][key];
|
|
};
|
|
};
|
|
/**
|
|
* Creates an add function under this and functions.add.
|
|
*
|
|
* @param {String} name The name of the group, from groupNames
|
|
*/
|
|
GroupHoldr.prototype.createFunctionAdd = function (name) {
|
|
var group = this.groups[name];
|
|
if (this.groupTypes[name] === Object) {
|
|
/**
|
|
* Adds a value to the group, referenced by the given key.
|
|
*
|
|
* @param {String} key The String key to reference the value to be
|
|
* added.
|
|
* @param value
|
|
*/
|
|
this.functions.add[name] = this["add" + name] = function (value, key) {
|
|
group[key] = value;
|
|
};
|
|
}
|
|
else {
|
|
/**
|
|
* Adds a value to the group, referenced by the given key.
|
|
*
|
|
* @param {String} value
|
|
*/
|
|
this.functions.add[name] = this["add" + name] = function (value, key) {
|
|
if (key !== undefined) {
|
|
group[key] = value;
|
|
}
|
|
else {
|
|
group.push(value);
|
|
}
|
|
};
|
|
}
|
|
};
|
|
/**
|
|
* Creates a del (delete) function under this and functions.delete.
|
|
*
|
|
* @param {String} name The name of the group, from groupNames
|
|
*/
|
|
GroupHoldr.prototype.createFunctionDelete = function (name) {
|
|
var group = this.groups[name];
|
|
if (this.groupTypes[name] === Object) {
|
|
/**
|
|
* Deletes a value from the group, referenced by the given key.
|
|
*
|
|
* @param {String} key The String key to reference the value to be
|
|
* deleted.
|
|
*/
|
|
this.functions.delete[name] = this["delete" + name] = function (key) {
|
|
delete group[key];
|
|
};
|
|
}
|
|
else {
|
|
/**
|
|
* Deletes a value from the group, referenced by the given key.
|
|
*
|
|
* @param {Mixed} value The value to be deleted.
|
|
*/
|
|
this.functions.delete[name] = this["delete" + name] = function (value, index) {
|
|
if (index === void 0) { index = group.indexOf(value); }
|
|
if (index !== -1) {
|
|
group.splice(index, 1);
|
|
}
|
|
};
|
|
}
|
|
};
|
|
/* Utilities
|
|
*/
|
|
/**
|
|
* Returns the name of a type specified by a string ("Array" or "Object").
|
|
*
|
|
* @param {String} str The name of the type. If falsy, defaults to Array
|
|
* @return {String}
|
|
* @remarks The type is determined by the str[0]; if it exists and is "o",
|
|
* the outcome is "Object", otherwise it's "Array".
|
|
*/
|
|
GroupHoldr.prototype.getTypeName = function (str) {
|
|
if (str && str.charAt && str.charAt(0).toLowerCase() === "o") {
|
|
return "Object";
|
|
}
|
|
return "Array";
|
|
};
|
|
/**
|
|
* Returns function specified by a string (Array or Object).
|
|
*
|
|
* @param {String} str The name of the type. If falsy, defaults to Array
|
|
* @return {Function}
|
|
* @remarks The type is determined by the str[0]; if it exists and is "o",
|
|
* the outcome is Object, otherwise it's Array.
|
|
*/
|
|
GroupHoldr.prototype.getTypeFunction = function (str) {
|
|
if (str && str.charAt && str.charAt(0).toLowerCase() === "o") {
|
|
return Object;
|
|
}
|
|
return Array;
|
|
};
|
|
return GroupHoldr;
|
|
})();
|
|
GroupHoldr_1.GroupHoldr = GroupHoldr;
|
|
})(GroupHoldr || (GroupHoldr = {}));
|