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