]> git.r.bdr.sh - rbdr/serpentity/blame - lib/serpentity.js
Make node components event emitters
[rbdr/serpentity] / lib / serpentity.js
CommitLineData
19e91cdd
BB
1export { Component } from './serpentity/component.js';
2export { Entity } from './serpentity/entity.js';
3export { Node } from './serpentity/node.js';
4export { System } from './serpentity/system.js';
5
6import { NodeCollection } from './serpentity/node_collection.js';
d0eb71f3
BB
7
8/*
988ca1a3
RBR
9 * Serpentity is the main engine class
10 */
19e91cdd 11export default class Serpentity {
b3b840f8
RBR
12
13 constructor(config) {
d0eb71f3 14
d0eb71f3
BB
15 this.systems = [];
16 this.entities = [];
17 this._nodeCollections = [];
18 this._nodeCollectionKeys = [];
19
b3b840f8 20 Object.assign(this, config);
d0eb71f3
BB
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 */
b3b840f8 29 addSystem(system, priority) {
d0eb71f3
BB
30
31 if (this.systems.indexOf(system) >= 0) {
32 return false;
33 }
34
35 system.priority = priority;
36
b3b840f8
RBR
37 let lastIndex = 0;
38
39 const found = this.systems.some((existingSystem, i) => {
d0eb71f3 40
d0eb71f3
BB
41 lastIndex = i;
42 if (existingSystem.priority >= system.priority) {
d0eb71f3
BB
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 */
b3b840f8 62 removeSystem(system) {
d0eb71f3 63
b3b840f8 64 const position = this.systems.indexOf(system);
d0eb71f3
BB
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 */
b3b840f8
RBR
79 addEntity(entity) {
80
d0eb71f3
BB
81 if (this.entities.indexOf(entity) >= 0) {
82 return false;
83 }
19e91cdd 84
d0eb71f3
BB
85 this.entities.push(entity);
86
b3b840f8 87 for (const collection of this._nodeCollections) {
d0eb71f3 88 collection.add(entity);
b3b840f8 89 }
d0eb71f3
BB
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 */
b3b840f8 99 removeEntity(entity) {
d0eb71f3 100
b3b840f8 101 const position = this.entities.indexOf(entity);
d0eb71f3 102 if (position >= 0) {
b3b840f8 103 for (const collection of this._nodeCollections) {
d0eb71f3 104 collection.remove(entity);
b3b840f8 105 }
d0eb71f3
BB
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 */
b3b840f8 118 getNodes(nodeType) {
d0eb71f3 119
b3b840f8 120 const position = this._nodeCollectionKeys.indexOf(nodeType);
d0eb71f3
BB
121
122 if (position >= 0) {
988ca1a3 123 return this._nodeCollections[position];
d0eb71f3
BB
124 }
125
19e91cdd
BB
126 const nodeCollection = new NodeCollection({
127 type: nodeType
d0eb71f3
BB
128 });
129
130 this._nodeCollectionKeys.push(nodeType);
131 this._nodeCollections.push(nodeCollection);
132
b3b840f8 133 for (const entity of this.entities) {
d0eb71f3 134 nodeCollection.add(entity);
b3b840f8 135 }
d0eb71f3 136
17e4efc7 137 return nodeCollection;
d0eb71f3
BB
138 }
139
140 /*
141 * Calls update for every loaded system.
142 */
b3b840f8
RBR
143 update(dt) {
144
145 for (const system of this.systems) {
d0eb71f3 146 system.update(dt);
b3b840f8 147 }
d0eb71f3 148 }
19e91cdd 149}