Skip to content

Commit

Permalink
Phaser.ArrayList is a new iterative object, similar in principal to a…
Browse files Browse the repository at this point in the history
… linked list but operating on a single array without modifying the object structure.

Input and Pointer now use the new ArrayList instead of a LinkedList, which resolve list item removable during callback issues.
Input.reset no longer resets every interactive item it knows of, because they are removed during the destroy phase and can now persist between States if needed.
  • Loading branch information
photonstorm committed Apr 25, 2014
1 parent 45aa486 commit 54b71dd
Show file tree
Hide file tree
Showing 10 changed files with 212 additions and 35 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ Version 2.0.4 - "Mos Shirare" - in development
* RandomDataGenerator.integerInRange uses a new method of rounding the value to an integer to avoid distribution probability issues (thanks PhaserFan)
* Updated the Device little / big endianess check.
* Time has been updated so that physicsElapsed can never be zero (falls back to 1/60), also fixes p2 elapsed time bug (thanks @georgiee, fix #758)
* Input and Pointer now use the new ArrayList instead of a LinkedList, which resolve list item removable during callback issues.
* Input.reset no longer resets every interactive item it knows of, because they are removed during the destroy phase and can now persist between States if needed.


### New Features
Expand All @@ -94,6 +96,8 @@ Version 2.0.4 - "Mos Shirare" - in development
* Device.support32bit is a new boolean that sets if the context supports 32bit pixel manipulation using array buffer views or not.
* BitmapData.processPixelRGB lets you perform a custom callback on every pixel in the BitmapData.
* P2.World now has its own pause and resume methods, so you can pause the physics simulation independent of your game (thanks @georgiee)
* Phaser.ArrayList is a new iterative object, similar in principal to a linked list but operating on a single array without modifying the object structure.



### Bug Fixes
Expand Down
1 change: 1 addition & 0 deletions build/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
<script src="$path/src/core/Camera.js"></script>
<script src="$path/src/core/State.js"></script>
<script src="$path/src/core/StateManager.js"></script>
<script src="$path/src/core/ArrayList.js"></script>
<script src="$path/src/core/LinkedList.js"></script>
<script src="$path/src/core/Signal.js"></script>
<script src="$path/src/core/SignalBinding.js"></script>
Expand Down
2 changes: 1 addition & 1 deletion plugins/Webcam.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Phaser.Plugin.Webcam.prototype.constructor = Phaser.Plugin.Webcam;

Phaser.Plugin.Webcam.prototype.start = function (width, height, context) {

console.log('Webcam start', width, height);
// console.log('Webcam start', width, height);

this.context = context;

Expand Down
191 changes: 191 additions & 0 deletions src/core/ArrayList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
/**
* @author Richard Davey <[email protected]>
* @copyright 2014 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* A basic linked list data structure.
*
* @class Phaser.ArrayList
* @constructor
*/
Phaser.ArrayList = function () {

/**
* @property {number} total - Number of objects in the list.
* @default
*/
this.total = 0;

/**
* @property {number} position - Current cursor position.
* @default
*/
this.position = 0;

/**
* @property {array} list - The list.
*/
this.list = [];

};

Phaser.ArrayList.prototype = {

/**
* Adds a new element to this linked list.
*
* @method Phaser.ArrayList#add
* @param {object} child - 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 child that was added.
*/
add: function (child) {

if (!this.exists(child))
{
this.list.push(child);
this.total++;
}

return child;

},

getIndex: function (child) {

var i = this.list.length;

while (i--)
{
if (this.list[i] === child)
{
return i;
}
}

return -1;

},

exists: function (child) {

var i = this.list.length;

while (i--)
{
if (this.list[i] === child)
{
return true;
}
}

return false;

},

/**
* Resets the first, last, next and previous node pointers in this list.
*
* @method Phaser.ArrayList#reset
*/
reset: function () {

this.list.length = 0;
this.total = 0;

},

/**
* Removes the given element from this linked list if it exists.
*
* @method Phaser.ArrayList#remove
* @param {object} child - The child to be removed from the list.
*/
remove: function (child) {

var idx = this.getIndex(child);

if (idx > -1)
{
this.list.splice(idx, 1);
this.total--;
return child;
}

},

/**
* 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.ArrayList#callAll
* @param {function} callback - The function to call.
* @param {...*} parameter - Additional parameters that will be passed to the callback.
*/
callAll: function (callback) {

var args = Array.prototype.splice.call(arguments, 1);

var i = this.list.length;

while (i--)
{
this.list[i][callback].apply(this.list[i], args);
}

}

};

/**
*
*
* @name Phaser.ArrayList#first
* @property {object} first - The first item in the list.
*/
Object.defineProperty(Phaser.ArrayList.prototype, "first", {

get: function () {

this.position = 0;

if (this.total > 0)
{
return this.list[0];
}
else
{
return null;
}

}

});

/**
*
*
* @name Phaser.ArrayList#next
* @property {object} next - Advanced the cursor and return.
*/
Object.defineProperty(Phaser.ArrayList.prototype, "next", {

get: function () {

if (this.position < this.total)
{
this.position++;

return this.list[this.position];
}
else
{
return null;
}

}

});

Phaser.ArrayList.prototype.constructor = Phaser.ArrayList;
2 changes: 1 addition & 1 deletion src/core/LinkedList.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Phaser.LinkedList = function () {
this.last = null;

/**
* @property {object} game - Number of elements in the list.
* @property {number} total - Number of elements in the list.
* @default
*/
this.total = 0;
Expand Down
4 changes: 2 additions & 2 deletions src/gameobjects/BitmapData.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,11 +198,11 @@ Phaser.BitmapData.prototype = {
* @param {number} r - The red color value, between 0 and 0xFF (255).
* @param {number} g - The green color value, between 0 and 0xFF (255).
* @param {number} b - The blue color value, between 0 and 0xFF (255).
* @param {number} [a=255] - The alpha color value, between 0 and 0xFF (255).
* @param {number} [a=1] - The alpha color value, between 0 and 1.
*/
fill: function (r, g, b, a) {

if (typeof a === 'undefined') { a = 255; }
if (typeof a === 'undefined') { a = 1; }

this.context.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
this.context.fillRect(0, 0, this.width, this.height);
Expand Down
8 changes: 3 additions & 5 deletions src/input/Input.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,10 +268,10 @@ Phaser.Input = function (game) {
this.onHold = null;

/**
* A linked list of interactive objects; the InputHandler components (belonging to Sprites) register themselves with this.
* @property {Phaser.LinkedList} interactiveItems
* A list of interactive objects. Te InputHandler components add and remove themselves from this.
* @property {Phaser.ArrayList} interactiveItems
*/
this.interactiveItems = new Phaser.LinkedList();
this.interactiveItems = new Phaser.ArrayList();

/**
* @property {Phaser.Point} _localPoint - Internal cache var.
Expand Down Expand Up @@ -521,8 +521,6 @@ Phaser.Input.prototype = {
this.onUp = new Phaser.Signal();
this.onTap = new Phaser.Signal();
this.onHold = new Phaser.Signal();

this.interactiveItems.callAll('reset');
}

this._pollCounter = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/input/InputHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ Phaser.InputHandler.prototype = {
start: function (priority, useHandCursor) {

priority = priority || 0;
if (typeof useHandCursor == 'undefined') { useHandCursor = false; }
if (typeof useHandCursor === 'undefined') { useHandCursor = false; }

// Turning on
if (this.enabled === false)
Expand Down
32 changes: 7 additions & 25 deletions src/input/Pointer.js
Original file line number Diff line number Diff line change
Expand Up @@ -364,15 +364,15 @@ Phaser.Pointer.prototype = {
this._highestRenderObject = null;
this._highestInputPriorityID = -1;

// Just run through the linked list
// Run through the list
if (this.game.input.interactiveItems.total > 0)
{
var currentNode = this.game.input.interactiveItems.next;
var currentNode = this.game.input.interactiveItems.first;

do
{
// If the object is using pixelPerfect checks, or has a higher InputManager.PriorityID OR if the priority ID is the same as the current highest AND it has a higher renderOrderID, then set it to the top
if (currentNode.validForInput(this._highestInputPriorityID, this._highestRenderOrderID))
if (currentNode && currentNode.validForInput(this._highestInputPriorityID, this._highestRenderOrderID))
{
if ((!fromClick && currentNode.checkPointerOver(this)) || (fromClick && currentNode.checkPointerDown(this)))
{
Expand All @@ -381,9 +381,9 @@ Phaser.Pointer.prototype = {
this._highestRenderObject = currentNode;
}
}
currentNode = currentNode.next;
currentNode = this.game.input.interactiveItems.next;
}
while (currentNode != null);
while (currentNode !== null);
}

if (this._highestRenderObject === null)
Expand Down Expand Up @@ -502,28 +502,10 @@ Phaser.Pointer.prototype = {
this.game.input.currentPointers--;
}

if (this.game.input.interactiveItems.total > 0)
{
var currentNode = this.game.input.interactiveItems.next;

do
{
if (currentNode)
{
currentNode._releasedHandler(this);
}

currentNode = currentNode.next;
}
while (currentNode != null);
}

if (this.targetObject)
{
this.targetObject._releasedHandler(this);
}
this.game.input.interactiveItems.callAll('_releasedHandler', this);

this.targetObject = null;

return this;

},
Expand Down
1 change: 1 addition & 0 deletions tasks/manifests/phaser.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"src/core/State.js",
"src/core/StateManager.js",
"src/core/LinkedList.js",
"src/core/ArrayList.js",
"src/core/Signal.js",
"src/core/SignalBinding.js",
"src/core/Filter.js",
Expand Down

0 comments on commit 54b71dd

Please sign in to comment.