@ste_tisci/ecs 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js DELETED
@@ -1,220 +0,0 @@
1
- // src/utils/SparseSet.ts
2
- function SparseSet() {
3
- const sparse = [];
4
- const dense = [];
5
- let size = 0;
6
- function has(eid) {
7
- const ID = getIndex(eid);
8
- const exist = ID !== void 0 && dense[ID] === eid;
9
- const isWhitinBounds = ID >= 0 && ID < size;
10
- return exist && isWhitinBounds;
11
- }
12
- function add(eid) {
13
- if (has(eid)) throw new Error(`ID ${eid} already present in the set`);
14
- sparse[eid] = size;
15
- dense[size] = eid;
16
- size++;
17
- }
18
- function remove(eid) {
19
- if (!has(eid)) throw new Error(`Cannot remove ID ${eid} because does not exists`);
20
- const ID = getIndex(eid);
21
- const last = dense[size - 1];
22
- dense[ID] = last;
23
- sparse[last] = ID;
24
- dense.pop();
25
- size--;
26
- delete sparse[eid];
27
- }
28
- function getIndex(eid) {
29
- return sparse[eid];
30
- }
31
- function getDense() {
32
- return dense;
33
- }
34
- function getSize() {
35
- return size;
36
- }
37
- return { has, add, remove, getIndex, getDense, getSize };
38
- }
39
-
40
- // src/ComponentStore.ts
41
- function ComponentStore() {
42
- const componentSet = SparseSet();
43
- const componentData = {};
44
- function add(eid, data) {
45
- if (componentSet.has(eid)) throw new Error(`Entity ${eid} already has this component`);
46
- const ID = componentSet.getSize();
47
- componentSet.add(eid);
48
- for (const key in data) {
49
- if (!componentData[key]) {
50
- componentData[key] = [];
51
- }
52
- componentData[key][ID] = data[key];
53
- }
54
- }
55
- function remove(eid) {
56
- if (!componentSet.has(eid)) throw new Error(`Entity ${eid} does not have this component`);
57
- const ID = componentSet.getIndex(eid);
58
- const lastID = componentSet.getSize() - 1;
59
- if (ID !== lastID) {
60
- for (const key of Object.keys(componentData)) {
61
- componentData[key][ID] = componentData[key][lastID];
62
- }
63
- }
64
- componentSet.remove(eid);
65
- for (const key in componentData) {
66
- componentData[key].pop();
67
- }
68
- }
69
- function getDense() {
70
- return componentSet.getDense();
71
- }
72
- function getData() {
73
- return componentData;
74
- }
75
- function getIndex(eid) {
76
- return componentSet.getIndex(eid);
77
- }
78
- function getSize() {
79
- return componentSet.getSize();
80
- }
81
- return { add, remove, getIndex, getDense, getData, getSize };
82
- }
83
-
84
- // src/EntityManager.ts
85
- function EntityManager(registry) {
86
- let nextID = 0;
87
- const recycledIDs = [];
88
- const bitMasks = [];
89
- function exists(eid) {
90
- const isWithinBounds = eid >= 0 && eid < nextID;
91
- const hasMask = bitMasks[eid] !== void 0;
92
- return isWithinBounds && hasMask;
93
- }
94
- function hasComponent(eid, name) {
95
- if (!exists(eid)) throw new Error(`Entity ${eid} does not exist`);
96
- const cid = registry.getID(name);
97
- return (bitMasks[eid] & 1n << BigInt(cid)) !== 0n;
98
- }
99
- function create() {
100
- const ID = recycledIDs.length > 0 ? recycledIDs.pop() : nextID++;
101
- bitMasks[ID] = 0n;
102
- return ID;
103
- }
104
- function remove(eid) {
105
- if (!exists(eid)) throw new Error(`Entity ${eid} does not exist`);
106
- bitMasks[eid] = void 0;
107
- recycledIDs.push(eid);
108
- }
109
- function addComponent(eid, name) {
110
- if (!exists(eid)) throw new Error(`Entity ${eid} does not exists`);
111
- if (hasComponent(eid, name)) throw new Error(`Entity ${eid} already has component ${name}`);
112
- const cid = registry.getID(name);
113
- bitMasks[eid] |= 1n << BigInt(cid);
114
- }
115
- function removeComponent(eid, name) {
116
- if (!exists(eid)) throw new Error(`Entity ${eid} does not exists`);
117
- if (!hasComponent(eid, name)) throw new Error(`Entity ${eid} does not have component ${name}`);
118
- const cid = registry.getID(name);
119
- bitMasks[eid] &= ~(1n << BigInt(cid));
120
- }
121
- function getMask(eid) {
122
- return bitMasks[eid];
123
- }
124
- return { exists, hasComponent, create, remove, addComponent, removeComponent, getMask };
125
- }
126
-
127
- // src/utils/ComponentRegistry.ts
128
- function createComponentRegistry() {
129
- const nameToID = /* @__PURE__ */ new Map();
130
- const IDtoName = /* @__PURE__ */ new Map();
131
- let nextID = 0;
132
- function register(name) {
133
- if (!nameToID.has(name)) {
134
- const eid = nextID++;
135
- nameToID.set(name, eid);
136
- IDtoName.set(eid, name);
137
- }
138
- }
139
- function getID(name) {
140
- const eid = nameToID.get(name);
141
- if (eid === void 0) throw new Error(`Component ${name} not registered`);
142
- return eid;
143
- }
144
- function getName(cid) {
145
- const name = IDtoName.get(cid);
146
- if (!name) throw new Error(`Component ID ${cid} not registered`);
147
- return name;
148
- }
149
- return { register, getID, getName };
150
- }
151
-
152
- // src/Ecs.ts
153
- function ECS() {
154
- const ComponentRegistry = createComponentRegistry();
155
- const Entities = EntityManager(ComponentRegistry);
156
- const internalStores = {};
157
- const components = {};
158
- function defineComponents(data) {
159
- for (const key in data) {
160
- ComponentRegistry.register(key);
161
- internalStores[key] = ComponentStore();
162
- components[key] = internalStores[key].getData();
163
- }
164
- }
165
- function createEntity() {
166
- return Entities.create();
167
- }
168
- function destroyEntity(eid) {
169
- const entityMask = Entities.getMask(eid);
170
- let cid = 0;
171
- let tempMask = entityMask;
172
- while (tempMask !== 0n) {
173
- if ((tempMask & 1n) !== 0n) {
174
- const name = ComponentRegistry.getName(cid);
175
- internalStores[name].remove(eid);
176
- }
177
- tempMask >>= 1n;
178
- cid++;
179
- }
180
- Entities.remove(eid);
181
- }
182
- function addComponent(eid, name, data) {
183
- Entities.addComponent(eid, name);
184
- internalStores[name].add(eid, data);
185
- }
186
- function removeComponent(eid, name) {
187
- Entities.removeComponent(eid, name);
188
- internalStores[name].remove(eid);
189
- }
190
- function* query(...componentName) {
191
- if (componentName.length === 0) return;
192
- let smallestStore = internalStores[componentName[0]];
193
- let smallestSize = smallestStore.getSize();
194
- for (let i = 1; i < componentName.length; i++) {
195
- const store = internalStores[componentName[i]];
196
- const size = store.getSize();
197
- if (size < smallestSize) {
198
- smallestStore = store;
199
- smallestSize = size;
200
- }
201
- }
202
- let targetMask = 0n;
203
- for (const name of componentName) {
204
- targetMask |= 1n << BigInt(ComponentRegistry.getID(name));
205
- }
206
- for (const eid of smallestStore.getDense()) {
207
- if ((Entities.getMask(eid) & targetMask) !== targetMask) continue;
208
- const result = {};
209
- for (const name of componentName) {
210
- const id = internalStores[name].getIndex(eid);
211
- result[name] = { id };
212
- }
213
- yield result;
214
- }
215
- }
216
- return { defineComponents, createEntity, destroyEntity, addComponent, removeComponent, query, components };
217
- }
218
- export {
219
- ECS
220
- };