]>
Commit | Line | Data |
---|---|---|
d0eb71f3 BB |
1 | 'use strict'; |
2 | ||
4908bfb5 BB |
3 | const Events = require('events'); |
4 | ||
85861d67 BB |
5 | /* |
6 | * Node Collections contain nodes, in order to keep the lists of nodes | |
7 | * that belong to each type. | |
8 | * | |
9 | * It has a type which is the class name of the node, and an array of | |
10 | * instances of that class. | |
11 | */ | |
d0eb71f3 | 12 | |
4908bfb5 | 13 | const NodeCollection = class NodeCollection extends Events { |
b3b840f8 RBR |
14 | |
15 | constructor(config) { | |
d0eb71f3 | 16 | |
2a2e1583 BB |
17 | super(); |
18 | ||
d0eb71f3 BB |
19 | this.nodes = []; |
20 | this.type = null; | |
21 | ||
b3b840f8 | 22 | Object.assign(this, config); |
d0eb71f3 BB |
23 | } |
24 | ||
25 | /* | |
26 | * Creates a node for an entity if it matches, and adds it to the | |
27 | * node list. | |
28 | * | |
29 | * Returns true if added, false otherwise. | |
30 | */ | |
b3b840f8 | 31 | add(entity) { |
d0eb71f3 BB |
32 | |
33 | if (this.type.matches(entity) && !this._entityExists(entity)) { | |
d0eb71f3 | 34 | |
b3b840f8 RBR |
35 | const node = new this.type({}); |
36 | const types = this.type.types; | |
37 | const typeNames = Object.keys(types); | |
6e4e4188 | 38 | |
d0eb71f3 | 39 | node.entity = entity; |
d0eb71f3 | 40 | |
b3b840f8 RBR |
41 | for (const typeName of typeNames) { |
42 | node[typeName] = entity.getComponent(types[typeName]); | |
d0eb71f3 BB |
43 | } |
44 | ||
45 | this.nodes.push(node); | |
4908bfb5 | 46 | this.emit('nodeAdded', { node }); |
d0eb71f3 BB |
47 | |
48 | return true; | |
49 | } | |
50 | ||
51 | return false; | |
52 | } | |
53 | ||
54 | /* | |
55 | * Removes an entity by removing its related node from the list of nodes | |
56 | * | |
57 | * returns true if it was removed, false otherwise. | |
58 | */ | |
b3b840f8 RBR |
59 | remove(entity) { |
60 | ||
61 | let foundIndex = -1; | |
b35f7b4b | 62 | let foundNode = null; |
b3b840f8 RBR |
63 | |
64 | const found = this.nodes.some((node, i) => { | |
d0eb71f3 | 65 | |
d0eb71f3 | 66 | if (node.entity === entity) { |
b3b840f8 | 67 | foundIndex = i; |
b35f7b4b | 68 | foundNode = node; |
b3b840f8 | 69 | return true; |
d0eb71f3 BB |
70 | } |
71 | }); | |
72 | ||
b3b840f8 RBR |
73 | if (found) { |
74 | this.nodes.splice(foundIndex, 1); | |
a2e39551 | 75 | this.emit('nodeRemoved', { node: foundNode }); |
85861d67 | 76 | } |
d0eb71f3 | 77 | |
b3b840f8 | 78 | return found; |
d0eb71f3 BB |
79 | } |
80 | ||
81 | /* | |
82 | * Checks whether we already have nodes for this entity. | |
83 | */ | |
b3b840f8 RBR |
84 | _entityExists(entity) { |
85 | ||
6e4e4188 | 86 | let found = false; |
d0eb71f3 | 87 | |
b3b840f8 | 88 | for (const node of this.nodes) { |
d0eb71f3 BB |
89 | if (node.entity === entity) { |
90 | found = true; | |
91 | } | |
92 | } | |
93 | ||
94 | return found; | |
95 | } | |
96 | }; | |
97 | ||
17e4efc7 BB |
98 | |
99 | /* | |
100 | * Make the node collection iterable without returning the array directly | |
101 | */ | |
102 | NodeCollection.prototype[Symbol.iterator] = function * () { | |
103 | ||
104 | yield* this.nodes; | |
105 | }; | |
106 | ||
b3b840f8 | 107 | module.exports = NodeCollection; |