Skip to content

Implement ObjectPool design pattern for FlxQuadTree #230

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

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
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
@@ -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();
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;
@@ -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)
@@ -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;
@@ -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;
@@ -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;
@@ -288,6 +298,8 @@ package flixel.physics
_object = null;
_processingCallback = null;
_notifyCallback = null;

quadTreePool.disposeObject(this);
}

/**
@@ -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;
}
@@ -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;
}
@@ -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();
}
}
@@ -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;
@@ -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;
10 changes: 9 additions & 1 deletion src/flixel/util/FlxList.as
Original file line number Diff line number Diff line change
@@ -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>.
*/
@@ -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);
}
}
}