/** * @author Richard Davey <rich@photonstorm.com> * @copyright 2016 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ /** * ArraySet is a Set data structure (items must be unique within the set) that also maintains order. * This allows specific items to be easily added or removed from the Set. * * Item equality (and uniqueness) is determined by the behavior of `Array.indexOf`. * * This used primarily by the Input subsystem. * * @class Phaser.ArraySet * @constructor * @param {any[]} [list=(new array)] - The backing array: if specified the items in the list _must_ be unique, per `Array.indexOf`, and the ownership of the array _should_ be relinquished to the ArraySet. */ Phaser.ArraySet = function (list) { /** * Current cursor position as established by `first` and `next`. * @property {integer} position * @default */ this.position = 0; /** * The backing array. * @property {any[]} list */ this.list = list || []; }; Phaser.ArraySet.prototype = { /** * Adds a new element to the end of the list. * If the item already exists in the list it is not moved. * * @method Phaser.ArraySet#add * @param {any} item - The element to add to this list. * @return {any} The item that was added. */ add: function (item) { if (!this.exists(item)) { this.list.push(item); } return item; }, /** * Gets the index of the item in the list, or -1 if it isn't in the list. * * @method Phaser.ArraySet#getIndex * @param {any} item - The element to get the list index for. * @return {integer} The index of the item or -1 if not found. */ getIndex: function (item) { return this.list.indexOf(item); }, /** * Gets an item from the set based on the property strictly equaling the value given. * Returns null if not found. * * @method Phaser.ArraySet#getByKey * @param {string} property - The property to check against the value. * @param {any} value - The value to check if the property strictly equals. * @return {any} The item that was found, or null if nothing matched. */ getByKey: function (property, value) { var i = this.list.length; while (i--) { if (this.list[i][property] === value) { return this.list[i]; } } return null; }, /** * Checks for the item within this list. * * @method Phaser.ArraySet#exists * @param {any} item - The element to get the list index for. * @return {boolean} True if the item is found in the list, otherwise false. */ exists: function (item) { return (this.list.indexOf(item) > -1); }, /** * Removes all the items. * * @method Phaser.ArraySet#reset */ reset: function () { this.list.length = 0; }, /** * Removes the given element from this list if it exists. * * @method Phaser.ArraySet#remove * @param {any} item - The item to be removed from the list. * @return {any} item - The item that was removed. */ remove: function (item) { var idx = this.list.indexOf(item); if (idx > -1) { this.list.splice(idx, 1); return item; } }, /** * Sets the property `key` to the given value on all members of this list. * * @method Phaser.ArraySet#setAll * @param {any} key - The property of the item to set. * @param {any} value - The value to set the property to. */ setAll: function (key, value) { var i = this.list.length; while (i--) { if (this.list[i]) { this.list[i][key] = value; } } }, /** * Calls a function on all members of this list, using the member as the context for the callback. * * If the `key` property is present it must be a function. * The function is invoked using the item as the context. * * @method Phaser.ArraySet#callAll * @param {string} key - The name of the property with the function to call. * @param {...*} parameter - Additional parameters that will be passed to the callback. */ callAll: function (key) { var args = Array.prototype.slice.call(arguments, 1); var i = this.list.length; while (i--) { if (this.list[i] && this.list[i][key]) { this.list[i][key].apply(this.list[i], args); } } }, /** * Removes every member from this ArraySet and optionally destroys it. * * @method Phaser.ArraySet#removeAll * @param {boolean} [destroy=false] - Call `destroy` on each member as it's removed from this set. */ removeAll: function (destroy) { if (destroy === undefined) { destroy = false; } var i = this.list.length; while (i--) { if (this.list[i]) { var item = this.remove(this.list[i]); if (destroy) { item.destroy(); } } } this.position = 0; this.list = []; } }; /** * Number of items in the ArraySet. Same as `list.length`. * * @name Phaser.ArraySet#total * @property {integer} total */ Object.defineProperty(Phaser.ArraySet.prototype, "total", { get: function () { return this.list.length; } }); /** * Returns the first item and resets the cursor to the start. * * @name Phaser.ArraySet#first * @property {any} first */ Object.defineProperty(Phaser.ArraySet.prototype, "first", { get: function () { this.position = 0; if (this.list.length > 0) { return this.list[0]; } else { return null; } } }); /** * Returns the the next item (based on the cursor) and advances the cursor. * * @name Phaser.ArraySet#next * @property {any} next */ Object.defineProperty(Phaser.ArraySet.prototype, "next", { get: function () { if (this.position < this.list.length) { this.position++; return this.list[this.position]; } else { return null; } } }); Phaser.ArraySet.prototype.constructor = Phaser.ArraySet;