Skip to content

Commit

Permalink
Fix component removal from entity in nodelist, fix memory leak in Nod…
Browse files Browse the repository at this point in the history
…ePool, remove entity.clone()
  • Loading branch information
Brett Jephson committed Sep 4, 2013
1 parent 5369737 commit b19977c
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 123 deletions.
123 changes: 78 additions & 45 deletions build/ash.js
Original file line number Diff line number Diff line change
Expand Up @@ -518,9 +518,11 @@ define('ash-core/nodepool',[
tail: null,
cacheTail: null,
nodeClass: null,

constructor: function (nodeClass) {
components : null,

constructor: function (nodeClass, components) {
this.nodeClass = nodeClass;
this.components = components;
},

get: function() {
Expand All @@ -535,6 +537,10 @@ define('ash-core/nodepool',[
},

dispose: function( node ) {
this.components.forEach(function(componentClass, componentName) {
node[componentName] = null;
});
node.entity = null;
node.next = null;
node.previous = this.tail;
this.tail = node;
Expand All @@ -549,9 +555,7 @@ define('ash-core/nodepool',[
while( this.cacheTail ) {
var node = this.cacheTail;
this.cacheTail = node.previous;
node.next = null;
node.previous = this.tail;
this.tail = node;
this.dispose( node );
}
}
});
Expand Down Expand Up @@ -1301,14 +1305,14 @@ define('ash-core/componentmatchingfamily',[
return this.nodes;
});

var nodePool = this.nodePool = new NodePool(nodeClass);
this.nodes = new NodeList();
this.entities = new Dictionary();
this.components = new Dictionary();

nodePool.dispose(nodePool.get());
this.entities = new Dictionary();
this.components = new Dictionary();
this.nodePool = new NodePool( this.nodeClass, this.components );

this.nodePool.dispose( this.nodePool.get() );

var nodeClassPrototype = nodeClass.prototype;
var nodeClassPrototype = this.nodeClass.prototype;

for(var property in nodeClassPrototype) {
///TODO - tidy this up...
Expand Down Expand Up @@ -1686,31 +1690,32 @@ define('ash-core/entity',[
this.componentRemoved = new signals.Signal();
},

add: function (component, componentObject) {
componentObject = componentObject || component.constructor;
componentObject = componentObject.prototype;

if ( this.components.has( componentObject ) ) {
this.remove( componentObject );
}
this.components.add(componentObject, component);
this.componentAdded.dispatch( this, componentObject );
add: function (component, componentClass ) {
if( typeof componentClass === "undefined" )
{
componentClass = component.constructor;
}
if ( this.components.has( componentClass ) )
{
this.remove( componentClass );
}
this.components.add(componentClass, component);
this.componentAdded.dispatch( this, componentClass );
return this;
},

remove: function (componentObject) {
componentObject = componentObject.prototype;
var component = this.components.retrieve( componentObject );
remove: function ( componentClass ) {
var component = this.components.retrieve( componentClass );
if ( component ) {
this.components.remove( componentObject );
this.componentRemoved.dispatch( this, componentObject );
this.components.remove( componentClass );
this.componentRemoved.dispatch( this, componentClass );
return component;
}
return null;
},

get: function (componentObject) {
return this.components.retrieve( componentObject.prototype );
get: function (componentClass) {
return this.components.retrieve( componentClass );
},

/**
Expand All @@ -1725,22 +1730,8 @@ define('ash-core/entity',[
return componentArray;
},

has: function (componentObject) {
return this.components.has( componentObject.prototype );
},

clone: function () {
var copy = new Entity();
this.components.forEach( function( componentObject, component ) {
var newComponent = new componentObject.constructor();
for( var property in component ) {
if( component.hasOwnProperty( property ) ) {
newComponent[property] = component[property];
}
}
copy.add( newComponent );
} );
return copy;
has: function (componentClass) {
return this.components.has( componentClass );
}
});

Expand All @@ -1759,10 +1750,52 @@ define('ash-core/node',[
entity: null,
previous: null,
next: null,
constructor: function () { }
});

/**
* A simpler way to create a node.
*
* Example: creating a node for component classes Point & energy:
*
* var PlayerNode = Ash.Node.create({
* point: Point,
* energy: Energy
* });
*
* This is the simpler version from:
*
* var PlayerNode = Ash.Node.extend({
* point: null,
* energy: null,
*
* types: {
* point: Point,
* energy: Energy
* }
* });
*/
Node.create = function (schema) {
var processedSchema = {
types: {},
constructor: function () { }
};

// process schema
for (var propertyName in schema) {
if (schema.hasOwnProperty(propertyName)) {
var propertyType = schema[propertyName];
if (propertyType) {
processedSchema.types[propertyName] = propertyType;
}
processedSchema[propertyName] = null;
}
}

return Node.extend(processedSchema);
};

return Node;
});

Expand Down Expand Up @@ -1808,7 +1841,7 @@ define('ash-core/system',[
*/
define('ash/ash-framework',['require','ash-core/engine','ash-core/componentmatchingfamily','ash-core/entity','ash-core/entitylist','ash-core/family','ash-core/node','ash-core/nodelist','ash-core/nodepool','ash-core/system','ash-core/systemlist','brejep/class','signals'],function (require) {
var core = {
VERSION: '0.1.0'
VERSION: '0.2.0'
};

core.Engine = require('ash-core/engine');
Expand Down
2 changes: 1 addition & 1 deletion build/ash.min.js

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions src/ash/core/componentmatchingfamily.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ define([
return this.nodes;
});

var nodePool = this.nodePool = new NodePool(nodeClass);
this.nodes = new NodeList();
this.entities = new Dictionary();
this.components = new Dictionary();
this.entities = new Dictionary();
this.components = new Dictionary();
this.nodePool = new NodePool( this.nodeClass, this.components );

this.nodePool.dispose( this.nodePool.get() );

nodePool.dispose(nodePool.get());

var nodeClassPrototype = nodeClass.prototype;
var nodeClassPrototype = this.nodeClass.prototype;

for(var property in nodeClassPrototype) {
///TODO - tidy this up...
Expand Down
49 changes: 18 additions & 31 deletions src/ash/core/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,32 @@ define([
this.componentRemoved = new signals.Signal();
},

add: function (component, componentObject) {
componentObject = componentObject || component.constructor;
componentObject = componentObject.prototype;

if ( this.components.has( componentObject ) ) {
this.remove( componentObject );
add: function (component, componentClass ) {
if( typeof componentClass === "undefined" )
{
componentClass = component.constructor;
}
if ( this.components.has( componentClass ) )
{
this.remove( componentClass );
}
this.components.add(componentObject, component);
this.componentAdded.dispatch( this, componentObject );
this.components.add(componentClass, component);
this.componentAdded.dispatch( this, componentClass );
return this;
},

remove: function (componentObject) {
componentObject = componentObject.prototype;
var component = this.components.retrieve( componentObject );
remove: function ( componentClass ) {
var component = this.components.retrieve( componentClass );
if ( component ) {
this.components.remove( componentObject );
this.componentRemoved.dispatch( this, componentObject );
this.components.remove( componentClass );
this.componentRemoved.dispatch( this, componentClass );
return component;
}
return null;
},

get: function (componentObject) {
return this.components.retrieve( componentObject.prototype );
get: function (componentClass) {
return this.components.retrieve( componentClass );
},

/**
Expand All @@ -59,22 +60,8 @@ define([
return componentArray;
},

has: function (componentObject) {
return this.components.has( componentObject.prototype );
},

clone: function () {
var copy = new Entity();
this.components.forEach( function( componentObject, component ) {
var newComponent = new componentObject.constructor();
for( var property in component ) {
if( component.hasOwnProperty( property ) ) {
newComponent[property] = component[property];
}
}
copy.add( newComponent );
} );
return copy;
has: function (componentClass) {
return this.components.has( componentClass );
}
});

Expand Down
2 changes: 1 addition & 1 deletion src/ash/core/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ define([
entity: null,
previous: null,
next: null,

constructor: function () { }
});

Expand Down
14 changes: 9 additions & 5 deletions src/ash/core/nodepool.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ define([
tail: null,
cacheTail: null,
nodeClass: null,

constructor: function (nodeClass) {
components : null,

constructor: function (nodeClass, components) {
this.nodeClass = nodeClass;
this.components = components;
},

get: function() {
Expand All @@ -27,6 +29,10 @@ define([
},

dispose: function( node ) {
this.components.forEach(function(componentClass, componentName) {
node[componentName] = null;
});
node.entity = null;
node.next = null;
node.previous = this.tail;
this.tail = node;
Expand All @@ -41,9 +47,7 @@ define([
while( this.cacheTail ) {
var node = this.cacheTail;
this.cacheTail = node.previous;
node.next = null;
node.previous = this.tail;
this.tail = node;
this.dispose( node );
}
}
});
Expand Down
29 changes: 26 additions & 3 deletions test/spec/componentmatchingfamily.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ define ([
'use strict';

var engine, family;

// prepare MockNode
var MockNode = Ash.Node.create({
point: Point
Expand Down Expand Up @@ -128,6 +128,30 @@ define ([
}
});

test("nodeListContainsOnlyMatchingEntitiesWhenComponentRemoved", function() {
var entity1 = new Ash.Entity();
entity1.add( new Point(), Point );

var entity2 = new Ash.Entity();
entity2.add( new Point() );
entity2.add( new Point3() );

var entity3 = new Ash.Entity();
entity3.add( new Point() );

family.newEntity( entity1 );
family.newEntity( entity2 );
family.newEntity( entity3 );

entity1.remove( Point );
entity2.remove( Point );

var nodes = family.nodeList;
console.log( family.nodeList );
strictEqual( nodes.head.entity, entity3 );
strictEqual( nodes.tail.entity, entity3 );
});

test("nodeListContainsAllMatchingEntities", function() {
var entities = [],
i = 0;
Expand Down Expand Up @@ -176,5 +200,4 @@ define ([
family.cleanUp();
strictEqual( node.next, null );
});

});
});
3 changes: 1 addition & 2 deletions test/spec/engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,10 @@ define ([
this.components = new Dictionary();
this.nodeObject = nodeObject;
this.engine = engine;
this.nodePool = new Ash.NodePool( nodeObject );
this.nodePool = new Ash.NodePool( nodeObject, this.components );
this.nodePool.dispose( this.nodePool.get() );
for( var property in nodeObject ) {
if(nodeObject.hasOwnProperty(property) &&
property != "types" &&
property != "next" &&
property != "previous" &&
property != "constructor" &&
Expand Down
Loading

0 comments on commit b19977c

Please sign in to comment.