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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
export { Component } from './serpentity/component.js';
export { Entity } from './serpentity/entity.js';
export { Node } from './serpentity/node.js';
export { System } from './serpentity/system.js';
import { NodeCollection } from './serpentity/node_collection.js';
/*
* Serpentity is the main engine class
*/
export default class Serpentity {
constructor(config) {
this.systems = [];
this.entities = [];
this._nodeCollections = [];
this._nodeCollectionKeys = [];
Object.assign(this, config);
}
/*
* Adds a system to the engine, so its update method will be called
* with the others. Triggers added hook.
*
* returns true if added succesfully, false if already added
*/
addSystem(system, priority) {
if (this.systems.indexOf(system) >= 0) {
return false;
}
system.priority = priority;
let lastIndex = 0;
const found = this.systems.some((existingSystem, i) => {
lastIndex = i;
if (existingSystem.priority >= system.priority) {
return true;
}
});
if (!found) {
lastIndex += 1;
}
this.systems.splice(lastIndex, 0, system);
system.added(this);
return true;
}
/*
* Removes a system from the engine, so its update method will no
* longer will be called. Triggers the removed hook.
*
* returns true if removed succesfully, false if already added
*/
removeSystem(system) {
const position = this.systems.indexOf(system);
if (position >= 0) {
this.systems[position].removed(this);
this.systems.splice(position, 1);
return true;
}
return false;
}
/*
* Adds an entity to the engine, adds to existing node collections
*
* returns true if added, false if already there
*/
addEntity(entity) {
if (this.entities.indexOf(entity) >= 0) {
return false;
}
this.entities.push(entity);
for (const collection of this._nodeCollections) {
collection.add(entity);
}
return true;
}
/*
* Removes entity from system, removing from all node collections
*
* returns true if removed, false if not present
*/
removeEntity(entity) {
const position = this.entities.indexOf(entity);
if (position >= 0) {
for (const collection of this._nodeCollections) {
collection.remove(entity);
}
this.entities.splice(position, 1);
return true;
}
return false;
}
/*
* Given a Node Class, retrieves a list of all the nodes for each
* applicable entity.
*/
getNodes(nodeType) {
const position = this._nodeCollectionKeys.indexOf(nodeType);
if (position >= 0) {
return this._nodeCollections[position];
}
const nodeCollection = new NodeCollection({
type: nodeType
});
this._nodeCollectionKeys.push(nodeType);
this._nodeCollections.push(nodeCollection);
for (const entity of this.entities) {
nodeCollection.add(entity);
}
return nodeCollection;
}
/*
* Calls update for every loaded system.
*/
update(dt) {
for (const system of this.systems) {
system.update(dt);
}
}
}
|