@oasys/oecs 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.cjs +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +355 -404
- package/dist/schedule.d.ts +3 -0
- package/dist/schedule.d.ts.map +1 -1
- package/dist/world.d.ts +11 -1
- package/dist/world.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,37 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
var X = (a, t, e) => t in a ? F(a, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : a[t] = e;
|
|
3
|
-
var l = (a, t, e) => X(a, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
-
class Y extends Error {
|
|
1
|
+
class R extends Error {
|
|
5
2
|
constructor(t, e, s) {
|
|
6
3
|
super(t), this.is_operational = e, this.context = s, this.name = this.constructor.name, Error.captureStackTrace(this, this.constructor);
|
|
7
4
|
}
|
|
8
5
|
}
|
|
9
|
-
var
|
|
10
|
-
class
|
|
6
|
+
var q = /* @__PURE__ */ ((a) => (a.EID_MAX_INDEX_OVERFLOW = "EID_MAX_INDEX_OVERFLOW", a.EID_MAX_GEN_OVERFLOW = "EID_MAX_GEN_OVERFLOW", a.COMPONENT_NOT_REGISTERED = "COMPONENT_NOT_REGISTERED", a.ENTITY_NOT_ALIVE = "ENTITY_NOT_ALIVE", a.CIRCULAR_SYSTEM_DEPENDENCY = "CIRCULAR_SYSTEM_DEPENDENCY", a.DUPLICATE_SYSTEM = "DUPLICATE_SYSTEM", a.ARCHETYPE_NOT_FOUND = "ARCHETYPE_NOT_FOUND", a))(q || {});
|
|
7
|
+
class Y extends R {
|
|
11
8
|
constructor(t, e, s) {
|
|
12
9
|
super(e ?? t, !0, s), this.category = t;
|
|
13
10
|
}
|
|
14
11
|
}
|
|
15
|
-
var C = /* @__PURE__ */ ((a) => (a.ASSERTION_FAIL_CONDITION = "ASSERTION_FAIL_CONDITION", a.VALIDATION_FAIL_CONDITION = "VALIDATION_FAIL_CONDITION", a))(C || {});
|
|
16
|
-
class G extends Y {
|
|
17
|
-
constructor(t, e, s) {
|
|
18
|
-
super(e, !1, s), this.category = t;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
const P = (a) => Number.isInteger(a) && a >= 0;
|
|
22
12
|
function b(a, t, e) {
|
|
23
|
-
if (process.env.NODE_ENV !== "production" && !t(a))
|
|
24
|
-
throw new G(
|
|
25
|
-
C.VALIDATION_FAIL_CONDITION,
|
|
26
|
-
`Expected value to meet validation: ${e}`
|
|
27
|
-
);
|
|
28
13
|
return a;
|
|
29
14
|
}
|
|
30
|
-
const
|
|
31
|
-
class
|
|
15
|
+
const X = 4;
|
|
16
|
+
class v {
|
|
17
|
+
_words;
|
|
32
18
|
constructor(t) {
|
|
33
|
-
|
|
34
|
-
this._words = t ?? new Array($).fill(0);
|
|
19
|
+
this._words = t ?? new Array(X).fill(0);
|
|
35
20
|
}
|
|
36
21
|
has(t) {
|
|
37
22
|
const e = t >>> 5;
|
|
@@ -56,8 +41,8 @@ class T {
|
|
|
56
41
|
contains(t) {
|
|
57
42
|
const e = t._words, s = this._words, n = s.length;
|
|
58
43
|
for (let r = 0; r < e.length; r++) {
|
|
59
|
-
const
|
|
60
|
-
if (
|
|
44
|
+
const i = e[r];
|
|
45
|
+
if (i !== 0 && (r >= n || (s[r] & i) !== i))
|
|
61
46
|
return !1;
|
|
62
47
|
}
|
|
63
48
|
return !0;
|
|
@@ -65,22 +50,22 @@ class T {
|
|
|
65
50
|
equals(t) {
|
|
66
51
|
const e = this._words, s = t._words, n = e.length > s.length ? e.length : s.length;
|
|
67
52
|
for (let r = 0; r < n; r++) {
|
|
68
|
-
const
|
|
69
|
-
if (
|
|
53
|
+
const i = r < e.length ? e[r] : 0, _ = r < s.length ? s[r] : 0;
|
|
54
|
+
if (i !== _) return !1;
|
|
70
55
|
}
|
|
71
56
|
return !0;
|
|
72
57
|
}
|
|
73
58
|
copy() {
|
|
74
|
-
return new
|
|
59
|
+
return new v(this._words.slice());
|
|
75
60
|
}
|
|
76
61
|
copy_with_set(t) {
|
|
77
62
|
const e = t >>> 5, s = e + 1, n = this._words.length > s ? this._words.length : s, r = new Array(n).fill(0);
|
|
78
|
-
for (let
|
|
79
|
-
return r[e] |= 1 << (t & 31), new
|
|
63
|
+
for (let i = 0; i < this._words.length; i++) r[i] = this._words[i];
|
|
64
|
+
return r[e] |= 1 << (t & 31), new v(r);
|
|
80
65
|
}
|
|
81
66
|
copy_with_clear(t) {
|
|
82
67
|
const e = this._words.slice(), s = t >>> 5;
|
|
83
|
-
return s < e.length && (e[s] &= ~(1 << (t & 31))), new
|
|
68
|
+
return s < e.length && (e[s] &= ~(1 << (t & 31))), new v(e);
|
|
84
69
|
}
|
|
85
70
|
/** FNV-1a hash. Skips trailing zero words so differently-sized arrays with the same bits hash equally. */
|
|
86
71
|
hash() {
|
|
@@ -100,8 +85,8 @@ class T {
|
|
|
100
85
|
if (n === 0) continue;
|
|
101
86
|
const r = s << 5;
|
|
102
87
|
for (; n !== 0; ) {
|
|
103
|
-
const
|
|
104
|
-
t(r + _), n ^=
|
|
88
|
+
const i = n & -n >>> 0, _ = 31 - Math.clz32(i);
|
|
89
|
+
t(r + _), n ^= i;
|
|
105
90
|
}
|
|
106
91
|
}
|
|
107
92
|
}
|
|
@@ -113,28 +98,16 @@ class T {
|
|
|
113
98
|
this._words = s;
|
|
114
99
|
}
|
|
115
100
|
}
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if (t < 0 || t > k)
|
|
121
|
-
throw new g(u.EID_MAX_GEN_OVERFLOW);
|
|
122
|
-
}
|
|
123
|
-
return t << D | a;
|
|
124
|
-
}, m = (a) => a & S, R = (a) => a >> D, Q = (a) => b(
|
|
125
|
-
a,
|
|
126
|
-
P,
|
|
127
|
-
"ComponentID must be a non-negative integer"
|
|
128
|
-
), K = (a) => b(
|
|
129
|
-
a,
|
|
130
|
-
P,
|
|
131
|
-
"EventID must be a non-negative integer"
|
|
101
|
+
const A = 20, P = (1 << A) - 1, L = 31 - A, U = (1 << L) - 1, F = (a, t) => t << A | a, f = (a) => a & P, M = (a) => a >> A, z = (a) => b(
|
|
102
|
+
a
|
|
103
|
+
), V = (a) => b(
|
|
104
|
+
a
|
|
132
105
|
);
|
|
133
|
-
class
|
|
106
|
+
class C {
|
|
107
|
+
field_names;
|
|
108
|
+
columns;
|
|
109
|
+
reader;
|
|
134
110
|
constructor(t) {
|
|
135
|
-
l(this, "field_names");
|
|
136
|
-
l(this, "columns");
|
|
137
|
-
l(this, "reader");
|
|
138
111
|
this.field_names = t, this.columns = [];
|
|
139
112
|
for (let s = 0; s < t.length; s++)
|
|
140
113
|
this.columns.push([]);
|
|
@@ -160,36 +133,34 @@ class J {
|
|
|
160
133
|
t[e].length = 0;
|
|
161
134
|
}
|
|
162
135
|
}
|
|
163
|
-
const
|
|
164
|
-
a
|
|
165
|
-
P,
|
|
166
|
-
"ArchetypeID must be a non-negative integer"
|
|
136
|
+
const G = (a) => b(
|
|
137
|
+
a
|
|
167
138
|
);
|
|
168
|
-
class
|
|
139
|
+
class W {
|
|
140
|
+
id;
|
|
141
|
+
mask;
|
|
142
|
+
has_columns;
|
|
143
|
+
entity_ids = [];
|
|
144
|
+
length = 0;
|
|
145
|
+
edges = [];
|
|
146
|
+
// Sparse array indexed by ComponentID — undefined for absent components.
|
|
147
|
+
// Allows O(1) column group lookup by component.
|
|
148
|
+
column_groups = [];
|
|
149
|
+
// Dense list of ComponentIDs that have columns — used to iterate only
|
|
150
|
+
// data-bearing components in copy/add/remove operations.
|
|
151
|
+
_column_ids = [];
|
|
169
152
|
constructor(t, e, s) {
|
|
170
|
-
l(this, "id");
|
|
171
|
-
l(this, "mask");
|
|
172
|
-
l(this, "has_columns");
|
|
173
|
-
l(this, "entity_ids", []);
|
|
174
|
-
l(this, "length", 0);
|
|
175
|
-
l(this, "edges", []);
|
|
176
|
-
// Sparse array indexed by ComponentID — undefined for absent components.
|
|
177
|
-
// Allows O(1) column group lookup by component.
|
|
178
|
-
l(this, "column_groups", []);
|
|
179
|
-
// Dense list of ComponentIDs that have columns — used to iterate only
|
|
180
|
-
// data-bearing components in copy/add/remove operations.
|
|
181
|
-
l(this, "_column_ids", []);
|
|
182
153
|
if (this.id = t, this.mask = e, s)
|
|
183
154
|
for (let n = 0; n < s.length; n++) {
|
|
184
|
-
const r = s[n],
|
|
155
|
+
const r = s[n], i = new Array(r.field_names.length);
|
|
185
156
|
for (let h = 0; h < r.field_names.length; h++)
|
|
186
|
-
|
|
157
|
+
i[h] = [];
|
|
187
158
|
const _ = /* @__PURE__ */ Object.create(null);
|
|
188
159
|
for (let h = 0; h < r.field_names.length; h++)
|
|
189
|
-
_[r.field_names[h]] =
|
|
160
|
+
_[r.field_names[h]] = i[h];
|
|
190
161
|
this.column_groups[r.component_id] = {
|
|
191
162
|
layout: r,
|
|
192
|
-
columns:
|
|
163
|
+
columns: i,
|
|
193
164
|
record: _
|
|
194
165
|
}, this._column_ids.push(r.component_id);
|
|
195
166
|
}
|
|
@@ -209,18 +180,7 @@ class H {
|
|
|
209
180
|
}
|
|
210
181
|
/** Get a single field's column. Valid data: indices 0..entity_count-1. */
|
|
211
182
|
get_column(t, e) {
|
|
212
|
-
const s = this.column_groups[t];
|
|
213
|
-
if (process.env.NODE_ENV !== "production" && !s)
|
|
214
|
-
throw new g(
|
|
215
|
-
u.COMPONENT_NOT_REGISTERED,
|
|
216
|
-
`Component ${t} not in archetype ${this.id}`
|
|
217
|
-
);
|
|
218
|
-
const n = s.layout.field_index[e];
|
|
219
|
-
if (process.env.NODE_ENV !== "production" && n === void 0)
|
|
220
|
-
throw new g(
|
|
221
|
-
u.COMPONENT_NOT_REGISTERED,
|
|
222
|
-
`Field "${e}" does not exist on component`
|
|
223
|
-
);
|
|
183
|
+
const s = this.column_groups[t], n = s.layout.field_index[e];
|
|
224
184
|
return s.columns[n];
|
|
225
185
|
}
|
|
226
186
|
/** Get all columns for a component as { fieldName: number[] }. */
|
|
@@ -232,8 +192,8 @@ class H {
|
|
|
232
192
|
const n = this.column_groups[e];
|
|
233
193
|
if (!n) return;
|
|
234
194
|
const { field_names: r } = n.layout;
|
|
235
|
-
for (let
|
|
236
|
-
n.columns[
|
|
195
|
+
for (let i = 0; i < r.length; i++)
|
|
196
|
+
n.columns[i][t] = s[r[i]];
|
|
237
197
|
}
|
|
238
198
|
read_field(t, e, s) {
|
|
239
199
|
const n = this.column_groups[e];
|
|
@@ -244,12 +204,12 @@ class H {
|
|
|
244
204
|
/** Copy all shared component columns from source archetype at src_row into dst_row. */
|
|
245
205
|
copy_shared_from(t, e, s) {
|
|
246
206
|
const n = t.column_groups, r = this._column_ids;
|
|
247
|
-
for (let
|
|
248
|
-
const _ = r[
|
|
207
|
+
for (let i = 0; i < r.length; i++) {
|
|
208
|
+
const _ = r[i], h = n[_];
|
|
249
209
|
if (!h) continue;
|
|
250
|
-
const
|
|
251
|
-
for (let c = 0; c <
|
|
252
|
-
|
|
210
|
+
const o = this.column_groups[_];
|
|
211
|
+
for (let c = 0; c < o.columns.length; c++)
|
|
212
|
+
o.columns[c][s] = h.columns[c][e];
|
|
253
213
|
}
|
|
254
214
|
}
|
|
255
215
|
/**
|
|
@@ -262,8 +222,8 @@ class H {
|
|
|
262
222
|
const s = this._column_ids;
|
|
263
223
|
for (let n = 0; n < s.length; n++) {
|
|
264
224
|
const r = this.column_groups[s[n]];
|
|
265
|
-
for (let
|
|
266
|
-
r.columns[
|
|
225
|
+
for (let i = 0; i < r.columns.length; i++)
|
|
226
|
+
r.columns[i].push(0);
|
|
267
227
|
}
|
|
268
228
|
return this.length++, e;
|
|
269
229
|
}
|
|
@@ -277,17 +237,17 @@ class H {
|
|
|
277
237
|
let s = -1;
|
|
278
238
|
const n = this._column_ids;
|
|
279
239
|
if (t !== e) {
|
|
280
|
-
this.entity_ids[t] = this.entity_ids[e], s =
|
|
240
|
+
this.entity_ids[t] = this.entity_ids[e], s = f(this.entity_ids[t]);
|
|
281
241
|
for (let r = 0; r < n.length; r++) {
|
|
282
|
-
const
|
|
283
|
-
for (let _ = 0; _ <
|
|
284
|
-
|
|
242
|
+
const i = this.column_groups[n[r]];
|
|
243
|
+
for (let _ = 0; _ < i.columns.length; _++)
|
|
244
|
+
i.columns[_][t] = i.columns[_][e], i.columns[_].pop();
|
|
285
245
|
}
|
|
286
246
|
} else
|
|
287
247
|
for (let r = 0; r < n.length; r++) {
|
|
288
|
-
const
|
|
289
|
-
for (let _ = 0; _ <
|
|
290
|
-
|
|
248
|
+
const i = this.column_groups[n[r]];
|
|
249
|
+
for (let _ = 0; _ < i.columns.length; _++)
|
|
250
|
+
i.columns[_].pop();
|
|
291
251
|
}
|
|
292
252
|
return this.entity_ids.pop(), this.length--, s;
|
|
293
253
|
}
|
|
@@ -300,7 +260,7 @@ class H {
|
|
|
300
260
|
remove_entity_tag(t) {
|
|
301
261
|
const e = this.length - 1;
|
|
302
262
|
let s = -1;
|
|
303
|
-
return t !== e && (this.entity_ids[t] = this.entity_ids[e], s =
|
|
263
|
+
return t !== e && (this.entity_ids[t] = this.entity_ids[e], s = f(this.entity_ids[t])), this.entity_ids.pop(), this.length--, s;
|
|
304
264
|
}
|
|
305
265
|
get_edge(t) {
|
|
306
266
|
return this.edges[t];
|
|
@@ -313,61 +273,56 @@ function j(a, t, e) {
|
|
|
313
273
|
const s = a.get(t);
|
|
314
274
|
s !== void 0 ? s.push(e) : a.set(t, [e]);
|
|
315
275
|
}
|
|
316
|
-
const
|
|
317
|
-
class
|
|
276
|
+
const y = -1, S = Object.freeze(/* @__PURE__ */ Object.create(null));
|
|
277
|
+
class $ {
|
|
278
|
+
// --- Entity ID management ---
|
|
279
|
+
// Generational slot allocator: entity_generations[index] holds the current
|
|
280
|
+
// generation for that slot. Free indices are recycled via a stack.
|
|
281
|
+
entity_generations = [];
|
|
282
|
+
entity_high_water = 0;
|
|
283
|
+
entity_free_indices = [];
|
|
284
|
+
entity_alive_count = 0;
|
|
285
|
+
// --- Component metadata ---
|
|
286
|
+
// Parallel array indexed by ComponentID: field_names and field_index
|
|
287
|
+
// for building archetype column layouts.
|
|
288
|
+
component_metas = [];
|
|
289
|
+
component_count = 0;
|
|
290
|
+
// --- Event channels ---
|
|
291
|
+
// Parallel array indexed by EventID: each channel holds SoA columns + reader.
|
|
292
|
+
event_channels = [];
|
|
293
|
+
event_count = 0;
|
|
294
|
+
// --- Archetype management ---
|
|
295
|
+
archetypes = [];
|
|
296
|
+
// Hash-bucketed lookup: BitSet.hash() → ArchetypeID[] for deduplication
|
|
297
|
+
archetype_map = /* @__PURE__ */ new Map();
|
|
298
|
+
next_archetype_id = 0;
|
|
299
|
+
// Inverted index: ComponentID → set of ArchetypeIDs containing that component.
|
|
300
|
+
// Used by get_matching_archetypes to start from the smallest set.
|
|
301
|
+
component_index = /* @__PURE__ */ new Map();
|
|
302
|
+
// Registered queries: the Store pushes newly-created archetypes into matching
|
|
303
|
+
// query result arrays, so queries are always up-to-date.
|
|
304
|
+
registered_queries = [];
|
|
305
|
+
empty_archetype_id;
|
|
306
|
+
// entity_index → ArchetypeID (UNASSIGNED = not in any archetype)
|
|
307
|
+
entity_archetype = [];
|
|
308
|
+
// entity_index → row within its archetype (UNASSIGNED = no row)
|
|
309
|
+
entity_row = [];
|
|
310
|
+
// --- Deferred operation buffers ---
|
|
311
|
+
// Flat parallel arrays: pending_add_ids[i], pending_add_defs[i], pending_add_values[i]
|
|
312
|
+
// describe one deferred add. No per-operation object allocation.
|
|
313
|
+
pending_destroy = [];
|
|
314
|
+
pending_add_ids = [];
|
|
315
|
+
pending_add_defs = [];
|
|
316
|
+
pending_add_values = [];
|
|
317
|
+
pending_remove_ids = [];
|
|
318
|
+
pending_remove_defs = [];
|
|
318
319
|
constructor() {
|
|
319
|
-
|
|
320
|
-
// Generational slot allocator: entity_generations[index] holds the current
|
|
321
|
-
// generation for that slot. Free indices are recycled via a stack.
|
|
322
|
-
l(this, "entity_generations", []);
|
|
323
|
-
l(this, "entity_high_water", 0);
|
|
324
|
-
l(this, "entity_free_indices", []);
|
|
325
|
-
l(this, "entity_alive_count", 0);
|
|
326
|
-
// --- Component metadata ---
|
|
327
|
-
// Parallel array indexed by ComponentID: field_names and field_index
|
|
328
|
-
// for building archetype column layouts.
|
|
329
|
-
l(this, "component_metas", []);
|
|
330
|
-
l(this, "component_count", 0);
|
|
331
|
-
// --- Event channels ---
|
|
332
|
-
// Parallel array indexed by EventID: each channel holds SoA columns + reader.
|
|
333
|
-
l(this, "event_channels", []);
|
|
334
|
-
l(this, "event_count", 0);
|
|
335
|
-
// --- Archetype management ---
|
|
336
|
-
l(this, "archetypes", []);
|
|
337
|
-
// Hash-bucketed lookup: BitSet.hash() → ArchetypeID[] for deduplication
|
|
338
|
-
l(this, "archetype_map", /* @__PURE__ */ new Map());
|
|
339
|
-
l(this, "next_archetype_id", 0);
|
|
340
|
-
// Inverted index: ComponentID → set of ArchetypeIDs containing that component.
|
|
341
|
-
// Used by get_matching_archetypes to start from the smallest set.
|
|
342
|
-
l(this, "component_index", /* @__PURE__ */ new Map());
|
|
343
|
-
// Registered queries: the Store pushes newly-created archetypes into matching
|
|
344
|
-
// query result arrays, so queries are always up-to-date.
|
|
345
|
-
l(this, "registered_queries", []);
|
|
346
|
-
l(this, "empty_archetype_id");
|
|
347
|
-
// entity_index → ArchetypeID (UNASSIGNED = not in any archetype)
|
|
348
|
-
l(this, "entity_archetype", []);
|
|
349
|
-
// entity_index → row within its archetype (UNASSIGNED = no row)
|
|
350
|
-
l(this, "entity_row", []);
|
|
351
|
-
// --- Deferred operation buffers ---
|
|
352
|
-
// Flat parallel arrays: pending_add_ids[i], pending_add_defs[i], pending_add_values[i]
|
|
353
|
-
// describe one deferred add. No per-operation object allocation.
|
|
354
|
-
l(this, "pending_destroy", []);
|
|
355
|
-
l(this, "pending_add_ids", []);
|
|
356
|
-
l(this, "pending_add_defs", []);
|
|
357
|
-
l(this, "pending_add_values", []);
|
|
358
|
-
l(this, "pending_remove_ids", []);
|
|
359
|
-
l(this, "pending_remove_defs", []);
|
|
360
|
-
this.empty_archetype_id = this.arch_get_or_create_from_mask(new T());
|
|
320
|
+
this.empty_archetype_id = this.arch_get_or_create_from_mask(new v());
|
|
361
321
|
}
|
|
362
322
|
// =======================================================
|
|
363
323
|
// Archetype graph
|
|
364
324
|
// =======================================================
|
|
365
325
|
arch_get(t) {
|
|
366
|
-
if (process.env.NODE_ENV !== "production" && (t < 0 || t >= this.archetypes.length))
|
|
367
|
-
throw new g(
|
|
368
|
-
u.ARCHETYPE_NOT_FOUND,
|
|
369
|
-
`Archetype with ID ${t} not found`
|
|
370
|
-
);
|
|
371
326
|
return this.archetypes[t];
|
|
372
327
|
}
|
|
373
328
|
/**
|
|
@@ -381,25 +336,25 @@ class tt {
|
|
|
381
336
|
if (this.archetypes[s[h]].mask.equals(t))
|
|
382
337
|
return s[h];
|
|
383
338
|
}
|
|
384
|
-
const n =
|
|
339
|
+
const n = G(this.next_archetype_id++), r = [];
|
|
385
340
|
t.for_each((h) => {
|
|
386
|
-
const
|
|
341
|
+
const o = h, c = this.component_metas[o];
|
|
387
342
|
c && c.field_names.length > 0 && r.push({
|
|
388
|
-
component_id:
|
|
343
|
+
component_id: o,
|
|
389
344
|
field_names: c.field_names,
|
|
390
345
|
field_index: c.field_index
|
|
391
346
|
});
|
|
392
347
|
});
|
|
393
|
-
const
|
|
394
|
-
this.archetypes.push(
|
|
395
|
-
const
|
|
396
|
-
let c = this.component_index.get(
|
|
397
|
-
c || (c = /* @__PURE__ */ new Set(), this.component_index.set(
|
|
348
|
+
const i = new W(n, t, r);
|
|
349
|
+
this.archetypes.push(i), j(this.archetype_map, e, n), t.for_each((h) => {
|
|
350
|
+
const o = h;
|
|
351
|
+
let c = this.component_index.get(o);
|
|
352
|
+
c || (c = /* @__PURE__ */ new Set(), this.component_index.set(o, c)), c.add(n);
|
|
398
353
|
});
|
|
399
354
|
const _ = this.registered_queries;
|
|
400
355
|
for (let h = 0; h < _.length; h++) {
|
|
401
|
-
const
|
|
402
|
-
|
|
356
|
+
const o = _[h];
|
|
357
|
+
i.matches(o.include_mask) && (!o.exclude_mask || !i.mask.overlaps(o.exclude_mask)) && (!o.any_of_mask || i.mask.overlaps(o.any_of_mask)) && o.result.push(i);
|
|
403
358
|
}
|
|
404
359
|
return n;
|
|
405
360
|
}
|
|
@@ -408,7 +363,7 @@ class tt {
|
|
|
408
363
|
const s = this.arch_get(t);
|
|
409
364
|
if (s.mask.has(e)) return t;
|
|
410
365
|
const n = s.get_edge(e);
|
|
411
|
-
if (
|
|
366
|
+
if (n?.add != null) return n.add;
|
|
412
367
|
const r = this.arch_get_or_create_from_mask(
|
|
413
368
|
s.mask.copy_with_set(e)
|
|
414
369
|
);
|
|
@@ -419,7 +374,7 @@ class tt {
|
|
|
419
374
|
const s = this.arch_get(t);
|
|
420
375
|
if (!s.mask.has(e)) return t;
|
|
421
376
|
const n = s.get_edge(e);
|
|
422
|
-
if (
|
|
377
|
+
if (n?.remove != null) return n.remove;
|
|
423
378
|
const r = this.arch_get_or_create_from_mask(
|
|
424
379
|
s.mask.copy_with_clear(e)
|
|
425
380
|
);
|
|
@@ -441,29 +396,25 @@ class tt {
|
|
|
441
396
|
create_entity() {
|
|
442
397
|
let t, e;
|
|
443
398
|
this.entity_free_indices.length > 0 ? (t = this.entity_free_indices.pop(), e = this.entity_generations[t]) : (t = this.entity_high_water++, this.entity_generations[t] = 0, e = 0), this.entity_alive_count++;
|
|
444
|
-
const s =
|
|
445
|
-
return this.entity_archetype[t] = this.empty_archetype_id, this.entity_row[t] =
|
|
399
|
+
const s = F(t, e);
|
|
400
|
+
return this.entity_archetype[t] = this.empty_archetype_id, this.entity_row[t] = y, s;
|
|
446
401
|
}
|
|
447
402
|
/** Immediately destroy an entity, removing it from its archetype. */
|
|
448
403
|
destroy_entity(t) {
|
|
449
|
-
if (!this.is_alive(t))
|
|
450
|
-
if (process.env.NODE_ENV !== "production") throw new g(u.ENTITY_NOT_ALIVE);
|
|
404
|
+
if (!this.is_alive(t))
|
|
451
405
|
return;
|
|
406
|
+
const e = f(t), s = this.entity_row[e];
|
|
407
|
+
if (s !== y) {
|
|
408
|
+
const i = this.arch_get(this.entity_archetype[e]).remove_entity(s);
|
|
409
|
+
i !== -1 && (this.entity_row[i] = s);
|
|
452
410
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
o !== -1 && (this.entity_row[o] = s);
|
|
457
|
-
}
|
|
458
|
-
this.entity_archetype[e] = w, this.entity_row[e] = w;
|
|
459
|
-
const n = R(t);
|
|
460
|
-
if (process.env.NODE_ENV !== "production" && n >= k)
|
|
461
|
-
throw new g(u.EID_MAX_GEN_OVERFLOW);
|
|
462
|
-
this.entity_generations[e] = n + 1 & k, this.entity_free_indices.push(e), this.entity_alive_count--;
|
|
411
|
+
this.entity_archetype[e] = y, this.entity_row[e] = y;
|
|
412
|
+
const n = M(t);
|
|
413
|
+
this.entity_generations[e] = n + 1 & U, this.entity_free_indices.push(e), this.entity_alive_count--;
|
|
463
414
|
}
|
|
464
415
|
is_alive(t) {
|
|
465
|
-
const e =
|
|
466
|
-
return e < this.entity_high_water && this.entity_generations[e] ===
|
|
416
|
+
const e = f(t);
|
|
417
|
+
return e < this.entity_high_water && this.entity_generations[e] === M(t);
|
|
467
418
|
}
|
|
468
419
|
get entity_count() {
|
|
469
420
|
return this.entity_alive_count;
|
|
@@ -472,26 +423,22 @@ class tt {
|
|
|
472
423
|
// Deferred destruction
|
|
473
424
|
// =======================================================
|
|
474
425
|
destroy_entity_deferred(t) {
|
|
475
|
-
if (process.env.NODE_ENV !== "production" && !this.is_alive(t))
|
|
476
|
-
throw new g(u.ENTITY_NOT_ALIVE);
|
|
477
426
|
this.pending_destroy.push(t);
|
|
478
427
|
}
|
|
479
428
|
/** Flush all buffered entity destructions in batch. */
|
|
480
429
|
flush_destroyed() {
|
|
481
430
|
const t = this.pending_destroy;
|
|
482
431
|
if (t.length === 0) return;
|
|
483
|
-
const e = this.entity_archetype, s = this.entity_row, n = this.entity_generations, r = this.archetypes,
|
|
432
|
+
const e = this.entity_archetype, s = this.entity_row, n = this.entity_generations, r = this.archetypes, i = this.entity_high_water;
|
|
484
433
|
for (let _ = 0; _ < t.length; _++) {
|
|
485
|
-
const h = t[_],
|
|
486
|
-
if (
|
|
487
|
-
const
|
|
488
|
-
if (
|
|
489
|
-
const
|
|
490
|
-
|
|
434
|
+
const h = t[_], o = h & P, c = h >> A;
|
|
435
|
+
if (o >= i || n[o] !== c) continue;
|
|
436
|
+
const l = s[o];
|
|
437
|
+
if (l !== y) {
|
|
438
|
+
const u = r[e[o]], d = u.has_columns ? u.remove_entity(l) : u.remove_entity_tag(l);
|
|
439
|
+
d !== -1 && (s[d] = l);
|
|
491
440
|
}
|
|
492
|
-
|
|
493
|
-
throw new g(u.EID_MAX_GEN_OVERFLOW);
|
|
494
|
-
n[i] = c + 1 & k, this.entity_free_indices.push(i), this.entity_alive_count--;
|
|
441
|
+
e[o] = y, s[o] = y, n[o] = c + 1 & U, this.entity_free_indices.push(o), this.entity_alive_count--;
|
|
495
442
|
}
|
|
496
443
|
t.length = 0;
|
|
497
444
|
}
|
|
@@ -499,13 +446,9 @@ class tt {
|
|
|
499
446
|
return this.pending_destroy.length;
|
|
500
447
|
}
|
|
501
448
|
add_component_deferred(t, e, s) {
|
|
502
|
-
|
|
503
|
-
throw new g(u.ENTITY_NOT_ALIVE);
|
|
504
|
-
this.pending_add_ids.push(t), this.pending_add_defs.push(e), this.pending_add_values.push(s ?? M);
|
|
449
|
+
this.pending_add_ids.push(t), this.pending_add_defs.push(e), this.pending_add_values.push(s ?? S);
|
|
505
450
|
}
|
|
506
451
|
remove_component_deferred(t, e) {
|
|
507
|
-
if (process.env.NODE_ENV !== "production" && !this.is_alive(t))
|
|
508
|
-
throw new g(u.ENTITY_NOT_ALIVE);
|
|
509
452
|
this.pending_remove_ids.push(t), this.pending_remove_defs.push(e);
|
|
510
453
|
}
|
|
511
454
|
flush_structural() {
|
|
@@ -513,37 +456,37 @@ class tt {
|
|
|
513
456
|
}
|
|
514
457
|
/** Batch-apply all deferred component additions. */
|
|
515
458
|
_flush_adds() {
|
|
516
|
-
const t = this.pending_add_ids, e = this.pending_add_defs, s = this.pending_add_values, n = t.length, r = this.entity_archetype,
|
|
517
|
-
for (let
|
|
518
|
-
const
|
|
519
|
-
if (
|
|
520
|
-
const
|
|
521
|
-
if (
|
|
522
|
-
|
|
459
|
+
const t = this.pending_add_ids, e = this.pending_add_defs, s = this.pending_add_values, n = t.length, r = this.entity_archetype, i = this.entity_row, _ = this.entity_generations, h = this.archetypes, o = this.component_metas, c = this.entity_high_water;
|
|
460
|
+
for (let l = 0; l < n; l++) {
|
|
461
|
+
const u = t[l], d = u & P, p = u >> A;
|
|
462
|
+
if (d >= c || _[d] !== p) continue;
|
|
463
|
+
const x = r[d], m = e[l], g = h[x];
|
|
464
|
+
if (g.mask.has(m)) {
|
|
465
|
+
o[m].field_names.length > 0 && g.write_fields(i[d], m, s[l]);
|
|
523
466
|
continue;
|
|
524
467
|
}
|
|
525
|
-
const
|
|
526
|
-
if (
|
|
527
|
-
|
|
528
|
-
const
|
|
529
|
-
|
|
468
|
+
const E = this.arch_resolve_add(x, m), w = h[E], T = i[d], k = !w.has_columns && !g.has_columns, N = k ? w.add_entity_tag(u) : w.add_entity(u);
|
|
469
|
+
if (T !== y) {
|
|
470
|
+
k || w.copy_shared_from(g, T, N);
|
|
471
|
+
const I = k ? g.remove_entity_tag(T) : g.remove_entity(T);
|
|
472
|
+
I !== -1 && (i[I] = T);
|
|
530
473
|
}
|
|
531
|
-
|
|
474
|
+
o[m].field_names.length > 0 && w.write_fields(N, m, s[l]), r[d] = E, i[d] = N;
|
|
532
475
|
}
|
|
533
476
|
t.length = 0, e.length = 0, s.length = 0;
|
|
534
477
|
}
|
|
535
478
|
/** Batch-apply all deferred component removals. */
|
|
536
479
|
_flush_removes() {
|
|
537
|
-
const t = this.pending_remove_ids, e = this.pending_remove_defs, s = t.length, n = this.entity_archetype, r = this.entity_row,
|
|
538
|
-
for (let
|
|
539
|
-
const c = t[
|
|
540
|
-
if (
|
|
541
|
-
const
|
|
542
|
-
if (!
|
|
543
|
-
const
|
|
544
|
-
|
|
545
|
-
const
|
|
546
|
-
|
|
480
|
+
const t = this.pending_remove_ids, e = this.pending_remove_defs, s = t.length, n = this.entity_archetype, r = this.entity_row, i = this.entity_generations, _ = this.archetypes, h = this.entity_high_water;
|
|
481
|
+
for (let o = 0; o < s; o++) {
|
|
482
|
+
const c = t[o], l = c & P, u = c >> A;
|
|
483
|
+
if (l >= h || i[l] !== u) continue;
|
|
484
|
+
const d = n[l], p = e[o], x = _[d];
|
|
485
|
+
if (!x.mask.has(p)) continue;
|
|
486
|
+
const m = this.arch_resolve_remove(d, p), g = _[m], E = r[l], w = !g.has_columns && !x.has_columns, T = w ? g.add_entity_tag(c) : g.add_entity(c);
|
|
487
|
+
w || g.copy_shared_from(x, E, T);
|
|
488
|
+
const k = w ? x.remove_entity_tag(E) : x.remove_entity(E);
|
|
489
|
+
k !== -1 && (r[k] = E), n[l] = m, r[l] = T;
|
|
547
490
|
}
|
|
548
491
|
t.length = 0, e.length = 0;
|
|
549
492
|
}
|
|
@@ -554,19 +497,17 @@ class tt {
|
|
|
554
497
|
// Component registration
|
|
555
498
|
// =======================================================
|
|
556
499
|
register_component(t) {
|
|
557
|
-
const e =
|
|
500
|
+
const e = z(this.component_count++), s = t, n = /* @__PURE__ */ Object.create(null);
|
|
558
501
|
for (let r = 0; r < s.length; r++)
|
|
559
502
|
n[s[r]] = r;
|
|
560
503
|
return this.component_metas.push({ field_names: s, field_index: n }), e;
|
|
561
504
|
}
|
|
562
505
|
add_component(t, e, s) {
|
|
563
|
-
if (!this.is_alive(t))
|
|
564
|
-
if (process.env.NODE_ENV !== "production") throw new g(u.ENTITY_NOT_ALIVE);
|
|
506
|
+
if (!this.is_alive(t))
|
|
565
507
|
return;
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
o.write_fields(
|
|
508
|
+
const n = f(t), r = this.entity_archetype[n], i = this.arch_get(r);
|
|
509
|
+
if (i.has_component(e)) {
|
|
510
|
+
i.write_fields(
|
|
570
511
|
this.entity_row[n],
|
|
571
512
|
e,
|
|
572
513
|
s
|
|
@@ -576,11 +517,11 @@ class tt {
|
|
|
576
517
|
const _ = this.arch_resolve_add(
|
|
577
518
|
r,
|
|
578
519
|
e
|
|
579
|
-
), h = this.arch_get(_),
|
|
580
|
-
if (
|
|
581
|
-
h.copy_shared_from(
|
|
582
|
-
const
|
|
583
|
-
|
|
520
|
+
), h = this.arch_get(_), o = this.entity_row[n], c = h.add_entity(t);
|
|
521
|
+
if (o !== y) {
|
|
522
|
+
h.copy_shared_from(i, o, c);
|
|
523
|
+
const l = i.remove_entity(o);
|
|
524
|
+
l !== -1 && (this.entity_row[l] = o);
|
|
584
525
|
}
|
|
585
526
|
h.write_fields(
|
|
586
527
|
c,
|
|
@@ -590,81 +531,73 @@ class tt {
|
|
|
590
531
|
}
|
|
591
532
|
/** Add multiple components in one transition (resolves final archetype, then moves once). */
|
|
592
533
|
add_components(t, e) {
|
|
593
|
-
if (!this.is_alive(t))
|
|
594
|
-
if (process.env.NODE_ENV !== "production") throw new g(u.ENTITY_NOT_ALIVE);
|
|
534
|
+
if (!this.is_alive(t))
|
|
595
535
|
return;
|
|
596
|
-
|
|
597
|
-
const s = m(t), n = this.entity_archetype[s];
|
|
536
|
+
const s = f(t), n = this.entity_archetype[s];
|
|
598
537
|
let r = n;
|
|
599
|
-
for (let
|
|
538
|
+
for (let i = 0; i < e.length; i++)
|
|
600
539
|
r = this.arch_resolve_add(
|
|
601
540
|
r,
|
|
602
|
-
e[
|
|
541
|
+
e[i].def
|
|
603
542
|
);
|
|
604
543
|
if (r !== n) {
|
|
605
|
-
const
|
|
606
|
-
if (h !==
|
|
607
|
-
_.copy_shared_from(
|
|
608
|
-
const c =
|
|
544
|
+
const i = this.arch_get(n), _ = this.arch_get(r), h = this.entity_row[s], o = _.add_entity(t);
|
|
545
|
+
if (h !== y) {
|
|
546
|
+
_.copy_shared_from(i, h, o);
|
|
547
|
+
const c = i.remove_entity(h);
|
|
609
548
|
c !== -1 && (this.entity_row[c] = h);
|
|
610
549
|
}
|
|
611
550
|
for (let c = 0; c < e.length; c++)
|
|
612
551
|
_.write_fields(
|
|
613
|
-
|
|
552
|
+
o,
|
|
614
553
|
e[c].def,
|
|
615
|
-
e[c].values ??
|
|
554
|
+
e[c].values ?? S
|
|
616
555
|
);
|
|
617
|
-
this.entity_archetype[s] = r, this.entity_row[s] =
|
|
556
|
+
this.entity_archetype[s] = r, this.entity_row[s] = o;
|
|
618
557
|
} else {
|
|
619
|
-
const
|
|
558
|
+
const i = this.arch_get(n), _ = this.entity_row[s];
|
|
620
559
|
for (let h = 0; h < e.length; h++)
|
|
621
|
-
|
|
560
|
+
i.write_fields(
|
|
622
561
|
_,
|
|
623
562
|
e[h].def,
|
|
624
|
-
e[h].values ??
|
|
563
|
+
e[h].values ?? S
|
|
625
564
|
);
|
|
626
565
|
}
|
|
627
566
|
}
|
|
628
567
|
remove_component(t, e) {
|
|
629
|
-
if (!this.is_alive(t))
|
|
630
|
-
if (process.env.NODE_ENV !== "production") throw new g(u.ENTITY_NOT_ALIVE);
|
|
568
|
+
if (!this.is_alive(t))
|
|
631
569
|
return;
|
|
632
|
-
|
|
633
|
-
const s = m(t), n = this.entity_archetype[s], r = this.arch_get(n);
|
|
570
|
+
const s = f(t), n = this.entity_archetype[s], r = this.arch_get(n);
|
|
634
571
|
if (!r.has_component(e)) return;
|
|
635
|
-
const
|
|
572
|
+
const i = this.arch_resolve_remove(
|
|
636
573
|
n,
|
|
637
574
|
e
|
|
638
|
-
), _ = this.arch_get(
|
|
639
|
-
_.copy_shared_from(r, h,
|
|
575
|
+
), _ = this.arch_get(i), h = this.entity_row[s], o = _.add_entity(t);
|
|
576
|
+
_.copy_shared_from(r, h, o);
|
|
640
577
|
const c = r.remove_entity(h);
|
|
641
|
-
c !== -1 && (this.entity_row[c] = h), this.entity_archetype[s] =
|
|
578
|
+
c !== -1 && (this.entity_row[c] = h), this.entity_archetype[s] = i, this.entity_row[s] = o;
|
|
642
579
|
}
|
|
643
580
|
/** Remove multiple components in one transition (resolves final archetype, then moves once). */
|
|
644
581
|
remove_components(t, e) {
|
|
645
|
-
if (!this.is_alive(t))
|
|
646
|
-
if (process.env.NODE_ENV !== "production") throw new g(u.ENTITY_NOT_ALIVE);
|
|
582
|
+
if (!this.is_alive(t))
|
|
647
583
|
return;
|
|
648
|
-
|
|
649
|
-
const s = m(t), n = this.entity_archetype[s];
|
|
584
|
+
const s = f(t), n = this.entity_archetype[s];
|
|
650
585
|
let r = n;
|
|
651
|
-
for (let
|
|
586
|
+
for (let l = 0; l < e.length; l++)
|
|
652
587
|
r = this.arch_resolve_remove(
|
|
653
588
|
r,
|
|
654
|
-
e[
|
|
589
|
+
e[l]
|
|
655
590
|
);
|
|
656
591
|
if (r === n) return;
|
|
657
|
-
const
|
|
658
|
-
_.copy_shared_from(
|
|
659
|
-
const c =
|
|
660
|
-
c !== -1 && (this.entity_row[c] = h), this.entity_archetype[s] = r, this.entity_row[s] =
|
|
592
|
+
const i = this.arch_get(n), _ = this.arch_get(r), h = this.entity_row[s], o = _.add_entity(t);
|
|
593
|
+
_.copy_shared_from(i, h, o);
|
|
594
|
+
const c = i.remove_entity(h);
|
|
595
|
+
c !== -1 && (this.entity_row[c] = h), this.entity_archetype[s] = r, this.entity_row[s] = o;
|
|
661
596
|
}
|
|
662
597
|
has_component(t, e) {
|
|
663
|
-
if (!this.is_alive(t))
|
|
664
|
-
if (process.env.NODE_ENV !== "production") throw new g(u.ENTITY_NOT_ALIVE);
|
|
598
|
+
if (!this.is_alive(t))
|
|
665
599
|
return !1;
|
|
666
|
-
|
|
667
|
-
const s = m(t);
|
|
600
|
+
const s = f(t);
|
|
668
601
|
return this.arch_get(
|
|
669
602
|
this.entity_archetype[s]
|
|
670
603
|
).has_component(e);
|
|
@@ -674,11 +607,11 @@ class tt {
|
|
|
674
607
|
// =======================================================
|
|
675
608
|
get_entity_archetype(t) {
|
|
676
609
|
return this.arch_get(
|
|
677
|
-
this.entity_archetype[
|
|
610
|
+
this.entity_archetype[f(t)]
|
|
678
611
|
);
|
|
679
612
|
}
|
|
680
613
|
get_entity_row(t) {
|
|
681
|
-
return this.entity_row[
|
|
614
|
+
return this.entity_row[f(t)];
|
|
682
615
|
}
|
|
683
616
|
// =======================================================
|
|
684
617
|
// Query support
|
|
@@ -691,36 +624,36 @@ class tt {
|
|
|
691
624
|
get_matching_archetypes(t, e, s) {
|
|
692
625
|
const n = t._words;
|
|
693
626
|
let r = !1;
|
|
694
|
-
for (let
|
|
695
|
-
if (n[
|
|
627
|
+
for (let o = 0; o < n.length; o++)
|
|
628
|
+
if (n[o] !== 0) {
|
|
696
629
|
r = !0;
|
|
697
630
|
break;
|
|
698
631
|
}
|
|
699
632
|
if (!r)
|
|
700
633
|
return this.archetypes.filter(
|
|
701
|
-
(
|
|
634
|
+
(o) => (!e || !o.mask.overlaps(e)) && (!s || o.mask.overlaps(s))
|
|
702
635
|
);
|
|
703
|
-
let
|
|
704
|
-
for (let
|
|
705
|
-
let c = n[
|
|
636
|
+
let i, _ = !1;
|
|
637
|
+
for (let o = 0; o < n.length; o++) {
|
|
638
|
+
let c = n[o];
|
|
706
639
|
if (c === 0) continue;
|
|
707
|
-
const
|
|
640
|
+
const l = o << 5;
|
|
708
641
|
for (; c !== 0; ) {
|
|
709
|
-
const
|
|
710
|
-
c ^=
|
|
711
|
-
const
|
|
712
|
-
if (!
|
|
642
|
+
const u = c & -c >>> 0, d = l + (31 - Math.clz32(u));
|
|
643
|
+
c ^= u;
|
|
644
|
+
const p = this.component_index.get(d);
|
|
645
|
+
if (!p || p.size === 0) {
|
|
713
646
|
_ = !0;
|
|
714
647
|
break;
|
|
715
648
|
}
|
|
716
|
-
(!
|
|
649
|
+
(!i || p.size < i.size) && (i = p);
|
|
717
650
|
}
|
|
718
651
|
if (_) break;
|
|
719
652
|
}
|
|
720
|
-
if (_ || !
|
|
653
|
+
if (_ || !i) return [];
|
|
721
654
|
const h = [];
|
|
722
|
-
for (const
|
|
723
|
-
const c = this.arch_get(
|
|
655
|
+
for (const o of i) {
|
|
656
|
+
const c = this.arch_get(o);
|
|
724
657
|
c.matches(t) && (!e || !c.mask.overlaps(e)) && (!s || c.mask.overlaps(s)) && h.push(c);
|
|
725
658
|
}
|
|
726
659
|
return h;
|
|
@@ -749,7 +682,7 @@ class tt {
|
|
|
749
682
|
// Event channels
|
|
750
683
|
// =======================================================
|
|
751
684
|
register_event(t) {
|
|
752
|
-
const e =
|
|
685
|
+
const e = V(this.event_count++), s = new C(t);
|
|
753
686
|
return this.event_channels.push(s), e;
|
|
754
687
|
}
|
|
755
688
|
emit_event(t, e) {
|
|
@@ -767,44 +700,39 @@ class tt {
|
|
|
767
700
|
t[e].clear();
|
|
768
701
|
}
|
|
769
702
|
}
|
|
770
|
-
var
|
|
771
|
-
const
|
|
703
|
+
var B = /* @__PURE__ */ ((a) => (a.PRE_STARTUP = "PRE_STARTUP", a.STARTUP = "STARTUP", a.POST_STARTUP = "POST_STARTUP", a.FIXED_UPDATE = "FIXED_UPDATE", a.PRE_UPDATE = "PRE_UPDATE", a.UPDATE = "UPDATE", a.POST_UPDATE = "POST_UPDATE", a))(B || {});
|
|
704
|
+
const D = [
|
|
772
705
|
"PRE_STARTUP",
|
|
773
706
|
"STARTUP",
|
|
774
707
|
"POST_STARTUP"
|
|
775
708
|
/* POST_STARTUP */
|
|
776
|
-
],
|
|
709
|
+
], O = [
|
|
777
710
|
"PRE_UPDATE",
|
|
778
711
|
"UPDATE",
|
|
779
712
|
"POST_UPDATE"
|
|
780
713
|
/* POST_UPDATE */
|
|
781
714
|
];
|
|
782
|
-
class
|
|
715
|
+
class Q {
|
|
716
|
+
label_systems = /* @__PURE__ */ new Map();
|
|
717
|
+
sorted_cache = /* @__PURE__ */ new Map();
|
|
718
|
+
system_index = /* @__PURE__ */ new Map();
|
|
719
|
+
next_insertion_order = 0;
|
|
783
720
|
constructor() {
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
this.label_systems.set(L[t], []);
|
|
790
|
-
for (let t = 0; t < U.length; t++)
|
|
791
|
-
this.label_systems.set(U[t], []);
|
|
721
|
+
for (let t = 0; t < D.length; t++)
|
|
722
|
+
this.label_systems.set(D[t], []);
|
|
723
|
+
this.label_systems.set("FIXED_UPDATE", []);
|
|
724
|
+
for (let t = 0; t < O.length; t++)
|
|
725
|
+
this.label_systems.set(O[t], []);
|
|
792
726
|
}
|
|
793
727
|
add_systems(t, ...e) {
|
|
794
728
|
for (const s of e) {
|
|
795
|
-
const n = "system" in s ? s.system : s, r = "system" in s ? s.ordering : void 0
|
|
796
|
-
if (process.env.NODE_ENV !== "production" && this.system_index.has(n))
|
|
797
|
-
throw new g(
|
|
798
|
-
u.DUPLICATE_SYSTEM,
|
|
799
|
-
`System ${n.id} is already scheduled`
|
|
800
|
-
);
|
|
801
|
-
const o = {
|
|
729
|
+
const n = "system" in s ? s.system : s, r = "system" in s ? s.ordering : void 0, i = {
|
|
802
730
|
descriptor: n,
|
|
803
731
|
insertion_order: this.next_insertion_order++,
|
|
804
|
-
before: new Set(
|
|
805
|
-
after: new Set(
|
|
732
|
+
before: new Set(r?.before ?? []),
|
|
733
|
+
after: new Set(r?.after ?? [])
|
|
806
734
|
};
|
|
807
|
-
this.label_systems.get(t).push(
|
|
735
|
+
this.label_systems.get(t).push(i), this.system_index.set(n, t), this.sorted_cache.delete(t);
|
|
808
736
|
}
|
|
809
737
|
}
|
|
810
738
|
remove_system(t) {
|
|
@@ -814,19 +742,28 @@ class st {
|
|
|
814
742
|
if (n !== -1) {
|
|
815
743
|
const r = s.length - 1;
|
|
816
744
|
n !== r && (s[n] = s[r]), s.pop();
|
|
817
|
-
for (const
|
|
818
|
-
|
|
745
|
+
for (const i of s)
|
|
746
|
+
i.before.delete(t), i.after.delete(t);
|
|
819
747
|
}
|
|
820
748
|
this.system_index.delete(t), this.sorted_cache.delete(e);
|
|
821
749
|
}
|
|
822
750
|
run_startup(t) {
|
|
823
|
-
for (const e of
|
|
751
|
+
for (const e of D)
|
|
824
752
|
this.run_label(e, t, 0);
|
|
825
753
|
}
|
|
826
754
|
run_update(t, e) {
|
|
827
|
-
for (const s of
|
|
755
|
+
for (const s of O)
|
|
828
756
|
this.run_label(s, t, e);
|
|
829
757
|
}
|
|
758
|
+
run_fixed_update(t, e) {
|
|
759
|
+
this.run_label("FIXED_UPDATE", t, e);
|
|
760
|
+
}
|
|
761
|
+
has_fixed_systems() {
|
|
762
|
+
return this.label_systems.get(
|
|
763
|
+
"FIXED_UPDATE"
|
|
764
|
+
/* FIXED_UPDATE */
|
|
765
|
+
).length > 0;
|
|
766
|
+
}
|
|
830
767
|
get_all_systems() {
|
|
831
768
|
const t = [];
|
|
832
769
|
for (const e of this.label_systems.values())
|
|
@@ -860,52 +797,52 @@ class st {
|
|
|
860
797
|
*/
|
|
861
798
|
topological_sort(t, e) {
|
|
862
799
|
if (t.length === 0) return [];
|
|
863
|
-
const s = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(),
|
|
864
|
-
for (const
|
|
865
|
-
s.set(
|
|
866
|
-
for (const
|
|
867
|
-
for (const c of
|
|
868
|
-
|
|
869
|
-
for (const c of
|
|
870
|
-
|
|
800
|
+
const s = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Set();
|
|
801
|
+
for (const o of t)
|
|
802
|
+
s.set(o.descriptor, /* @__PURE__ */ new Set()), n.set(o.descriptor, 0), r.set(o.descriptor, o.insertion_order), i.add(o.descriptor);
|
|
803
|
+
for (const o of t) {
|
|
804
|
+
for (const c of o.before)
|
|
805
|
+
i.has(c) && (s.get(o.descriptor).add(c), n.set(c, n.get(c) + 1));
|
|
806
|
+
for (const c of o.after)
|
|
807
|
+
i.has(c) && (s.get(c).add(o.descriptor), n.set(o.descriptor, n.get(o.descriptor) + 1));
|
|
871
808
|
}
|
|
872
809
|
let _ = [];
|
|
873
|
-
for (const
|
|
874
|
-
n.get(
|
|
875
|
-
_.sort((
|
|
810
|
+
for (const o of t)
|
|
811
|
+
n.get(o.descriptor) === 0 && _.push(o.descriptor);
|
|
812
|
+
_.sort((o, c) => r.get(c) - r.get(o));
|
|
876
813
|
const h = [];
|
|
877
814
|
for (; _.length > 0; ) {
|
|
878
|
-
const
|
|
879
|
-
h.push(
|
|
880
|
-
for (const c of s.get(
|
|
881
|
-
const
|
|
882
|
-
n.set(c,
|
|
815
|
+
const o = _.pop();
|
|
816
|
+
h.push(o);
|
|
817
|
+
for (const c of s.get(o)) {
|
|
818
|
+
const l = n.get(c) - 1;
|
|
819
|
+
n.set(c, l), l === 0 && _.push(c);
|
|
883
820
|
}
|
|
884
|
-
_.sort((c,
|
|
821
|
+
_.sort((c, l) => r.get(l) - r.get(c));
|
|
885
822
|
}
|
|
886
823
|
if (h.length !== t.length) {
|
|
887
|
-
const
|
|
888
|
-
throw new
|
|
889
|
-
|
|
824
|
+
const o = new Set(h), c = t.filter((l) => !o.has(l.descriptor)).map((l) => `system_${l.descriptor.id}`);
|
|
825
|
+
throw new Y(
|
|
826
|
+
q.CIRCULAR_SYSTEM_DEPENDENCY,
|
|
890
827
|
`Circular system dependency detected in ${e}: [${c.join(", ")}]`
|
|
891
828
|
);
|
|
892
829
|
}
|
|
893
830
|
return h;
|
|
894
831
|
}
|
|
895
832
|
}
|
|
896
|
-
const
|
|
897
|
-
class
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
this._archetypes = t, this._defs = e, this._resolver = s, this._include = n, this._exclude = r, this._any_of =
|
|
833
|
+
const K = Object.freeze(/* @__PURE__ */ Object.create(null));
|
|
834
|
+
class J {
|
|
835
|
+
_archetypes;
|
|
836
|
+
_defs;
|
|
837
|
+
_resolver;
|
|
838
|
+
_include;
|
|
839
|
+
_exclude;
|
|
840
|
+
_any_of;
|
|
841
|
+
// Pre-allocated args buffer for each() — avoids allocating a new array per
|
|
842
|
+
// archetype. Holds [columnGroup0, columnGroup1, ..., entityCount].
|
|
843
|
+
_args_buf;
|
|
844
|
+
constructor(t, e, s, n, r, i) {
|
|
845
|
+
this._archetypes = t, this._defs = e, this._resolver = s, this._include = n, this._exclude = r, this._any_of = i, this._args_buf = new Array(e.length + 1);
|
|
909
846
|
}
|
|
910
847
|
/** Number of matching archetypes (including empty ones). */
|
|
911
848
|
get length() {
|
|
@@ -935,10 +872,10 @@ class rt {
|
|
|
935
872
|
each(t) {
|
|
936
873
|
const e = this._archetypes, s = this._defs, n = this._args_buf;
|
|
937
874
|
for (let r = 0; r < e.length; r++) {
|
|
938
|
-
const
|
|
875
|
+
const i = e[r], _ = i.entity_count;
|
|
939
876
|
if (_ !== 0) {
|
|
940
877
|
for (let h = 0; h < s.length; h++)
|
|
941
|
-
n[h] =
|
|
878
|
+
n[h] = i.get_column_group(s[h]);
|
|
942
879
|
n[s.length] = _, t.apply(null, n);
|
|
943
880
|
}
|
|
944
881
|
}
|
|
@@ -957,7 +894,7 @@ class rt {
|
|
|
957
894
|
}
|
|
958
895
|
/** Exclude archetypes that have any of these components. */
|
|
959
896
|
not(...t) {
|
|
960
|
-
const e = this._exclude ? this._exclude.copy() : new
|
|
897
|
+
const e = this._exclude ? this._exclude.copy() : new v();
|
|
961
898
|
for (let s = 0; s < t.length; s++) e.set(t[s]);
|
|
962
899
|
return this._resolver._resolve_query(
|
|
963
900
|
this._include,
|
|
@@ -968,7 +905,7 @@ class rt {
|
|
|
968
905
|
}
|
|
969
906
|
/** Require at least one of these components. */
|
|
970
907
|
or(...t) {
|
|
971
|
-
const e = this._any_of ? this._any_of.copy() : new
|
|
908
|
+
const e = this._any_of ? this._any_of.copy() : new v();
|
|
972
909
|
for (let s = 0; s < t.length; s++) e.set(t[s]);
|
|
973
910
|
return this._resolver._resolve_query(
|
|
974
911
|
this._include,
|
|
@@ -978,19 +915,19 @@ class rt {
|
|
|
978
915
|
);
|
|
979
916
|
}
|
|
980
917
|
}
|
|
981
|
-
class
|
|
918
|
+
class Z {
|
|
982
919
|
constructor(t) {
|
|
983
920
|
this._resolver = t;
|
|
984
921
|
}
|
|
985
922
|
every(...t) {
|
|
986
|
-
const e = new
|
|
923
|
+
const e = new v();
|
|
987
924
|
for (let s = 0; s < t.length; s++) e.set(t[s]);
|
|
988
925
|
return this._resolver._resolve_query(e, null, null, t);
|
|
989
926
|
}
|
|
990
927
|
}
|
|
991
|
-
class
|
|
928
|
+
class H {
|
|
929
|
+
store;
|
|
992
930
|
constructor(t) {
|
|
993
|
-
l(this, "store");
|
|
994
931
|
this.store = t;
|
|
995
932
|
}
|
|
996
933
|
create_entity() {
|
|
@@ -1001,8 +938,8 @@ class it {
|
|
|
1001
938
|
return n.read_field(r, t, s);
|
|
1002
939
|
}
|
|
1003
940
|
set_field(t, e, s, n) {
|
|
1004
|
-
const r = this.store.get_entity_archetype(e),
|
|
1005
|
-
_[
|
|
941
|
+
const r = this.store.get_entity_archetype(e), i = this.store.get_entity_row(e), _ = r.get_column(t, s);
|
|
942
|
+
_[i] = n;
|
|
1006
943
|
}
|
|
1007
944
|
/** Buffer an entity for deferred destruction (applied at phase flush). */
|
|
1008
945
|
destroy_entity(t) {
|
|
@@ -1012,7 +949,7 @@ class it {
|
|
|
1012
949
|
this.store.flush_destroyed();
|
|
1013
950
|
}
|
|
1014
951
|
add_component(t, e, s) {
|
|
1015
|
-
return this.store.add_component_deferred(t, e, s ??
|
|
952
|
+
return this.store.add_component_deferred(t, e, s ?? K), this;
|
|
1016
953
|
}
|
|
1017
954
|
remove_component(t, e) {
|
|
1018
955
|
return this.store.remove_component_deferred(t, e), this;
|
|
@@ -1028,24 +965,35 @@ class it {
|
|
|
1028
965
|
return this.store.get_event_reader(t);
|
|
1029
966
|
}
|
|
1030
967
|
}
|
|
1031
|
-
const
|
|
1032
|
-
a
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
968
|
+
const tt = (a) => b(
|
|
969
|
+
a
|
|
970
|
+
), et = Object.freeze(/* @__PURE__ */ Object.create(null));
|
|
971
|
+
class st {
|
|
972
|
+
store;
|
|
973
|
+
schedule;
|
|
974
|
+
ctx;
|
|
975
|
+
systems = /* @__PURE__ */ new Set();
|
|
976
|
+
next_system_id = 0;
|
|
977
|
+
// Fixed timestep accumulator
|
|
978
|
+
_fixed_timestep;
|
|
979
|
+
_accumulator = 0;
|
|
980
|
+
_max_fixed_steps;
|
|
981
|
+
// Query deduplication: hash(include, exclude, any_of) → bucket of cache entries.
|
|
982
|
+
// Multiple queries can share the same hash (collision), so each bucket is an array.
|
|
983
|
+
query_cache = /* @__PURE__ */ new Map();
|
|
984
|
+
// Reusable BitSet for building query masks — avoids allocation per query() call
|
|
985
|
+
scratch_mask = new v();
|
|
986
|
+
constructor(t) {
|
|
987
|
+
this.store = new $(), this.schedule = new Q(), this.ctx = new H(this.store), this._fixed_timestep = t?.fixed_timestep ?? 1 / 60, this._max_fixed_steps = t?.max_fixed_steps ?? 4;
|
|
988
|
+
}
|
|
989
|
+
get fixed_timestep() {
|
|
990
|
+
return this._fixed_timestep;
|
|
991
|
+
}
|
|
992
|
+
set fixed_timestep(t) {
|
|
993
|
+
this._fixed_timestep = t;
|
|
994
|
+
}
|
|
995
|
+
get fixed_alpha() {
|
|
996
|
+
return this._accumulator / this._fixed_timestep;
|
|
1049
997
|
}
|
|
1050
998
|
register_component(t) {
|
|
1051
999
|
return this.store.register_component(t);
|
|
@@ -1072,7 +1020,7 @@ class at {
|
|
|
1072
1020
|
return this.store.entity_count;
|
|
1073
1021
|
}
|
|
1074
1022
|
add_component(t, e, s) {
|
|
1075
|
-
this.store.add_component(t, e, s ??
|
|
1023
|
+
this.store.add_component(t, e, s ?? et);
|
|
1076
1024
|
}
|
|
1077
1025
|
add_components(t, e) {
|
|
1078
1026
|
this.store.add_components(t, e);
|
|
@@ -1102,32 +1050,32 @@ class at {
|
|
|
1102
1050
|
}
|
|
1103
1051
|
/** QueryResolver implementation — creates or retrieves a cached Query. */
|
|
1104
1052
|
_resolve_query(t, e, s, n) {
|
|
1105
|
-
const r = t.hash(),
|
|
1106
|
-
if (
|
|
1053
|
+
const r = t.hash(), i = e ? e.hash() : 0, _ = s ? s.hash() : 0, h = r ^ Math.imul(i, 2654435769) ^ Math.imul(_, 1367130551) | 0, o = this._find_cached(h, t, e, s);
|
|
1054
|
+
if (o !== void 0) return o.query;
|
|
1107
1055
|
const c = this.store.register_query(
|
|
1108
1056
|
t,
|
|
1109
1057
|
e ?? void 0,
|
|
1110
1058
|
s ?? void 0
|
|
1111
|
-
),
|
|
1059
|
+
), l = new J(
|
|
1112
1060
|
c,
|
|
1113
1061
|
n,
|
|
1114
1062
|
this,
|
|
1115
1063
|
t.copy(),
|
|
1116
|
-
|
|
1117
|
-
|
|
1064
|
+
e?.copy() ?? null,
|
|
1065
|
+
s?.copy() ?? null
|
|
1118
1066
|
);
|
|
1119
1067
|
return j(this.query_cache, h, {
|
|
1120
1068
|
include_mask: t.copy(),
|
|
1121
|
-
exclude_mask:
|
|
1122
|
-
any_of_mask:
|
|
1123
|
-
query:
|
|
1124
|
-
}),
|
|
1069
|
+
exclude_mask: e?.copy() ?? null,
|
|
1070
|
+
any_of_mask: s?.copy() ?? null,
|
|
1071
|
+
query: l
|
|
1072
|
+
}), l;
|
|
1125
1073
|
}
|
|
1126
1074
|
_find_cached(t, e, s, n) {
|
|
1127
1075
|
const r = this.query_cache.get(t);
|
|
1128
1076
|
if (r)
|
|
1129
|
-
for (let
|
|
1130
|
-
const _ = r[
|
|
1077
|
+
for (let i = 0; i < r.length; i++) {
|
|
1078
|
+
const _ = r[i];
|
|
1131
1079
|
if (!(!_.include_mask.equals(e) || !(s === null ? _.exclude_mask === null : _.exclude_mask !== null && _.exclude_mask.equals(s)) || !(n === null ? _.any_of_mask === null : _.any_of_mask !== null && _.any_of_mask.equals(n))))
|
|
1132
1080
|
return _;
|
|
1133
1081
|
}
|
|
@@ -1135,11 +1083,11 @@ class at {
|
|
|
1135
1083
|
register_system(t, e) {
|
|
1136
1084
|
let s;
|
|
1137
1085
|
if (typeof t == "function") {
|
|
1138
|
-
const
|
|
1139
|
-
s = { fn: (h,
|
|
1086
|
+
const i = e(new Z(this)), _ = this.ctx;
|
|
1087
|
+
s = { fn: (h, o) => t(i, _, o) };
|
|
1140
1088
|
} else
|
|
1141
1089
|
s = t;
|
|
1142
|
-
const n =
|
|
1090
|
+
const n = tt(this.next_system_id++), r = Object.freeze(
|
|
1143
1091
|
Object.assign({ id: n }, s)
|
|
1144
1092
|
);
|
|
1145
1093
|
return this.systems.add(r), r;
|
|
@@ -1148,35 +1096,38 @@ class at {
|
|
|
1148
1096
|
return this.schedule.add_systems(t, ...e), this;
|
|
1149
1097
|
}
|
|
1150
1098
|
remove_system(t) {
|
|
1151
|
-
|
|
1152
|
-
this.schedule.remove_system(t), (e = t.on_removed) == null || e.call(t), this.systems.delete(t);
|
|
1099
|
+
this.schedule.remove_system(t), t.on_removed?.(), this.systems.delete(t);
|
|
1153
1100
|
}
|
|
1154
1101
|
get system_count() {
|
|
1155
1102
|
return this.systems.size;
|
|
1156
1103
|
}
|
|
1157
1104
|
startup() {
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
(t = e.on_added) == null || t.call(e, this.store);
|
|
1105
|
+
for (const t of this.systems.values())
|
|
1106
|
+
t.on_added?.(this.store);
|
|
1161
1107
|
this.schedule.run_startup(this.ctx);
|
|
1162
1108
|
}
|
|
1163
1109
|
update(t) {
|
|
1164
|
-
this.store.clear_events(), this.schedule.
|
|
1110
|
+
if (this.store.clear_events(), this.schedule.has_fixed_systems()) {
|
|
1111
|
+
this._accumulator += t;
|
|
1112
|
+
const e = this._max_fixed_steps * this._fixed_timestep;
|
|
1113
|
+
for (this._accumulator > e && (this._accumulator = e); this._accumulator >= this._fixed_timestep; )
|
|
1114
|
+
this.schedule.run_fixed_update(this.ctx, this._fixed_timestep), this._accumulator -= this._fixed_timestep;
|
|
1115
|
+
}
|
|
1116
|
+
this.schedule.run_update(this.ctx, t);
|
|
1165
1117
|
}
|
|
1166
1118
|
flush() {
|
|
1167
1119
|
this.ctx.flush();
|
|
1168
1120
|
}
|
|
1169
1121
|
dispose() {
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
(t = s.dispose) == null || t.call(s), (e = s.on_removed) == null || e.call(s);
|
|
1122
|
+
for (const t of this.systems.values())
|
|
1123
|
+
t.dispose?.(), t.on_removed?.();
|
|
1173
1124
|
this.systems.clear(), this.schedule.clear();
|
|
1174
1125
|
}
|
|
1175
1126
|
}
|
|
1176
1127
|
export {
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1128
|
+
J as Query,
|
|
1129
|
+
Z as QueryBuilder,
|
|
1130
|
+
B as SCHEDULE,
|
|
1131
|
+
H as SystemContext,
|
|
1132
|
+
st as World
|
|
1182
1133
|
};
|