]> git.r.bdr.sh - rbdr/serpentity/blob - lib/serpentity.js
Make node components event emitters
[rbdr/serpentity] / lib / serpentity.js
1 export { Component } from './serpentity/component.js';
2 export { Entity } from './serpentity/entity.js';
3 export { Node } from './serpentity/node.js';
4 export { System } from './serpentity/system.js';
5
6 import { NodeCollection } from './serpentity/node_collection.js';
7
8 /*
9 * Serpentity is the main engine class
10 */
11 export default class Serpentity {
12
13 constructor(config) {
14
15 this.systems = [];
16 this.entities = [];
17 this._nodeCollections = [];
18 this._nodeCollectionKeys = [];
19
20 Object.assign(this, config);
21 }
22
23 /*
24 * Adds a system to the engine, so its update method will be called
25 * with the others. Triggers added hook.
26 *
27 * returns true if added succesfully, false if already added
28 */
29 addSystem(system, priority) {
30
31 if (this.systems.indexOf(system) >= 0) {
32 return false;
33 }
34
35 system.priority = priority;
36
37 let lastIndex = 0;
38
39 const found = this.systems.some((existingSystem, i) => {
40
41 lastIndex = i;
42 if (existingSystem.priority >= system.priority) {
43 return true;
44 }
45 });
46
47 if (!found) {
48 lastIndex += 1;
49 }
50
51 this.systems.splice(lastIndex, 0, system);
52 system.added(this);
53 return true;
54 }
55
56 /*
57 * Removes a system from the engine, so its update method will no
58 * longer will be called. Triggers the removed hook.
59 *
60 * returns true if removed succesfully, false if already added
61 */
62 removeSystem(system) {
63
64 const position = this.systems.indexOf(system);
65 if (position >= 0) {
66 this.systems[position].removed(this);
67 this.systems.splice(position, 1);
68 return true;
69 }
70
71 return false;
72 }
73
74 /*
75 * Adds an entity to the engine, adds to existing node collections
76 *
77 * returns true if added, false if already there
78 */
79 addEntity(entity) {
80
81 if (this.entities.indexOf(entity) >= 0) {
82 return false;
83 }
84
85 this.entities.push(entity);
86
87 for (const collection of this._nodeCollections) {
88 collection.add(entity);
89 }
90
91 return true;
92 }
93
94 /*
95 * Removes entity from system, removing from all node collections
96 *
97 * returns true if removed, false if not present
98 */
99 removeEntity(entity) {
100
101 const position = this.entities.indexOf(entity);
102 if (position >= 0) {
103 for (const collection of this._nodeCollections) {
104 collection.remove(entity);
105 }
106
107 this.entities.splice(position, 1);
108 return true;
109 }
110
111 return false;
112 }
113
114 /*
115 * Given a Node Class, retrieves a list of all the nodes for each
116 * applicable entity.
117 */
118 getNodes(nodeType) {
119
120 const position = this._nodeCollectionKeys.indexOf(nodeType);
121
122 if (position >= 0) {
123 return this._nodeCollections[position];
124 }
125
126 const nodeCollection = new NodeCollection({
127 type: nodeType
128 });
129
130 this._nodeCollectionKeys.push(nodeType);
131 this._nodeCollections.push(nodeCollection);
132
133 for (const entity of this.entities) {
134 nodeCollection.add(entity);
135 }
136
137 return nodeCollection;
138 }
139
140 /*
141 * Calls update for every loaded system.
142 */
143 update(dt) {
144
145 for (const system of this.systems) {
146 system.update(dt);
147 }
148 }
149 }