Skip to content

Commit

Permalink
Add object pool for reusing node objects.
Browse files Browse the repository at this point in the history
  • Loading branch information
richardlord committed Feb 25, 2012
1 parent 5b8749f commit b0143e3
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 7 deletions.
4 changes: 2 additions & 2 deletions src/net/richardlord/ash/core/Entity.as
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ package net.richardlord.ash.core
public class Entity
{
public var name : String;
public var componentAdded : Signal2;
public var componentRemoved : Signal2;

internal var componentAdded : Signal2;
internal var componentRemoved : Signal2;
internal var previous : Entity;
internal var next : Entity;

Expand Down
23 changes: 21 additions & 2 deletions src/net/richardlord/ash/core/Family.as
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,19 @@ package net.richardlord.ash.core
internal var entities : Dictionary;
private var nodeClass : Class;
private var components : Dictionary;
private var nodePool : NodePool;
private var game : Game;

public function Family( nodeClass : Class )
public function Family( nodeClass : Class, game : Game )
{
this.nodeClass = nodeClass;
this.game = game;
init();
}

private function init() : void
{
nodePool = new NodePool( nodeClass );
nodes = new NodeList();
entities = new Dictionary();

Expand Down Expand Up @@ -50,7 +54,7 @@ package net.richardlord.ash.core
return;
}
}
var node : Node = new nodeClass();
var node : Node = nodePool.get();
node.entity = entity;
for ( componentClass in components )
{
Expand All @@ -68,10 +72,25 @@ package net.richardlord.ash.core
{
entity.componentRemoved.remove( componentRemoved );
nodes.remove( entities[entity] );
if( game.updating )
{
nodePool.cache( entities[entity] );
game.updateComplete.add( releaseNodePoolCache );
}
else
{
nodePool.dispose( entities[entity] );
}
delete entities[entity];
}
}

private function releaseNodePoolCache() : void
{
game.updateComplete.remove( releaseNodePoolCache );
nodePool.releaseCache();
}

internal function cleanUp() : void
{
for( var node : Node = nodes.head; node; node = node.next )
Expand Down
2 changes: 1 addition & 1 deletion src/net/richardlord/ash/core/Game.as
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ package net.richardlord.ash.core
{
return Family( families[nodeClass] ).nodes;
}
var family : Family = new Family( nodeClass );
var family : Family = new Family( nodeClass, this );
families[nodeClass] = family;
for( var entity : Entity = entities.head; entity; entity = entity.next )
{
Expand Down
54 changes: 54 additions & 0 deletions src/net/richardlord/ash/core/NodePool.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package net.richardlord.ash.core
{
internal class NodePool
{
private var tail : Node;
private var nodeClass : Class;
private var cacheTail : Node;

public function NodePool( nodeClass : Class )
{
this.nodeClass = nodeClass;
}

internal function get() : Node
{
if ( tail )
{
var node : Node = tail;
tail = tail.previous;
node.previous = null;
return node;
}
else
{
return new nodeClass();
}
}

internal function dispose( node : Node ) : void
{
node.next = null;
node.previous = tail;
tail = node;
}

internal function cache( node : Node ) : void
{
node.previous = cacheTail;
cacheTail = node;
}

internal function releaseCache() : void
{
while( cacheTail )
{
var node : Node = cacheTail;
cacheTail = node.previous;
node.next = null;
node.previous = tail;
tail = node;
}
}
}
}
48 changes: 48 additions & 0 deletions src/net/richardlord/ash/signals/ListenerNodePool.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package net.richardlord.ash.signals
{
internal class ListenerNodePool
{
private var tail : ListenerNode;
private var cacheTail : ListenerNode;

internal function get():ListenerNode
{
if( tail )
{
var node : ListenerNode = tail;
tail = tail.previous;
node.previous = null;
return node;
}
else
{
return new ListenerNode();
}
}

internal function dispose( node : ListenerNode ):void
{
node.next = null;
node.previous = tail;
tail = node;
}

internal function cache( node : ListenerNode ) : void
{
node.previous = cacheTail;
cacheTail = node;
}

internal function releaseCache() : void
{
while( cacheTail )
{
var node : ListenerNode = cacheTail;
cacheTail = node.previous;
node.next = null;
node.previous = tail;
tail = node;
}
}
}
}
15 changes: 13 additions & 2 deletions src/net/richardlord/ash/signals/SignalBase.as
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ package net.richardlord.ash.signals
internal var tail : ListenerNode;

private var nodes : Dictionary;
private var listenerNodePool : ListenerNodePool;
private var toAddHead : ListenerNode;
private var toAddTail : ListenerNode;
protected var dispatching : Boolean;
private var dispatching : Boolean;

public function SignalBase()
{
nodes = new Dictionary( true );
listenerNodePool = new ListenerNodePool();
}

protected function startDispatch() : void
Expand All @@ -45,6 +47,7 @@ package net.richardlord.ash.signals
toAddHead = null;
toAddTail = null;
}
listenerNodePool.releaseCache();
}

public function add( listener : Function ) : void
Expand All @@ -53,7 +56,7 @@ package net.richardlord.ash.signals
{
return;
}
var node : ListenerNode = new ListenerNode();
var node : ListenerNode = listenerNodePool.get();
node.listener = listener;
nodes[ listener ] = node;
if( dispatching )
Expand Down Expand Up @@ -114,6 +117,14 @@ package net.richardlord.ash.signals
node.next.previous = node.previous;
}
delete nodes[ listener ];
if( dispatching )
{
listenerNodePool.cache( node );
}
else
{
listenerNodePool.dispose( node );
}
}
}

Expand Down

0 comments on commit b0143e3

Please sign in to comment.