forked from qiao/ces.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfamily.js
126 lines (111 loc) · 3.03 KB
/
family.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
var Class = require('./class'),
EntityList = require('./entitylist'),
Signal = require('./signal');
/**
* The family is a collection of entities having all the specified components.
* @class
*/
var Family = module.exports = Class.extend({
/**
* @constructor
* @param {Array} componentNames
*/
init: function (componentNames) {
/**
* @private
*/
this._componentNames = componentNames;
/**
* A linked list holding the entities;
* @private
*/
this._entities = new EntityList();
/**
* @public
* @readonly
*/
this.entityAdded = new Signal();
/**
* @public
* @readonly
*/
this.entityRemoved = new Signal();
},
/**
* Get the entities of this family.
* @public
* @return {Array}
*/
getEntities: function () {
return this._entities.toArray();
},
/**
* Add the entity into the family if match.
* @public
* @param {Entity} entity
*/
addEntityIfMatch: function (entity) {
if (!this._entities.has(entity) && this._matchEntity(entity)) {
this._entities.add(entity);
this.entityAdded.emit(entity);
}
},
/**
* Remove the entity into the family if match.
* @public
* @function
* @param {Entity} entity
*/
removeEntity: function (entity) {
if (this._entities.has(entity)) {
this._entities.remove(entity);
this.entityRemoved.emit(entity);
}
},
/**
* Handler to be called when a component is added to an entity.
* @public
* @param {Entity} entity
* @param {String} componentName
*/
onComponentAdded: function (entity, componentName) {
this.addEntityIfMatch(entity);
},
/**
* Handler to be called when a component is removed from an entity.
* @public
* @param {Entity} entity
* @param {String} componentName
*/
onComponentRemoved: function (entity, componentName) {
var names, i, len;
// return if the entity is not in this family
if (!this._entities.has(entity)) {
return;
}
// remove the node if the removed component is required by this family
names = this._componentNames;
for (i = 0, len = names.length; i < len; ++i) {
if (names[i] === componentName) {
this._entities.remove(entity);
this.entityRemoved.emit(entity);
}
}
},
/**
* Check if an entity belongs to this family.
* @private
* @param {Entity} entity
* @return {Boolean}
*/
_matchEntity: function (entity) {
var componentNames, i, len;
componentNames = this._componentNames;
for (i = 0, len = componentNames.length; i < len; ++i) {
if (!entity.hasComponent(componentNames[i])) {
return false;
}
}
return true;
}
});