/** * @author Richard Davey <rich@photonstorm.com> * @copyright 2016 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ /** * A basic Linked List data structure. * * This implementation _modifies_ the `prev` and `next` properties of each item added: * - The `prev` and `next` properties must be writable and should not be used for any other purpose. * - Items _cannot_ be added to multiple LinkedLists at the same time. * - Only objects can be added. * * @class Phaser.LinkedList * @constructor */ Phaser.LinkedList = function () { /** * Next element in the list. * @property {object} next * @default */ this.next = null; /** * Previous element in the list. * @property {object} prev * @default */ this.prev = null; /** * First element in the list. * @property {object} first * @default */ this.first = null; /** * Last element in the list. * @property {object} last * @default */ this.last = null; /** * Number of elements in the list. * @property {integer} total * @default */ this.total = 0; }; Phaser.LinkedList.prototype = { /** * Adds a new element to this linked list. * * @method Phaser.LinkedList#add * @param {object} item - The element to add to this list. Can be a Phaser.Sprite or any other object you need to quickly iterate through. * @return {object} The item that was added. */ add: function (item) { // If the list is empty if (this.total === 0 && this.first === null && this.last === null) { this.first = item; this.last = item; this.next = item; item.prev = this; this.total++; return item; } // Gets appended to the end of the list, regardless of anything, and it won't have any children of its own (non-nested list) this.last.next = item; item.prev = this.last; this.last = item; this.total++; return item; }, /** * Resets the first, last, next and previous node pointers in this list. * * @method Phaser.LinkedList#reset */ reset: function () { this.first = null; this.last = null; this.next = null; this.prev = null; this.total = 0; }, /** * Removes the given element from this linked list if it exists. * * @method Phaser.LinkedList#remove * @param {object} item - The item to be removed from the list. */ remove: function (item) { if (this.total === 1) { this.reset(); item.next = item.prev = null; return; } if (item === this.first) { // It was 'first', make 'first' point to first.next this.first = this.first.next; } else if (item === this.last) { // It was 'last', make 'last' point to last.prev this.last = this.last.prev; } if (item.prev) { // make item.prev.next point to childs.next instead of item item.prev.next = item.next; } if (item.next) { // make item.next.prev point to item.prev instead of item item.next.prev = item.prev; } item.next = item.prev = null; if (this.first === null ) { this.last = null; } this.total--; }, /** * Calls a function on all members of this list, using the member as the context for the callback. * The function must exist on the member. * * @method Phaser.LinkedList#callAll * @param {function} callback - The function to call. */ callAll: function (callback) { if (!this.first || !this.last) { return; } var entity = this.first; do { if (entity && entity[callback]) { entity[callback].call(entity); } entity = entity.next; } while(entity != this.last.next); } }; Phaser.LinkedList.prototype.constructor = Phaser.LinkedList;