waves/public/assets/g/mario/References/GroupHoldr-0.2.1.js
2025-04-09 17:11:14 -05:00

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 = {}));