Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement ObjectPool design pattern for FlxQuadTree #230

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/flixel/FlxG.as
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,8 @@ package flixel
if(ObjectOrGroup2 === ObjectOrGroup1)
ObjectOrGroup2 = null;
FlxQuadTree.divisions = FlxG.worldDivisions;
var quadTree:FlxQuadTree = new FlxQuadTree(FlxG.worldBounds.x,FlxG.worldBounds.y,FlxG.worldBounds.width,FlxG.worldBounds.height);
var quadTree:FlxQuadTree = FlxQuadTree.quadTreePool.getNew();
quadTree.init(FlxG.worldBounds.x, FlxG.worldBounds.y, FlxG.worldBounds.width, FlxG.worldBounds.height);
quadTree.load(ObjectOrGroup1,ObjectOrGroup2,NotifyCallback,ProcessCallback);
var result:Boolean = quadTree.execute();
quadTree.destroy();
Expand Down
88 changes: 66 additions & 22 deletions src/flixel/physics/FlxQuadTree.as
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package flixel.physics
{
import flixel.util.FlxList;
import flixel.util.FlxObjectPool;
import flixel.FlxBasic;
import flixel.FlxGroup;
import flixel.FlxObject;
Expand Down Expand Up @@ -185,19 +186,31 @@ package flixel.physics
static protected var _checkObjectHullHeight:Number;

/**
* Instantiate a new Quad Tree node.
* A pool to prevent repeated <code>new</code> calls.
*/
static public var quadTreePool:FlxObjectPool = new FlxObjectPool(FlxQuadTree);

/**
* local reference to FlxList's object pool
*/
protected var _listPool:FlxObjectPool;

/**
* Initialize a Quad Tree node.
*
* @param X The X-coordinate of the point in space.
* @param Y The Y-coordinate of the point in space.
* @param Width Desired width of this node.
* @param Height Desired height of this node.
* @param Parent The parent branch or node. Pass null to create a root.
*/
public function FlxQuadTree(X:Number, Y:Number, Width:Number, Height:Number, Parent:FlxQuadTree=null)
public function init(X:Number, Y:Number, Width:Number, Height:Number, Parent:FlxQuadTree=null):void
{
super(X,Y,Width,Height);
_headA = _tailA = new FlxList();
_headB = _tailB = new FlxList();
_listPool = FlxList.listPool;

make(X,Y,Width,Height);
_headA = _tailA = _listPool.getNew();
_headB = _tailB = _listPool.getNew();

//Copy the parent's children (if there are any)
if(Parent != null)
Expand All @@ -212,7 +225,7 @@ package flixel.physics
if(_tailA.object != null)
{
ot = _tailA;
_tailA = new FlxList();
_tailA = _listPool.getNew();
ot.next = _tailA;
}
_tailA.object = iterator.object;
Expand All @@ -227,7 +240,7 @@ package flixel.physics
if(_tailB.object != null)
{
ot = _tailB;
_tailB = new FlxList();
_tailB = _listPool.getNew();
ot.next = _tailB;
}
_tailB.object = iterator.object;
Expand Down Expand Up @@ -262,16 +275,13 @@ package flixel.physics
if(_headA != null)
_headA.destroy();
_headA = null;
if(_tailA != null)
_tailA.destroy();
_tailA = null;

if(_headB != null)
_headB.destroy();
_headB = null;
if(_tailB != null)
_tailB.destroy();
_tailB = null;

if(_northWestTree != null)
_northWestTree.destroy();
_northWestTree = null;
Expand All @@ -288,6 +298,8 @@ package flixel.physics
_object = null;
_processingCallback = null;
_notifyCallback = null;

quadTreePool.disposeObject(this);
}

/**
Expand Down Expand Up @@ -384,14 +396,22 @@ package flixel.physics
if((_objectTopEdge > _topEdge) && (_objectBottomEdge < _midpointY))
{
if(_northWestTree == null)
_northWestTree = new FlxQuadTree(_leftEdge,_topEdge,_halfWidth,_halfHeight,this);
{
_northWestTree = quadTreePool.getNew();
_northWestTree.init(_leftEdge, _topEdge, _halfWidth, _halfHeight, this);
}

_northWestTree.addObject();
return;
}
if((_objectTopEdge > _midpointY) && (_objectBottomEdge < _bottomEdge))
{
if(_southWestTree == null)
_southWestTree = new FlxQuadTree(_leftEdge,_midpointY,_halfWidth,_halfHeight,this);
{
_southWestTree = quadTreePool.getNew();
_southWestTree.init(_leftEdge, _midpointY, _halfWidth, _halfHeight, this);
}

_southWestTree.addObject();
return;
}
Expand All @@ -401,14 +421,22 @@ package flixel.physics
if((_objectTopEdge > _topEdge) && (_objectBottomEdge < _midpointY))
{
if(_northEastTree == null)
_northEastTree = new FlxQuadTree(_midpointX,_topEdge,_halfWidth,_halfHeight,this);
{
_northEastTree = quadTreePool.getNew();
_northEastTree.init(_midpointX, _topEdge, _halfWidth, _halfHeight, this);
}

_northEastTree.addObject();
return;
}
if((_objectTopEdge > _midpointY) && (_objectBottomEdge < _bottomEdge))
{
if(_southEastTree == null)
_southEastTree = new FlxQuadTree(_midpointX,_midpointY,_halfWidth,_halfHeight,this);
{
_southEastTree = quadTreePool.getNew();
_southEastTree.init(_midpointX, _midpointY, _halfWidth, _halfHeight, this);
}

_southEastTree.addObject();
return;
}
Expand All @@ -418,25 +446,41 @@ package flixel.physics
if((_objectRightEdge > _leftEdge) && (_objectLeftEdge < _midpointX) && (_objectBottomEdge > _topEdge) && (_objectTopEdge < _midpointY))
{
if(_northWestTree == null)
_northWestTree = new FlxQuadTree(_leftEdge,_topEdge,_halfWidth,_halfHeight,this);
{
_northWestTree = quadTreePool.getNew();
_northWestTree.init(_leftEdge, _topEdge, _halfWidth, _halfHeight, this);
}

_northWestTree.addObject();
}
if((_objectRightEdge > _midpointX) && (_objectLeftEdge < _rightEdge) && (_objectBottomEdge > _topEdge) && (_objectTopEdge < _midpointY))
{
if(_northEastTree == null)
_northEastTree = new FlxQuadTree(_midpointX,_topEdge,_halfWidth,_halfHeight,this);
{
_northEastTree = quadTreePool.getNew();
_northEastTree.init(_midpointX, _topEdge, _halfWidth, _halfHeight, this);
}

_northEastTree.addObject();
}
if((_objectRightEdge > _midpointX) && (_objectLeftEdge < _rightEdge) && (_objectBottomEdge > _midpointY) && (_objectTopEdge < _bottomEdge))
{
if(_southEastTree == null)
_southEastTree = new FlxQuadTree(_midpointX,_midpointY,_halfWidth,_halfHeight,this);
{
_southEastTree = quadTreePool.getNew();
_southEastTree.init(_midpointX, _midpointY, _halfWidth, _halfHeight, this);
}

_southEastTree.addObject();
}
if((_objectRightEdge > _leftEdge) && (_objectLeftEdge < _midpointX) && (_objectBottomEdge > _midpointY) && (_objectTopEdge < _bottomEdge))
{
if(_southWestTree == null)
_southWestTree = new FlxQuadTree(_leftEdge,_midpointY,_halfWidth,_halfHeight,this);
{
_southWestTree = quadTreePool.getNew();
_southWestTree.init(_leftEdge, _midpointY, _halfWidth, _halfHeight, this);
}

_southWestTree.addObject();
}
}
Expand All @@ -452,7 +496,7 @@ package flixel.physics
if(_tailA.object != null)
{
ot = _tailA;
_tailA = new FlxList();
_tailA = _listPool.getNew();
ot.next = _tailA;
}
_tailA.object = _object;
Expand All @@ -462,7 +506,7 @@ package flixel.physics
if(_tailB.object != null)
{
ot = _tailB;
_tailB = new FlxList();
_tailB = _listPool.getNew();
ot.next = _tailB;
}
_tailB.object = _object;
Expand Down
10 changes: 9 additions & 1 deletion src/flixel/util/FlxList.as
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,17 @@ package flixel.util
* Stores a reference to a <code>FlxObject</code>.
*/
public var object:FlxObject;

/**
* Stores a reference to the next link in the list.
*/
public var next:FlxList;


/**
* A pool to prevent repeated <code>new</code> calls
*/
static public var listPool:FlxObjectPool = new FlxObjectPool(FlxList);

/**
* Creates a new link, and sets <code>object</code> and <code>next</code> to <code>null</code>.
*/
Expand All @@ -36,6 +42,8 @@ package flixel.util
if(next != null)
next.destroy();
next = null;

listPool.disposeObject(this);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is why trying to destroy the same FlxList twice would be disastrous. If it's in the FlxObjectPool twice, then two completely different objects could get pointers to it, erroneously thinking they each had a unique FlxList

}
}
}
41 changes: 41 additions & 0 deletions src/flixel/util/FlxObjectPool.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package flixel.util
{
/**
* TODO: Write documentation
*
* @author moly
* @author greysondn
*/
public class FlxObjectPool
{
protected var _objects:Array;
protected var _objectClass:Class;

public function FlxObjectPool(ObjectClass:Class)
{
_objectClass = ObjectClass;
_objects = new Array();
}

public function getNew():*
{
var object:* = null;

if (_objects.length > 0)
{
object = _objects.pop();
}
else
{
object = new _objectClass();
}

return object;
}

public function disposeObject(OldObject:Object):void
{
_objects.push(OldObject);
}
}
}