entt-js 0.0.0
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/README.md +552 -0
- package/dist/browser/entt.js +4004 -0
- package/dist/browser/entt.min.js +1 -0
- package/dist/browser/index.js +3929 -0
- package/dist/browser/index.min.js +1 -0
- package/dist/entt.d.ts +1069 -0
- package/dist/entt.js +3944 -0
- package/dist/entt.min.js +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,4004 @@
|
|
|
1
|
+
var entt = (function(exports) {
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
//#region src/error.ts
|
|
5
|
+
const NotConstructorError = /* @__PURE__ */ (function() {
|
|
6
|
+
class NotConstructorError$1 extends TypeError {
|
|
7
|
+
constructor(message) {
|
|
8
|
+
super(message);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(NotConstructorError$1.prototype, "name", {
|
|
12
|
+
value: "NotConstructorError",
|
|
13
|
+
configurable: true
|
|
14
|
+
});
|
|
15
|
+
return NotConstructorError$1;
|
|
16
|
+
})();
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/util.ts
|
|
20
|
+
const assert = typeof ENTT_ASSERT !== "undefined" ? ENTT_ASSERT : /* @__NO_SIDE_EFFECTS__ */ function(condition, message) {
|
|
21
|
+
if (!condition) throw new AssertionError(message);
|
|
22
|
+
};
|
|
23
|
+
function cloneObject(obj, result) {
|
|
24
|
+
if (typeof obj.clone === "function") return obj.clone();
|
|
25
|
+
const descriptors = Object.getOwnPropertyDescriptors(obj);
|
|
26
|
+
result ??= Object.create(Object.getPrototypeOf(obj));
|
|
27
|
+
for (const [key, descriptor] of Object.entries(descriptors)) Object.defineProperty(result, key, {
|
|
28
|
+
...descriptor,
|
|
29
|
+
..."value" in descriptor ? { value: clone(descriptor.value) } : void 0
|
|
30
|
+
});
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
function clone(obj) {
|
|
34
|
+
const type = typeof obj;
|
|
35
|
+
if (type !== "object" || obj === null) {
|
|
36
|
+
if (type === "symbol") {
|
|
37
|
+
if (Symbol.keyFor(obj) != null) throw new Error("Cannot clone global symbol");
|
|
38
|
+
return Symbol(obj.description);
|
|
39
|
+
}
|
|
40
|
+
if (type === "function") return function() {
|
|
41
|
+
return obj.apply(this, arguments);
|
|
42
|
+
};
|
|
43
|
+
return obj;
|
|
44
|
+
}
|
|
45
|
+
if (Array.isArray(obj) || obj instanceof ArrayBuffer || ArrayBuffer.isView(obj) || obj instanceof DataView || obj instanceof Date || obj instanceof RegExp || obj instanceof Map || obj instanceof Set || obj instanceof Error || obj instanceof Number || obj instanceof String || obj instanceof Boolean) try {
|
|
46
|
+
const result = structuredClone(obj);
|
|
47
|
+
Object.setPrototypeOf(result, Object.getPrototypeOf(obj));
|
|
48
|
+
return result;
|
|
49
|
+
} catch (_) {
|
|
50
|
+
if (Array.isArray(obj)) return obj.map((v) => clone(v));
|
|
51
|
+
if (obj instanceof ArrayBuffer) return obj.slice(0);
|
|
52
|
+
if (ArrayBuffer.isView(obj)) return new obj.constructor(obj.buffer, obj.byteOffset, obj.byteLength / obj.constructor.BYTES_PER_ELEMENT);
|
|
53
|
+
if (obj instanceof DataView) return new DataView(obj.buffer, obj.byteOffset, obj.byteLength);
|
|
54
|
+
if (obj instanceof Date) return new Date(obj.getTime());
|
|
55
|
+
if (obj instanceof RegExp) return new RegExp(obj.source, obj.flags);
|
|
56
|
+
if (obj instanceof Map) {
|
|
57
|
+
const result = /* @__PURE__ */ new Map();
|
|
58
|
+
obj.forEach((v, k) => {
|
|
59
|
+
result.set(clone(k), clone(v));
|
|
60
|
+
});
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
if (obj instanceof Set) {
|
|
64
|
+
const result = /* @__PURE__ */ new Set();
|
|
65
|
+
obj.forEach((v) => {
|
|
66
|
+
result.add(clone(v));
|
|
67
|
+
});
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
if (obj instanceof Error) return cloneObject(obj, new obj.constructor(obj.message));
|
|
71
|
+
if (obj instanceof Number || obj instanceof String || obj instanceof Boolean) {
|
|
72
|
+
const Ctor = obj.constructor;
|
|
73
|
+
return new Ctor(obj.valueOf());
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (obj instanceof Promise) return obj.then(clone);
|
|
77
|
+
return cloneObject(obj);
|
|
78
|
+
}
|
|
79
|
+
function popcount(value) {
|
|
80
|
+
const b = typeof value === "bigint";
|
|
81
|
+
if (!b) value = value >>> 0;
|
|
82
|
+
const _1 = b ? BigInt(1) : 1;
|
|
83
|
+
return value ? Number((value & _1) + (b ? BigInt(popcount(value >> _1)) : popcount(value >>> _1))) : 0;
|
|
84
|
+
}
|
|
85
|
+
function defineStaticMethod(Class, name, method) {
|
|
86
|
+
Object.defineProperty(Class, name, {
|
|
87
|
+
value: method,
|
|
88
|
+
configurable: true,
|
|
89
|
+
writable: true
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
function inherits(Derived, Base) {
|
|
93
|
+
Object.setPrototypeOf(Derived, Base);
|
|
94
|
+
Object.setPrototypeOf(Derived.prototype, Base.prototype);
|
|
95
|
+
Object.defineProperty(Derived, "super_", {
|
|
96
|
+
value: Base,
|
|
97
|
+
writable: true,
|
|
98
|
+
configurable: true
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
function hasSingleBit(value) {
|
|
102
|
+
if (!(value >= 0 && (value | 0n) === value)) throw new TypeError("value must be unsigned integer");
|
|
103
|
+
return value !== 0n && (value & value - 1n) === 0n;
|
|
104
|
+
}
|
|
105
|
+
function fastMod(value, mod) {
|
|
106
|
+
if (!(value >= 0n && (value | 0n) === value)) throw new TypeError("value must be unsigned integer");
|
|
107
|
+
assert(hasSingleBit(mod), "mod must be a power of two");
|
|
108
|
+
return Number(value & mod - 1n);
|
|
109
|
+
}
|
|
110
|
+
function isExtendsFrom(Type, Classes) {
|
|
111
|
+
let T = Type;
|
|
112
|
+
do {
|
|
113
|
+
if (Classes.includes(T)) return T;
|
|
114
|
+
T = Object.getPrototypeOf(T);
|
|
115
|
+
} while (T != null);
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
const AssertionError = /* @__PURE__ */ (function() {
|
|
119
|
+
class AssertionError$1 extends Error {
|
|
120
|
+
constructor(message) {
|
|
121
|
+
super(message);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
Object.defineProperty(AssertionError$1.prototype, "name", {
|
|
125
|
+
value: "AssertionError",
|
|
126
|
+
configurable: true
|
|
127
|
+
});
|
|
128
|
+
return AssertionError$1;
|
|
129
|
+
})();
|
|
130
|
+
const less = (a, b) => {
|
|
131
|
+
if (a < b) return -1;
|
|
132
|
+
if (a > b) return 1;
|
|
133
|
+
return 0;
|
|
134
|
+
};
|
|
135
|
+
function defaultSort(arr, compareFn = less) {
|
|
136
|
+
return arr.sort(compareFn);
|
|
137
|
+
}
|
|
138
|
+
function insertionSort(arr, compareFn = less) {
|
|
139
|
+
const last = arr.length;
|
|
140
|
+
if (last > 0) {
|
|
141
|
+
const first = 0;
|
|
142
|
+
for (let it = first + 1; it < last; ++it) {
|
|
143
|
+
const value = arr[it];
|
|
144
|
+
let pre = it;
|
|
145
|
+
for (; pre > first && compareFn(value, arr[pre - 1]) < 0; --pre) arr[pre] = arr[pre - 1];
|
|
146
|
+
arr[pre] = value;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return arr;
|
|
150
|
+
}
|
|
151
|
+
function destructKey(k) {
|
|
152
|
+
return Array.isArray(k) ? k : typeof k === "function" || k === void 0 ? [k, k] : [null, k];
|
|
153
|
+
}
|
|
154
|
+
var Ref = class {
|
|
155
|
+
value;
|
|
156
|
+
constructor(value) {
|
|
157
|
+
this.value = value;
|
|
158
|
+
}
|
|
159
|
+
get() {
|
|
160
|
+
return this.value;
|
|
161
|
+
}
|
|
162
|
+
set(value) {
|
|
163
|
+
this.value = value;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
//#endregion
|
|
168
|
+
//#region src/type.ts
|
|
169
|
+
const Uint8 = /* @__PURE__ */ (function() {
|
|
170
|
+
const Uint8$1 = function Uint8$2(num) {
|
|
171
|
+
if (typeof num === "bigint") return Math.fround(Number(num & BigInt(255)));
|
|
172
|
+
return num & 255;
|
|
173
|
+
};
|
|
174
|
+
inherits(Uint8$1, Number);
|
|
175
|
+
Object.defineProperty(Uint8$1, "MIN_VALUE", { value: 0 });
|
|
176
|
+
Object.defineProperty(Uint8$1, "MAX_VALUE", { value: 255 });
|
|
177
|
+
defineStaticMethod(Uint8$1, "is", function(instance) {
|
|
178
|
+
if (typeof instance === "number" || Object.getPrototypeOf(instance) === Number.prototype) return Uint8$1(instance) === Number(instance);
|
|
179
|
+
return false;
|
|
180
|
+
});
|
|
181
|
+
return Uint8$1;
|
|
182
|
+
})();
|
|
183
|
+
const Float32 = /* @__PURE__ */ (function() {
|
|
184
|
+
const Float32$1 = function Float32$2(num) {
|
|
185
|
+
if (typeof num === "bigint") return Math.fround(Number(num & BigInt(4294967295)) | 0);
|
|
186
|
+
return Math.fround(num ?? 0);
|
|
187
|
+
};
|
|
188
|
+
inherits(Float32$1, Number);
|
|
189
|
+
return Float32$1;
|
|
190
|
+
})();
|
|
191
|
+
const Float64 = /* @__PURE__ */ (function() {
|
|
192
|
+
const Float64$1 = function Float64$2(num) {
|
|
193
|
+
return Number(num ?? 0);
|
|
194
|
+
};
|
|
195
|
+
inherits(Float64$1, Number);
|
|
196
|
+
return Float64$1;
|
|
197
|
+
})();
|
|
198
|
+
const Int8 = /* @__PURE__ */ (function() {
|
|
199
|
+
const Int8$1 = function Int8$2(num) {
|
|
200
|
+
if (typeof num === "bigint") return Number(num & BigInt(255)) << 24 >> 24;
|
|
201
|
+
return num << 24 >> 24;
|
|
202
|
+
};
|
|
203
|
+
inherits(Int8$1, Number);
|
|
204
|
+
Object.defineProperty(Int8$1, "MIN_VALUE", { value: -128 });
|
|
205
|
+
Object.defineProperty(Int8$1, "MAX_VALUE", { value: 127 });
|
|
206
|
+
defineStaticMethod(Int8$1, "is", function(instance) {
|
|
207
|
+
if (typeof instance === "number" || Object.getPrototypeOf(instance) === Number.prototype) return Int8$1(instance) === Number(instance);
|
|
208
|
+
return false;
|
|
209
|
+
});
|
|
210
|
+
return Int8$1;
|
|
211
|
+
})();
|
|
212
|
+
const Uint16 = /* @__PURE__ */ (function() {
|
|
213
|
+
const Uint16$1 = function Uint16$2(num) {
|
|
214
|
+
if (typeof num === "bigint") return Number(num & BigInt(65535));
|
|
215
|
+
return num & 65535;
|
|
216
|
+
};
|
|
217
|
+
inherits(Uint16$1, Number);
|
|
218
|
+
Object.defineProperty(Uint16$1, "MIN_VALUE", { value: 0 });
|
|
219
|
+
Object.defineProperty(Uint16$1, "MAX_VALUE", { value: 65535 });
|
|
220
|
+
defineStaticMethod(Uint16$1, "is", function(instance) {
|
|
221
|
+
if (typeof instance === "number" || Object.getPrototypeOf(instance) === Number.prototype) return Uint16$1(instance) === Number(instance);
|
|
222
|
+
return false;
|
|
223
|
+
});
|
|
224
|
+
return Uint16$1;
|
|
225
|
+
})();
|
|
226
|
+
const Int16 = /* @__PURE__ */ (function() {
|
|
227
|
+
const Int16$1 = function Int16$2(num) {
|
|
228
|
+
if (typeof num === "bigint") return Number(num & BigInt(65535)) << 16 >> 16;
|
|
229
|
+
return num << 16 >> 16;
|
|
230
|
+
};
|
|
231
|
+
inherits(Int16$1, Number);
|
|
232
|
+
Object.defineProperty(Int16$1, "MIN_VALUE", { value: -32768 });
|
|
233
|
+
Object.defineProperty(Int16$1, "MAX_VALUE", { value: 32767 });
|
|
234
|
+
defineStaticMethod(Int16$1, "is", function(instance) {
|
|
235
|
+
if (typeof instance === "number" || Object.getPrototypeOf(instance) === Number.prototype) return Int16$1(instance) === Number(instance);
|
|
236
|
+
return false;
|
|
237
|
+
});
|
|
238
|
+
return Int16$1;
|
|
239
|
+
})();
|
|
240
|
+
const Uint32 = /* @__PURE__ */ (function() {
|
|
241
|
+
const Uint32$1 = function Uint32$2(num) {
|
|
242
|
+
if (typeof num === "bigint") return Number(num & BigInt(4294967295));
|
|
243
|
+
return (num | 0) >>> 0;
|
|
244
|
+
};
|
|
245
|
+
inherits(Uint32$1, Number);
|
|
246
|
+
Object.defineProperty(Uint32$1, "MIN_VALUE", { value: 0 });
|
|
247
|
+
Object.defineProperty(Uint32$1, "MAX_VALUE", { value: 4294967295 });
|
|
248
|
+
defineStaticMethod(Uint32$1, "is", function(instance) {
|
|
249
|
+
if (typeof instance === "number" || Object.getPrototypeOf(instance) === Number.prototype) return Uint32$1(instance) === Number(instance);
|
|
250
|
+
return false;
|
|
251
|
+
});
|
|
252
|
+
return Uint32$1;
|
|
253
|
+
})();
|
|
254
|
+
const Int32 = /* @__PURE__ */ (function() {
|
|
255
|
+
const Int32$1 = function Int32$2(num) {
|
|
256
|
+
if (typeof num === "bigint") return Number(num & BigInt(4294967295)) | 0;
|
|
257
|
+
return num | 0;
|
|
258
|
+
};
|
|
259
|
+
inherits(Int32$1, Number);
|
|
260
|
+
Object.defineProperty(Int32$1, "MIN_VALUE", { value: -2147483648 });
|
|
261
|
+
Object.defineProperty(Int32$1, "MAX_VALUE", { value: 2147483647 });
|
|
262
|
+
defineStaticMethod(Int32$1, "is", function(instance) {
|
|
263
|
+
if (typeof instance === "number" || Object.getPrototypeOf(instance) === Number.prototype) return Int32$1(instance) === Number(instance);
|
|
264
|
+
return false;
|
|
265
|
+
});
|
|
266
|
+
return Int32$1;
|
|
267
|
+
})();
|
|
268
|
+
const maxUint64 = /* @__PURE__ */ BigInt("0xFFFFFFFFFFFFFFFF");
|
|
269
|
+
const Uint64 = /* @__PURE__ */ (function() {
|
|
270
|
+
const Uint64$1 = function Uint64$2(num) {
|
|
271
|
+
if (num == null) return BigInt(0);
|
|
272
|
+
try {
|
|
273
|
+
return BigInt(num) & maxUint64;
|
|
274
|
+
} catch (_) {
|
|
275
|
+
return BigInt(0);
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
inherits(Uint64$1, BigInt);
|
|
279
|
+
Object.defineProperty(Uint64$1, "MIN_VALUE", { value: BigInt(0) });
|
|
280
|
+
Object.defineProperty(Uint64$1, "MAX_VALUE", { value: maxUint64 });
|
|
281
|
+
defineStaticMethod(Uint64$1, "is", function(instance) {
|
|
282
|
+
if (typeof instance === "bigint" || Object.getPrototypeOf(instance) === BigInt.prototype) return Uint64$1(instance) === BigInt(instance);
|
|
283
|
+
return false;
|
|
284
|
+
});
|
|
285
|
+
return Uint64$1;
|
|
286
|
+
})();
|
|
287
|
+
const Int64 = /* @__PURE__ */ (function() {
|
|
288
|
+
const minInt64 = -BigInt("0x8000000000000000");
|
|
289
|
+
const maxInt64 = BigInt("0x7FFFFFFFFFFFFFFF");
|
|
290
|
+
const Int64$1 = function Int64$2(num) {
|
|
291
|
+
if (num == null) return BigInt(0);
|
|
292
|
+
try {
|
|
293
|
+
const value = BigInt(num);
|
|
294
|
+
if (value < minInt64) return value & maxUint64;
|
|
295
|
+
else if (value > maxInt64) return (value & maxUint64) - (maxUint64 + BigInt(1));
|
|
296
|
+
return value;
|
|
297
|
+
} catch (_) {
|
|
298
|
+
return BigInt(0);
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
inherits(Int64$1, BigInt);
|
|
302
|
+
Object.defineProperty(Int64$1, "MIN_VALUE", { value: minInt64 });
|
|
303
|
+
Object.defineProperty(Int64$1, "MAX_VALUE", { value: maxInt64 });
|
|
304
|
+
defineStaticMethod(Int64$1, "is", function(instance) {
|
|
305
|
+
if (typeof instance === "bigint" || Object.getPrototypeOf(instance) === BigInt.prototype) return Int64$1(instance) === BigInt(instance);
|
|
306
|
+
return false;
|
|
307
|
+
});
|
|
308
|
+
return Int64$1;
|
|
309
|
+
})();
|
|
310
|
+
const Entity = /* @__PURE__ */ (function() {
|
|
311
|
+
const Entity$1 = function Entity$2(value) {
|
|
312
|
+
return Uint32(value);
|
|
313
|
+
};
|
|
314
|
+
inherits(Entity$1, Uint32);
|
|
315
|
+
return Entity$1;
|
|
316
|
+
})();
|
|
317
|
+
|
|
318
|
+
//#endregion
|
|
319
|
+
//#region src/config.ts
|
|
320
|
+
const EmptyTypeOptimization = {
|
|
321
|
+
Disabled: 0,
|
|
322
|
+
Static: 1,
|
|
323
|
+
0: "Disabled",
|
|
324
|
+
1: "Static"
|
|
325
|
+
};
|
|
326
|
+
const directCall = (Type, ...args) => Type(...args);
|
|
327
|
+
const config = /* @__PURE__ */ (() => {
|
|
328
|
+
const customCalls = /* @__PURE__ */ new WeakMap();
|
|
329
|
+
customCalls.set(Boolean, directCall);
|
|
330
|
+
customCalls.set(Number, directCall);
|
|
331
|
+
customCalls.set(String, directCall);
|
|
332
|
+
customCalls.set(Symbol, directCall);
|
|
333
|
+
customCalls.set(Entity, directCall);
|
|
334
|
+
customCalls.set(Uint8, directCall);
|
|
335
|
+
customCalls.set(Int8, directCall);
|
|
336
|
+
customCalls.set(Uint16, directCall);
|
|
337
|
+
customCalls.set(Int16, directCall);
|
|
338
|
+
customCalls.set(Uint32, directCall);
|
|
339
|
+
customCalls.set(Int32, directCall);
|
|
340
|
+
customCalls.set(Uint64, directCall);
|
|
341
|
+
customCalls.set(Int64, directCall);
|
|
342
|
+
customCalls.set(Float32, directCall);
|
|
343
|
+
customCalls.set(Float64, directCall);
|
|
344
|
+
customCalls.set(BigInt, (Type, ...args) => Type(args.length === 0 ? 0 : args[0]));
|
|
345
|
+
return {
|
|
346
|
+
customCalls,
|
|
347
|
+
emptyClasses: /* @__PURE__ */ new WeakMap(),
|
|
348
|
+
eto: typeof ENTT_NO_ETO !== "undefined" ? ENTT_NO_ETO ? EmptyTypeOptimization.Disabled : EmptyTypeOptimization.Static : EmptyTypeOptimization.Static,
|
|
349
|
+
mixin: typeof ENTT_NO_MIXIN !== "undefined" ? !ENTT_NO_MIXIN : true,
|
|
350
|
+
sparsePage: typeof ENTT_SPARSE_PAGE !== "undefined" ? Number(ENTT_SPARSE_PAGE) : 4096,
|
|
351
|
+
packedPage: typeof ENTT_PACKED_PAGE !== "undefined" ? Number(ENTT_PACKED_PAGE) : 1024
|
|
352
|
+
};
|
|
353
|
+
})();
|
|
354
|
+
function createSafeNew(Type) {
|
|
355
|
+
if (config.customCalls.has(Type)) {
|
|
356
|
+
const func = config.customCalls.get(Type);
|
|
357
|
+
return (...args) => func(Type, ...args);
|
|
358
|
+
}
|
|
359
|
+
return (...args) => {
|
|
360
|
+
try {
|
|
361
|
+
return new Type(...args);
|
|
362
|
+
} catch (err) {
|
|
363
|
+
if (err instanceof NotConstructorError || err instanceof TypeError && err.message.includes("is not a constructor")) return Type(...args);
|
|
364
|
+
throw err;
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
function getBlockBody(str, match) {
|
|
369
|
+
if (!match) return "";
|
|
370
|
+
let bracketCount = 0;
|
|
371
|
+
const begin = match.index + match[0].length - 1;
|
|
372
|
+
let curr = begin;
|
|
373
|
+
do {
|
|
374
|
+
const char = str[curr];
|
|
375
|
+
if (char === "{") bracketCount++;
|
|
376
|
+
else if (char === "}") bracketCount--;
|
|
377
|
+
curr++;
|
|
378
|
+
} while (bracketCount > 0 && curr < str.length);
|
|
379
|
+
return str.slice(begin, curr);
|
|
380
|
+
}
|
|
381
|
+
function isEmptyClass(Type) {
|
|
382
|
+
if (config.eto === EmptyTypeOptimization.Disabled) return false;
|
|
383
|
+
if (typeof Type !== "function" || Type.prototype == null) return false;
|
|
384
|
+
if (config.emptyClasses.has(Type)) return config.emptyClasses.get(Type);
|
|
385
|
+
if (config.eto === EmptyTypeOptimization.Static) {
|
|
386
|
+
let str = "";
|
|
387
|
+
try {
|
|
388
|
+
str = Function.prototype.toString.call(Type);
|
|
389
|
+
} catch (_) {
|
|
390
|
+
return false;
|
|
391
|
+
}
|
|
392
|
+
if (str.startsWith("class")) {
|
|
393
|
+
const match = str.match(/^class\s+\w*(\s+extends\s+[\w$]+)?\s*{/);
|
|
394
|
+
const classBody = getBlockBody(str, match);
|
|
395
|
+
if (!classBody) throw new Error("impossible");
|
|
396
|
+
if (/^\{\s*(\r?\n)*\s*\}$/.test(classBody)) return match[1] ? isEmptyClass(Object.getPrototypeOf(Type)) : true;
|
|
397
|
+
return false;
|
|
398
|
+
} else if (str.startsWith("function")) {
|
|
399
|
+
const constructorBody = getBlockBody(str, str.match(/^function\s+\w*\s*\(([^)]*)\)\s*{/));
|
|
400
|
+
if (constructorBody) return constructorBody === "{ [native code] }" ? false : !/this|return/.test(constructorBody);
|
|
401
|
+
else throw new Error("impossible");
|
|
402
|
+
} else return false;
|
|
403
|
+
}
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
//#endregion
|
|
408
|
+
//#region node_modules/stable-hash/dist/index.mjs
|
|
409
|
+
const o = /* @__PURE__ */ new WeakMap();
|
|
410
|
+
let u = 0;
|
|
411
|
+
function stableHash(t) {
|
|
412
|
+
const i = typeof t, s = t && t.constructor, c = s === Date;
|
|
413
|
+
if (Object(t) === t && !c && s != RegExp) {
|
|
414
|
+
let e = o.get(t);
|
|
415
|
+
if (e) return e;
|
|
416
|
+
e = ++u + "~", o.set(t, e);
|
|
417
|
+
let n;
|
|
418
|
+
if (s === Array) {
|
|
419
|
+
for (e = "@", n = 0; n < t.length; n++) e += stableHash(t[n]) + ",";
|
|
420
|
+
o.set(t, e);
|
|
421
|
+
} else if (s === Object) {
|
|
422
|
+
e = "#";
|
|
423
|
+
const f = Object.keys(t).sort();
|
|
424
|
+
for (; (n = f.pop()) !== void 0;) t[n] !== void 0 && (e += n + ":" + stableHash(t[n]) + ",");
|
|
425
|
+
o.set(t, e);
|
|
426
|
+
}
|
|
427
|
+
return e;
|
|
428
|
+
}
|
|
429
|
+
return c ? t.toJSON() : i === "symbol" ? t.toString() : i === "string" ? JSON.stringify(t) : "" + t;
|
|
430
|
+
}
|
|
431
|
+
var dist_default = stableHash;
|
|
432
|
+
|
|
433
|
+
//#endregion
|
|
434
|
+
//#region src/disposable.ts
|
|
435
|
+
const Disposable = /* @__PURE__ */ (function() {
|
|
436
|
+
class Disposable$1 {
|
|
437
|
+
/** @virtual */
|
|
438
|
+
dispose() {}
|
|
439
|
+
[Symbol.dispose]() {
|
|
440
|
+
this.dispose();
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
if (typeof Symbol.dispose !== "symbol") delete Disposable$1.prototype[Symbol.dispose];
|
|
444
|
+
return Disposable$1;
|
|
445
|
+
})();
|
|
446
|
+
|
|
447
|
+
//#endregion
|
|
448
|
+
//#region src/template.ts
|
|
449
|
+
var Template = class extends Disposable {
|
|
450
|
+
_registry;
|
|
451
|
+
_specializations;
|
|
452
|
+
instantiate;
|
|
453
|
+
defaultRender;
|
|
454
|
+
constructor(render, specializations = []) {
|
|
455
|
+
super();
|
|
456
|
+
const registry = /* @__PURE__ */ new Map();
|
|
457
|
+
this._registry = registry;
|
|
458
|
+
this.defaultRender = render;
|
|
459
|
+
this._specializations = specializations.map((spec) => ({
|
|
460
|
+
...spec,
|
|
461
|
+
userland: false
|
|
462
|
+
}));
|
|
463
|
+
this.instantiate = function(...args) {
|
|
464
|
+
const r = this.selectSpecialization(...args) ?? render;
|
|
465
|
+
const hash = dist_default([r, args]);
|
|
466
|
+
if (registry.has(hash)) return registry.get(hash);
|
|
467
|
+
const ret = r.apply(this, args);
|
|
468
|
+
registry.set(hash, ret);
|
|
469
|
+
return ret;
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
selectSpecialization(...args) {
|
|
473
|
+
for (const spec of this._specializations) if (spec.predicate.apply(this, args)) return spec.render;
|
|
474
|
+
return null;
|
|
475
|
+
}
|
|
476
|
+
addSpecialization(spec) {
|
|
477
|
+
this._specializations.push({
|
|
478
|
+
...spec,
|
|
479
|
+
userland: true
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
removeSpecialization(spec) {
|
|
483
|
+
const index = this._specializations.findIndex((s) => s.predicate === spec.predicate && s.render === spec.render && s.userland);
|
|
484
|
+
if (index !== -1) this._specializations.splice(index, 1);
|
|
485
|
+
}
|
|
486
|
+
removeAllUserlandSpecializations() {
|
|
487
|
+
this._specializations = this._specializations.filter((s) => !s.userland);
|
|
488
|
+
}
|
|
489
|
+
dispose() {
|
|
490
|
+
this._registry.clear();
|
|
491
|
+
this._specializations.length = 0;
|
|
492
|
+
}
|
|
493
|
+
};
|
|
494
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
495
|
+
function defineTemplate(render, specializations = []) {
|
|
496
|
+
return new Template(render, specializations);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
//#endregion
|
|
500
|
+
//#region src/entity.ts
|
|
501
|
+
const internalEnttTraits = /* @__PURE__ */ defineTemplate(function(ValueType) {
|
|
502
|
+
if (typeof ValueType === "function" && ValueType.prototype != null) {
|
|
503
|
+
const BaseEntityType = isExtendsFrom(ValueType, [
|
|
504
|
+
Number,
|
|
505
|
+
BigInt,
|
|
506
|
+
Uint32,
|
|
507
|
+
Uint64
|
|
508
|
+
]);
|
|
509
|
+
if (BaseEntityType) {
|
|
510
|
+
const traits$1 = this.selectSpecialization(BaseEntityType).call(this, BaseEntityType);
|
|
511
|
+
traits$1.ValueType = ValueType;
|
|
512
|
+
return traits$1;
|
|
513
|
+
}
|
|
514
|
+
const EntityType = ValueType.EntityType;
|
|
515
|
+
if (!EntityType) throw new TypeError("Invalid EntityType");
|
|
516
|
+
const traits = internalEnttTraits.instantiate(EntityType);
|
|
517
|
+
traits.ValueType = ValueType;
|
|
518
|
+
return traits;
|
|
519
|
+
}
|
|
520
|
+
throw new TypeError("Invalid ValueType");
|
|
521
|
+
}, [
|
|
522
|
+
{
|
|
523
|
+
predicate: (ValueType) => ValueType === Number,
|
|
524
|
+
render: function() {
|
|
525
|
+
return {
|
|
526
|
+
ValueType: Number,
|
|
527
|
+
EntityType: Number,
|
|
528
|
+
VersionType: Number,
|
|
529
|
+
entityMask: 1048575,
|
|
530
|
+
versionMask: 4095
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
predicate: (ValueType) => ValueType === BigInt,
|
|
536
|
+
render: function() {
|
|
537
|
+
return {
|
|
538
|
+
ValueType: BigInt,
|
|
539
|
+
EntityType: BigInt,
|
|
540
|
+
VersionType: Number,
|
|
541
|
+
entityMask: BigInt(4294967295),
|
|
542
|
+
versionMask: BigInt(4294967295)
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
predicate: (ValueType) => ValueType === Uint32,
|
|
548
|
+
render: function() {
|
|
549
|
+
return {
|
|
550
|
+
ValueType: Uint32,
|
|
551
|
+
EntityType: Uint32,
|
|
552
|
+
VersionType: Uint16,
|
|
553
|
+
entityMask: Uint32(1048575),
|
|
554
|
+
versionMask: Uint32(4095)
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
predicate: (ValueType) => ValueType === Uint64,
|
|
560
|
+
render: function() {
|
|
561
|
+
return {
|
|
562
|
+
ValueType: Uint64,
|
|
563
|
+
EntityType: Uint64,
|
|
564
|
+
VersionType: Uint32,
|
|
565
|
+
entityMask: Uint64(4294967295),
|
|
566
|
+
versionMask: Uint64(4294967295)
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
]);
|
|
571
|
+
const basicEnttTraitsTemplate = /* @__PURE__ */ defineTemplate(function(traits) {
|
|
572
|
+
const { ValueType, EntityType, VersionType, entityMask, versionMask } = traits;
|
|
573
|
+
const length = popcount(entityMask);
|
|
574
|
+
assert(entityMask && (entityMask & entityMask + EntityType(1)) === EntityType(0), "Invalid entity mask");
|
|
575
|
+
assert((versionMask & versionMask + EntityType(1)) === EntityType(0), "Invalid version mask");
|
|
576
|
+
const newValueType = createSafeNew(ValueType);
|
|
577
|
+
const toIntegral = EntityType === Number ? (value) => EntityType(value) >>> 0 : (value) => EntityType(value);
|
|
578
|
+
const toEntity = ((value) => toIntegral(value) & entityMask);
|
|
579
|
+
const toVersion = VersionType === Number ? (value) => VersionType(!versionMask ? 0 : toIntegral(value) >> EntityType(length) & versionMask) >>> 0 : (value) => VersionType(!versionMask ? 0 : toIntegral(value) >> EntityType(length) & versionMask);
|
|
580
|
+
const c = isExtendsFrom(ValueType, [Number, BigInt]) ? (v) => ValueType(v) : (v) => newValueType(v);
|
|
581
|
+
const _construct = (entity, version$1) => {
|
|
582
|
+
let v = EntityType(entity) & entityMask;
|
|
583
|
+
if (versionMask) v = v | (EntityType(version$1) & versionMask) << EntityType(length);
|
|
584
|
+
return v;
|
|
585
|
+
};
|
|
586
|
+
const construct = EntityType === Number ? (entity, version$1) => c(_construct(entity, version$1) >>> 0) : (entity, version$1) => c(EntityType(_construct(entity, version$1)));
|
|
587
|
+
const next = ((value) => {
|
|
588
|
+
const vers = toVersion(value) + VersionType(1);
|
|
589
|
+
return construct(toIntegral(value), vers + (vers === versionMask ? VersionType(1) : VersionType(0)));
|
|
590
|
+
});
|
|
591
|
+
const _combine = (lhs, rhs) => {
|
|
592
|
+
let v = EntityType(lhs) & entityMask;
|
|
593
|
+
if (versionMask) v = v | EntityType(rhs) & versionMask << EntityType(length);
|
|
594
|
+
return v;
|
|
595
|
+
};
|
|
596
|
+
const combine = EntityType === Number ? (lhs, rhs) => c(_combine(lhs, rhs) >>> 0) : (lhs, rhs) => c(EntityType(_combine(lhs, rhs)));
|
|
597
|
+
const nul = construct(entityMask, versionMask);
|
|
598
|
+
const tombstone = construct(entityMask, versionMask);
|
|
599
|
+
const isNull = (value) => toEntity(value) === toEntity(nul);
|
|
600
|
+
return {
|
|
601
|
+
ValueType,
|
|
602
|
+
EntityType,
|
|
603
|
+
VersionType,
|
|
604
|
+
entityMask,
|
|
605
|
+
versionMask,
|
|
606
|
+
length,
|
|
607
|
+
null: nul,
|
|
608
|
+
tombstone,
|
|
609
|
+
toIntegral,
|
|
610
|
+
toEntity,
|
|
611
|
+
toVersion,
|
|
612
|
+
next,
|
|
613
|
+
construct,
|
|
614
|
+
combine,
|
|
615
|
+
isNull,
|
|
616
|
+
isTombstone: !versionMask ? (value) => toIntegral(value) === toIntegral(tombstone) : (value) => toVersion(value) === toVersion(tombstone)
|
|
617
|
+
};
|
|
618
|
+
});
|
|
619
|
+
const enttTraitsTemplate = /* @__PURE__ */ defineTemplate(function(ValueType) {
|
|
620
|
+
const traits = internalEnttTraits.instantiate(ValueType);
|
|
621
|
+
const BaseType = basicEnttTraitsTemplate.instantiate(traits);
|
|
622
|
+
return {
|
|
623
|
+
...BaseType,
|
|
624
|
+
BaseType,
|
|
625
|
+
pageSize: config.sparsePage
|
|
626
|
+
};
|
|
627
|
+
});
|
|
628
|
+
|
|
629
|
+
//#endregion
|
|
630
|
+
//#region src/iterator.ts
|
|
631
|
+
var ReversePointer = class ReversePointer {
|
|
632
|
+
it;
|
|
633
|
+
constructor(it) {
|
|
634
|
+
this.it = it.clone();
|
|
635
|
+
}
|
|
636
|
+
clone(target) {
|
|
637
|
+
if (target) {
|
|
638
|
+
if (this === target) return target;
|
|
639
|
+
this.it.clone(target.it);
|
|
640
|
+
return target;
|
|
641
|
+
}
|
|
642
|
+
return new ReversePointer(this.it);
|
|
643
|
+
}
|
|
644
|
+
swap(other) {
|
|
645
|
+
if (this === other) return;
|
|
646
|
+
this.it.swap(other.it);
|
|
647
|
+
}
|
|
648
|
+
base() {
|
|
649
|
+
return this.it.clone();
|
|
650
|
+
}
|
|
651
|
+
selfPlus(n = 1) {
|
|
652
|
+
this.it.selfMinus(n);
|
|
653
|
+
return this;
|
|
654
|
+
}
|
|
655
|
+
selfMinus(n = 1) {
|
|
656
|
+
this.it.selfPlus(n);
|
|
657
|
+
return this;
|
|
658
|
+
}
|
|
659
|
+
plus(n) {
|
|
660
|
+
return new ReversePointer(this.it.minus(n));
|
|
661
|
+
}
|
|
662
|
+
minus(n) {
|
|
663
|
+
return new ReversePointer(this.it.plus(n));
|
|
664
|
+
}
|
|
665
|
+
diff(other) {
|
|
666
|
+
return other.it.diff(this.it);
|
|
667
|
+
}
|
|
668
|
+
equals(other) {
|
|
669
|
+
return this.it.equals(other.it);
|
|
670
|
+
}
|
|
671
|
+
lt(other) {
|
|
672
|
+
return this.it.gt(other.it);
|
|
673
|
+
}
|
|
674
|
+
gt(other) {
|
|
675
|
+
return this.it.lt(other.it);
|
|
676
|
+
}
|
|
677
|
+
le(other) {
|
|
678
|
+
return this.it.ge(other.it);
|
|
679
|
+
}
|
|
680
|
+
ge(other) {
|
|
681
|
+
return this.it.le(other.it);
|
|
682
|
+
}
|
|
683
|
+
deref() {
|
|
684
|
+
return this.it.clone().selfMinus().deref();
|
|
685
|
+
}
|
|
686
|
+
write(value) {
|
|
687
|
+
return this.it.write(value);
|
|
688
|
+
}
|
|
689
|
+
access(value) {
|
|
690
|
+
return this.it.access(-1 - value);
|
|
691
|
+
}
|
|
692
|
+
set(off, value) {
|
|
693
|
+
this.it.set(-1 - off, value);
|
|
694
|
+
}
|
|
695
|
+
};
|
|
696
|
+
function makeReversePointer(it) {
|
|
697
|
+
return new ReversePointer(it);
|
|
698
|
+
}
|
|
699
|
+
function makeRangePointer(first, last) {
|
|
700
|
+
return [last != null ? first.clone() : first.begin(), last != null ? last.clone() : first.end()];
|
|
701
|
+
}
|
|
702
|
+
var RangeIterator = class extends Iterator {
|
|
703
|
+
first;
|
|
704
|
+
curr;
|
|
705
|
+
last;
|
|
706
|
+
constructor(first, last) {
|
|
707
|
+
super();
|
|
708
|
+
this.first = first.clone();
|
|
709
|
+
this.last = last.clone();
|
|
710
|
+
this.curr = first.clone();
|
|
711
|
+
}
|
|
712
|
+
begin() {
|
|
713
|
+
return this.first.clone();
|
|
714
|
+
}
|
|
715
|
+
end() {
|
|
716
|
+
return this.last.clone();
|
|
717
|
+
}
|
|
718
|
+
next() {
|
|
719
|
+
if (this.curr.equals(this.last)) return {
|
|
720
|
+
done: true,
|
|
721
|
+
value: void 0
|
|
722
|
+
};
|
|
723
|
+
const value = this.curr.deref();
|
|
724
|
+
this.curr.selfPlus();
|
|
725
|
+
return {
|
|
726
|
+
done: false,
|
|
727
|
+
value
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
[Symbol.iterator]() {
|
|
731
|
+
return this;
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
var AggregatePointer = class AggregatePointer {
|
|
735
|
+
pointers;
|
|
736
|
+
constructor(pointers) {
|
|
737
|
+
this.pointers = pointers;
|
|
738
|
+
}
|
|
739
|
+
base() {
|
|
740
|
+
return this.pointers[0];
|
|
741
|
+
}
|
|
742
|
+
deref() {
|
|
743
|
+
return this.pointers.map((p) => p.deref());
|
|
744
|
+
}
|
|
745
|
+
write(value) {
|
|
746
|
+
this.pointers.forEach((p, i) => p.write(value[i]));
|
|
747
|
+
return value;
|
|
748
|
+
}
|
|
749
|
+
clone(target) {
|
|
750
|
+
if (target) {
|
|
751
|
+
if (this === target) return target;
|
|
752
|
+
this.pointers.forEach((p, i) => {
|
|
753
|
+
target.pointers[i] = p.clone();
|
|
754
|
+
});
|
|
755
|
+
return target;
|
|
756
|
+
}
|
|
757
|
+
return new AggregatePointer(this.pointers.map((p) => p.clone()));
|
|
758
|
+
}
|
|
759
|
+
swap(other) {
|
|
760
|
+
if (this === other) return;
|
|
761
|
+
const tmp = this.pointers;
|
|
762
|
+
this.pointers = other.pointers;
|
|
763
|
+
other.pointers = tmp;
|
|
764
|
+
}
|
|
765
|
+
selfPlus() {
|
|
766
|
+
this.pointers.forEach((p) => p.selfPlus());
|
|
767
|
+
return this;
|
|
768
|
+
}
|
|
769
|
+
equals(other) {
|
|
770
|
+
return this.pointers.every((p, i) => p.equals(other.pointers[i]));
|
|
771
|
+
}
|
|
772
|
+
};
|
|
773
|
+
function toIterator(first, last) {
|
|
774
|
+
const [f, l] = makeRangePointer(first, last);
|
|
775
|
+
return new RangeIterator(f, l);
|
|
776
|
+
}
|
|
777
|
+
var ArrayPointer = class ArrayPointer {
|
|
778
|
+
array;
|
|
779
|
+
pos;
|
|
780
|
+
constructor(array, index) {
|
|
781
|
+
this.array = array;
|
|
782
|
+
this.pos = index;
|
|
783
|
+
}
|
|
784
|
+
clone(target) {
|
|
785
|
+
if (target) {
|
|
786
|
+
if (this === target) return target;
|
|
787
|
+
target.array = this.array;
|
|
788
|
+
target.pos = this.pos;
|
|
789
|
+
return target;
|
|
790
|
+
}
|
|
791
|
+
return new ArrayPointer(this.array, this.pos);
|
|
792
|
+
}
|
|
793
|
+
swap(other) {
|
|
794
|
+
if (this === other) return;
|
|
795
|
+
const tmpArray = this.array;
|
|
796
|
+
const tmpIndex = this.pos;
|
|
797
|
+
this.array = other.array;
|
|
798
|
+
this.pos = other.pos;
|
|
799
|
+
other.array = tmpArray;
|
|
800
|
+
other.pos = tmpIndex;
|
|
801
|
+
}
|
|
802
|
+
selfPlus(n = 1) {
|
|
803
|
+
this.pos += n;
|
|
804
|
+
return this;
|
|
805
|
+
}
|
|
806
|
+
plus(n) {
|
|
807
|
+
return new ArrayPointer(this.array, this.pos + n);
|
|
808
|
+
}
|
|
809
|
+
selfMinus(n = 1) {
|
|
810
|
+
this.pos -= n;
|
|
811
|
+
return this;
|
|
812
|
+
}
|
|
813
|
+
minus(n) {
|
|
814
|
+
return new ArrayPointer(this.array, this.pos - n);
|
|
815
|
+
}
|
|
816
|
+
diff(other) {
|
|
817
|
+
return this.pos - other.pos;
|
|
818
|
+
}
|
|
819
|
+
lt(other) {
|
|
820
|
+
return this.pos < other.pos;
|
|
821
|
+
}
|
|
822
|
+
gt(other) {
|
|
823
|
+
return this.pos > other.pos;
|
|
824
|
+
}
|
|
825
|
+
le(other) {
|
|
826
|
+
return this.pos <= other.pos;
|
|
827
|
+
}
|
|
828
|
+
ge(other) {
|
|
829
|
+
return this.pos >= other.pos;
|
|
830
|
+
}
|
|
831
|
+
equals(other) {
|
|
832
|
+
return this.pos === other.pos;
|
|
833
|
+
}
|
|
834
|
+
deref() {
|
|
835
|
+
return this.array[this.pos];
|
|
836
|
+
}
|
|
837
|
+
write(value) {
|
|
838
|
+
this.array[this.pos] = value;
|
|
839
|
+
return value;
|
|
840
|
+
}
|
|
841
|
+
access(n) {
|
|
842
|
+
return this.array[this.pos + n];
|
|
843
|
+
}
|
|
844
|
+
set(n, value) {
|
|
845
|
+
this.array[this.pos + n] = value;
|
|
846
|
+
}
|
|
847
|
+
};
|
|
848
|
+
var ArrayRange = class {
|
|
849
|
+
array;
|
|
850
|
+
constructor(array) {
|
|
851
|
+
this.array = array;
|
|
852
|
+
}
|
|
853
|
+
data() {
|
|
854
|
+
return this.array;
|
|
855
|
+
}
|
|
856
|
+
begin() {
|
|
857
|
+
return new ArrayPointer(this.array, 0);
|
|
858
|
+
}
|
|
859
|
+
end() {
|
|
860
|
+
return new ArrayPointer(this.array, this.array.length);
|
|
861
|
+
}
|
|
862
|
+
rbegin() {
|
|
863
|
+
return new ReversePointer(this.end());
|
|
864
|
+
}
|
|
865
|
+
rend() {
|
|
866
|
+
return new ReversePointer(this.begin());
|
|
867
|
+
}
|
|
868
|
+
[Symbol.iterator]() {
|
|
869
|
+
return toIterator(this);
|
|
870
|
+
}
|
|
871
|
+
};
|
|
872
|
+
function toRange(value) {
|
|
873
|
+
if (Array.isArray(value)) return new ArrayRange(value);
|
|
874
|
+
throw new Error("Invalid argument");
|
|
875
|
+
}
|
|
876
|
+
function distance(first, last) {
|
|
877
|
+
first = first.clone();
|
|
878
|
+
last = last.clone();
|
|
879
|
+
if (typeof first.diff === "function" && typeof last.diff === "function") return last.diff(first);
|
|
880
|
+
let r = 0;
|
|
881
|
+
for (; !first.equals(last); first.selfPlus()) ++r;
|
|
882
|
+
return r;
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
//#endregion
|
|
886
|
+
//#region src/sparse-set.ts
|
|
887
|
+
const DeletionPolicy = {
|
|
888
|
+
SwapAndPop: 0,
|
|
889
|
+
InPlace: 1,
|
|
890
|
+
SwapOnly: 2,
|
|
891
|
+
Unspecified: 0,
|
|
892
|
+
0: "SwapAndPop",
|
|
893
|
+
1: "InPlace",
|
|
894
|
+
2: "SwapOnly"
|
|
895
|
+
};
|
|
896
|
+
var SparseSetPointer = class SparseSetPointer {
|
|
897
|
+
packed;
|
|
898
|
+
offset;
|
|
899
|
+
constructor(packed = null, offset = 0) {
|
|
900
|
+
this.packed = packed;
|
|
901
|
+
this.offset = offset;
|
|
902
|
+
}
|
|
903
|
+
clone(target) {
|
|
904
|
+
if (target) {
|
|
905
|
+
if (this === target) return target;
|
|
906
|
+
target.packed = this.packed;
|
|
907
|
+
target.offset = this.offset;
|
|
908
|
+
return target;
|
|
909
|
+
}
|
|
910
|
+
return new SparseSetPointer(this.packed, this.offset);
|
|
911
|
+
}
|
|
912
|
+
swap(other) {
|
|
913
|
+
if (this === other) return;
|
|
914
|
+
const t = this.packed;
|
|
915
|
+
this.packed = other.packed;
|
|
916
|
+
other.packed = t;
|
|
917
|
+
const o$1 = this.offset;
|
|
918
|
+
this.offset = other.offset;
|
|
919
|
+
other.offset = o$1;
|
|
920
|
+
}
|
|
921
|
+
data() {
|
|
922
|
+
return this.packed;
|
|
923
|
+
}
|
|
924
|
+
selfPlus(n = 1) {
|
|
925
|
+
this.offset -= n;
|
|
926
|
+
return this;
|
|
927
|
+
}
|
|
928
|
+
selfMinus(n = 1) {
|
|
929
|
+
this.offset += n;
|
|
930
|
+
return this;
|
|
931
|
+
}
|
|
932
|
+
plus(n) {
|
|
933
|
+
return new SparseSetPointer(this.packed, this.offset - n);
|
|
934
|
+
}
|
|
935
|
+
minus(n) {
|
|
936
|
+
return new SparseSetPointer(this.packed, this.offset + n);
|
|
937
|
+
}
|
|
938
|
+
diff(other) {
|
|
939
|
+
return other.index() - this.index();
|
|
940
|
+
}
|
|
941
|
+
equals(other) {
|
|
942
|
+
return this.index() === other.index();
|
|
943
|
+
}
|
|
944
|
+
lt(other) {
|
|
945
|
+
return this.index() > other.index();
|
|
946
|
+
}
|
|
947
|
+
gt(other) {
|
|
948
|
+
return this.index() < other.index();
|
|
949
|
+
}
|
|
950
|
+
le(other) {
|
|
951
|
+
return !this.gt(other);
|
|
952
|
+
}
|
|
953
|
+
ge(other) {
|
|
954
|
+
return !this.lt(other);
|
|
955
|
+
}
|
|
956
|
+
deref() {
|
|
957
|
+
return this.access(0);
|
|
958
|
+
}
|
|
959
|
+
write(value) {
|
|
960
|
+
this.set(0, value);
|
|
961
|
+
return value;
|
|
962
|
+
}
|
|
963
|
+
access(value) {
|
|
964
|
+
const idx = this.index() - value;
|
|
965
|
+
if (idx < 0 || idx >= this.packed.length) throw new RangeError(`Iterator access out of range: ${idx}, [0, ${this.packed.length})`);
|
|
966
|
+
return this.packed[idx];
|
|
967
|
+
}
|
|
968
|
+
set(off, value) {
|
|
969
|
+
const idx = this.index() - off;
|
|
970
|
+
if (idx < 0 || idx >= this.packed.length) throw new RangeError(`Iterator access out of range: ${idx}, [0, ${this.packed.length})`);
|
|
971
|
+
this.packed[idx] = value;
|
|
972
|
+
}
|
|
973
|
+
index() {
|
|
974
|
+
return this.offset - 1;
|
|
975
|
+
}
|
|
976
|
+
[Symbol.toPrimitive](hint) {
|
|
977
|
+
const pos = this.packed.length - 1 - this.index();
|
|
978
|
+
if (hint === "string") return pos.toString();
|
|
979
|
+
return pos;
|
|
980
|
+
}
|
|
981
|
+
};
|
|
982
|
+
const basicSparseSetTemplate = /* @__PURE__ */ defineTemplate(function(EntityType) {
|
|
983
|
+
const traits = enttTraitsTemplate.instantiate(EntityType);
|
|
984
|
+
const typeName = traits.ValueType.name;
|
|
985
|
+
const maxSize = Uint64(traits.toEntity(traits.null));
|
|
986
|
+
const pageSize = Uint64(traits.pageSize);
|
|
987
|
+
const policyToHead = (mode) => mode === DeletionPolicy.SwapOnly ? Uint64(0) : maxSize;
|
|
988
|
+
const entityToPos = (entity) => Uint64(traits.toEntity(entity));
|
|
989
|
+
const posToPage = (pos) => pos / pageSize;
|
|
990
|
+
const _contains = (() => {
|
|
991
|
+
const cap = traits.entityMask;
|
|
992
|
+
const mask = traits.toIntegral(traits.null) & ~cap;
|
|
993
|
+
return isExtendsFrom(traits.EntityType, [Number]) ? (self, entity) => {
|
|
994
|
+
const elem = self.sparsePtr(entity);
|
|
995
|
+
if (elem == null) return false;
|
|
996
|
+
return (mask & traits.toIntegral(entity) ^ traits.toIntegral(elem)) >>> 0 < traits.entityMask;
|
|
997
|
+
} : (self, entity) => {
|
|
998
|
+
const elem = self.sparsePtr(entity);
|
|
999
|
+
if (elem == null) return false;
|
|
1000
|
+
return traits.EntityType(mask & traits.toIntegral(entity) ^ traits.toIntegral(elem)) < traits.entityMask;
|
|
1001
|
+
};
|
|
1002
|
+
})();
|
|
1003
|
+
return class BasicSparseSet extends Disposable {
|
|
1004
|
+
static BasicIterator = SparseSetPointer;
|
|
1005
|
+
static Iterator = BasicSparseSet.BasicIterator;
|
|
1006
|
+
static ReverseIterator = ReversePointer;
|
|
1007
|
+
static TraitsType = traits;
|
|
1008
|
+
static EntityType = traits.ValueType;
|
|
1009
|
+
sparse;
|
|
1010
|
+
packed;
|
|
1011
|
+
mode;
|
|
1012
|
+
head;
|
|
1013
|
+
Type;
|
|
1014
|
+
sparsePtr(entity) {
|
|
1015
|
+
const pos = entityToPos(entity);
|
|
1016
|
+
const page = posToPage(pos);
|
|
1017
|
+
return page < this.sparse.length && this.sparse[page] ? this.sparse[page][fastMod(pos, pageSize)] : null;
|
|
1018
|
+
}
|
|
1019
|
+
sparseRef(entity) {
|
|
1020
|
+
const pos = entityToPos(entity);
|
|
1021
|
+
const page = posToPage(pos);
|
|
1022
|
+
assert(page < this.sparse.length && this.sparse[page], "Invalid element");
|
|
1023
|
+
const pageIndex = fastMod(pos, pageSize);
|
|
1024
|
+
return {
|
|
1025
|
+
get: () => this.sparse[page][pageIndex],
|
|
1026
|
+
set: (value) => {
|
|
1027
|
+
this.sparse[page][pageIndex] = value;
|
|
1028
|
+
}
|
|
1029
|
+
};
|
|
1030
|
+
}
|
|
1031
|
+
assureAtLeast(entity) {
|
|
1032
|
+
const pos = entityToPos(entity);
|
|
1033
|
+
const page = posToPage(pos);
|
|
1034
|
+
while (this.sparse.length <= page) this.sparse.push(Array(traits.pageSize).fill(traits.null));
|
|
1035
|
+
const pageIndex = fastMod(pos, pageSize);
|
|
1036
|
+
return {
|
|
1037
|
+
get: () => this.sparse[page][pageIndex],
|
|
1038
|
+
set: (value) => {
|
|
1039
|
+
this.sparse[page][pageIndex] = value;
|
|
1040
|
+
}
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
static isNull(entity) {
|
|
1044
|
+
return traits.isNull(entity);
|
|
1045
|
+
}
|
|
1046
|
+
static isTombstone(entity) {
|
|
1047
|
+
return traits.isTombstone(entity);
|
|
1048
|
+
}
|
|
1049
|
+
constructor(TypeOrMode, modeOrUndefined) {
|
|
1050
|
+
super();
|
|
1051
|
+
this.sparse = [];
|
|
1052
|
+
this.packed = [];
|
|
1053
|
+
const mode = typeof TypeOrMode === "number" ? TypeOrMode : modeOrUndefined ?? DeletionPolicy.SwapAndPop;
|
|
1054
|
+
this.mode = mode;
|
|
1055
|
+
this.head = policyToHead(mode);
|
|
1056
|
+
this.Type = typeof TypeOrMode === "function" ? TypeOrMode : void 0;
|
|
1057
|
+
assert(traits.versionMask || mode !== DeletionPolicy.InPlace, "Policy does not support zero-sized versions");
|
|
1058
|
+
}
|
|
1059
|
+
dispose() {
|
|
1060
|
+
this.clear();
|
|
1061
|
+
}
|
|
1062
|
+
reserve(cap) {
|
|
1063
|
+
if (cap > this.packed.length) this.packed.length = cap;
|
|
1064
|
+
}
|
|
1065
|
+
data() {
|
|
1066
|
+
return this.packed;
|
|
1067
|
+
}
|
|
1068
|
+
policy() {
|
|
1069
|
+
return this.mode;
|
|
1070
|
+
}
|
|
1071
|
+
isNull(entity) {
|
|
1072
|
+
return traits.isNull(entity);
|
|
1073
|
+
}
|
|
1074
|
+
isTombstone(entity) {
|
|
1075
|
+
return traits.isTombstone(entity);
|
|
1076
|
+
}
|
|
1077
|
+
type() {
|
|
1078
|
+
return this.Type;
|
|
1079
|
+
}
|
|
1080
|
+
empty() {
|
|
1081
|
+
return this.packed.length === 0;
|
|
1082
|
+
}
|
|
1083
|
+
get size() {
|
|
1084
|
+
return this.packed.length;
|
|
1085
|
+
}
|
|
1086
|
+
freeList(value) {
|
|
1087
|
+
if (value != null) {
|
|
1088
|
+
assert(this.mode === DeletionPolicy.SwapOnly && !(value > this.packed.length), "Invalid value");
|
|
1089
|
+
this.head = Uint64(value);
|
|
1090
|
+
}
|
|
1091
|
+
return this.head;
|
|
1092
|
+
}
|
|
1093
|
+
contiguous() {
|
|
1094
|
+
return this.mode !== DeletionPolicy.InPlace || this.head === maxSize;
|
|
1095
|
+
}
|
|
1096
|
+
access(pos) {
|
|
1097
|
+
assert(pos < this.packed.length, "Index out of bounds");
|
|
1098
|
+
return this.packed[pos];
|
|
1099
|
+
}
|
|
1100
|
+
swapAt(lhs, rhs) {
|
|
1101
|
+
const from = this.packed[lhs];
|
|
1102
|
+
const to = this.packed[rhs];
|
|
1103
|
+
this.sparseRef(from).set(traits.combine(traits.EntityType(rhs), traits.toIntegral(from)));
|
|
1104
|
+
this.sparseRef(to).set(traits.combine(traits.EntityType(lhs), traits.toIntegral(to)));
|
|
1105
|
+
this.packed[lhs] = to;
|
|
1106
|
+
this.packed[rhs] = from;
|
|
1107
|
+
}
|
|
1108
|
+
/** @virtual */
|
|
1109
|
+
tryEmplace(entity, forceBack = false, _value) {
|
|
1110
|
+
assert(!traits.isNull(entity) && !traits.isTombstone(entity), "Invalid element");
|
|
1111
|
+
const elem = BasicSparseSet.prototype.assureAtLeast.call(this, entity);
|
|
1112
|
+
let pos = this.size;
|
|
1113
|
+
switch (this.mode) {
|
|
1114
|
+
case DeletionPolicy.InPlace: if (this.head !== maxSize && !forceBack) {
|
|
1115
|
+
pos = Number(this.head);
|
|
1116
|
+
assert(elem.get() == null || traits.isNull(elem.get()), "Slot not available");
|
|
1117
|
+
elem.set(traits.combine(traits.EntityType(this.head), traits.toIntegral(entity)));
|
|
1118
|
+
this.head = Uint64(traits.toEntity(this.packed[pos]));
|
|
1119
|
+
this.packed[pos] = entity;
|
|
1120
|
+
break;
|
|
1121
|
+
}
|
|
1122
|
+
case DeletionPolicy.SwapAndPop:
|
|
1123
|
+
assert(elem.get() == null || traits.isNull(elem.get()), "Slot not available");
|
|
1124
|
+
this.packed.push(entity);
|
|
1125
|
+
elem.set(traits.combine(traits.EntityType(this.packed.length - 1), traits.toIntegral(entity)));
|
|
1126
|
+
break;
|
|
1127
|
+
case DeletionPolicy.SwapOnly:
|
|
1128
|
+
if (elem.get() == null || traits.isNull(elem.get())) {
|
|
1129
|
+
this.packed.push(entity);
|
|
1130
|
+
elem.set(traits.combine(traits.EntityType(this.packed.length - 1), traits.toIntegral(entity)));
|
|
1131
|
+
} else {
|
|
1132
|
+
assert(!(entityToPos(elem.get()) < this.head), "Slot not available");
|
|
1133
|
+
this.bump(entity);
|
|
1134
|
+
}
|
|
1135
|
+
pos = Number(this.head);
|
|
1136
|
+
this.head++;
|
|
1137
|
+
BasicSparseSet.prototype.swapAt.call(this, entityToPos(elem.get()), pos);
|
|
1138
|
+
break;
|
|
1139
|
+
default: throw new Error("Unsupported operation");
|
|
1140
|
+
}
|
|
1141
|
+
return new BasicSparseSet.BasicIterator(this.packed, pos + 1);
|
|
1142
|
+
}
|
|
1143
|
+
push(entity, elem) {
|
|
1144
|
+
return this.tryEmplace(entity, false, elem);
|
|
1145
|
+
}
|
|
1146
|
+
pushRange(iterable, last) {
|
|
1147
|
+
let first = void 0;
|
|
1148
|
+
if (last != null) {
|
|
1149
|
+
first = iterable.clone();
|
|
1150
|
+
last = last.clone();
|
|
1151
|
+
} else {
|
|
1152
|
+
first = iterable.begin();
|
|
1153
|
+
last = iterable.end();
|
|
1154
|
+
}
|
|
1155
|
+
let curr = BasicSparseSet.prototype.end.call(this);
|
|
1156
|
+
for (; !first.equals(last); first.selfPlus()) curr = this.tryEmplace(first.deref(), true);
|
|
1157
|
+
return curr;
|
|
1158
|
+
}
|
|
1159
|
+
add(entity) {
|
|
1160
|
+
this.push(entity);
|
|
1161
|
+
return this;
|
|
1162
|
+
}
|
|
1163
|
+
contains(entity) {
|
|
1164
|
+
return _contains(this, entity);
|
|
1165
|
+
}
|
|
1166
|
+
has(entity) {
|
|
1167
|
+
return this.contains(entity);
|
|
1168
|
+
}
|
|
1169
|
+
swapAndPop(entity) {
|
|
1170
|
+
assert(this.mode === DeletionPolicy.SwapAndPop, "Deletion policy mismatch");
|
|
1171
|
+
const self = this.sparseRef(entity);
|
|
1172
|
+
const entt = traits.toEntity(self.get());
|
|
1173
|
+
this.sparseRef(this.packed[this.packed.length - 1]).set(traits.combine(entt, traits.toIntegral(this.packed[this.packed.length - 1])));
|
|
1174
|
+
this.packed[entt] = this.packed[this.packed.length - 1];
|
|
1175
|
+
assert((this.packed[this.packed.length - 1] = traits.null, true), "");
|
|
1176
|
+
self.set(traits.null);
|
|
1177
|
+
this.packed.pop();
|
|
1178
|
+
}
|
|
1179
|
+
inPlacePop(entity) {
|
|
1180
|
+
assert(this.mode === DeletionPolicy.InPlace, "Deletion policy mismatch");
|
|
1181
|
+
const ref = this.sparseRef(entity);
|
|
1182
|
+
const tmp = ref.get();
|
|
1183
|
+
ref.set(traits.null);
|
|
1184
|
+
const pos = entityToPos(tmp);
|
|
1185
|
+
const head = this.head;
|
|
1186
|
+
this.head = Uint64(traits.EntityType(pos));
|
|
1187
|
+
this.packed[pos] = traits.combine(traits.EntityType(head), traits.EntityType(traits.tombstone));
|
|
1188
|
+
}
|
|
1189
|
+
swapOnly(entity) {
|
|
1190
|
+
assert(this.mode === DeletionPolicy.SwapOnly, "Deletion policy mismatch");
|
|
1191
|
+
const pos = this.index(entity);
|
|
1192
|
+
this.bump(traits.next(entity));
|
|
1193
|
+
if (pos < this.head) this.head--;
|
|
1194
|
+
BasicSparseSet.prototype.swapAt.call(this, pos, this.head);
|
|
1195
|
+
}
|
|
1196
|
+
/** @virtual */
|
|
1197
|
+
pop(first, last) {
|
|
1198
|
+
first = first.clone();
|
|
1199
|
+
last = last.clone();
|
|
1200
|
+
if (this.mode === DeletionPolicy.SwapAndPop) for (; !first.equals(last); first.selfPlus()) this.swapAndPop(first.deref());
|
|
1201
|
+
else if (this.mode === DeletionPolicy.InPlace) for (; !first.equals(last); first.selfPlus()) this.inPlacePop(first.deref());
|
|
1202
|
+
else if (this.mode === DeletionPolicy.SwapOnly) for (; !first.equals(last); first.selfPlus()) this.swapOnly(first.deref());
|
|
1203
|
+
else throw new Error("Unsupported operation");
|
|
1204
|
+
}
|
|
1205
|
+
/** @virtual */
|
|
1206
|
+
popAll() {
|
|
1207
|
+
switch (this.mode) {
|
|
1208
|
+
case DeletionPolicy.InPlace: if (this.head !== maxSize) {
|
|
1209
|
+
for (const elem of this.packed) if (!traits.isTombstone(elem)) this.sparseRef(elem).set(traits.null);
|
|
1210
|
+
break;
|
|
1211
|
+
}
|
|
1212
|
+
case DeletionPolicy.SwapOnly:
|
|
1213
|
+
case DeletionPolicy.SwapAndPop:
|
|
1214
|
+
for (const elem of this.packed) this.sparseRef(elem).set(traits.null);
|
|
1215
|
+
break;
|
|
1216
|
+
}
|
|
1217
|
+
this.head = policyToHead(this.mode);
|
|
1218
|
+
this.packed.length = 0;
|
|
1219
|
+
}
|
|
1220
|
+
erase(first, last) {
|
|
1221
|
+
if (last != null) if (first instanceof SparseSetPointer && last instanceof SparseSetPointer) this.pop(first, last);
|
|
1222
|
+
else {
|
|
1223
|
+
const f = first.clone();
|
|
1224
|
+
last = last.clone();
|
|
1225
|
+
for (; !f.equals(last); f.selfPlus()) this.erase(f.deref());
|
|
1226
|
+
}
|
|
1227
|
+
else {
|
|
1228
|
+
const it = this.toIterator(first);
|
|
1229
|
+
this.pop(it, it.plus(1));
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
remove(entity, last) {
|
|
1233
|
+
if (last != null) {
|
|
1234
|
+
let count = 0;
|
|
1235
|
+
const first = entity.clone();
|
|
1236
|
+
const l = last.clone();
|
|
1237
|
+
if (entity instanceof SparseSetPointer && last instanceof SparseSetPointer) while (!first.equals(l)) {
|
|
1238
|
+
while (!first.equals(l) && !this.contains(first.deref())) first.selfPlus();
|
|
1239
|
+
const it = first.clone();
|
|
1240
|
+
while (!first.equals(l) && this.contains(first.deref())) first.selfPlus();
|
|
1241
|
+
count += first.diff(it);
|
|
1242
|
+
this.erase(it, first);
|
|
1243
|
+
}
|
|
1244
|
+
else for (; !first.equals(l); first.selfPlus()) count += Number(this.remove(first.deref()));
|
|
1245
|
+
return count;
|
|
1246
|
+
} else {
|
|
1247
|
+
if (!this.has(entity)) return false;
|
|
1248
|
+
this.erase(entity);
|
|
1249
|
+
return true;
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
delete(entity) {
|
|
1253
|
+
return this.remove(entity);
|
|
1254
|
+
}
|
|
1255
|
+
clear() {
|
|
1256
|
+
this.popAll();
|
|
1257
|
+
assert((this.compact(), this.size) === 0, "Non-empty set");
|
|
1258
|
+
this.head = policyToHead(this.mode);
|
|
1259
|
+
this.packed.length = 0;
|
|
1260
|
+
}
|
|
1261
|
+
forEach(callbackfn, thisArg) {
|
|
1262
|
+
for (let i = this.packed.length - 1; i >= 0; --i) {
|
|
1263
|
+
const item = this.packed[i];
|
|
1264
|
+
callbackfn.call(thisArg, item, item, this);
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
at(index) {
|
|
1268
|
+
return this.packed[(this.packed.length - 1 - index) % this.packed.length];
|
|
1269
|
+
}
|
|
1270
|
+
keys() {
|
|
1271
|
+
return this[Symbol.iterator]();
|
|
1272
|
+
}
|
|
1273
|
+
values() {
|
|
1274
|
+
return this[Symbol.iterator]();
|
|
1275
|
+
}
|
|
1276
|
+
entries() {
|
|
1277
|
+
const begin = BasicSparseSet.prototype.begin.call(this);
|
|
1278
|
+
const end = BasicSparseSet.prototype.end.call(this);
|
|
1279
|
+
return toIterator(new AggregatePointer([begin, begin.clone()]), new AggregatePointer([end, end.clone()]));
|
|
1280
|
+
}
|
|
1281
|
+
current(entt) {
|
|
1282
|
+
const elem = this.sparsePtr(entt);
|
|
1283
|
+
return elem != null ? traits.toVersion(elem) : traits.toVersion(traits.tombstone);
|
|
1284
|
+
}
|
|
1285
|
+
bump(entt) {
|
|
1286
|
+
const elem = this.sparseRef(entt);
|
|
1287
|
+
assert(!traits.isNull(entt) && (elem.get() == null || !traits.isTombstone(elem.get())), "Cannot set the required version");
|
|
1288
|
+
elem.set(traits.combine(traits.toIntegral(elem.get()), traits.toIntegral(entt)));
|
|
1289
|
+
this.packed[entityToPos(elem.get())] = entt;
|
|
1290
|
+
return traits.toVersion(entt);
|
|
1291
|
+
}
|
|
1292
|
+
index(value) {
|
|
1293
|
+
assert(this.contains(value), "Set does not contain entity");
|
|
1294
|
+
return Number(entityToPos(this.sparsePtr(value)));
|
|
1295
|
+
}
|
|
1296
|
+
find(value) {
|
|
1297
|
+
return this.has(value) ? this.toIterator(value) : BasicSparseSet.prototype.end.call(this);
|
|
1298
|
+
}
|
|
1299
|
+
begin() {
|
|
1300
|
+
return new BasicSparseSet.BasicIterator(this.packed, this.packed.length);
|
|
1301
|
+
}
|
|
1302
|
+
end() {
|
|
1303
|
+
return new BasicSparseSet.BasicIterator(this.packed, 0);
|
|
1304
|
+
}
|
|
1305
|
+
rbegin() {
|
|
1306
|
+
return makeReversePointer(BasicSparseSet.prototype.end.call(this));
|
|
1307
|
+
}
|
|
1308
|
+
rend() {
|
|
1309
|
+
return makeReversePointer(BasicSparseSet.prototype.begin.call(this));
|
|
1310
|
+
}
|
|
1311
|
+
toIterator(entt) {
|
|
1312
|
+
return BasicSparseSet.prototype.end.call(this).minus(this.index(entt)).selfMinus();
|
|
1313
|
+
}
|
|
1314
|
+
/** @virtual */
|
|
1315
|
+
bindAny(_value) {}
|
|
1316
|
+
bind(value) {
|
|
1317
|
+
this.bindAny(value);
|
|
1318
|
+
}
|
|
1319
|
+
/** @virtual */
|
|
1320
|
+
swapOrMove(_lhs, _rhs) {
|
|
1321
|
+
assert(this.mode !== DeletionPolicy.SwapOnly || _lhs < this.head === _rhs < this.head, "Cross swapping is not supported");
|
|
1322
|
+
}
|
|
1323
|
+
compact() {
|
|
1324
|
+
if (this.mode === DeletionPolicy.InPlace) {
|
|
1325
|
+
let from = this.packed.length;
|
|
1326
|
+
let pos = this.head;
|
|
1327
|
+
this.head = maxSize;
|
|
1328
|
+
for (; from && traits.isTombstone(this.packed[from - 1]); --from);
|
|
1329
|
+
while (pos !== maxSize) {
|
|
1330
|
+
const to = pos;
|
|
1331
|
+
pos = Uint64(entityToPos(this.packed[pos]));
|
|
1332
|
+
if (to < from) {
|
|
1333
|
+
--from;
|
|
1334
|
+
this.swapOrMove(from, Number(to));
|
|
1335
|
+
this.packed[to] = this.packed[from];
|
|
1336
|
+
const elem = traits.EntityType(to);
|
|
1337
|
+
this.sparseRef(this.packed[to]).set(traits.combine(elem, traits.toIntegral(this.packed[to])));
|
|
1338
|
+
for (; from && traits.isTombstone(this.packed[from - 1]); --from);
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
this.packed.length = from;
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
sort(compareFn, algo = defaultSort) {
|
|
1345
|
+
const len = this.mode === DeletionPolicy.SwapOnly ? Number(this.head) : this.packed.length;
|
|
1346
|
+
this.sortN(len, compareFn, algo);
|
|
1347
|
+
}
|
|
1348
|
+
sortN(length, compareFn, algo = defaultSort) {
|
|
1349
|
+
assert(this.mode !== DeletionPolicy.InPlace || this.head === maxSize, "Sorting with tombstones is not allowed");
|
|
1350
|
+
assert(!(length > this.packed.length), "Length exceeds the number of elements");
|
|
1351
|
+
const reversedSlice = this.packed.slice(0, length).reverse();
|
|
1352
|
+
algo(reversedSlice, compareFn);
|
|
1353
|
+
for (let i = 0; i < length; ++i) this.packed[length - 1 - i] = reversedSlice[i];
|
|
1354
|
+
for (let pos = 0; pos < length; ++pos) {
|
|
1355
|
+
let curr = pos;
|
|
1356
|
+
let next = this.index(this.packed[curr]);
|
|
1357
|
+
while (curr !== next) {
|
|
1358
|
+
const idx = this.index(this.packed[next]);
|
|
1359
|
+
const entt = this.packed[curr];
|
|
1360
|
+
this.swapOrMove(next, idx);
|
|
1361
|
+
const elem = traits.EntityType(curr);
|
|
1362
|
+
this.sparseRef(entt).set(traits.combine(elem, traits.toIntegral(this.packed[curr])));
|
|
1363
|
+
const old = next;
|
|
1364
|
+
next = idx;
|
|
1365
|
+
curr = old;
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
swapElements(lhs, rhs) {
|
|
1370
|
+
const from = this.index(lhs);
|
|
1371
|
+
const to = this.index(rhs);
|
|
1372
|
+
this.swapOrMove(from, to);
|
|
1373
|
+
BasicSparseSet.prototype.swapAt.call(this, from, to);
|
|
1374
|
+
}
|
|
1375
|
+
sortAs(rangeOrFirst, lastOrNull) {
|
|
1376
|
+
assert(this.mode !== DeletionPolicy.InPlace || this.head === maxSize, "Sorting with tombstones is not allowed");
|
|
1377
|
+
const first = lastOrNull != null ? rangeOrFirst.clone() : rangeOrFirst.begin();
|
|
1378
|
+
const last = lastOrNull != null ? lastOrNull.clone() : rangeOrFirst.end();
|
|
1379
|
+
const len = this.mode === DeletionPolicy.SwapOnly ? Number(this.head) : this.packed.length;
|
|
1380
|
+
const it = BasicSparseSet.prototype.end.call(this).minus(len);
|
|
1381
|
+
const other = BasicSparseSet.prototype.end.call(this);
|
|
1382
|
+
for (; !it.equals(other) && !first.equals(last); first.selfPlus()) {
|
|
1383
|
+
const curr = first.deref();
|
|
1384
|
+
if (this.contains(curr)) {
|
|
1385
|
+
const entt = it.deref();
|
|
1386
|
+
if (traits.toIntegral(entt) !== traits.toIntegral(curr)) this.swapElements(entt, curr);
|
|
1387
|
+
it.selfPlus();
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
return it;
|
|
1391
|
+
}
|
|
1392
|
+
get [Symbol.toStringTag]() {
|
|
1393
|
+
return `BasicSparseSet<${typeName}>`;
|
|
1394
|
+
}
|
|
1395
|
+
[Symbol.iterator]() {
|
|
1396
|
+
return toIterator(BasicSparseSet.prototype.begin.call(this), BasicSparseSet.prototype.end.call(this));
|
|
1397
|
+
}
|
|
1398
|
+
};
|
|
1399
|
+
});
|
|
1400
|
+
const SparseSet = /* @__PURE__ */ (() => basicSparseSetTemplate.instantiate(Entity))();
|
|
1401
|
+
|
|
1402
|
+
//#endregion
|
|
1403
|
+
//#region src/component.ts
|
|
1404
|
+
const componentTraitsTemplate = /* @__PURE__ */ defineTemplate(function(Type, Entity$1) {
|
|
1405
|
+
return {
|
|
1406
|
+
ElementType: Type,
|
|
1407
|
+
EntityType: Entity$1,
|
|
1408
|
+
pageSize: Type == null ? 0 : "pageSize" in Type ? Type.pageSize : isEmptyClass(Type) ? 0 : config.packedPage,
|
|
1409
|
+
inPlaceDelete: Type != null && "inPlaceDelete" in Type ? Type.inPlaceDelete : false
|
|
1410
|
+
};
|
|
1411
|
+
});
|
|
1412
|
+
|
|
1413
|
+
//#endregion
|
|
1414
|
+
//#region src/signal.ts
|
|
1415
|
+
var Delegate = class extends Disposable {
|
|
1416
|
+
fn;
|
|
1417
|
+
instance;
|
|
1418
|
+
constructor(fn, instance) {
|
|
1419
|
+
super();
|
|
1420
|
+
this.fn = fn;
|
|
1421
|
+
this.instance = instance;
|
|
1422
|
+
}
|
|
1423
|
+
dispose() {
|
|
1424
|
+
this.reset();
|
|
1425
|
+
}
|
|
1426
|
+
reset() {
|
|
1427
|
+
this.fn = null;
|
|
1428
|
+
this.instance = null;
|
|
1429
|
+
}
|
|
1430
|
+
empty() {
|
|
1431
|
+
return this.fn == null;
|
|
1432
|
+
}
|
|
1433
|
+
connect(fn, instance) {
|
|
1434
|
+
this.fn = fn;
|
|
1435
|
+
this.instance = instance;
|
|
1436
|
+
}
|
|
1437
|
+
invoke(...args) {
|
|
1438
|
+
const fn = this.fn;
|
|
1439
|
+
return this.instance ? fn.apply(this.instance, args) : fn(...args);
|
|
1440
|
+
}
|
|
1441
|
+
};
|
|
1442
|
+
var Sink = class Sink extends Disposable {
|
|
1443
|
+
signal;
|
|
1444
|
+
constructor(signal) {
|
|
1445
|
+
super();
|
|
1446
|
+
this.signal = signal;
|
|
1447
|
+
}
|
|
1448
|
+
dispose() {
|
|
1449
|
+
this.signal?.dispose();
|
|
1450
|
+
this.signal = void 0;
|
|
1451
|
+
}
|
|
1452
|
+
empty() {
|
|
1453
|
+
assert(this.signal != null, "Invalid reference to signal");
|
|
1454
|
+
return this.signal.calls.length === 0;
|
|
1455
|
+
}
|
|
1456
|
+
disconnectIf(callback) {
|
|
1457
|
+
assert(this.signal != null, "Invalid reference to signal");
|
|
1458
|
+
for (let pos = this.signal.calls.length - 1; pos >= 0; --pos) {
|
|
1459
|
+
const elem = this.signal.calls[pos];
|
|
1460
|
+
if (callback(elem)) {
|
|
1461
|
+
const tmp = this.signal.calls[pos];
|
|
1462
|
+
this.signal.calls[pos] = this.signal.calls[this.signal.calls.length - 1];
|
|
1463
|
+
this.signal.calls[this.signal.calls.length - 1] = tmp;
|
|
1464
|
+
this.signal.calls.pop();
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
disconnect(fn, instance) {
|
|
1469
|
+
assert(this.signal != null, "Invalid reference to signal");
|
|
1470
|
+
if (fn != null && instance != null) this.disconnectIf((elem) => Object.is(elem.fn, fn) && Object.is(elem.instance, instance));
|
|
1471
|
+
else if (fn != null) this.disconnectIf((elem) => Object.is(elem.fn, fn));
|
|
1472
|
+
else if (instance != null) this.disconnectIf((elem) => Object.is(elem.instance, instance));
|
|
1473
|
+
else this.signal.calls.length = 0;
|
|
1474
|
+
}
|
|
1475
|
+
connect(fn, instance) {
|
|
1476
|
+
this.disconnect(fn, instance);
|
|
1477
|
+
const delegate = new Delegate(fn, instance);
|
|
1478
|
+
this.signal.calls.push(delegate);
|
|
1479
|
+
return new Connection(new Delegate(function(signal) {
|
|
1480
|
+
new Sink(signal).disconnect(fn, this);
|
|
1481
|
+
}, instance), this.signal);
|
|
1482
|
+
}
|
|
1483
|
+
};
|
|
1484
|
+
var Sigh = class extends Disposable {
|
|
1485
|
+
calls;
|
|
1486
|
+
static SinkType = Sink;
|
|
1487
|
+
constructor() {
|
|
1488
|
+
super();
|
|
1489
|
+
this.calls = [];
|
|
1490
|
+
}
|
|
1491
|
+
dispose() {
|
|
1492
|
+
this.calls.length = 0;
|
|
1493
|
+
}
|
|
1494
|
+
get size() {
|
|
1495
|
+
return this.calls.length;
|
|
1496
|
+
}
|
|
1497
|
+
empty() {
|
|
1498
|
+
return this.calls.length === 0;
|
|
1499
|
+
}
|
|
1500
|
+
publish(...args) {
|
|
1501
|
+
for (let i = this.calls.length - 1; i >= 0; --i) this.calls[i].invoke(...args);
|
|
1502
|
+
}
|
|
1503
|
+
collect(fn, ...args) {
|
|
1504
|
+
for (let i = this.calls.length - 1; i >= 0; --i) if (fn(this.calls[i].invoke(...args))) break;
|
|
1505
|
+
}
|
|
1506
|
+
};
|
|
1507
|
+
var Connection = class {
|
|
1508
|
+
signal;
|
|
1509
|
+
disconnect;
|
|
1510
|
+
constructor(fn, ref) {
|
|
1511
|
+
this.disconnect = fn;
|
|
1512
|
+
this.signal = ref;
|
|
1513
|
+
}
|
|
1514
|
+
empty() {
|
|
1515
|
+
return this.disconnect.empty();
|
|
1516
|
+
}
|
|
1517
|
+
release() {
|
|
1518
|
+
if (!this.disconnect.empty()) {
|
|
1519
|
+
this.disconnect.invoke(this.signal);
|
|
1520
|
+
this.disconnect.reset();
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
};
|
|
1524
|
+
var ScopedConnection = class extends Disposable {
|
|
1525
|
+
conn;
|
|
1526
|
+
constructor(conn) {
|
|
1527
|
+
super();
|
|
1528
|
+
this.conn = conn;
|
|
1529
|
+
}
|
|
1530
|
+
dispose() {
|
|
1531
|
+
this.conn.release();
|
|
1532
|
+
}
|
|
1533
|
+
empty() {
|
|
1534
|
+
return this.conn.empty();
|
|
1535
|
+
}
|
|
1536
|
+
release() {
|
|
1537
|
+
this.conn.release();
|
|
1538
|
+
}
|
|
1539
|
+
};
|
|
1540
|
+
var BasicDispatcherHandler = class extends Disposable {};
|
|
1541
|
+
const dispatcherHandlerTemplate = /* @__PURE__ */ defineTemplate(function(Type) {
|
|
1542
|
+
const newType = createSafeNew(Type);
|
|
1543
|
+
return class DispatcherHandler extends BasicDispatcherHandler {
|
|
1544
|
+
signal;
|
|
1545
|
+
events;
|
|
1546
|
+
constructor() {
|
|
1547
|
+
super();
|
|
1548
|
+
this.signal = new Sigh();
|
|
1549
|
+
this.events = [];
|
|
1550
|
+
}
|
|
1551
|
+
dispose() {
|
|
1552
|
+
this.signal.dispose();
|
|
1553
|
+
this.events.length = 0;
|
|
1554
|
+
}
|
|
1555
|
+
publish() {
|
|
1556
|
+
while (this.events.length > 0) {
|
|
1557
|
+
const event = this.events.shift();
|
|
1558
|
+
this.signal.publish(event);
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
disconnect(instance) {
|
|
1562
|
+
new Sigh.SinkType(this.signal).disconnect(void 0, instance);
|
|
1563
|
+
}
|
|
1564
|
+
clear() {
|
|
1565
|
+
this.events.length = 0;
|
|
1566
|
+
}
|
|
1567
|
+
bucket() {
|
|
1568
|
+
return new Sigh.SinkType(this.signal);
|
|
1569
|
+
}
|
|
1570
|
+
trigger(event) {
|
|
1571
|
+
this.signal.publish(event);
|
|
1572
|
+
}
|
|
1573
|
+
enqueue(...args) {
|
|
1574
|
+
this.events.push(newType(...args));
|
|
1575
|
+
}
|
|
1576
|
+
get size() {
|
|
1577
|
+
return this.events.length;
|
|
1578
|
+
}
|
|
1579
|
+
};
|
|
1580
|
+
});
|
|
1581
|
+
var BasicDispatcher = class extends Disposable {
|
|
1582
|
+
pools;
|
|
1583
|
+
constructor() {
|
|
1584
|
+
super();
|
|
1585
|
+
this.pools = /* @__PURE__ */ new Map();
|
|
1586
|
+
}
|
|
1587
|
+
dispose() {
|
|
1588
|
+
this.pools.forEach((pool) => {
|
|
1589
|
+
pool.dispose();
|
|
1590
|
+
});
|
|
1591
|
+
this.pools.clear();
|
|
1592
|
+
}
|
|
1593
|
+
assure(Type) {
|
|
1594
|
+
if (!this.pools.has(Type)) {
|
|
1595
|
+
const handler = new (dispatcherHandlerTemplate.instantiate(Type))();
|
|
1596
|
+
this.pools.set(Type, handler);
|
|
1597
|
+
return handler;
|
|
1598
|
+
}
|
|
1599
|
+
return this.pools.get(Type);
|
|
1600
|
+
}
|
|
1601
|
+
constAssure(Type) {
|
|
1602
|
+
return this.pools.get(Type);
|
|
1603
|
+
}
|
|
1604
|
+
size(Type) {
|
|
1605
|
+
if (Type != null) {
|
|
1606
|
+
const cpool = this.constAssure(Type);
|
|
1607
|
+
return cpool ? cpool.size : 0;
|
|
1608
|
+
}
|
|
1609
|
+
let size = 0;
|
|
1610
|
+
this.pools.forEach((cpool) => {
|
|
1611
|
+
size += cpool.size;
|
|
1612
|
+
});
|
|
1613
|
+
return size;
|
|
1614
|
+
}
|
|
1615
|
+
sink(Type) {
|
|
1616
|
+
return this.assure(Type).bucket();
|
|
1617
|
+
}
|
|
1618
|
+
trigger(Type, event) {
|
|
1619
|
+
this.assure(Type).trigger(event);
|
|
1620
|
+
}
|
|
1621
|
+
enqueue(Type, ...args) {
|
|
1622
|
+
this.assure(Type).enqueue(...args);
|
|
1623
|
+
}
|
|
1624
|
+
disconnect(instance) {
|
|
1625
|
+
this.pools.forEach((handler) => {
|
|
1626
|
+
handler.disconnect(instance);
|
|
1627
|
+
});
|
|
1628
|
+
}
|
|
1629
|
+
clear(Type) {
|
|
1630
|
+
if (Type != null) this.assure(Type).clear();
|
|
1631
|
+
else this.pools.forEach((handler) => {
|
|
1632
|
+
handler.clear();
|
|
1633
|
+
});
|
|
1634
|
+
}
|
|
1635
|
+
update(Type) {
|
|
1636
|
+
if (Type != null) this.assure(Type).publish();
|
|
1637
|
+
else this.pools.forEach((handler) => {
|
|
1638
|
+
handler.publish();
|
|
1639
|
+
});
|
|
1640
|
+
}
|
|
1641
|
+
};
|
|
1642
|
+
var Emitter = class extends Disposable {
|
|
1643
|
+
handlers;
|
|
1644
|
+
constructor() {
|
|
1645
|
+
super();
|
|
1646
|
+
this.handlers = /* @__PURE__ */ new Map();
|
|
1647
|
+
}
|
|
1648
|
+
dispose() {
|
|
1649
|
+
this.handlers.clear();
|
|
1650
|
+
}
|
|
1651
|
+
on(Type, fn) {
|
|
1652
|
+
this.handlers.set(Type, (value) => {
|
|
1653
|
+
fn(value, this);
|
|
1654
|
+
});
|
|
1655
|
+
}
|
|
1656
|
+
publish(value) {
|
|
1657
|
+
const Constructor = value.constructor;
|
|
1658
|
+
const handler = this.handlers.get(Constructor);
|
|
1659
|
+
if (handler) handler(value);
|
|
1660
|
+
}
|
|
1661
|
+
erase(Type) {
|
|
1662
|
+
this.handlers.delete(Type);
|
|
1663
|
+
}
|
|
1664
|
+
clear() {
|
|
1665
|
+
this.handlers.clear();
|
|
1666
|
+
}
|
|
1667
|
+
contains(Type) {
|
|
1668
|
+
return this.handlers.has(Type);
|
|
1669
|
+
}
|
|
1670
|
+
empty() {
|
|
1671
|
+
return this.handlers.size === 0;
|
|
1672
|
+
}
|
|
1673
|
+
};
|
|
1674
|
+
|
|
1675
|
+
//#endregion
|
|
1676
|
+
//#region src/mixin.ts
|
|
1677
|
+
const basicSighMixinTemplate = /* @__PURE__ */ defineTemplate(function(Type) {
|
|
1678
|
+
const UnderlyingType = Type;
|
|
1679
|
+
return class BasicSighMixin extends Type {
|
|
1680
|
+
static UnderlyingType = UnderlyingType;
|
|
1681
|
+
owner;
|
|
1682
|
+
construction;
|
|
1683
|
+
destruction;
|
|
1684
|
+
update;
|
|
1685
|
+
constructor(...args) {
|
|
1686
|
+
super(...args);
|
|
1687
|
+
this.owner = null;
|
|
1688
|
+
this.construction = new Sigh();
|
|
1689
|
+
this.destruction = new Sigh();
|
|
1690
|
+
this.update = new Sigh();
|
|
1691
|
+
}
|
|
1692
|
+
dispose() {
|
|
1693
|
+
this.construction.dispose();
|
|
1694
|
+
this.destruction.dispose();
|
|
1695
|
+
this.update.dispose();
|
|
1696
|
+
super.dispose();
|
|
1697
|
+
this.owner = null;
|
|
1698
|
+
}
|
|
1699
|
+
ownerOrAssert() {
|
|
1700
|
+
assert(this.owner != null, "Invalid reference to registry");
|
|
1701
|
+
return this.owner;
|
|
1702
|
+
}
|
|
1703
|
+
pop(first, last) {
|
|
1704
|
+
const reg = this.ownerOrAssert();
|
|
1705
|
+
if (this.destruction.empty()) super.pop(first, last);
|
|
1706
|
+
else {
|
|
1707
|
+
first = first.clone();
|
|
1708
|
+
last = last.clone();
|
|
1709
|
+
for (; !first.equals(last); first.selfPlus()) {
|
|
1710
|
+
const entt = first.deref();
|
|
1711
|
+
this.destruction.publish(reg, entt);
|
|
1712
|
+
const it = super.find(entt);
|
|
1713
|
+
super.pop(it, it.plus(1));
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1717
|
+
popAll() {
|
|
1718
|
+
const reg = this.ownerOrAssert();
|
|
1719
|
+
if (!this.destruction.empty()) if ("ElementType" in UnderlyingType && "EntityType" in UnderlyingType && UnderlyingType.ElementType === UnderlyingType.EntityType) for (let pos = 0, last = super.freeList(); pos < last; ++pos) this.destruction.publish(reg, super.access(pos));
|
|
1720
|
+
else for (const entt of UnderlyingType.BaseType.prototype[Symbol.iterator].call(this)) if (UnderlyingType.storagePolicy === DeletionPolicy.InPlace) {
|
|
1721
|
+
if (!this.isTombstone(entt)) this.destruction.publish(reg, entt);
|
|
1722
|
+
} else this.destruction.publish(reg, entt);
|
|
1723
|
+
super.popAll();
|
|
1724
|
+
}
|
|
1725
|
+
tryEmplace(entt, forceback, value) {
|
|
1726
|
+
const reg = this.ownerOrAssert();
|
|
1727
|
+
const it = super.tryEmplace(entt, forceback, value);
|
|
1728
|
+
if (!this.construction.empty()) this.construction.publish(reg, it.deref());
|
|
1729
|
+
}
|
|
1730
|
+
insert(first, last, ...args) {
|
|
1731
|
+
let from = super.size;
|
|
1732
|
+
super.insert(first, last, ...args);
|
|
1733
|
+
const reg = this.ownerOrAssert();
|
|
1734
|
+
if (!this.construction.empty()) {
|
|
1735
|
+
const to = super.size;
|
|
1736
|
+
for (; from !== to; ++from) this.construction.publish(reg, super.access(from));
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
bindAny(value) {
|
|
1740
|
+
this.owner = value;
|
|
1741
|
+
super.bindAny(value);
|
|
1742
|
+
}
|
|
1743
|
+
onConstruct() {
|
|
1744
|
+
return new Sink(this.construction);
|
|
1745
|
+
}
|
|
1746
|
+
onUpdate() {
|
|
1747
|
+
return new Sink(this.update);
|
|
1748
|
+
}
|
|
1749
|
+
onDestroy() {
|
|
1750
|
+
return new Sink(this.destruction);
|
|
1751
|
+
}
|
|
1752
|
+
registry() {
|
|
1753
|
+
return this.ownerOrAssert();
|
|
1754
|
+
}
|
|
1755
|
+
generate(hint) {
|
|
1756
|
+
const e = super.generate(hint);
|
|
1757
|
+
if (!this.construction.empty()) this.construction.publish(this.ownerOrAssert(), e);
|
|
1758
|
+
return e;
|
|
1759
|
+
}
|
|
1760
|
+
generateRange(first, last) {
|
|
1761
|
+
super.generateRange(first, last);
|
|
1762
|
+
const reg = this.ownerOrAssert();
|
|
1763
|
+
if (!this.construction.empty()) {
|
|
1764
|
+
const [f, l] = makeRangePointer(first, last);
|
|
1765
|
+
for (; !f.equals(l); f.selfPlus()) this.construction.publish(reg, f.deref());
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
emplace(entt, ...args) {
|
|
1769
|
+
super.emplace(entt, ...args);
|
|
1770
|
+
if (!this.construction.empty()) this.construction.publish(this.ownerOrAssert(), entt);
|
|
1771
|
+
return this.get(entt);
|
|
1772
|
+
}
|
|
1773
|
+
patch(entt, ...args) {
|
|
1774
|
+
super.patch(entt, ...args);
|
|
1775
|
+
if (!this.update.empty()) this.update.publish(this.ownerOrAssert(), entt);
|
|
1776
|
+
return this.get(entt);
|
|
1777
|
+
}
|
|
1778
|
+
};
|
|
1779
|
+
});
|
|
1780
|
+
|
|
1781
|
+
//#endregion
|
|
1782
|
+
//#region src/storage.ts
|
|
1783
|
+
var StoragePointer = class StoragePointer {
|
|
1784
|
+
payload;
|
|
1785
|
+
offset;
|
|
1786
|
+
pageSize;
|
|
1787
|
+
constructor(pageSize, payload, offset) {
|
|
1788
|
+
this.pageSize = pageSize ?? 0;
|
|
1789
|
+
this.payload = payload ?? null;
|
|
1790
|
+
this.offset = offset ?? 0;
|
|
1791
|
+
}
|
|
1792
|
+
dispose() {
|
|
1793
|
+
this.payload = null;
|
|
1794
|
+
this.offset = 0;
|
|
1795
|
+
this.pageSize = 0;
|
|
1796
|
+
}
|
|
1797
|
+
clone(target) {
|
|
1798
|
+
if (target) {
|
|
1799
|
+
if (target === this) return target;
|
|
1800
|
+
target.payload = this.payload;
|
|
1801
|
+
target.offset = this.offset;
|
|
1802
|
+
target.pageSize = this.pageSize;
|
|
1803
|
+
return target;
|
|
1804
|
+
}
|
|
1805
|
+
return new StoragePointer(this.pageSize, this.payload, this.offset);
|
|
1806
|
+
}
|
|
1807
|
+
swap(other) {
|
|
1808
|
+
if (this === other) return;
|
|
1809
|
+
const t = this.payload;
|
|
1810
|
+
this.payload = other.payload;
|
|
1811
|
+
other.payload = t;
|
|
1812
|
+
const o$1 = this.offset;
|
|
1813
|
+
this.offset = other.offset;
|
|
1814
|
+
other.offset = o$1;
|
|
1815
|
+
const p = this.pageSize;
|
|
1816
|
+
this.pageSize = other.pageSize;
|
|
1817
|
+
other.pageSize = p;
|
|
1818
|
+
}
|
|
1819
|
+
data() {
|
|
1820
|
+
return this.payload;
|
|
1821
|
+
}
|
|
1822
|
+
selfPlus(n = 1) {
|
|
1823
|
+
this.offset -= n;
|
|
1824
|
+
return this;
|
|
1825
|
+
}
|
|
1826
|
+
selfMinus(n = 1) {
|
|
1827
|
+
this.offset += n;
|
|
1828
|
+
return this;
|
|
1829
|
+
}
|
|
1830
|
+
plus(n) {
|
|
1831
|
+
return new StoragePointer(this.pageSize, this.payload, this.offset - n);
|
|
1832
|
+
}
|
|
1833
|
+
minus(n) {
|
|
1834
|
+
return new StoragePointer(this.pageSize, this.payload, this.offset + n);
|
|
1835
|
+
}
|
|
1836
|
+
diff(other) {
|
|
1837
|
+
return other.index() - this.index();
|
|
1838
|
+
}
|
|
1839
|
+
equals(other) {
|
|
1840
|
+
return this.index() === other.index();
|
|
1841
|
+
}
|
|
1842
|
+
lt(other) {
|
|
1843
|
+
return this.index() > other.index();
|
|
1844
|
+
}
|
|
1845
|
+
gt(other) {
|
|
1846
|
+
return this.index() < other.index();
|
|
1847
|
+
}
|
|
1848
|
+
le(other) {
|
|
1849
|
+
return !this.gt(other);
|
|
1850
|
+
}
|
|
1851
|
+
ge(other) {
|
|
1852
|
+
return !this.lt(other);
|
|
1853
|
+
}
|
|
1854
|
+
deref() {
|
|
1855
|
+
return this.access(0);
|
|
1856
|
+
}
|
|
1857
|
+
write(value) {
|
|
1858
|
+
this.set(0, value);
|
|
1859
|
+
return value;
|
|
1860
|
+
}
|
|
1861
|
+
access(value) {
|
|
1862
|
+
const idx = this.index() - value;
|
|
1863
|
+
if (this.pageSize === 0) return this.payload[0][idx];
|
|
1864
|
+
return this.payload[idx / this.pageSize >>> 0][(idx & this.pageSize - 1) >>> 0];
|
|
1865
|
+
}
|
|
1866
|
+
set(off, value) {
|
|
1867
|
+
const idx = this.index() - off;
|
|
1868
|
+
if (this.pageSize === 0) this.payload[0][idx] = value;
|
|
1869
|
+
else this.payload[idx / this.pageSize >>> 0][(idx & this.pageSize - 1) >>> 0] = value;
|
|
1870
|
+
}
|
|
1871
|
+
index() {
|
|
1872
|
+
return this.offset - 1;
|
|
1873
|
+
}
|
|
1874
|
+
};
|
|
1875
|
+
const basicStorageTemplate = /* @__PURE__ */ defineTemplate(function(Type, Entity$1) {
|
|
1876
|
+
const BaseType = basicSparseSetTemplate.instantiate(Entity$1);
|
|
1877
|
+
const TraitsType = componentTraitsTemplate.instantiate(Type, Entity$1);
|
|
1878
|
+
const _new = createSafeNew(TraitsType.ElementType);
|
|
1879
|
+
const storagePolicy = TraitsType.inPlaceDelete ? DeletionPolicy.InPlace : DeletionPolicy.SwapAndPop;
|
|
1880
|
+
if (TraitsType.pageSize === 0) return class BasicStorage$1 extends BaseType {
|
|
1881
|
+
static TraitsType = TraitsType;
|
|
1882
|
+
static storagePolicy = storagePolicy;
|
|
1883
|
+
static EntityType = Entity$1;
|
|
1884
|
+
static ElementType = Type;
|
|
1885
|
+
static BaseType = BaseType;
|
|
1886
|
+
static ValueType = void 0;
|
|
1887
|
+
constructor() {
|
|
1888
|
+
super(TraitsType.ElementType, storagePolicy);
|
|
1889
|
+
}
|
|
1890
|
+
get(entt) {
|
|
1891
|
+
assert(super.contains(entt), "Invalid entity");
|
|
1892
|
+
}
|
|
1893
|
+
getAsRef(entt) {
|
|
1894
|
+
assert(super.contains(entt), "Invalid entity");
|
|
1895
|
+
return {
|
|
1896
|
+
get: () => {},
|
|
1897
|
+
set: () => {}
|
|
1898
|
+
};
|
|
1899
|
+
}
|
|
1900
|
+
getAsTuple(entt) {
|
|
1901
|
+
assert(super.contains(entt), "Invalid entity");
|
|
1902
|
+
return [];
|
|
1903
|
+
}
|
|
1904
|
+
emplace(entt, ..._args) {
|
|
1905
|
+
super.tryEmplace(entt, false);
|
|
1906
|
+
}
|
|
1907
|
+
insert(first, last, _) {
|
|
1908
|
+
first = first.clone();
|
|
1909
|
+
last = last.clone();
|
|
1910
|
+
for (; !first.equals(last); first.selfPlus()) {
|
|
1911
|
+
const entt = first.deref();
|
|
1912
|
+
super.tryEmplace(entt, true);
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1915
|
+
patch(entt, ...func) {
|
|
1916
|
+
assert(super.contains(entt), "Invalid entity");
|
|
1917
|
+
for (const f of func) f();
|
|
1918
|
+
}
|
|
1919
|
+
[Symbol.iterator]() {
|
|
1920
|
+
return toIterator(this);
|
|
1921
|
+
}
|
|
1922
|
+
each() {
|
|
1923
|
+
const kBegin = super.begin();
|
|
1924
|
+
const kEnd = super.end();
|
|
1925
|
+
return toIterator(new AggregatePointer([kBegin]), new AggregatePointer([kEnd]));
|
|
1926
|
+
}
|
|
1927
|
+
reach() {
|
|
1928
|
+
const kBegin = super.rbegin();
|
|
1929
|
+
const kEnd = super.rend();
|
|
1930
|
+
return toIterator(new AggregatePointer([kBegin]), new AggregatePointer([kEnd]));
|
|
1931
|
+
}
|
|
1932
|
+
};
|
|
1933
|
+
const BasicStorage = class extends BaseType {
|
|
1934
|
+
payload;
|
|
1935
|
+
static TraitsType = TraitsType;
|
|
1936
|
+
static Iterator = StoragePointer;
|
|
1937
|
+
static ReverseIterator = ReversePointer;
|
|
1938
|
+
static storagePolicy = storagePolicy;
|
|
1939
|
+
static EntityType = Entity$1;
|
|
1940
|
+
static ElementType = Type;
|
|
1941
|
+
static BaseType = BaseType;
|
|
1942
|
+
static ValueType = Type;
|
|
1943
|
+
elementAt(pos) {
|
|
1944
|
+
return this.payload[pos / TraitsType.pageSize >>> 0]?.[(pos & TraitsType.pageSize - 1) >>> 0];
|
|
1945
|
+
}
|
|
1946
|
+
elementSet(pos, value) {
|
|
1947
|
+
const page = this.assureAtLeast(pos);
|
|
1948
|
+
this.payload[page][(pos & TraitsType.pageSize - 1) >>> 0] = value;
|
|
1949
|
+
}
|
|
1950
|
+
assureAtLeast(pos) {
|
|
1951
|
+
const page = pos / TraitsType.pageSize >>> 0;
|
|
1952
|
+
while (this.payload.length <= page) if (this.payload.length === page) this.payload.push(Array(((pos & TraitsType.pageSize - 1) >>> 0) + 1));
|
|
1953
|
+
else this.payload.push(Array(TraitsType.pageSize).fill(void 0));
|
|
1954
|
+
return page;
|
|
1955
|
+
}
|
|
1956
|
+
constructor() {
|
|
1957
|
+
super(TraitsType.ElementType, storagePolicy);
|
|
1958
|
+
this.payload = [];
|
|
1959
|
+
}
|
|
1960
|
+
dispose() {
|
|
1961
|
+
this.payload.length = 0;
|
|
1962
|
+
super.dispose();
|
|
1963
|
+
}
|
|
1964
|
+
reserve(cap) {
|
|
1965
|
+
if (cap !== 0) {
|
|
1966
|
+
super.reserve(cap);
|
|
1967
|
+
this.assureAtLeast(cap - 1);
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
get(entt) {
|
|
1971
|
+
return this.elementAt(super.index(entt));
|
|
1972
|
+
}
|
|
1973
|
+
getAsRef(entt) {
|
|
1974
|
+
return {
|
|
1975
|
+
get: () => this.elementAt(super.index(entt)),
|
|
1976
|
+
set: (value) => {
|
|
1977
|
+
this.elementSet(super.index(entt), value);
|
|
1978
|
+
}
|
|
1979
|
+
};
|
|
1980
|
+
}
|
|
1981
|
+
getAsTuple(entt) {
|
|
1982
|
+
return [this.get(entt)];
|
|
1983
|
+
}
|
|
1984
|
+
emplaceElement(entt, forceBack, ...args) {
|
|
1985
|
+
const it = super.tryEmplace(entt, forceBack);
|
|
1986
|
+
let elem = void 0;
|
|
1987
|
+
try {
|
|
1988
|
+
if (args.length === 1 && args[0] instanceof TraitsType.ElementType) elem = clone(args[0]);
|
|
1989
|
+
else elem = _new(...args);
|
|
1990
|
+
this.elementSet(it.index(), elem);
|
|
1991
|
+
} catch (e) {
|
|
1992
|
+
super.pop(it, it.plus(1));
|
|
1993
|
+
throw e;
|
|
1994
|
+
}
|
|
1995
|
+
return it;
|
|
1996
|
+
}
|
|
1997
|
+
tryEmplace(entt, forceBack, value) {
|
|
1998
|
+
if (value != null) return this.emplaceElement(entt, forceBack, value);
|
|
1999
|
+
return this.emplaceElement(entt, forceBack);
|
|
2000
|
+
}
|
|
2001
|
+
emplace(entt, ...args) {
|
|
2002
|
+
const it = this.emplaceElement(entt, false, ...args);
|
|
2003
|
+
return this.elementAt(it.index());
|
|
2004
|
+
}
|
|
2005
|
+
insert(first, last, value = _new()) {
|
|
2006
|
+
first = first.clone();
|
|
2007
|
+
last = last.clone();
|
|
2008
|
+
for (; !first.equals(last); first.selfPlus()) {
|
|
2009
|
+
const entt = first.deref();
|
|
2010
|
+
this.emplaceElement(entt, true, value);
|
|
2011
|
+
}
|
|
2012
|
+
return this.begin();
|
|
2013
|
+
}
|
|
2014
|
+
insertRange(first, last, from) {
|
|
2015
|
+
first = first.clone();
|
|
2016
|
+
last = last.clone();
|
|
2017
|
+
from = from.clone();
|
|
2018
|
+
for (; !first.equals(last); first.selfPlus(), from.selfPlus()) {
|
|
2019
|
+
const entt = first.deref();
|
|
2020
|
+
this.emplaceElement(entt, true, from.deref());
|
|
2021
|
+
}
|
|
2022
|
+
return this.begin();
|
|
2023
|
+
}
|
|
2024
|
+
patch(entt, ...func) {
|
|
2025
|
+
const idx = super.index(entt);
|
|
2026
|
+
let elem = void 0;
|
|
2027
|
+
for (const f of func) {
|
|
2028
|
+
elem = this.elementAt(idx);
|
|
2029
|
+
const update = f(elem);
|
|
2030
|
+
if (update != null) {
|
|
2031
|
+
this.elementSet(idx, update);
|
|
2032
|
+
elem = update;
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2035
|
+
return elem;
|
|
2036
|
+
}
|
|
2037
|
+
pop(first, last) {
|
|
2038
|
+
first = first.clone();
|
|
2039
|
+
last = last.clone();
|
|
2040
|
+
for (; !first.equals(last); first.selfPlus()) if (TraitsType.inPlaceDelete) {
|
|
2041
|
+
const entt = first.deref();
|
|
2042
|
+
const idx = super.index(entt);
|
|
2043
|
+
super.inPlacePop(entt);
|
|
2044
|
+
this.elementSet(idx, void 0);
|
|
2045
|
+
} else {
|
|
2046
|
+
const lastIndex = super.size - 1;
|
|
2047
|
+
const entt = first.deref();
|
|
2048
|
+
const idx = super.index(entt);
|
|
2049
|
+
if (idx !== lastIndex) {
|
|
2050
|
+
const tmp = this.elementAt(lastIndex);
|
|
2051
|
+
this.elementSet(idx, tmp);
|
|
2052
|
+
this.elementSet(lastIndex, void 0);
|
|
2053
|
+
} else this.elementSet(lastIndex, void 0);
|
|
2054
|
+
super.swapAndPop(entt);
|
|
2055
|
+
}
|
|
2056
|
+
}
|
|
2057
|
+
popAll() {
|
|
2058
|
+
for (const first = super.begin(); !(first.index() < 0); first.selfPlus()) if (TraitsType.inPlaceDelete) {
|
|
2059
|
+
if (!this.isTombstone(first.deref())) {
|
|
2060
|
+
super.inPlacePop(first.deref());
|
|
2061
|
+
this.elementSet(first.index(), void 0);
|
|
2062
|
+
}
|
|
2063
|
+
} else {
|
|
2064
|
+
super.swapAndPop(first.deref());
|
|
2065
|
+
this.elementSet(first.index(), void 0);
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
swapAt(from, to) {
|
|
2069
|
+
const tmp = this.elementAt(from);
|
|
2070
|
+
this.elementSet(from, this.elementAt(to));
|
|
2071
|
+
this.elementSet(to, tmp);
|
|
2072
|
+
}
|
|
2073
|
+
moveTo(from, to) {
|
|
2074
|
+
const tmp = this.elementAt(from);
|
|
2075
|
+
this.elementSet(from, void 0);
|
|
2076
|
+
this.elementSet(to, tmp);
|
|
2077
|
+
}
|
|
2078
|
+
swapOrMove(from, to) {
|
|
2079
|
+
if (this.mode === DeletionPolicy.InPlace) {
|
|
2080
|
+
const entity = super.access(to);
|
|
2081
|
+
if (entity != null && BaseType.TraitsType.isTombstone(entity)) this.moveTo(from, to);
|
|
2082
|
+
else BasicStorage.prototype.swapAt.call(this, from, to);
|
|
2083
|
+
} else BasicStorage.prototype.swapAt.call(this, from, to);
|
|
2084
|
+
}
|
|
2085
|
+
[Symbol.iterator]() {
|
|
2086
|
+
return toIterator(this);
|
|
2087
|
+
}
|
|
2088
|
+
entries() {
|
|
2089
|
+
const kBegin = super.begin();
|
|
2090
|
+
const vBegin = this.begin();
|
|
2091
|
+
const kEnd = super.end();
|
|
2092
|
+
const vEnd = this.end();
|
|
2093
|
+
return toIterator(new AggregatePointer([kBegin, vBegin]), new AggregatePointer([kEnd, vEnd]));
|
|
2094
|
+
}
|
|
2095
|
+
capacity() {
|
|
2096
|
+
return this.payload.length * TraitsType.pageSize;
|
|
2097
|
+
}
|
|
2098
|
+
begin() {
|
|
2099
|
+
return new StoragePointer(TraitsType.pageSize, this.payload, this.size);
|
|
2100
|
+
}
|
|
2101
|
+
end() {
|
|
2102
|
+
return new StoragePointer(TraitsType.pageSize, this.payload, 0);
|
|
2103
|
+
}
|
|
2104
|
+
rbegin() {
|
|
2105
|
+
return makeReversePointer(this.end());
|
|
2106
|
+
}
|
|
2107
|
+
rend() {
|
|
2108
|
+
return makeReversePointer(this.begin());
|
|
2109
|
+
}
|
|
2110
|
+
each() {
|
|
2111
|
+
return this.entries();
|
|
2112
|
+
}
|
|
2113
|
+
reach() {
|
|
2114
|
+
const kBegin = super.rbegin();
|
|
2115
|
+
const vBegin = this.rbegin();
|
|
2116
|
+
const kEnd = super.rend();
|
|
2117
|
+
const vEnd = this.rend();
|
|
2118
|
+
return toIterator(new AggregatePointer([kBegin, vBegin]), new AggregatePointer([kEnd, vEnd]));
|
|
2119
|
+
}
|
|
2120
|
+
forEach(callbackfn, thisArg) {
|
|
2121
|
+
const begin = this.begin();
|
|
2122
|
+
const end = this.end();
|
|
2123
|
+
for (; !begin.equals(end); begin.selfPlus()) {
|
|
2124
|
+
const value = begin.deref();
|
|
2125
|
+
const key = this.data()[begin.index()];
|
|
2126
|
+
callbackfn.call(thisArg, value, key, this);
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
};
|
|
2130
|
+
return BasicStorage;
|
|
2131
|
+
}, [{
|
|
2132
|
+
predicate: (Type, Entity$1) => Entity$1 === void 0 || Object.is(Entity$1, Type),
|
|
2133
|
+
render: ((Entity$1) => {
|
|
2134
|
+
const BaseType = basicSparseSetTemplate.instantiate(Entity$1);
|
|
2135
|
+
const TraitsType = enttTraitsTemplate.instantiate(Entity$1);
|
|
2136
|
+
const storagePolicy = DeletionPolicy.SwapOnly;
|
|
2137
|
+
return class BasicStorage extends BaseType {
|
|
2138
|
+
placeholder;
|
|
2139
|
+
static TraitsType = TraitsType;
|
|
2140
|
+
static storagePolicy = storagePolicy;
|
|
2141
|
+
static EntityType = Entity$1;
|
|
2142
|
+
static ElementType = Entity$1;
|
|
2143
|
+
static BaseType = BaseType;
|
|
2144
|
+
static ValueType = void 0;
|
|
2145
|
+
static Iterator = SparseSetPointer;
|
|
2146
|
+
static ReverseIterator = ReversePointer;
|
|
2147
|
+
constructor() {
|
|
2148
|
+
super(TraitsType.ValueType, storagePolicy);
|
|
2149
|
+
this.placeholder = 0n;
|
|
2150
|
+
}
|
|
2151
|
+
dispose() {
|
|
2152
|
+
this.placeholder = 0n;
|
|
2153
|
+
super.dispose();
|
|
2154
|
+
}
|
|
2155
|
+
fromPlaceholder() {
|
|
2156
|
+
const entt = TraitsType.combine(TraitsType.EntityType(this.placeholder), TraitsType.EntityType(0));
|
|
2157
|
+
const isNullEntity = TraitsType.isNull(entt);
|
|
2158
|
+
assert(!isNullEntity, "No more entities available");
|
|
2159
|
+
this.placeholder += !isNullEntity ? 1n : 0n;
|
|
2160
|
+
return entt;
|
|
2161
|
+
}
|
|
2162
|
+
next() {
|
|
2163
|
+
let entt = this.fromPlaceholder();
|
|
2164
|
+
while (super.current(entt) !== TraitsType.toVersion(TraitsType.tombstone) && !TraitsType.isNull(entt)) entt = this.fromPlaceholder();
|
|
2165
|
+
return entt;
|
|
2166
|
+
}
|
|
2167
|
+
popAll() {
|
|
2168
|
+
super.popAll();
|
|
2169
|
+
this.placeholder = 0n;
|
|
2170
|
+
}
|
|
2171
|
+
tryEmplace(hint) {
|
|
2172
|
+
return super.find(this.generate(hint));
|
|
2173
|
+
}
|
|
2174
|
+
get(entt) {
|
|
2175
|
+
assert(super.index(entt) < super.freeList(), "The requested entity is not a live one");
|
|
2176
|
+
}
|
|
2177
|
+
getAsRef(entt) {
|
|
2178
|
+
assert(super.index(entt) < super.freeList(), "The requested entity is not a live one");
|
|
2179
|
+
return {
|
|
2180
|
+
get: () => {},
|
|
2181
|
+
set: () => {}
|
|
2182
|
+
};
|
|
2183
|
+
}
|
|
2184
|
+
getAsTuple(entt) {
|
|
2185
|
+
assert(super.index(entt) < super.freeList(), "The requested entity is not a live one");
|
|
2186
|
+
return [];
|
|
2187
|
+
}
|
|
2188
|
+
startFrom(hint) {
|
|
2189
|
+
this.placeholder = BigInt(TraitsType.toEntity(hint));
|
|
2190
|
+
}
|
|
2191
|
+
generate(hint) {
|
|
2192
|
+
if (hint != null && !TraitsType.isNull(hint) && !TraitsType.isTombstone(hint)) {
|
|
2193
|
+
const curr = TraitsType.construct(TraitsType.toEntity(hint), super.current(hint));
|
|
2194
|
+
if (TraitsType.isTombstone(curr) || super.index(curr) >= super.freeList()) return super.tryEmplace(hint, true).deref();
|
|
2195
|
+
}
|
|
2196
|
+
const len = super.freeList();
|
|
2197
|
+
const entt = len === Uint64(super.size) ? this.next() : super.data()[len];
|
|
2198
|
+
return super.tryEmplace(entt, true).deref();
|
|
2199
|
+
}
|
|
2200
|
+
generateRange(first, last) {
|
|
2201
|
+
const [f, l] = makeRangePointer(first, last);
|
|
2202
|
+
const sz = Uint64(super.size);
|
|
2203
|
+
for (; !f.equals(l) && super.freeList() !== sz; f.selfPlus()) f.write(super.tryEmplace(super.data()[super.freeList()], true).deref());
|
|
2204
|
+
for (; !f.equals(l); f.selfPlus()) f.write(super.tryEmplace(this.next(), true).deref());
|
|
2205
|
+
}
|
|
2206
|
+
insert(first, last) {
|
|
2207
|
+
first = first.clone();
|
|
2208
|
+
last = last.clone();
|
|
2209
|
+
for (; !first.equals(last); first.selfPlus()) {
|
|
2210
|
+
const entt = first.deref();
|
|
2211
|
+
super.tryEmplace(entt, true);
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
patch(entt, ...func) {
|
|
2215
|
+
assert(super.index(entt) < super.freeList(), "The requested entity is not a live one");
|
|
2216
|
+
for (const f of func) f();
|
|
2217
|
+
}
|
|
2218
|
+
each() {
|
|
2219
|
+
const it = super.end();
|
|
2220
|
+
const offset = super.freeList();
|
|
2221
|
+
return toIterator(new AggregatePointer([it.minus(Number(offset))]), new AggregatePointer([it]));
|
|
2222
|
+
}
|
|
2223
|
+
reach() {
|
|
2224
|
+
const it = super.rbegin();
|
|
2225
|
+
const offset = super.freeList();
|
|
2226
|
+
return toIterator(new AggregatePointer([new ReversePointer(it)]), new AggregatePointer([new ReversePointer(it.plus(Number(offset)))]));
|
|
2227
|
+
}
|
|
2228
|
+
};
|
|
2229
|
+
})
|
|
2230
|
+
}]);
|
|
2231
|
+
const storageTemplate = /* @__PURE__ */ defineTemplate(function(Type) {
|
|
2232
|
+
return basicStorageTemplate.instantiate(Type, Entity);
|
|
2233
|
+
});
|
|
2234
|
+
const storageTypeTemplate = /* @__PURE__ */ defineTemplate(function(Type, EntityType) {
|
|
2235
|
+
return class StorageType {
|
|
2236
|
+
static Type = config.mixin ? basicSighMixinTemplate.instantiate(basicStorageTemplate.instantiate(Type, EntityType)) : basicStorageTemplate.instantiate(Type, EntityType);
|
|
2237
|
+
};
|
|
2238
|
+
});
|
|
2239
|
+
const storageTypeTTemplate = /* @__PURE__ */ defineTemplate(function(...args) {
|
|
2240
|
+
return storageTypeTemplate.instantiate(...args).Type;
|
|
2241
|
+
});
|
|
2242
|
+
|
|
2243
|
+
//#endregion
|
|
2244
|
+
//#region src/view.ts
|
|
2245
|
+
const tombstoneCheck = (...args) => args.length === 1 && args[0].storagePolicy === DeletionPolicy.InPlace;
|
|
2246
|
+
const placeholderMap = /* @__PURE__ */ new Map();
|
|
2247
|
+
const viewPlaceholder = (Type) => {
|
|
2248
|
+
if (!placeholderMap.has(Type)) {
|
|
2249
|
+
const instance = new Type();
|
|
2250
|
+
placeholderMap.set(Type, instance);
|
|
2251
|
+
return instance;
|
|
2252
|
+
}
|
|
2253
|
+
return placeholderMap.get(Type);
|
|
2254
|
+
};
|
|
2255
|
+
function allOf(first, last, entt) {
|
|
2256
|
+
first = first.clone();
|
|
2257
|
+
last = last.clone();
|
|
2258
|
+
for (; !first.equals(last) && first.deref().contains(entt); first.selfPlus());
|
|
2259
|
+
return first.equals(last);
|
|
2260
|
+
}
|
|
2261
|
+
function noneOf(first, last, entt) {
|
|
2262
|
+
first = first.clone();
|
|
2263
|
+
last = last.clone();
|
|
2264
|
+
for (; !first.equals(last) && !first.deref().contains(entt); first.selfPlus());
|
|
2265
|
+
return first.equals(last);
|
|
2266
|
+
}
|
|
2267
|
+
function fullyInitialized(first, last, placeholder) {
|
|
2268
|
+
first = first.clone();
|
|
2269
|
+
last = last.clone();
|
|
2270
|
+
for (; !first.equals(last) && first.deref() !== placeholder; first.selfPlus());
|
|
2271
|
+
return first.equals(last);
|
|
2272
|
+
}
|
|
2273
|
+
function findSameBase(A, B) {
|
|
2274
|
+
if (A === B) return A;
|
|
2275
|
+
let CurrentA = A;
|
|
2276
|
+
while (CurrentA != null) {
|
|
2277
|
+
let CurrentB = B;
|
|
2278
|
+
while (CurrentB != null) {
|
|
2279
|
+
if (CurrentA === CurrentB) return CurrentA;
|
|
2280
|
+
CurrentB = Object.getPrototypeOf(CurrentB);
|
|
2281
|
+
}
|
|
2282
|
+
CurrentA = Object.getPrototypeOf(CurrentA);
|
|
2283
|
+
}
|
|
2284
|
+
return null;
|
|
2285
|
+
}
|
|
2286
|
+
function commonType(...instances) {
|
|
2287
|
+
if (instances.length === 0) throw new Error("No storage type provided");
|
|
2288
|
+
let Target = instances[0];
|
|
2289
|
+
for (let pos = 1; pos < instances.length; ++pos) {
|
|
2290
|
+
const Current = instances[pos];
|
|
2291
|
+
Target = findSameBase(Target, Current);
|
|
2292
|
+
if (Target == null) throw new Error("No common storage type found");
|
|
2293
|
+
}
|
|
2294
|
+
return Target;
|
|
2295
|
+
}
|
|
2296
|
+
const viewPointerTemplate = /* @__PURE__ */ defineTemplate(function(Type, checked, get, exclude) {
|
|
2297
|
+
const PointerType = Type.Iterator;
|
|
2298
|
+
class ViewPointer {
|
|
2299
|
+
it;
|
|
2300
|
+
pools;
|
|
2301
|
+
filter;
|
|
2302
|
+
index;
|
|
2303
|
+
valid(entt) {
|
|
2304
|
+
const pools = toRange(this.pools);
|
|
2305
|
+
const filter = toRange(this.filter);
|
|
2306
|
+
return (!checked || !Type.isTombstone(entt)) && (get === 1 || allOf(pools.begin(), pools.begin().plus(this.index), entt) && allOf(pools.begin().plus(this.index + 1), pools.end(), entt)) && (exclude === 0 || noneOf(filter.begin(), filter.end(), entt));
|
|
2307
|
+
}
|
|
2308
|
+
seekNext() {
|
|
2309
|
+
for (const sentinel = new PointerType(); !this.it.equals(sentinel) && !this.valid(this.it.deref()); this.it.selfPlus());
|
|
2310
|
+
}
|
|
2311
|
+
constructor(first, values, excl, idx) {
|
|
2312
|
+
if (first != null && values != null && excl != null && idx != null) {
|
|
2313
|
+
this.it = first.clone();
|
|
2314
|
+
this.pools = values;
|
|
2315
|
+
this.filter = excl;
|
|
2316
|
+
this.index = idx;
|
|
2317
|
+
if (values.length !== get) throw new AssertionError("View iterator get count mismatch");
|
|
2318
|
+
if (excl.length !== exclude) throw new AssertionError("View iterator exclude count mismatch");
|
|
2319
|
+
assert(get !== 1 || exclude !== 0 || this.pools[0].policy() === DeletionPolicy.InPlace, "Non in-place storage view iterator");
|
|
2320
|
+
this.seekNext();
|
|
2321
|
+
} else {
|
|
2322
|
+
this.it = new PointerType();
|
|
2323
|
+
this.pools = Array(get);
|
|
2324
|
+
this.filter = Array(exclude);
|
|
2325
|
+
this.index = 0;
|
|
2326
|
+
}
|
|
2327
|
+
}
|
|
2328
|
+
selfPlus() {
|
|
2329
|
+
this.it.selfPlus();
|
|
2330
|
+
this.seekNext();
|
|
2331
|
+
return this;
|
|
2332
|
+
}
|
|
2333
|
+
write(_value) {
|
|
2334
|
+
throw new Error("Unsupported operation");
|
|
2335
|
+
}
|
|
2336
|
+
deref() {
|
|
2337
|
+
return this.it.deref();
|
|
2338
|
+
}
|
|
2339
|
+
equals(other) {
|
|
2340
|
+
return this.it.equals(other.it);
|
|
2341
|
+
}
|
|
2342
|
+
clone(target) {
|
|
2343
|
+
if (target) {
|
|
2344
|
+
if (this === target) return target;
|
|
2345
|
+
this.it.clone(target.it);
|
|
2346
|
+
target.pools = this.pools;
|
|
2347
|
+
target.filter = this.filter;
|
|
2348
|
+
target.index = this.index;
|
|
2349
|
+
return target;
|
|
2350
|
+
}
|
|
2351
|
+
return new ViewPointer(this.it, this.pools, this.filter, this.index);
|
|
2352
|
+
}
|
|
2353
|
+
swap(other) {
|
|
2354
|
+
if (this === other) return;
|
|
2355
|
+
const it = this.it;
|
|
2356
|
+
this.it = other.it;
|
|
2357
|
+
other.it = it;
|
|
2358
|
+
const pools = this.pools;
|
|
2359
|
+
this.pools = other.pools;
|
|
2360
|
+
other.pools = pools;
|
|
2361
|
+
const filter = this.filter;
|
|
2362
|
+
this.filter = other.filter;
|
|
2363
|
+
other.filter = filter;
|
|
2364
|
+
const index = this.index;
|
|
2365
|
+
this.index = other.index;
|
|
2366
|
+
other.index = index;
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
return ViewPointer;
|
|
2370
|
+
});
|
|
2371
|
+
var ExtendedViewPointer = class ExtendedViewPointer {
|
|
2372
|
+
it;
|
|
2373
|
+
constructor(it) {
|
|
2374
|
+
this.it = it.clone();
|
|
2375
|
+
}
|
|
2376
|
+
selfPlus() {
|
|
2377
|
+
this.it.selfPlus();
|
|
2378
|
+
return this;
|
|
2379
|
+
}
|
|
2380
|
+
write(_value) {
|
|
2381
|
+
throw new Error("Unsupported operation");
|
|
2382
|
+
}
|
|
2383
|
+
deref() {
|
|
2384
|
+
return [this.it.deref(), ...this.it.pools.flatMap((pool) => pool.getAsTuple(this.it.deref()))];
|
|
2385
|
+
}
|
|
2386
|
+
equals(other) {
|
|
2387
|
+
return this.it.equals(other.it);
|
|
2388
|
+
}
|
|
2389
|
+
clone(target) {
|
|
2390
|
+
if (target) {
|
|
2391
|
+
if (this === target) return target;
|
|
2392
|
+
this.it.clone(target.it);
|
|
2393
|
+
return target;
|
|
2394
|
+
}
|
|
2395
|
+
return new ExtendedViewPointer(this.it);
|
|
2396
|
+
}
|
|
2397
|
+
swap(other) {
|
|
2398
|
+
if (this === other) return;
|
|
2399
|
+
this.it.swap(other.it);
|
|
2400
|
+
}
|
|
2401
|
+
base() {
|
|
2402
|
+
return this.it.clone();
|
|
2403
|
+
}
|
|
2404
|
+
};
|
|
2405
|
+
const basicCommonViewTemplate = /* @__PURE__ */ defineTemplate(function(Type, checked, get, exclude) {
|
|
2406
|
+
const BasicCommonView = class {
|
|
2407
|
+
pools;
|
|
2408
|
+
filter;
|
|
2409
|
+
index;
|
|
2410
|
+
placeholder;
|
|
2411
|
+
static Iterator = viewPointerTemplate.instantiate(Type, checked, get, exclude);
|
|
2412
|
+
static CommonType = Type;
|
|
2413
|
+
static EntityType = Type.EntityType;
|
|
2414
|
+
offset() {
|
|
2415
|
+
assert(this.index !== get, "Invalid view");
|
|
2416
|
+
return this.pools[this.index].policy() === DeletionPolicy.SwapOnly ? Number(this.pools[this.index].freeList()) : this.pools[this.index].size;
|
|
2417
|
+
}
|
|
2418
|
+
uncheckedRefresh() {
|
|
2419
|
+
this.index = 0;
|
|
2420
|
+
if (get > 1) {
|
|
2421
|
+
for (let pos = 1; pos < get; ++pos) if (this.pools[pos].size < this.pools[this.index].size) this.index = pos;
|
|
2422
|
+
}
|
|
2423
|
+
}
|
|
2424
|
+
constructor(value, excl) {
|
|
2425
|
+
this.placeholder = viewPlaceholder(Type);
|
|
2426
|
+
if (Array.isArray(value) && Array.isArray(excl)) {
|
|
2427
|
+
if (value.length !== get) throw new Error("View pool count mismatch");
|
|
2428
|
+
if (excl.length !== exclude) throw new Error("View exclude count mismatch");
|
|
2429
|
+
this.pools = value;
|
|
2430
|
+
this.filter = excl;
|
|
2431
|
+
this.index = get;
|
|
2432
|
+
this.uncheckedRefresh();
|
|
2433
|
+
} else {
|
|
2434
|
+
this.pools = Array(get);
|
|
2435
|
+
this.filter = Array(exclude);
|
|
2436
|
+
this.index = get;
|
|
2437
|
+
for (let pos = 0, last = this.filter.length; pos < last; ++pos) this.filter[pos] = this.placeholder;
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2440
|
+
poolAt(index, elem) {
|
|
2441
|
+
if (index < 0 || index >= get) throw new Error("View pool index out of range");
|
|
2442
|
+
if (elem !== void 0) {
|
|
2443
|
+
assert(elem !== null, "Unexpected element");
|
|
2444
|
+
this.pools[index] = elem;
|
|
2445
|
+
this.refresh();
|
|
2446
|
+
} else return this.pools[index];
|
|
2447
|
+
}
|
|
2448
|
+
filterAt(index, elem) {
|
|
2449
|
+
if (index < 0 || index >= exclude) throw new Error("View filter index out of range");
|
|
2450
|
+
if (elem !== void 0) {
|
|
2451
|
+
assert(elem !== null, "Unexpected element");
|
|
2452
|
+
this.filter[index] = elem;
|
|
2453
|
+
} else return this.filter[index] === this.placeholder ? null : this.filter[index];
|
|
2454
|
+
}
|
|
2455
|
+
noneOf(entt) {
|
|
2456
|
+
const range = toRange(this.filter);
|
|
2457
|
+
return noneOf(range.begin(), range.end(), entt);
|
|
2458
|
+
}
|
|
2459
|
+
use(pos) {
|
|
2460
|
+
this.index = this.index !== get ? pos : get;
|
|
2461
|
+
}
|
|
2462
|
+
refresh() {
|
|
2463
|
+
let pos = Number(this.index !== get) * get;
|
|
2464
|
+
for (; pos < get && this.pools[pos] != null; ++pos);
|
|
2465
|
+
if (pos === get) this.uncheckedRefresh();
|
|
2466
|
+
}
|
|
2467
|
+
handle() {
|
|
2468
|
+
return this.index !== get ? this.pools[this.index] : null;
|
|
2469
|
+
}
|
|
2470
|
+
sizeHint() {
|
|
2471
|
+
return this.index !== get ? this.offset() : 0;
|
|
2472
|
+
}
|
|
2473
|
+
begin() {
|
|
2474
|
+
return this.index !== get ? new BasicCommonView.Iterator(Type.prototype.end.call(this.pools[this.index]).minus(this.offset()), this.pools, this.filter, this.index) : new BasicCommonView.Iterator();
|
|
2475
|
+
}
|
|
2476
|
+
end() {
|
|
2477
|
+
return this.index !== get ? new BasicCommonView.Iterator(Type.prototype.end.call(this.pools[this.index]), this.pools, this.filter, this.index) : new BasicCommonView.Iterator();
|
|
2478
|
+
}
|
|
2479
|
+
front() {
|
|
2480
|
+
const it = this.begin();
|
|
2481
|
+
return it.equals(this.end()) ? Type.TraitsType.null : it.deref();
|
|
2482
|
+
}
|
|
2483
|
+
back() {
|
|
2484
|
+
if (this.index !== get) {
|
|
2485
|
+
const it = this.pools[this.index].rbegin();
|
|
2486
|
+
const last = it.plus(this.offset());
|
|
2487
|
+
for (const idx = this.index; !it.equals(last) && !(allOf(toRange(this.pools).begin(), toRange(this.pools).begin().plus(idx), it.deref()) && allOf(toRange(this.pools).begin().plus(idx).plus(1), toRange(this.pools).end(), it.deref()) && noneOf(toRange(this.filter).begin(), toRange(this.filter).end(), it.deref())); it.selfPlus());
|
|
2488
|
+
return it.equals(last) ? Type.TraitsType.null : it.deref();
|
|
2489
|
+
}
|
|
2490
|
+
return Type.TraitsType.null;
|
|
2491
|
+
}
|
|
2492
|
+
find(entt) {
|
|
2493
|
+
return this.contains(entt) ? new BasicCommonView.Iterator(this.pools[this.index].find(entt), this.pools, this.filter, this.index) : this.end();
|
|
2494
|
+
}
|
|
2495
|
+
ok() {
|
|
2496
|
+
return this.index !== get && fullyInitialized(toRange(this.filter).begin(), toRange(this.filter).end(), this.placeholder);
|
|
2497
|
+
}
|
|
2498
|
+
[Symbol.toPrimitive]() {
|
|
2499
|
+
return this.ok();
|
|
2500
|
+
}
|
|
2501
|
+
contains(entt) {
|
|
2502
|
+
return this.index !== get && (checked ? !Type.isTombstone(entt) : true) && allOf(toRange(this.pools).begin(), toRange(this.pools).begin().plus(this.index), entt) && allOf(toRange(this.pools).begin().plus(this.index + 1), toRange(this.pools).end(), entt) && this.noneOf(entt);
|
|
2503
|
+
}
|
|
2504
|
+
[Symbol.iterator]() {
|
|
2505
|
+
return toIterator(this);
|
|
2506
|
+
}
|
|
2507
|
+
};
|
|
2508
|
+
return BasicCommonView;
|
|
2509
|
+
});
|
|
2510
|
+
const basicViewTemplate = /* @__PURE__ */ defineTemplate(function(_Gets, _Excludes) {
|
|
2511
|
+
throw new Error("Invalid BasicView instantiation");
|
|
2512
|
+
}, [{
|
|
2513
|
+
predicate: (Gets, Excludes) => Gets.length === 1 && (Excludes == null || Excludes.length === 0),
|
|
2514
|
+
render(Gets, _Excludes) {
|
|
2515
|
+
const Get = Gets[0].constructor;
|
|
2516
|
+
const BasicStorageView = basicStorageViewTemplate.instantiate(Get.BaseType, Get.storagePolicy);
|
|
2517
|
+
const BaseType = BasicStorageView;
|
|
2518
|
+
class BasicView extends BasicStorageView {
|
|
2519
|
+
static CommonType = BaseType.CommonType;
|
|
2520
|
+
static EntityType = BaseType.EntityType;
|
|
2521
|
+
static Iterator = BaseType.Iterator;
|
|
2522
|
+
static ReverseIterator = BaseType.ReverseIterator;
|
|
2523
|
+
constructor(value, _) {
|
|
2524
|
+
super(Array.isArray(value) ? value[0] : value);
|
|
2525
|
+
}
|
|
2526
|
+
getStorageByElementType(_ElementType) {
|
|
2527
|
+
return this.getStorageByIndex(0);
|
|
2528
|
+
}
|
|
2529
|
+
getStorageByIndex(index = 0) {
|
|
2530
|
+
if (index !== 0) throw new Error("Index out of bounds");
|
|
2531
|
+
return super.handle();
|
|
2532
|
+
}
|
|
2533
|
+
setStorageByType(elem) {
|
|
2534
|
+
this.setStorage(0, elem);
|
|
2535
|
+
}
|
|
2536
|
+
setStorage(index, elem) {
|
|
2537
|
+
if (index !== 0) throw new Error("Index out of bounds");
|
|
2538
|
+
this.leading = elem;
|
|
2539
|
+
}
|
|
2540
|
+
access(entt) {
|
|
2541
|
+
return this.getStorageByIndex()?.get(entt);
|
|
2542
|
+
}
|
|
2543
|
+
getByElementType(entt, ElementType) {
|
|
2544
|
+
if (ElementType !== Get.ElementType) throw new Error("Invalid element type");
|
|
2545
|
+
return this.get(entt, 0);
|
|
2546
|
+
}
|
|
2547
|
+
get(entt, index) {
|
|
2548
|
+
if (index == null) return this.getStorageByIndex()?.getAsTuple(entt) ?? [void 0];
|
|
2549
|
+
return this.getStorageByIndex(index)?.get(entt);
|
|
2550
|
+
}
|
|
2551
|
+
each(func, componentsOnly) {
|
|
2552
|
+
if (func != null && typeof func === "function") {
|
|
2553
|
+
if (!componentsOnly) for (const pack of this.each()) func.apply(this, pack);
|
|
2554
|
+
else if (Get.storagePolicy === DeletionPolicy.SwapAndPop || Get.storagePolicy === DeletionPolicy.SwapOnly) if (Get.ValueType === void 0) for (let pos = super.size; pos; --pos) func.call(this);
|
|
2555
|
+
else {
|
|
2556
|
+
const len = super.size;
|
|
2557
|
+
if (len !== 0) for (let last = this.getStorageByIndex().end(), first = last.minus(len); !first.equals(last); first.selfPlus()) func.call(this, first.deref());
|
|
2558
|
+
}
|
|
2559
|
+
else {
|
|
2560
|
+
if (Get.storagePolicy !== DeletionPolicy.InPlace) throw new AssertionError("Unexpected storage policy");
|
|
2561
|
+
for (const pack of this.each()) func.call(this, ...pack.slice(1));
|
|
2562
|
+
}
|
|
2563
|
+
return;
|
|
2564
|
+
}
|
|
2565
|
+
if (Get.storagePolicy === DeletionPolicy.SwapAndPop || Get.storagePolicy === DeletionPolicy.SwapOnly) return super.handle() ? this.getStorageByIndex().each() : toIterator(new AggregatePointer([new SparseSetPointer()]), new AggregatePointer([new SparseSetPointer()]));
|
|
2566
|
+
else {
|
|
2567
|
+
if (Get.storagePolicy !== DeletionPolicy.InPlace) throw new AssertionError("Unexpected storage policy");
|
|
2568
|
+
return toIterator(new ExtendedViewPointer(super.begin()), new ExtendedViewPointer(super.end()));
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2571
|
+
bitOr(other) {
|
|
2572
|
+
const pools = [this.leading, ...other.pools ?? [other.leading]];
|
|
2573
|
+
const placeholder = viewPlaceholder(commonType(...pools.map((storage) => storage.constructor.BaseType)));
|
|
2574
|
+
const filterOrPlaceholder = (value) => value ?? placeholder;
|
|
2575
|
+
const filter = other.filter ? [...other.filter.map((_, i) => filterOrPlaceholder(other.getStorageByIndex(other.pools.length + i)))] : [];
|
|
2576
|
+
const elem = new (basicViewTemplate.instantiate(pools, filter))();
|
|
2577
|
+
elem.pools = pools;
|
|
2578
|
+
elem.filter = filter;
|
|
2579
|
+
elem.refresh();
|
|
2580
|
+
return elem;
|
|
2581
|
+
}
|
|
2582
|
+
}
|
|
2583
|
+
return BasicView;
|
|
2584
|
+
}
|
|
2585
|
+
}, {
|
|
2586
|
+
predicate: (Gets, _Excludes) => Gets.length !== 0,
|
|
2587
|
+
render(Gets, Excludes) {
|
|
2588
|
+
const BasicCommonView = basicCommonViewTemplate.instantiate(commonType(...Gets.map((storage) => storage.constructor.BaseType)), tombstoneCheck(...Gets), Gets.length, Excludes.length);
|
|
2589
|
+
const BaseType = BasicCommonView;
|
|
2590
|
+
class BasicView extends BasicCommonView {
|
|
2591
|
+
static BaseType = BaseType;
|
|
2592
|
+
static indexOf = (Type) => {
|
|
2593
|
+
return [...Gets.map((t) => t.constructor.ElementType), ...Excludes.map((t) => t.constructor.ElementType)].indexOf(Type);
|
|
2594
|
+
};
|
|
2595
|
+
get(entt, ...indexes) {
|
|
2596
|
+
return indexes.map((index) => this.getStorageByIndex(index)?.getAsTuple(entt) ?? []).flat();
|
|
2597
|
+
}
|
|
2598
|
+
dispatchGet(Curr, Other, curr) {
|
|
2599
|
+
if (Curr === Other) return [curr[Curr + 1]];
|
|
2600
|
+
else return this.getStorageByIndex(Other)?.getAsTuple(curr[0]) ?? [];
|
|
2601
|
+
}
|
|
2602
|
+
_each(Curr, func, componentsOnly, ...indexes) {
|
|
2603
|
+
const storage = this.getStorageByIndex(Curr);
|
|
2604
|
+
for (const curr of storage.each()) {
|
|
2605
|
+
const entt = curr[0];
|
|
2606
|
+
if ((!tombstoneCheck(...Gets) || !storage.isTombstone(entt)) && indexes.every((index) => Curr === index || super.poolAt(index).contains(entt)) && super.noneOf(entt)) {
|
|
2607
|
+
const comps = indexes.flatMap((index) => this.dispatchGet(Curr, index, curr));
|
|
2608
|
+
if (componentsOnly) func.apply(this, comps);
|
|
2609
|
+
else func.call(this, entt, ...comps);
|
|
2610
|
+
}
|
|
2611
|
+
}
|
|
2612
|
+
}
|
|
2613
|
+
pickAndEach(func, componentsOnly, ...indexes) {
|
|
2614
|
+
const view = super.handle();
|
|
2615
|
+
if (view != null) indexes.forEach((index) => {
|
|
2616
|
+
if (view === super.poolAt(index)) this._each(index, func, componentsOnly, ...indexes);
|
|
2617
|
+
});
|
|
2618
|
+
}
|
|
2619
|
+
static CommonType = BaseType.CommonType;
|
|
2620
|
+
static EntityType = BaseType.EntityType;
|
|
2621
|
+
static Iterator = BaseType.Iterator;
|
|
2622
|
+
constructor(value, excl = []) {
|
|
2623
|
+
if (Array.isArray(value) && Array.isArray(excl)) super([...value], [...excl]);
|
|
2624
|
+
else super();
|
|
2625
|
+
}
|
|
2626
|
+
useByType(ElementType) {
|
|
2627
|
+
this.use(BasicView.indexOf(ElementType));
|
|
2628
|
+
}
|
|
2629
|
+
use(index) {
|
|
2630
|
+
this.use(index);
|
|
2631
|
+
}
|
|
2632
|
+
getStorageByElementType(ElementType) {
|
|
2633
|
+
return this.getStorageByIndex(BasicView.indexOf(ElementType));
|
|
2634
|
+
}
|
|
2635
|
+
getStorageByIndex(index) {
|
|
2636
|
+
if (index < Gets.length) return super.poolAt(index);
|
|
2637
|
+
else return super.filterAt(index - Gets.length);
|
|
2638
|
+
}
|
|
2639
|
+
setStorageByType(elem) {
|
|
2640
|
+
const index = BasicView.indexOf(elem.constructor.ElementType);
|
|
2641
|
+
this.setStorage(index, elem);
|
|
2642
|
+
}
|
|
2643
|
+
setStorage(index, elem) {
|
|
2644
|
+
if (index < 0 || index >= Gets.length + Excludes.length) throw new Error("View storage index out of range");
|
|
2645
|
+
if (index < Gets.length) super.poolAt(index, elem);
|
|
2646
|
+
else super.filterAt(index - Gets.length, elem);
|
|
2647
|
+
}
|
|
2648
|
+
access(entt) {
|
|
2649
|
+
return this.get(entt);
|
|
2650
|
+
}
|
|
2651
|
+
getByElementType(entt, ...ElementTypes) {
|
|
2652
|
+
const ret = this.get(entt, ...ElementTypes.map((t) => BasicView.indexOf(t)));
|
|
2653
|
+
return ret.length === 1 ? ret[0] : ret;
|
|
2654
|
+
}
|
|
2655
|
+
getByIndexes(entt, ...indexes) {
|
|
2656
|
+
if (indexes.length === 0) return this.get(entt);
|
|
2657
|
+
else if (indexes.length === 1) return this.getStorageByIndex(indexes[0])?.get(entt);
|
|
2658
|
+
else return indexes.map((index) => this.getStorageByIndex(index)?.getAsTuple(entt)).flat();
|
|
2659
|
+
}
|
|
2660
|
+
each(func, componentsOnly) {
|
|
2661
|
+
if (func != null && typeof func === "function") this.pickAndEach(func, componentsOnly, ...Array.from({ length: Gets.length }, (_, i) => i));
|
|
2662
|
+
else return toIterator(new ExtendedViewPointer(super.begin()), new ExtendedViewPointer(super.end()));
|
|
2663
|
+
}
|
|
2664
|
+
bitOr(other) {
|
|
2665
|
+
const pools = [...this.pools, ...other.pools ?? [other.leading]];
|
|
2666
|
+
const placeholder = viewPlaceholder(commonType(...pools.map((storage) => storage.constructor.BaseType)));
|
|
2667
|
+
const filterOrPlaceholder = (value) => value ?? placeholder;
|
|
2668
|
+
const filter = [...this.filter.map((_, i) => filterOrPlaceholder(this.getStorageByIndex(this.pools.length + i))), ...other.filter ? other.filter.map((_, i) => filterOrPlaceholder(other.getStorageByIndex(other.pools.length + i))) : []];
|
|
2669
|
+
const elem = new (basicViewTemplate.instantiate(pools, filter))();
|
|
2670
|
+
elem.pools = pools;
|
|
2671
|
+
elem.filter = filter;
|
|
2672
|
+
elem.refresh();
|
|
2673
|
+
return elem;
|
|
2674
|
+
}
|
|
2675
|
+
}
|
|
2676
|
+
return BasicView;
|
|
2677
|
+
}
|
|
2678
|
+
}]);
|
|
2679
|
+
function makeView(gets, excl = []) {
|
|
2680
|
+
return new (basicViewTemplate.instantiate(gets, excl))(gets, excl);
|
|
2681
|
+
}
|
|
2682
|
+
const basicStorageViewTemplate = /* @__PURE__ */ defineTemplate(function(Type, policy) {
|
|
2683
|
+
class BasicStorageView {
|
|
2684
|
+
leading;
|
|
2685
|
+
static CommonType = Type;
|
|
2686
|
+
static EntityType = Type.EntityType;
|
|
2687
|
+
static Iterator = policy === DeletionPolicy.InPlace ? viewPointerTemplate.instantiate(Type, true, 1, 0) : Type.Iterator;
|
|
2688
|
+
static ReverseIterator = policy === DeletionPolicy.InPlace ? void 0 : Type.ReverseIterator;
|
|
2689
|
+
constructor(value) {
|
|
2690
|
+
this.leading = value ?? null;
|
|
2691
|
+
assert(this.leading?.policy() === policy, "Unexpected storage policy");
|
|
2692
|
+
}
|
|
2693
|
+
handle() {
|
|
2694
|
+
return this.leading;
|
|
2695
|
+
}
|
|
2696
|
+
get size() {
|
|
2697
|
+
if (policy === DeletionPolicy.InPlace) throw new Error("Size not available for in-place storage views");
|
|
2698
|
+
if (policy === DeletionPolicy.SwapAndPop) return this.leading != null ? Number(this.leading.size) : 0;
|
|
2699
|
+
if (policy !== DeletionPolicy.SwapOnly) throw new AssertionError("Unexpected storage policy");
|
|
2700
|
+
return this.leading != null ? Number(this.leading.freeList()) : 0;
|
|
2701
|
+
}
|
|
2702
|
+
sizeHint() {
|
|
2703
|
+
if (policy !== DeletionPolicy.InPlace) throw new Error("Size hint not available for non in-place storage views");
|
|
2704
|
+
return this.leading != null ? Number(this.leading.size) : 0;
|
|
2705
|
+
}
|
|
2706
|
+
empty() {
|
|
2707
|
+
if (policy === DeletionPolicy.InPlace) throw new Error("Empty not available for in-place storage views");
|
|
2708
|
+
if (policy === DeletionPolicy.SwapAndPop) return !this.leading || this.leading.empty();
|
|
2709
|
+
if (policy !== DeletionPolicy.SwapOnly) throw new AssertionError("Unexpected storage policy");
|
|
2710
|
+
return !this.leading || Number(this.leading.freeList()) === 0;
|
|
2711
|
+
}
|
|
2712
|
+
begin() {
|
|
2713
|
+
if (policy === DeletionPolicy.SwapAndPop) return this.leading ? Type.prototype.begin.call(this.leading) : new BasicStorageView.Iterator();
|
|
2714
|
+
else if (policy === DeletionPolicy.SwapOnly) return this.leading ? Type.prototype.end.call(this.leading).minus(Number(this.leading.freeList())) : new BasicStorageView.Iterator();
|
|
2715
|
+
else {
|
|
2716
|
+
if (policy !== DeletionPolicy.InPlace) throw new AssertionError("Unexpected storage policy");
|
|
2717
|
+
return this.leading ? new BasicStorageView.Iterator(Type.prototype.begin.call(this.leading), [this.leading], [], 0) : new BasicStorageView.Iterator();
|
|
2718
|
+
}
|
|
2719
|
+
}
|
|
2720
|
+
end() {
|
|
2721
|
+
if (policy === DeletionPolicy.SwapAndPop || policy === DeletionPolicy.SwapOnly) return this.leading ? Type.prototype.end.call(this.leading) : new BasicStorageView.Iterator();
|
|
2722
|
+
else {
|
|
2723
|
+
if (policy !== DeletionPolicy.InPlace) throw new AssertionError("Unexpected storage policy");
|
|
2724
|
+
return this.leading ? new BasicStorageView.Iterator(Type.prototype.end.call(this.leading), [this.leading], [], 0) : new BasicStorageView.Iterator();
|
|
2725
|
+
}
|
|
2726
|
+
}
|
|
2727
|
+
rbegin() {
|
|
2728
|
+
if (policy === DeletionPolicy.InPlace) throw new Error("Reverse begin not available for in-place storage views");
|
|
2729
|
+
return this.leading ? Type.prototype.rbegin.call(this.leading) : new BasicStorageView.ReverseIterator(new Type.BasicIterator());
|
|
2730
|
+
}
|
|
2731
|
+
rend() {
|
|
2732
|
+
if (policy === DeletionPolicy.InPlace) throw new Error("Reverse end not available for in-place storage views");
|
|
2733
|
+
if (policy === DeletionPolicy.SwapAndPop) return this.leading ? Type.prototype.rend.call(this.leading) : new BasicStorageView.ReverseIterator(new Type.BasicIterator());
|
|
2734
|
+
else {
|
|
2735
|
+
if (policy !== DeletionPolicy.SwapOnly) throw new AssertionError("Unexpected storage policy");
|
|
2736
|
+
return this.leading ? Type.prototype.rend.call(this.leading).plus(Number(this.leading.freeList())) : new BasicStorageView.ReverseIterator(new Type.BasicIterator());
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
front() {
|
|
2740
|
+
if (policy === DeletionPolicy.SwapAndPop) return this.empty() ? Type.TraitsType.null : Type.prototype.begin.call(this.leading).deref();
|
|
2741
|
+
else if (policy === DeletionPolicy.SwapOnly) return this.empty() ? Type.TraitsType.null : Type.prototype.end.call(this.leading).minus(Number(this.leading.freeList())).deref();
|
|
2742
|
+
else {
|
|
2743
|
+
if (policy !== DeletionPolicy.InPlace) throw new AssertionError("Unexpected storage policy");
|
|
2744
|
+
const it = this.begin();
|
|
2745
|
+
return it.equals(this.end()) ? Type.TraitsType.null : it.deref();
|
|
2746
|
+
}
|
|
2747
|
+
}
|
|
2748
|
+
back() {
|
|
2749
|
+
if (policy === DeletionPolicy.SwapAndPop || policy === DeletionPolicy.SwapOnly) return this.empty() ? Type.TraitsType.null : Type.prototype.rbegin.call(this.leading).deref();
|
|
2750
|
+
else {
|
|
2751
|
+
if (policy !== DeletionPolicy.InPlace) throw new AssertionError("Unexpected storage policy");
|
|
2752
|
+
if (this.leading != null) {
|
|
2753
|
+
const it = Type.prototype.rbegin.call(this.leading);
|
|
2754
|
+
const last = Type.prototype.rend.call(this.leading);
|
|
2755
|
+
for (; !it.equals(last) && Type.isTombstone(it.deref()); it.selfPlus());
|
|
2756
|
+
return it.equals(last) ? Type.TraitsType.null : it.deref();
|
|
2757
|
+
}
|
|
2758
|
+
return Type.TraitsType.null;
|
|
2759
|
+
}
|
|
2760
|
+
}
|
|
2761
|
+
find(entt) {
|
|
2762
|
+
if (policy === DeletionPolicy.SwapAndPop) return this.leading != null ? this.leading.find(entt) : new BasicStorageView.Iterator();
|
|
2763
|
+
else if (policy === DeletionPolicy.SwapOnly) {
|
|
2764
|
+
const it = this.leading != null ? this.leading.find(entt) : new BasicStorageView.Iterator();
|
|
2765
|
+
return this.leading != null && it.index() < Number(this.leading.freeList()) ? it : new BasicStorageView.Iterator();
|
|
2766
|
+
} else return this.leading != null ? new BasicStorageView.Iterator(this.leading.find(entt), [this.leading], [], 0) : new BasicStorageView.Iterator();
|
|
2767
|
+
}
|
|
2768
|
+
ok() {
|
|
2769
|
+
return this.leading != null;
|
|
2770
|
+
}
|
|
2771
|
+
contains(entt) {
|
|
2772
|
+
if (policy === DeletionPolicy.SwapAndPop || policy === DeletionPolicy.InPlace) return this.leading?.contains(entt);
|
|
2773
|
+
else {
|
|
2774
|
+
if (policy !== DeletionPolicy.SwapOnly) throw new AssertionError("Unexpected storage policy");
|
|
2775
|
+
return this.leading != null && this.leading.contains(entt) && this.leading.index(entt) < Number(this.leading.freeList());
|
|
2776
|
+
}
|
|
2777
|
+
}
|
|
2778
|
+
[Symbol.iterator]() {
|
|
2779
|
+
return toIterator(this);
|
|
2780
|
+
}
|
|
2781
|
+
}
|
|
2782
|
+
return BasicStorageView;
|
|
2783
|
+
});
|
|
2784
|
+
|
|
2785
|
+
//#endregion
|
|
2786
|
+
//#region src/group.ts
|
|
2787
|
+
var ExtendedGroupPointer = class ExtendedGroupPointer {
|
|
2788
|
+
it;
|
|
2789
|
+
owned;
|
|
2790
|
+
get;
|
|
2791
|
+
get pools() {
|
|
2792
|
+
return [...this.owned, ...this.get];
|
|
2793
|
+
}
|
|
2794
|
+
indexToElement(cpool) {
|
|
2795
|
+
if (cpool.constructor.ValueType == null) return [];
|
|
2796
|
+
return [cpool.rbegin().access(this.it.index())];
|
|
2797
|
+
}
|
|
2798
|
+
constructor(it, owned, get) {
|
|
2799
|
+
if (it && owned && get) {
|
|
2800
|
+
this.it = it.clone();
|
|
2801
|
+
this.owned = owned;
|
|
2802
|
+
this.get = get;
|
|
2803
|
+
} else {
|
|
2804
|
+
this.it = new it();
|
|
2805
|
+
this.owned = [];
|
|
2806
|
+
this.get = [];
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
selfPlus() {
|
|
2810
|
+
this.it.selfPlus();
|
|
2811
|
+
return this;
|
|
2812
|
+
}
|
|
2813
|
+
write(value) {
|
|
2814
|
+
this.it.write(value);
|
|
2815
|
+
return value;
|
|
2816
|
+
}
|
|
2817
|
+
deref() {
|
|
2818
|
+
return [
|
|
2819
|
+
this.it.deref(),
|
|
2820
|
+
...this.owned.flatMap((o$1) => this.indexToElement(o$1)),
|
|
2821
|
+
...this.get.flatMap((g) => g.getAsTuple(this.it.deref()))
|
|
2822
|
+
];
|
|
2823
|
+
}
|
|
2824
|
+
equals(other) {
|
|
2825
|
+
return this.it.equals(other.it);
|
|
2826
|
+
}
|
|
2827
|
+
clone(target) {
|
|
2828
|
+
if (target) {
|
|
2829
|
+
if (this === target) return target;
|
|
2830
|
+
this.it.clone(target.it);
|
|
2831
|
+
this.owned = target.owned.slice();
|
|
2832
|
+
this.get = target.get.slice();
|
|
2833
|
+
return target;
|
|
2834
|
+
}
|
|
2835
|
+
return new ExtendedGroupPointer(this.it, this.owned, this.get);
|
|
2836
|
+
}
|
|
2837
|
+
swap(other) {
|
|
2838
|
+
if (this === other) return;
|
|
2839
|
+
this.it.swap(other.it);
|
|
2840
|
+
const tmpOwned = this.owned;
|
|
2841
|
+
this.owned = other.owned;
|
|
2842
|
+
other.owned = tmpOwned;
|
|
2843
|
+
const tmpGet = this.get;
|
|
2844
|
+
this.get = other.get;
|
|
2845
|
+
other.get = tmpGet;
|
|
2846
|
+
}
|
|
2847
|
+
base() {
|
|
2848
|
+
return this.it.clone();
|
|
2849
|
+
}
|
|
2850
|
+
};
|
|
2851
|
+
var GroupDescriptor = class extends Disposable {
|
|
2852
|
+
/** @virtual */
|
|
2853
|
+
owned(_id) {
|
|
2854
|
+
return false;
|
|
2855
|
+
}
|
|
2856
|
+
};
|
|
2857
|
+
const groupHandlerTemplate = /* @__PURE__ */ defineTemplate(function(Type, Owned, Get, Exclude) {
|
|
2858
|
+
class GroupHandler extends GroupDescriptor {
|
|
2859
|
+
static EntityType = Type.EntityType;
|
|
2860
|
+
pools;
|
|
2861
|
+
filter;
|
|
2862
|
+
len;
|
|
2863
|
+
swapElements(pos, entt) {
|
|
2864
|
+
for (let next = 0; next < Owned; ++next) this.pools[next].swapElements(this.pools[next].access(pos), entt);
|
|
2865
|
+
}
|
|
2866
|
+
pushOnConstruct(entt) {
|
|
2867
|
+
const pos = this.len;
|
|
2868
|
+
if (((...args) => {
|
|
2869
|
+
const [cpool, ...other] = args;
|
|
2870
|
+
return cpool.contains(entt) && !(cpool.index(entt) < pos) && other.every((o$1) => o$1.contains(entt));
|
|
2871
|
+
})(...this.pools) && ((...cpool) => cpool.every((c) => !c.contains(entt)))(...this.filter)) this.swapElements(this.len++, entt);
|
|
2872
|
+
}
|
|
2873
|
+
pushOnDestroy(entt) {
|
|
2874
|
+
const pos = this.len;
|
|
2875
|
+
if (((...args) => {
|
|
2876
|
+
const [cpool, ...other] = args;
|
|
2877
|
+
return cpool.contains(entt) && !(cpool.index(entt) < pos) && other.every((o$1) => o$1.contains(entt));
|
|
2878
|
+
})(...this.pools) && ((...cpool) => cpool.reduce((p, c) => p + Number(c.contains(entt)), 0) === 1)(...this.filter)) this.swapElements(this.len++, entt);
|
|
2879
|
+
}
|
|
2880
|
+
removeIf(entt) {
|
|
2881
|
+
const pools = this.pools;
|
|
2882
|
+
if (pools[0].contains(entt) && pools[0].index(entt) < this.len) this.swapElements(--this.len, entt);
|
|
2883
|
+
}
|
|
2884
|
+
commonSetup() {
|
|
2885
|
+
const pools = this.pools;
|
|
2886
|
+
for (const first = Type.prototype.rbegin.call(pools[0]), last = first.plus(pools[0].size); !first.equals(last); first.selfPlus()) this.pushOnConstruct(first.deref());
|
|
2887
|
+
}
|
|
2888
|
+
CommonType = Type;
|
|
2889
|
+
constructor(ogpool, epool) {
|
|
2890
|
+
super();
|
|
2891
|
+
this.pools = Array(Owned + Get);
|
|
2892
|
+
this.filter = Array(Exclude);
|
|
2893
|
+
for (let i = 0; i < Owned + Get; ++i) this.pools[i] = ogpool[i];
|
|
2894
|
+
for (let i = 0; i < Exclude; ++i) this.filter[i] = epool[i];
|
|
2895
|
+
this.len = 0;
|
|
2896
|
+
ogpool.forEach((cpool) => {
|
|
2897
|
+
cpool.onConstruct().connect(function(_, entt) {
|
|
2898
|
+
GroupHandler.prototype.pushOnConstruct.call(this, entt);
|
|
2899
|
+
}, this);
|
|
2900
|
+
cpool.onDestroy().connect(function(_, entt) {
|
|
2901
|
+
GroupHandler.prototype.removeIf.call(this, entt);
|
|
2902
|
+
}, this);
|
|
2903
|
+
});
|
|
2904
|
+
epool.forEach((cpool) => {
|
|
2905
|
+
cpool.onConstruct().connect(function(_, entt) {
|
|
2906
|
+
GroupHandler.prototype.removeIf.call(this, entt);
|
|
2907
|
+
}, this);
|
|
2908
|
+
cpool.onDestroy().connect(function(_, entt) {
|
|
2909
|
+
GroupHandler.prototype.pushOnDestroy.call(this, entt);
|
|
2910
|
+
}, this);
|
|
2911
|
+
});
|
|
2912
|
+
this.commonSetup();
|
|
2913
|
+
}
|
|
2914
|
+
owned(t) {
|
|
2915
|
+
for (let pos = 0; pos < Owned; ++pos) if (Object.is(this.pools[pos].type(), t) || dist_default(this.pools[pos].type()) === t) return true;
|
|
2916
|
+
return false;
|
|
2917
|
+
}
|
|
2918
|
+
length() {
|
|
2919
|
+
return this.len;
|
|
2920
|
+
}
|
|
2921
|
+
storage(index) {
|
|
2922
|
+
if (index < Owned + Get) return this.pools[index];
|
|
2923
|
+
else return this.filter[index - (Owned + Get)];
|
|
2924
|
+
}
|
|
2925
|
+
}
|
|
2926
|
+
return GroupHandler;
|
|
2927
|
+
}, [{
|
|
2928
|
+
predicate: (_0, Owned, _2, Exclude) => Owned === 0 || Exclude === void 0,
|
|
2929
|
+
render: (Type, Owned, Get, Exclude) => {
|
|
2930
|
+
if (Exclude === void 0) {
|
|
2931
|
+
Exclude = Get;
|
|
2932
|
+
Get = Owned;
|
|
2933
|
+
Owned = 0;
|
|
2934
|
+
}
|
|
2935
|
+
const newType = createSafeNew(Type);
|
|
2936
|
+
class GroupHandler extends GroupDescriptor {
|
|
2937
|
+
static EntityType = Type.EntityType;
|
|
2938
|
+
pools;
|
|
2939
|
+
filter;
|
|
2940
|
+
elem;
|
|
2941
|
+
pushOnConstruct(entt) {
|
|
2942
|
+
if (!this.elem.contains(entt) && this.pools.every((c) => c.contains(entt)) && this.filter.every((f) => !f.contains(entt))) this.elem.push(entt);
|
|
2943
|
+
}
|
|
2944
|
+
pushOnDestroy(entt) {
|
|
2945
|
+
if (this.elem.contains(entt) && this.pools.every((c) => c.contains(entt)) && this.filter.reduce((c, f) => c + Number(f.contains(entt)), 0) === 1) this.elem.remove(entt);
|
|
2946
|
+
}
|
|
2947
|
+
removeIf(entt) {
|
|
2948
|
+
this.elem.remove(entt);
|
|
2949
|
+
}
|
|
2950
|
+
commonSetup() {
|
|
2951
|
+
const jsIt = toIterator(Type.prototype.begin.call(this.pools[0]), Type.prototype.end.call(this.pools[0]));
|
|
2952
|
+
for (const entity of jsIt) this.pushOnConstruct(entity);
|
|
2953
|
+
}
|
|
2954
|
+
static CommonType = Type;
|
|
2955
|
+
constructor(gpool, epool) {
|
|
2956
|
+
super();
|
|
2957
|
+
this.pools = Array(Get);
|
|
2958
|
+
this.filter = Array(Exclude);
|
|
2959
|
+
for (let i = 0; i < Get; ++i) this.pools[i] = gpool[i];
|
|
2960
|
+
for (let i = 0; i < Exclude; ++i) this.filter[i] = epool[i];
|
|
2961
|
+
this.elem = newType();
|
|
2962
|
+
gpool.forEach((cpool) => {
|
|
2963
|
+
cpool.onConstruct().connect(function(_, entt) {
|
|
2964
|
+
GroupHandler.prototype.pushOnConstruct.call(this, entt);
|
|
2965
|
+
}, this);
|
|
2966
|
+
cpool.onDestroy().connect(function(_, entt) {
|
|
2967
|
+
GroupHandler.prototype.removeIf.call(this, entt);
|
|
2968
|
+
}, this);
|
|
2969
|
+
});
|
|
2970
|
+
epool.forEach((cpool) => {
|
|
2971
|
+
cpool.onConstruct().connect(function(_, entt) {
|
|
2972
|
+
GroupHandler.prototype.removeIf.call(this, entt);
|
|
2973
|
+
}, this);
|
|
2974
|
+
cpool.onDestroy().connect(function(_, entt) {
|
|
2975
|
+
GroupHandler.prototype.pushOnDestroy.call(this, entt);
|
|
2976
|
+
}, this);
|
|
2977
|
+
});
|
|
2978
|
+
this.commonSetup();
|
|
2979
|
+
}
|
|
2980
|
+
handle() {
|
|
2981
|
+
return this.elem;
|
|
2982
|
+
}
|
|
2983
|
+
storage(index) {
|
|
2984
|
+
if (index < Get) return this.pools[index];
|
|
2985
|
+
else return this.filter[index - Get];
|
|
2986
|
+
}
|
|
2987
|
+
}
|
|
2988
|
+
return GroupHandler;
|
|
2989
|
+
}
|
|
2990
|
+
}]);
|
|
2991
|
+
const basicGroupTemplate = /* @__PURE__ */ defineTemplate(function(_owned, _get, _exclude) {
|
|
2992
|
+
throw new Error("Invalid BasicGroup instantiation");
|
|
2993
|
+
}, [{
|
|
2994
|
+
predicate: (owned, get, exclude) => owned.length === 0 || owned == null || Array.isArray(owned) && Array.isArray(get) && exclude === void 0,
|
|
2995
|
+
render(owned, get, exclude) {
|
|
2996
|
+
if (Array.isArray(owned) && Array.isArray(get) && exclude === void 0) {
|
|
2997
|
+
exclude = get;
|
|
2998
|
+
get = owned;
|
|
2999
|
+
}
|
|
3000
|
+
const BaseType = commonType(...get.map((g) => g.constructor.BaseType), ...exclude.map((e) => e.constructor.BaseType));
|
|
3001
|
+
const UnderlyingType = BaseType.EntityType;
|
|
3002
|
+
const Handler = groupHandlerTemplate.instantiate(BaseType, 0, get.length, exclude.length);
|
|
3003
|
+
if (get.length === 0) throw new Error("Non-owning group must have at least one get type");
|
|
3004
|
+
class BasicGroup {
|
|
3005
|
+
static BaseType = BaseType;
|
|
3006
|
+
static UnderlyingType = UnderlyingType;
|
|
3007
|
+
static indexOf(T) {
|
|
3008
|
+
return [...get.map((g) => g.constructor.ElementType), ...exclude.map((e) => e.constructor.ElementType)].indexOf(T);
|
|
3009
|
+
}
|
|
3010
|
+
poolsFor(...indexes) {
|
|
3011
|
+
return this.descriptor ? indexes.map((i) => this.descriptor.storage(i)) : [];
|
|
3012
|
+
}
|
|
3013
|
+
static EntityType = UnderlyingType;
|
|
3014
|
+
static CommonType = BaseType;
|
|
3015
|
+
static Iterator = BaseType.Iterator;
|
|
3016
|
+
static ReverseIterator = BaseType.ReverseIterator;
|
|
3017
|
+
static Handler = Handler;
|
|
3018
|
+
descriptor;
|
|
3019
|
+
static groupId() {
|
|
3020
|
+
return dist_default([
|
|
3021
|
+
"non-owning",
|
|
3022
|
+
...get,
|
|
3023
|
+
...exclude
|
|
3024
|
+
]);
|
|
3025
|
+
}
|
|
3026
|
+
constructor(handler) {
|
|
3027
|
+
this.descriptor = handler ?? null;
|
|
3028
|
+
}
|
|
3029
|
+
handle() {
|
|
3030
|
+
return this.descriptor.handle();
|
|
3031
|
+
}
|
|
3032
|
+
storage(ElementType) {
|
|
3033
|
+
if (typeof ElementType === "number") return this.ok() ? this.descriptor.storage(ElementType) : null;
|
|
3034
|
+
return this.storage(BasicGroup.indexOf(ElementType));
|
|
3035
|
+
}
|
|
3036
|
+
ok() {
|
|
3037
|
+
return this.descriptor != null;
|
|
3038
|
+
}
|
|
3039
|
+
get size() {
|
|
3040
|
+
return this.ok() ? this.handle().size : 0;
|
|
3041
|
+
}
|
|
3042
|
+
capacity() {
|
|
3043
|
+
return this.ok() ? this.handle().capacity() : 0;
|
|
3044
|
+
}
|
|
3045
|
+
empty() {
|
|
3046
|
+
return !this.ok() || this.handle().empty();
|
|
3047
|
+
}
|
|
3048
|
+
begin() {
|
|
3049
|
+
return this.ok() ? this.handle().begin() : new BaseType.Iterator();
|
|
3050
|
+
}
|
|
3051
|
+
end() {
|
|
3052
|
+
return this.ok() ? this.handle().end() : new BaseType.Iterator();
|
|
3053
|
+
}
|
|
3054
|
+
rbegin() {
|
|
3055
|
+
return this.ok() ? this.handle().rbegin() : new BaseType.ReverseIterator(new BaseType.Iterator());
|
|
3056
|
+
}
|
|
3057
|
+
rend() {
|
|
3058
|
+
return this.ok() ? this.handle().rend() : new BaseType.ReverseIterator(new BaseType.Iterator());
|
|
3059
|
+
}
|
|
3060
|
+
front() {
|
|
3061
|
+
const it = this.begin();
|
|
3062
|
+
return !it.equals(this.end()) ? it.deref() : BaseType.TraitsType.null;
|
|
3063
|
+
}
|
|
3064
|
+
back() {
|
|
3065
|
+
const rit = this.rbegin();
|
|
3066
|
+
return !rit.equals(this.rend()) ? rit.deref() : BaseType.TraitsType.null;
|
|
3067
|
+
}
|
|
3068
|
+
find(entt) {
|
|
3069
|
+
return this.ok() ? this.handle().find(entt) : new BaseType.Iterator();
|
|
3070
|
+
}
|
|
3071
|
+
access(pos) {
|
|
3072
|
+
return this.begin().access(pos);
|
|
3073
|
+
}
|
|
3074
|
+
contains(entt) {
|
|
3075
|
+
return this.ok() && this.handle().contains(entt);
|
|
3076
|
+
}
|
|
3077
|
+
get(entt, ...types) {
|
|
3078
|
+
return this.getByIndexes(entt, ...types.map((t) => BasicGroup.indexOf(t)));
|
|
3079
|
+
}
|
|
3080
|
+
getByIndexes(entt, ...indexes) {
|
|
3081
|
+
const cpools = this.poolsFor(...Array.from({ length: get.length }, (_, i) => i));
|
|
3082
|
+
if (indexes.length === 0) return cpools.flatMap((c) => c.getAsTuple(entt));
|
|
3083
|
+
else if (indexes.length === 1) return cpools[indexes[0]].get(entt);
|
|
3084
|
+
else return indexes.flatMap((i) => cpools[i].getAsTuple(entt));
|
|
3085
|
+
}
|
|
3086
|
+
each(func, componentsOnly) {
|
|
3087
|
+
if (typeof func === "function") for (const entt of this) {
|
|
3088
|
+
const components = this.get(entt);
|
|
3089
|
+
if (componentsOnly) func.apply(this, components);
|
|
3090
|
+
else func.call(this, entt, ...components);
|
|
3091
|
+
}
|
|
3092
|
+
else {
|
|
3093
|
+
const cpools = this.poolsFor(...Array.from({ length: get.length }, (_, i) => i));
|
|
3094
|
+
return new RangeIterator(new ExtendedGroupPointer(this.begin(), [], cpools), new ExtendedGroupPointer(this.end(), [], cpools));
|
|
3095
|
+
}
|
|
3096
|
+
}
|
|
3097
|
+
[Symbol.iterator]() {
|
|
3098
|
+
return toIterator(this);
|
|
3099
|
+
}
|
|
3100
|
+
sort(compareFn, types, algo = defaultSort) {
|
|
3101
|
+
this.sortByIndexes(compareFn, types.map((t) => BasicGroup.indexOf(t)), algo);
|
|
3102
|
+
}
|
|
3103
|
+
sortByIndexes(compareFn, indexes, algo = defaultSort) {
|
|
3104
|
+
if (!this.ok()) return;
|
|
3105
|
+
if (indexes.length === 0) this.descriptor.handle().sort(compareFn, algo);
|
|
3106
|
+
else {
|
|
3107
|
+
const cpools = this.poolsFor(...indexes);
|
|
3108
|
+
const comp = (lhs, rhs) => {
|
|
3109
|
+
if (indexes.length === 1) return compareFn(cpools[indexes[0]].get(lhs), cpools[indexes[0]].get(rhs));
|
|
3110
|
+
else return compareFn(indexes.map((i) => cpools[i].get(lhs)), indexes.map((i) => cpools[i].get(rhs)));
|
|
3111
|
+
};
|
|
3112
|
+
this.descriptor.handle().sort(comp, algo);
|
|
3113
|
+
}
|
|
3114
|
+
}
|
|
3115
|
+
sortAs(first, last) {
|
|
3116
|
+
if (this.ok()) this.descriptor.handle().sortAs(first, last);
|
|
3117
|
+
}
|
|
3118
|
+
}
|
|
3119
|
+
return BasicGroup;
|
|
3120
|
+
}
|
|
3121
|
+
}, {
|
|
3122
|
+
predicate: (owned, _get, _exclude) => owned.length > 0,
|
|
3123
|
+
render(owned, get, exclude) {
|
|
3124
|
+
if (owned.some((o$1) => o$1.constructor.storagePolicy === DeletionPolicy.InPlace)) throw new AssertionError("Groups do not support in-place delete");
|
|
3125
|
+
const BaseType = commonType(...owned.map((o$1) => o$1.constructor.BaseType), ...get.map((g) => g.constructor.BaseType), ...exclude.map((e) => e.constructor.BaseType));
|
|
3126
|
+
const UnderlyingType = BaseType.EntityType;
|
|
3127
|
+
const Handler = groupHandlerTemplate.instantiate(BaseType, owned.length, get.length, exclude.length);
|
|
3128
|
+
class BasicGroup {
|
|
3129
|
+
static BaseType = BaseType;
|
|
3130
|
+
static UnderlyingType = UnderlyingType;
|
|
3131
|
+
static indexOf(T) {
|
|
3132
|
+
return [
|
|
3133
|
+
...owned.map((o$1) => o$1.constructor.ElementType),
|
|
3134
|
+
...get.map((g) => g.constructor.ElementType),
|
|
3135
|
+
...exclude.map((e) => e.constructor.ElementType)
|
|
3136
|
+
].indexOf(T);
|
|
3137
|
+
}
|
|
3138
|
+
poolsFor(indexes, other) {
|
|
3139
|
+
return this.descriptor ? [...indexes.map((i) => this.descriptor.storage(i)), ...other.map((i) => this.descriptor.storage(i + owned.length))] : [];
|
|
3140
|
+
}
|
|
3141
|
+
static EntityType = UnderlyingType;
|
|
3142
|
+
static CommonType = BaseType;
|
|
3143
|
+
static Iterator = BaseType.Iterator;
|
|
3144
|
+
static ReverseIterator = BaseType.ReverseIterator;
|
|
3145
|
+
static Handler = Handler;
|
|
3146
|
+
descriptor;
|
|
3147
|
+
static groupId() {
|
|
3148
|
+
return dist_default([
|
|
3149
|
+
owned,
|
|
3150
|
+
get,
|
|
3151
|
+
exclude
|
|
3152
|
+
]);
|
|
3153
|
+
}
|
|
3154
|
+
constructor(handler) {
|
|
3155
|
+
this.descriptor = handler ?? null;
|
|
3156
|
+
}
|
|
3157
|
+
handle() {
|
|
3158
|
+
return this.storage(0);
|
|
3159
|
+
}
|
|
3160
|
+
ok() {
|
|
3161
|
+
return this.descriptor != null;
|
|
3162
|
+
}
|
|
3163
|
+
storage(ElementType) {
|
|
3164
|
+
if (typeof ElementType === "number") return this.ok() ? this.descriptor.storage(ElementType) : null;
|
|
3165
|
+
return this.storage(BasicGroup.indexOf(ElementType));
|
|
3166
|
+
}
|
|
3167
|
+
get size() {
|
|
3168
|
+
return this.ok() ? this.descriptor.length() : 0;
|
|
3169
|
+
}
|
|
3170
|
+
empty() {
|
|
3171
|
+
return !this.ok() || !this.descriptor.length();
|
|
3172
|
+
}
|
|
3173
|
+
begin() {
|
|
3174
|
+
return this.ok() ? BaseType.prototype.end.call(this.handle()).minus(this.descriptor.length()) : new BaseType.Iterator();
|
|
3175
|
+
}
|
|
3176
|
+
end() {
|
|
3177
|
+
return this.ok() ? BaseType.prototype.end.call(this.handle()) : new BaseType.Iterator();
|
|
3178
|
+
}
|
|
3179
|
+
rbegin() {
|
|
3180
|
+
return this.ok() ? BaseType.prototype.rbegin.call(this.handle()) : new BaseType.ReverseIterator(new BaseType.Iterator());
|
|
3181
|
+
}
|
|
3182
|
+
rend() {
|
|
3183
|
+
return this.ok() ? BaseType.prototype.rbegin.call(this.handle()).plus(this.descriptor.length()) : new BaseType.ReverseIterator(new BaseType.Iterator());
|
|
3184
|
+
}
|
|
3185
|
+
front() {
|
|
3186
|
+
const it = this.begin();
|
|
3187
|
+
return !it.equals(this.end()) ? it.deref() : BaseType.TraitsType.null;
|
|
3188
|
+
}
|
|
3189
|
+
back() {
|
|
3190
|
+
const rit = this.rbegin();
|
|
3191
|
+
return !rit.equals(this.rend()) ? rit.deref() : BaseType.TraitsType.null;
|
|
3192
|
+
}
|
|
3193
|
+
find(entt) {
|
|
3194
|
+
const it = this.ok() ? this.handle().find(entt) : new BaseType.Iterator();
|
|
3195
|
+
return it.gte(this.begin()) ? it : new BaseType.Iterator();
|
|
3196
|
+
}
|
|
3197
|
+
access(pos) {
|
|
3198
|
+
return this.begin().access(pos);
|
|
3199
|
+
}
|
|
3200
|
+
contains(entt) {
|
|
3201
|
+
return this.ok() && this.handle().contains(entt) && this.handle().index(entt) < this.descriptor.length();
|
|
3202
|
+
}
|
|
3203
|
+
get(entt, ...types) {
|
|
3204
|
+
return this.getByIndexes(entt, ...types.map((t) => BasicGroup.indexOf(t)));
|
|
3205
|
+
}
|
|
3206
|
+
getByIndexes(entt, ...indexes) {
|
|
3207
|
+
const cpools = this.poolsFor(Array.from({ length: owned.length }, (_, i) => i), Array.from({ length: get.length }, (_, i) => i));
|
|
3208
|
+
if (indexes.length === 0) return cpools.flatMap((c) => c.getAsTuple(entt));
|
|
3209
|
+
else if (indexes.length === 1) return cpools[indexes[0]].get(entt);
|
|
3210
|
+
else return indexes.flatMap((i) => cpools[i].getAsTuple(entt));
|
|
3211
|
+
}
|
|
3212
|
+
each(func, componentsOnly) {
|
|
3213
|
+
if (typeof func === "function") for (const args of this.each()) if (componentsOnly) func.apply(this, args.slice(1));
|
|
3214
|
+
else func.apply(this, args);
|
|
3215
|
+
else {
|
|
3216
|
+
const cpools = this.poolsFor(Array.from({ length: owned.length }, (_, i) => i), Array.from({ length: get.length }, (_, i) => i));
|
|
3217
|
+
const begin = this.begin();
|
|
3218
|
+
const end = this.end();
|
|
3219
|
+
return new RangeIterator(new ExtendedGroupPointer(begin, cpools.slice(0, owned.length), cpools.slice(owned.length)), new ExtendedGroupPointer(end, cpools.slice(0, owned.length), cpools.slice(owned.length)));
|
|
3220
|
+
}
|
|
3221
|
+
}
|
|
3222
|
+
[Symbol.iterator]() {
|
|
3223
|
+
return toIterator(this);
|
|
3224
|
+
}
|
|
3225
|
+
sort(compareFn, types, algo = defaultSort) {
|
|
3226
|
+
this.sortByIndexes(compareFn, types.map((t) => BasicGroup.indexOf(t)), algo);
|
|
3227
|
+
}
|
|
3228
|
+
sortByIndexes(compareFn, indexes, algo = defaultSort) {
|
|
3229
|
+
const cpools = this.poolsFor(Array.from({ length: owned.length }, (_, i) => i), Array.from({ length: get.length }, (_, i) => i));
|
|
3230
|
+
if (indexes.length === 0) this.storage(0).sortN(this.descriptor.length(), compareFn, algo);
|
|
3231
|
+
else {
|
|
3232
|
+
const comp = (lhs, rhs) => {
|
|
3233
|
+
if (indexes.length === 1) return compareFn(cpools[indexes[0]].get(lhs), cpools[indexes[0]].get(rhs));
|
|
3234
|
+
else return compareFn(indexes.map((i) => cpools[i].get(lhs)), indexes.map((i) => cpools[i].get(rhs)));
|
|
3235
|
+
};
|
|
3236
|
+
this.storage(0).sortN(this.descriptor.length(), comp, algo);
|
|
3237
|
+
}
|
|
3238
|
+
const cb = (...args) => {
|
|
3239
|
+
const [head, ...other] = args;
|
|
3240
|
+
for (let next = this.descriptor.length(); next; --next) {
|
|
3241
|
+
const pos = next - 1;
|
|
3242
|
+
const entt = head.data()[pos];
|
|
3243
|
+
other.forEach((o$1) => {
|
|
3244
|
+
o$1.swapElements(o$1.data()[pos], entt);
|
|
3245
|
+
});
|
|
3246
|
+
}
|
|
3247
|
+
};
|
|
3248
|
+
cb.apply(this, cpools);
|
|
3249
|
+
}
|
|
3250
|
+
}
|
|
3251
|
+
return BasicGroup;
|
|
3252
|
+
}
|
|
3253
|
+
}]);
|
|
3254
|
+
function makeGroup(owned, get, exclude = []) {
|
|
3255
|
+
return new (basicGroupTemplate.instantiate(owned, get, exclude))();
|
|
3256
|
+
}
|
|
3257
|
+
|
|
3258
|
+
//#endregion
|
|
3259
|
+
//#region src/registry.ts
|
|
3260
|
+
const basicRegistryTemplate = /* @__PURE__ */ defineTemplate(function templateBasicRegistry(ValueType) {
|
|
3261
|
+
const EntityStorageClass = storageTypeTTemplate.instantiate(ValueType, ValueType);
|
|
3262
|
+
const TraitsType = EntityStorageClass.TraitsType;
|
|
3263
|
+
const EntityType = TraitsType.ValueType;
|
|
3264
|
+
const BaseType = basicSparseSetTemplate.instantiate(ValueType);
|
|
3265
|
+
return class extends Disposable {
|
|
3266
|
+
static TraitsType = TraitsType;
|
|
3267
|
+
static EntityType = EntityType;
|
|
3268
|
+
static CommonType = BaseType;
|
|
3269
|
+
entities;
|
|
3270
|
+
vars;
|
|
3271
|
+
groups;
|
|
3272
|
+
pools;
|
|
3273
|
+
constructor() {
|
|
3274
|
+
super();
|
|
3275
|
+
this.entities = new EntityStorageClass();
|
|
3276
|
+
this.entities.bind(this);
|
|
3277
|
+
this.vars = Object.create(null);
|
|
3278
|
+
this.groups = /* @__PURE__ */ new Map();
|
|
3279
|
+
this.pools = /* @__PURE__ */ new Map();
|
|
3280
|
+
}
|
|
3281
|
+
dispose() {
|
|
3282
|
+
for (const group of this.groups.values()) group.dispose();
|
|
3283
|
+
this.groups.clear();
|
|
3284
|
+
for (const pool of this.pools.values()) pool.dispose();
|
|
3285
|
+
this.pools.clear();
|
|
3286
|
+
this.entities.dispose();
|
|
3287
|
+
Object.keys(this.vars).forEach((_, key) => {
|
|
3288
|
+
delete this.vars[key];
|
|
3289
|
+
});
|
|
3290
|
+
}
|
|
3291
|
+
assure(k) {
|
|
3292
|
+
const [ComponentType, id] = destructKey(k);
|
|
3293
|
+
if (typeof ComponentType !== "function" && ComponentType !== void 0) throw new Error("Invalid component type");
|
|
3294
|
+
if (Object.is(ComponentType, EntityType)) {
|
|
3295
|
+
assert(id === EntityType, "User entity storage not allowed");
|
|
3296
|
+
return this.entities;
|
|
3297
|
+
}
|
|
3298
|
+
if (this.pools.has(id)) {
|
|
3299
|
+
assert(this.pools.get(id).type() === ComponentType, "Unexpected type");
|
|
3300
|
+
return this.pools.get(id);
|
|
3301
|
+
}
|
|
3302
|
+
const cpool = new (storageTypeTTemplate.instantiate(ComponentType, EntityType))();
|
|
3303
|
+
this.pools.set(id, cpool);
|
|
3304
|
+
cpool.bind(this);
|
|
3305
|
+
return cpool;
|
|
3306
|
+
}
|
|
3307
|
+
constAssure(k) {
|
|
3308
|
+
const [ComponentType, id] = destructKey(k);
|
|
3309
|
+
const hasType = typeof ComponentType === "function" || ComponentType === void 0;
|
|
3310
|
+
if (hasType) {
|
|
3311
|
+
if (Object.is(ComponentType, EntityType)) {
|
|
3312
|
+
assert(id === EntityType, "User entity storage not allowed");
|
|
3313
|
+
return this.entities;
|
|
3314
|
+
}
|
|
3315
|
+
}
|
|
3316
|
+
const cpool = this.pools.get(id);
|
|
3317
|
+
if (!cpool) return void 0;
|
|
3318
|
+
assert(!hasType || cpool.type() === ComponentType, "Unexpected type");
|
|
3319
|
+
return cpool;
|
|
3320
|
+
}
|
|
3321
|
+
ctx() {
|
|
3322
|
+
return this.vars;
|
|
3323
|
+
}
|
|
3324
|
+
create(hint) {
|
|
3325
|
+
return this.entities.generate(hint);
|
|
3326
|
+
}
|
|
3327
|
+
createRange(first, last) {
|
|
3328
|
+
this.entities.generateRange(first, last);
|
|
3329
|
+
}
|
|
3330
|
+
insert(ComponentType, first, last, value) {
|
|
3331
|
+
last = last.clone();
|
|
3332
|
+
for (let it = first.clone(); !it.equals(last); it.selfPlus()) assert(this.valid(it.deref()), "Invalid entity");
|
|
3333
|
+
this.assure(ComponentType).insert(first, last, value);
|
|
3334
|
+
}
|
|
3335
|
+
insertRange(ComponentType, first, last, from) {
|
|
3336
|
+
last = last.clone();
|
|
3337
|
+
for (let it = first.clone(); !it.equals(last); it.selfPlus()) assert(this.valid(it.deref()), "Invalid entity");
|
|
3338
|
+
this.assure(ComponentType).insertRange(first, last, from);
|
|
3339
|
+
}
|
|
3340
|
+
storage() {
|
|
3341
|
+
return this.pools.entries();
|
|
3342
|
+
}
|
|
3343
|
+
getStorage(k, forceConst = false) {
|
|
3344
|
+
if (!forceConst && (typeof k === "function" || Array.isArray(k) || k === void 0)) return this.assure(k);
|
|
3345
|
+
return this.constAssure(k);
|
|
3346
|
+
}
|
|
3347
|
+
reset(id) {
|
|
3348
|
+
assert(id !== EntityType, "Cannot reset entity storage");
|
|
3349
|
+
return this.pools.delete(id);
|
|
3350
|
+
}
|
|
3351
|
+
valid(entt) {
|
|
3352
|
+
const idx = this.entities.find(entt).index();
|
|
3353
|
+
return idx >= 0 && idx < this.entities.freeList();
|
|
3354
|
+
}
|
|
3355
|
+
current(entt) {
|
|
3356
|
+
return this.entities.current(entt);
|
|
3357
|
+
}
|
|
3358
|
+
destroy(entt, version$1) {
|
|
3359
|
+
const pools = [...this.pools.values()];
|
|
3360
|
+
for (let pos = pools.length - 1; pos >= 0; --pos) pools[pos].remove(entt);
|
|
3361
|
+
this.entities.erase(entt);
|
|
3362
|
+
const ret = this.entities.current(entt);
|
|
3363
|
+
if (version$1 !== void 0) {
|
|
3364
|
+
const elem = TraitsType.construct(TraitsType.toEntity(entt), version$1);
|
|
3365
|
+
return this.entities.bump(TraitsType.isTombstone(elem) ? TraitsType.next(elem) : elem);
|
|
3366
|
+
}
|
|
3367
|
+
return ret;
|
|
3368
|
+
}
|
|
3369
|
+
destroyRange(iterable, last) {
|
|
3370
|
+
const to = last == null ? this.entities.sortAs(iterable) : this.entities.sortAs(iterable, last);
|
|
3371
|
+
const from = this.entities.end().minus(Number(this.entities.freeList()));
|
|
3372
|
+
for (const pool of this.pools.values()) pool.remove(from, to);
|
|
3373
|
+
this.entities.erase(from, to);
|
|
3374
|
+
}
|
|
3375
|
+
emplace(entt, ComponentType, ...args) {
|
|
3376
|
+
assert(this.valid(entt), "Invalid entity");
|
|
3377
|
+
return this.assure(ComponentType).emplace(entt, ...args);
|
|
3378
|
+
}
|
|
3379
|
+
emplaceOrReplace(entt, ComponentType, ...args) {
|
|
3380
|
+
const cpool = this.assure(ComponentType);
|
|
3381
|
+
assert(this.valid(entt), "Invalid entity");
|
|
3382
|
+
return cpool.has(entt) ? cpool.patch(entt, () => createSafeNew(cpool.type())(...args)) : cpool.emplace(entt, ...args);
|
|
3383
|
+
}
|
|
3384
|
+
patch(entt, ComponentType, ...func) {
|
|
3385
|
+
return this.assure(ComponentType).patch(entt, ...func);
|
|
3386
|
+
}
|
|
3387
|
+
replace(entt, ComponentType, ...args) {
|
|
3388
|
+
const cpool = this.assure(ComponentType);
|
|
3389
|
+
return cpool.patch(entt, () => createSafeNew(cpool.type())(...args));
|
|
3390
|
+
}
|
|
3391
|
+
remove(entt, ...ComponentTypes) {
|
|
3392
|
+
let removed = 0;
|
|
3393
|
+
for (const ComponentType of ComponentTypes) if (this.assure(ComponentType).delete(entt)) ++removed;
|
|
3394
|
+
return removed;
|
|
3395
|
+
}
|
|
3396
|
+
removeRange(first, last, ...ComponentTypes) {
|
|
3397
|
+
let count = 0;
|
|
3398
|
+
first = first.clone();
|
|
3399
|
+
last = last.clone();
|
|
3400
|
+
if (first instanceof SparseSetPointer && last instanceof SparseSetPointer) {
|
|
3401
|
+
const array = ComponentTypes.map((ComponentType) => this.assure(ComponentType));
|
|
3402
|
+
const cpools = toRange(array);
|
|
3403
|
+
const from = cpools.begin();
|
|
3404
|
+
const to = cpools.end();
|
|
3405
|
+
for (; !from.equals(to); from.selfPlus()) {
|
|
3406
|
+
if (ComponentTypes.length > 1) {
|
|
3407
|
+
if (from.deref().data() === first.data()) {
|
|
3408
|
+
const tmp = from.deref();
|
|
3409
|
+
from.write(array[array.length - 1]);
|
|
3410
|
+
array[array.length - 1] = tmp;
|
|
3411
|
+
}
|
|
3412
|
+
}
|
|
3413
|
+
count += from.deref().remove(first, last);
|
|
3414
|
+
}
|
|
3415
|
+
} else for (const cpools = ComponentTypes.map((ComponentType) => this.assure(ComponentType)); !first.equals(last); first.selfPlus()) {
|
|
3416
|
+
const entt = first.deref();
|
|
3417
|
+
for (const cpool of cpools) count += cpool.remove(entt) ? 1 : 0;
|
|
3418
|
+
}
|
|
3419
|
+
return count;
|
|
3420
|
+
}
|
|
3421
|
+
eraseIf(entt, func) {
|
|
3422
|
+
for (const [id, cpool] of this.storage()) if (cpool.contains(entt) && func(id, cpool)) cpool.erase(entt);
|
|
3423
|
+
}
|
|
3424
|
+
erase(entt, ...ComponentTypes) {
|
|
3425
|
+
for (const ComponentType of ComponentTypes) this.assure(ComponentType).erase(entt);
|
|
3426
|
+
}
|
|
3427
|
+
eraseRange(first, last, ...ComponentTypes) {
|
|
3428
|
+
first = first.clone();
|
|
3429
|
+
last = last.clone();
|
|
3430
|
+
if (first instanceof SparseSetPointer && last instanceof SparseSetPointer) {
|
|
3431
|
+
const array = ComponentTypes.map((ComponentType) => this.assure(ComponentType));
|
|
3432
|
+
const cpools = toRange(array);
|
|
3433
|
+
const from = cpools.begin();
|
|
3434
|
+
const to = cpools.end();
|
|
3435
|
+
for (; !from.equals(to); from.selfPlus()) {
|
|
3436
|
+
if (ComponentTypes.length > 1) {
|
|
3437
|
+
if (from.deref().data() === first.data()) {
|
|
3438
|
+
const tmp = from.deref();
|
|
3439
|
+
from.write(array[array.length - 1]);
|
|
3440
|
+
array[array.length - 1] = tmp;
|
|
3441
|
+
}
|
|
3442
|
+
}
|
|
3443
|
+
from.deref().erase(first, last);
|
|
3444
|
+
}
|
|
3445
|
+
} else for (const cpools = ComponentTypes.map((ComponentType) => this.assure(ComponentType)); !first.equals(last); first.selfPlus()) {
|
|
3446
|
+
const entt = first.deref();
|
|
3447
|
+
for (const cpool of cpools) cpool.erase(entt);
|
|
3448
|
+
}
|
|
3449
|
+
}
|
|
3450
|
+
compact(...ComponentTypes) {
|
|
3451
|
+
if (ComponentTypes.length === 0) for (const pool of this.pools.values()) pool.compact();
|
|
3452
|
+
else for (const ComponentType of ComponentTypes) this.assure(ComponentType).compact();
|
|
3453
|
+
}
|
|
3454
|
+
allOf(entt, ...ComponentTypes) {
|
|
3455
|
+
if (ComponentTypes.length === 1) {
|
|
3456
|
+
const cpool = this.constAssure(ComponentTypes[0]);
|
|
3457
|
+
return cpool != null && cpool?.has(entt);
|
|
3458
|
+
}
|
|
3459
|
+
return ComponentTypes.every((ComponentType) => this.allOf(entt, ComponentType));
|
|
3460
|
+
}
|
|
3461
|
+
anyOf(entt, ...ComponentTypes) {
|
|
3462
|
+
return ComponentTypes.some((ComponentType) => this.allOf(entt, ComponentType));
|
|
3463
|
+
}
|
|
3464
|
+
tryGet(entt, ...ComponentType) {
|
|
3465
|
+
if (ComponentType.length === 1) {
|
|
3466
|
+
const cpool = this.constAssure(ComponentType[0]);
|
|
3467
|
+
return cpool ? cpool.has(entt) ? cpool.get(entt) : void 0 : void 0;
|
|
3468
|
+
}
|
|
3469
|
+
return ComponentType.map((Type) => this.tryGet(entt, Type));
|
|
3470
|
+
}
|
|
3471
|
+
get(entt, ...ComponentType) {
|
|
3472
|
+
if (ComponentType.length === 1) return this.assure(ComponentType[0]).get(entt);
|
|
3473
|
+
return ComponentType.map((Type) => this.get(entt, Type));
|
|
3474
|
+
}
|
|
3475
|
+
getOrEmplace(entt, ComponentType, ...args) {
|
|
3476
|
+
const cpool = this.assure(ComponentType);
|
|
3477
|
+
assert(this.valid(entt), "Invalid entity");
|
|
3478
|
+
return cpool.has(entt) ? cpool.get(entt) : cpool.emplace(entt, ...args);
|
|
3479
|
+
}
|
|
3480
|
+
clear(...ComponentTypes) {
|
|
3481
|
+
if (ComponentTypes.length === 0) {
|
|
3482
|
+
const pools = [...this.pools.values()];
|
|
3483
|
+
for (let pos = pools.length - 1; pos >= 0; --pos) pools[pos].clear();
|
|
3484
|
+
const elem = this.entities.each();
|
|
3485
|
+
this.entities.erase(elem.begin().base(), elem.end().base());
|
|
3486
|
+
} else ComponentTypes.forEach((ComponentType) => {
|
|
3487
|
+
this.assure(ComponentType).clear();
|
|
3488
|
+
});
|
|
3489
|
+
}
|
|
3490
|
+
orphan(entt) {
|
|
3491
|
+
return ![...this.pools.values()].some((pool) => pool.has(entt));
|
|
3492
|
+
}
|
|
3493
|
+
onConstruct(ComponentType) {
|
|
3494
|
+
return this.assure(ComponentType).onConstruct();
|
|
3495
|
+
}
|
|
3496
|
+
onUpdate(ComponentType) {
|
|
3497
|
+
return this.assure(ComponentType).onUpdate();
|
|
3498
|
+
}
|
|
3499
|
+
onDestroy(ComponentType) {
|
|
3500
|
+
return this.assure(ComponentType).onDestroy();
|
|
3501
|
+
}
|
|
3502
|
+
sort(ComponentType, compare, algo = defaultSort) {
|
|
3503
|
+
{
|
|
3504
|
+
const [C] = destructKey(ComponentType);
|
|
3505
|
+
if (typeof C !== "function" && C !== void 0) throw new Error("Invalid component type");
|
|
3506
|
+
assert(!this.owned(C), "Cannot sort owned storage");
|
|
3507
|
+
}
|
|
3508
|
+
const cpool = this.assure(ComponentType);
|
|
3509
|
+
cpool.sort((a, b) => compare(cpool.get(a), cpool.get(b)), algo);
|
|
3510
|
+
}
|
|
3511
|
+
sortByEntity(ComponentType, compare, algo = defaultSort) {
|
|
3512
|
+
{
|
|
3513
|
+
const [C] = destructKey(ComponentType);
|
|
3514
|
+
if (typeof C !== "function" && C !== void 0) throw new Error("Invalid component type");
|
|
3515
|
+
assert(!this.owned(C), "Cannot sort owned storage");
|
|
3516
|
+
}
|
|
3517
|
+
this.assure(ComponentType).sort(compare, algo);
|
|
3518
|
+
}
|
|
3519
|
+
sortAs(To, From) {
|
|
3520
|
+
{
|
|
3521
|
+
const [ComponentType] = destructKey(To);
|
|
3522
|
+
if (typeof ComponentType !== "function" && ComponentType !== void 0) throw new Error("Invalid component type");
|
|
3523
|
+
assert(!this.owned(ComponentType), "Cannot sort owned storage");
|
|
3524
|
+
}
|
|
3525
|
+
const cpool = this.assure(From);
|
|
3526
|
+
this.assure(To).sortAs(cpool.begin(), cpool.end());
|
|
3527
|
+
}
|
|
3528
|
+
view(types, excludes = []) {
|
|
3529
|
+
const gets = types.map((Type) => this.assure(Type));
|
|
3530
|
+
const excl = excludes.map((Type) => this.assure(Type));
|
|
3531
|
+
return new (basicViewTemplate.instantiate(gets, excl))(gets, excl);
|
|
3532
|
+
}
|
|
3533
|
+
group(owned, get = [], exclude = []) {
|
|
3534
|
+
const o$1 = owned.map((Type) => this.assure(Type));
|
|
3535
|
+
const g = get.map((Type) => this.assure(Type));
|
|
3536
|
+
const e = exclude.map((Type) => this.assure(Type));
|
|
3537
|
+
const GroupType = basicGroupTemplate.instantiate(o$1, g, e);
|
|
3538
|
+
const HandlerType = GroupType.Handler;
|
|
3539
|
+
if (this.groups.has(GroupType.groupId())) return new GroupType(this.groups.get(GroupType.groupId()));
|
|
3540
|
+
let handler = void 0;
|
|
3541
|
+
if (o$1.length === 0) handler = new HandlerType(g, e);
|
|
3542
|
+
else {
|
|
3543
|
+
handler = new HandlerType([...o$1, ...g], e);
|
|
3544
|
+
this.groups.forEach((group) => {
|
|
3545
|
+
assert(!o$1.every((p) => !group.owned(p)), "Conflicting groups");
|
|
3546
|
+
});
|
|
3547
|
+
}
|
|
3548
|
+
this.groups.set(GroupType.groupId(), handler);
|
|
3549
|
+
return new GroupType(handler);
|
|
3550
|
+
}
|
|
3551
|
+
groupIfExists(owned, get = [], exclude = []) {
|
|
3552
|
+
const o$1 = owned.map((Type) => this.assure(Type));
|
|
3553
|
+
const g = get.map((Type) => this.assure(Type));
|
|
3554
|
+
const e = exclude.map((Type) => this.assure(Type));
|
|
3555
|
+
const GroupType = basicGroupTemplate.instantiate(o$1, g, e);
|
|
3556
|
+
if (this.groups.has(GroupType.groupId())) return new GroupType(this.groups.get(GroupType.groupId()));
|
|
3557
|
+
return new GroupType();
|
|
3558
|
+
}
|
|
3559
|
+
owned(...Types) {
|
|
3560
|
+
for (const group of this.groups.values()) if (Types.some((Type) => group.owned(Type))) return true;
|
|
3561
|
+
return false;
|
|
3562
|
+
}
|
|
3563
|
+
};
|
|
3564
|
+
});
|
|
3565
|
+
const Registry = /* @__PURE__ */ (() => basicRegistryTemplate.instantiate(Entity))();
|
|
3566
|
+
|
|
3567
|
+
//#endregion
|
|
3568
|
+
//#region src/runtime-view.ts
|
|
3569
|
+
var RuntimeViewIterator = class RuntimeViewIterator {
|
|
3570
|
+
pools;
|
|
3571
|
+
filter;
|
|
3572
|
+
it;
|
|
3573
|
+
tombstoneCheck;
|
|
3574
|
+
valid() {
|
|
3575
|
+
const entt = this.it.deref();
|
|
3576
|
+
return (!this.tombstoneCheck || !this.pools[0].isTombstone(entt)) && this.pools.every((curr) => curr.contains(entt)) && !this.filter.some((curr) => curr?.contains(entt));
|
|
3577
|
+
}
|
|
3578
|
+
constructor(cpools, curr, ignore) {
|
|
3579
|
+
if (cpools != null && curr != null && ignore != null) {
|
|
3580
|
+
this.pools = cpools;
|
|
3581
|
+
this.it = curr.clone();
|
|
3582
|
+
this.filter = ignore;
|
|
3583
|
+
this.tombstoneCheck = cpools.length === 1 && cpools[0].policy() === DeletionPolicy.InPlace;
|
|
3584
|
+
if (!this.it.equals(SparseSet.prototype.end.call(cpools[0])) && !this.valid()) this.selfPlus();
|
|
3585
|
+
} else {
|
|
3586
|
+
this.pools = [];
|
|
3587
|
+
this.it = new SparseSetPointer();
|
|
3588
|
+
this.filter = [];
|
|
3589
|
+
this.tombstoneCheck = false;
|
|
3590
|
+
}
|
|
3591
|
+
}
|
|
3592
|
+
clone(target) {
|
|
3593
|
+
if (target) {
|
|
3594
|
+
if (target === this) return this;
|
|
3595
|
+
target.pools = this.pools.slice();
|
|
3596
|
+
target.it = this.it.clone();
|
|
3597
|
+
target.filter = this.filter.slice();
|
|
3598
|
+
target.tombstoneCheck = this.tombstoneCheck;
|
|
3599
|
+
return target;
|
|
3600
|
+
}
|
|
3601
|
+
const copied = new RuntimeViewIterator();
|
|
3602
|
+
copied.pools = this.pools.slice();
|
|
3603
|
+
copied.it = this.it.clone();
|
|
3604
|
+
copied.filter = this.filter.slice();
|
|
3605
|
+
copied.tombstoneCheck = this.tombstoneCheck;
|
|
3606
|
+
return copied;
|
|
3607
|
+
}
|
|
3608
|
+
swap(other) {
|
|
3609
|
+
if (this === other) return;
|
|
3610
|
+
this.it.swap(other.it);
|
|
3611
|
+
const tmpPools = this.pools;
|
|
3612
|
+
const tmpFilter = this.filter;
|
|
3613
|
+
const tmpTombstoneCheck = this.tombstoneCheck;
|
|
3614
|
+
this.pools = other.pools;
|
|
3615
|
+
this.filter = other.filter;
|
|
3616
|
+
this.tombstoneCheck = other.tombstoneCheck;
|
|
3617
|
+
other.pools = tmpPools;
|
|
3618
|
+
other.filter = tmpFilter;
|
|
3619
|
+
other.tombstoneCheck = tmpTombstoneCheck;
|
|
3620
|
+
}
|
|
3621
|
+
write(value) {
|
|
3622
|
+
return this.it.write(value);
|
|
3623
|
+
}
|
|
3624
|
+
deref() {
|
|
3625
|
+
return this.it.deref();
|
|
3626
|
+
}
|
|
3627
|
+
selfPlus() {
|
|
3628
|
+
this.it.selfPlus();
|
|
3629
|
+
for (const last = SparseSet.prototype.end.call(this.pools[0]); !this.it.equals(last) && !this.valid(); this.it.selfPlus());
|
|
3630
|
+
return this;
|
|
3631
|
+
}
|
|
3632
|
+
selfMinus() {
|
|
3633
|
+
this.it.selfMinus();
|
|
3634
|
+
for (const first = SparseSet.prototype.begin.call(this.pools[0]); !this.it.equals(first) && !this.valid(); this.it.selfMinus());
|
|
3635
|
+
return this;
|
|
3636
|
+
}
|
|
3637
|
+
equals(other) {
|
|
3638
|
+
return this.it.equals(other.it);
|
|
3639
|
+
}
|
|
3640
|
+
};
|
|
3641
|
+
const basicRuntimeViewTemplate = /* @__PURE__ */ defineTemplate(function(Type) {
|
|
3642
|
+
class BasicRuntimeView extends Disposable {
|
|
3643
|
+
pools;
|
|
3644
|
+
filter;
|
|
3645
|
+
offset() {
|
|
3646
|
+
assert(this.pools.length !== 0, "Invalid view");
|
|
3647
|
+
const leading = this.pools[0];
|
|
3648
|
+
return leading.policy() === DeletionPolicy.SwapOnly ? Number(leading.freeList()) : leading.size;
|
|
3649
|
+
}
|
|
3650
|
+
static EntityType = Type.EntityType;
|
|
3651
|
+
static CommonType = Type;
|
|
3652
|
+
static Iterator = RuntimeViewIterator;
|
|
3653
|
+
constructor() {
|
|
3654
|
+
super();
|
|
3655
|
+
this.pools = [];
|
|
3656
|
+
this.filter = [];
|
|
3657
|
+
}
|
|
3658
|
+
dispose() {
|
|
3659
|
+
this.pools.length = 0;
|
|
3660
|
+
this.filter.length = 0;
|
|
3661
|
+
}
|
|
3662
|
+
clear() {
|
|
3663
|
+
this.pools.length = 0;
|
|
3664
|
+
this.filter.length = 0;
|
|
3665
|
+
}
|
|
3666
|
+
iterate(base) {
|
|
3667
|
+
if (this.pools.length === 0 || !(base.size < this.pools[0].size)) this.pools.push(base);
|
|
3668
|
+
else {
|
|
3669
|
+
const front = this.pools[0];
|
|
3670
|
+
this.pools[0] = base;
|
|
3671
|
+
this.pools.push(front);
|
|
3672
|
+
}
|
|
3673
|
+
return this;
|
|
3674
|
+
}
|
|
3675
|
+
exclude(base) {
|
|
3676
|
+
this.filter.push(base);
|
|
3677
|
+
return this;
|
|
3678
|
+
}
|
|
3679
|
+
sizeHint() {
|
|
3680
|
+
return this.pools.length === 0 ? 0 : this.offset();
|
|
3681
|
+
}
|
|
3682
|
+
begin() {
|
|
3683
|
+
return this.pools.length === 0 ? new RuntimeViewIterator() : new RuntimeViewIterator(this.pools, Type.prototype.end.call(this.pools[0]).minus(this.offset()), this.filter);
|
|
3684
|
+
}
|
|
3685
|
+
end() {
|
|
3686
|
+
return this.pools.length === 0 ? new RuntimeViewIterator() : new RuntimeViewIterator(this.pools, Type.prototype.end.call(this.pools[0]), this.filter);
|
|
3687
|
+
}
|
|
3688
|
+
ok() {
|
|
3689
|
+
return !(this.pools.length === 0 && this.filter.length === 0);
|
|
3690
|
+
}
|
|
3691
|
+
contains(entt) {
|
|
3692
|
+
return this.pools.length !== 0 && this.pools.every((curr) => curr.contains(entt)) && !this.filter.some((curr) => curr?.contains(entt)) && this.pools[0].index(entt) < this.offset();
|
|
3693
|
+
}
|
|
3694
|
+
each(func) {
|
|
3695
|
+
for (const entity of this) func(entity);
|
|
3696
|
+
}
|
|
3697
|
+
[Symbol.iterator]() {
|
|
3698
|
+
return toIterator(this.begin(), this.end());
|
|
3699
|
+
}
|
|
3700
|
+
}
|
|
3701
|
+
return BasicRuntimeView;
|
|
3702
|
+
});
|
|
3703
|
+
const RuntimeView = /* @__PURE__ */ (() => basicRuntimeViewTemplate.instantiate(SparseSet))();
|
|
3704
|
+
|
|
3705
|
+
//#endregion
|
|
3706
|
+
//#region src/snapshot.ts
|
|
3707
|
+
function orphans(registry) {
|
|
3708
|
+
const storage = registry.getStorage(registry.constructor.EntityType);
|
|
3709
|
+
for (const entt of storage) if (registry.orphan(entt)) storage.erase(entt);
|
|
3710
|
+
}
|
|
3711
|
+
const basicSnapshotTemplate = /* @__PURE__ */ defineTemplate(function(Registry$1) {
|
|
3712
|
+
const TraitsType = enttTraitsTemplate.instantiate(Registry$1.EntityType);
|
|
3713
|
+
const EntityType = Registry$1.EntityType;
|
|
3714
|
+
class BasicSnapshot extends Disposable {
|
|
3715
|
+
static TraitsType = TraitsType;
|
|
3716
|
+
static RegistryType = Registry$1;
|
|
3717
|
+
static EntityType = EntityType;
|
|
3718
|
+
reg;
|
|
3719
|
+
constructor(registry) {
|
|
3720
|
+
super();
|
|
3721
|
+
this.reg = registry;
|
|
3722
|
+
}
|
|
3723
|
+
dispose() {
|
|
3724
|
+
this.reg = null;
|
|
3725
|
+
}
|
|
3726
|
+
get(archive, Type) {
|
|
3727
|
+
const [ComponentType] = destructKey(Type);
|
|
3728
|
+
const storage = this.reg.getStorage(Type, true);
|
|
3729
|
+
if (storage) {
|
|
3730
|
+
const base = storage;
|
|
3731
|
+
archive.saveSize(TraitsType.EntityType(storage.size));
|
|
3732
|
+
if (ComponentType === EntityType) {
|
|
3733
|
+
archive.saveSize(TraitsType.EntityType(storage.freeList()));
|
|
3734
|
+
const first = Registry$1.CommonType.prototype.rbegin.call(base);
|
|
3735
|
+
const last = Registry$1.CommonType.prototype.rend.call(base);
|
|
3736
|
+
for (; !first.equals(last); first.selfPlus()) archive.saveEntity(first.deref());
|
|
3737
|
+
} else if (storageTypeTTemplate.instantiate(ComponentType, Registry$1.EntityType).storagePolicy === DeletionPolicy.InPlace) {
|
|
3738
|
+
const it = Registry$1.CommonType.prototype.rbegin.call(base);
|
|
3739
|
+
const last = Registry$1.CommonType.prototype.rend.call(base);
|
|
3740
|
+
for (; !it.equals(last); it.selfPlus()) {
|
|
3741
|
+
const entt = it.deref();
|
|
3742
|
+
if (Registry$1.CommonType.isTombstone(entt)) archive.saveEntity(TraitsType.null);
|
|
3743
|
+
else {
|
|
3744
|
+
archive.saveEntity(entt);
|
|
3745
|
+
const tuple = storage.getAsTuple(entt);
|
|
3746
|
+
for (let i = 0; i < tuple.length; ++i) archive.saveComponent(tuple[i]);
|
|
3747
|
+
}
|
|
3748
|
+
}
|
|
3749
|
+
} else for (const elem of storage.reach()) {
|
|
3750
|
+
archive.saveEntity(elem[0]);
|
|
3751
|
+
if (elem.length > 1) archive.saveComponent(elem[1]);
|
|
3752
|
+
}
|
|
3753
|
+
} else archive.saveSize(TraitsType.EntityType(0));
|
|
3754
|
+
return this;
|
|
3755
|
+
}
|
|
3756
|
+
getRange(archive, first, last, Type) {
|
|
3757
|
+
const [ComponentType] = destructKey(Type);
|
|
3758
|
+
assert(ComponentType !== EntityType, "Entity types not supported");
|
|
3759
|
+
const storage = this.reg.getStorage(Type, true);
|
|
3760
|
+
if (storage && !storage.empty()) {
|
|
3761
|
+
archive.saveSize(TraitsType.EntityType(distance(first, last)));
|
|
3762
|
+
first = first.clone();
|
|
3763
|
+
last = last.clone();
|
|
3764
|
+
for (; !first.equals(last); first.selfPlus()) {
|
|
3765
|
+
const entt = first.deref();
|
|
3766
|
+
if (storage.contains(entt)) {
|
|
3767
|
+
archive.saveEntity(entt);
|
|
3768
|
+
const tuple = storage.getAsTuple(entt);
|
|
3769
|
+
for (let i = 0; i < tuple.length; ++i) archive.saveComponent(tuple[i]);
|
|
3770
|
+
} else archive.saveEntity(TraitsType.null);
|
|
3771
|
+
}
|
|
3772
|
+
} else archive.saveSize(TraitsType.EntityType(0));
|
|
3773
|
+
return this;
|
|
3774
|
+
}
|
|
3775
|
+
}
|
|
3776
|
+
return BasicSnapshot;
|
|
3777
|
+
});
|
|
3778
|
+
const basicSnapshotLoaderTemplate = /* @__PURE__ */ defineTemplate(function(Registry$1) {
|
|
3779
|
+
const TraitsType = enttTraitsTemplate.instantiate(Registry$1.EntityType);
|
|
3780
|
+
const EntityType = Registry$1.EntityType;
|
|
3781
|
+
const newEntityType = createSafeNew(EntityType);
|
|
3782
|
+
class BasicSnapshotLoader extends Disposable {
|
|
3783
|
+
static TraitsType = TraitsType;
|
|
3784
|
+
static RegistryType = Registry$1;
|
|
3785
|
+
static EntityType = EntityType;
|
|
3786
|
+
reg;
|
|
3787
|
+
constructor(registry) {
|
|
3788
|
+
super();
|
|
3789
|
+
this.reg = registry;
|
|
3790
|
+
}
|
|
3791
|
+
dispose() {
|
|
3792
|
+
this.reg = null;
|
|
3793
|
+
}
|
|
3794
|
+
get(archive, Type) {
|
|
3795
|
+
const [ComponentType] = destructKey(Type);
|
|
3796
|
+
const storage = this.reg.getStorage(Type);
|
|
3797
|
+
const length = new Ref(TraitsType.EntityType(0));
|
|
3798
|
+
archive.loadSize(length);
|
|
3799
|
+
if (ComponentType === EntityType) {
|
|
3800
|
+
const count = new Ref(TraitsType.EntityType(0));
|
|
3801
|
+
let placeholder = newEntityType();
|
|
3802
|
+
storage.reserve(length.value);
|
|
3803
|
+
archive.loadSize(count);
|
|
3804
|
+
const entityRef = new Ref(TraitsType.null);
|
|
3805
|
+
for (; length.value > 0; --length.value) {
|
|
3806
|
+
archive.loadEntity(entityRef);
|
|
3807
|
+
storage.generate(entityRef.value);
|
|
3808
|
+
placeholder = entityRef.value > placeholder ? entityRef.value : placeholder;
|
|
3809
|
+
}
|
|
3810
|
+
storage.startFrom(TraitsType.next(placeholder));
|
|
3811
|
+
storage.freeList(count.value);
|
|
3812
|
+
} else {
|
|
3813
|
+
const other = this.reg.getStorage(EntityType);
|
|
3814
|
+
const enttRef = new Ref(TraitsType.null);
|
|
3815
|
+
const isEmptyStorage = componentTraitsTemplate.instantiate(storage.constructor.ElementType, storage.constructor.EntityType).pageSize === 0;
|
|
3816
|
+
const newComponentType = isEmptyStorage ? (() => void 0) : createSafeNew(ComponentType);
|
|
3817
|
+
while (length.value--) {
|
|
3818
|
+
archive.loadEntity(enttRef);
|
|
3819
|
+
if (!TraitsType.isNull(enttRef.value)) {
|
|
3820
|
+
const entity = other.contains(enttRef.value) ? enttRef.value : other.generate(enttRef.value);
|
|
3821
|
+
assert(TraitsType.toIntegral(entity) === TraitsType.toIntegral(enttRef.value), "Entity not available for use");
|
|
3822
|
+
if (isEmptyStorage) storage.emplace(entity);
|
|
3823
|
+
else {
|
|
3824
|
+
const compRef = new Ref(newComponentType());
|
|
3825
|
+
archive.loadComponent(compRef);
|
|
3826
|
+
storage.emplace(entity, compRef.value);
|
|
3827
|
+
}
|
|
3828
|
+
}
|
|
3829
|
+
}
|
|
3830
|
+
}
|
|
3831
|
+
return this;
|
|
3832
|
+
}
|
|
3833
|
+
orphans() {
|
|
3834
|
+
orphans(this.reg);
|
|
3835
|
+
return this;
|
|
3836
|
+
}
|
|
3837
|
+
}
|
|
3838
|
+
return BasicSnapshotLoader;
|
|
3839
|
+
});
|
|
3840
|
+
const basicContinuousLoaderTemplate = /* @__PURE__ */ defineTemplate(function(Registry$1) {
|
|
3841
|
+
const TraitsType = enttTraitsTemplate.instantiate(Registry$1.EntityType);
|
|
3842
|
+
const EntityType = Registry$1.EntityType;
|
|
3843
|
+
class BasicContinuousLoader extends Disposable {
|
|
3844
|
+
static RegistryType = Registry$1;
|
|
3845
|
+
static EntityType = EntityType;
|
|
3846
|
+
static TraitsType = TraitsType;
|
|
3847
|
+
remloc;
|
|
3848
|
+
reg;
|
|
3849
|
+
restore(entt) {
|
|
3850
|
+
const entity = TraitsType.toEntity(entt);
|
|
3851
|
+
const record = this.remloc.get(entity);
|
|
3852
|
+
if (record !== void 0 && TraitsType.toIntegral(record[0]) === TraitsType.toIntegral(entt)) {
|
|
3853
|
+
if (!this.reg.valid(record[1])) record[1] = this.reg.create();
|
|
3854
|
+
} else this.remloc.set(entity, [entt, this.reg.create()]);
|
|
3855
|
+
}
|
|
3856
|
+
constructor(registry) {
|
|
3857
|
+
super();
|
|
3858
|
+
this.remloc = /* @__PURE__ */ new Map();
|
|
3859
|
+
this.reg = registry;
|
|
3860
|
+
}
|
|
3861
|
+
dispose() {
|
|
3862
|
+
this.remloc.clear();
|
|
3863
|
+
this.reg = null;
|
|
3864
|
+
}
|
|
3865
|
+
get(archive, Type) {
|
|
3866
|
+
const [ComponentType] = destructKey(Type);
|
|
3867
|
+
const storage = this.reg.getStorage(Type);
|
|
3868
|
+
const length = new Ref(TraitsType.EntityType(0));
|
|
3869
|
+
const enttRef = new Ref(TraitsType.null);
|
|
3870
|
+
archive.loadSize(length);
|
|
3871
|
+
if (ComponentType === EntityType) {
|
|
3872
|
+
const inUse = new Ref(TraitsType.EntityType(0));
|
|
3873
|
+
storage.reserve(length.value);
|
|
3874
|
+
archive.loadSize(inUse);
|
|
3875
|
+
for (let pos = 0; pos < inUse.value; ++pos) {
|
|
3876
|
+
archive.loadEntity(enttRef);
|
|
3877
|
+
this.restore(enttRef.value);
|
|
3878
|
+
}
|
|
3879
|
+
for (let pos = inUse.value; pos < length.value; ++pos) {
|
|
3880
|
+
archive.loadEntity(enttRef);
|
|
3881
|
+
const entity = TraitsType.toEntity(enttRef.value);
|
|
3882
|
+
const record = this.remloc.get(entity);
|
|
3883
|
+
if (record !== void 0) {
|
|
3884
|
+
if (this.reg.valid(record[1])) this.reg.destroy(record[1]);
|
|
3885
|
+
this.remloc.delete(entity);
|
|
3886
|
+
}
|
|
3887
|
+
}
|
|
3888
|
+
} else {
|
|
3889
|
+
for (const record of this.remloc.values()) storage.remove(record[1]);
|
|
3890
|
+
const isEmptyStorage = componentTraitsTemplate.instantiate(storage.constructor.ElementType, storage.constructor.EntityType).pageSize === 0;
|
|
3891
|
+
const newComponentType = isEmptyStorage ? (() => void 0) : createSafeNew(ComponentType);
|
|
3892
|
+
while (length.value--) {
|
|
3893
|
+
archive.loadEntity(enttRef);
|
|
3894
|
+
if (!TraitsType.isNull(enttRef.value)) {
|
|
3895
|
+
this.restore(enttRef.value);
|
|
3896
|
+
if (isEmptyStorage) storage.emplace(this.map(enttRef.value));
|
|
3897
|
+
else {
|
|
3898
|
+
const compRef = new Ref(newComponentType());
|
|
3899
|
+
archive.loadComponent(compRef);
|
|
3900
|
+
storage.emplace(this.map(enttRef.value), compRef.value);
|
|
3901
|
+
}
|
|
3902
|
+
}
|
|
3903
|
+
}
|
|
3904
|
+
}
|
|
3905
|
+
return this;
|
|
3906
|
+
}
|
|
3907
|
+
orphans() {
|
|
3908
|
+
orphans(this.reg);
|
|
3909
|
+
return this;
|
|
3910
|
+
}
|
|
3911
|
+
contains(entt) {
|
|
3912
|
+
const record = this.remloc.get(TraitsType.toEntity(entt));
|
|
3913
|
+
return record !== void 0 && TraitsType.toIntegral(record[0]) === TraitsType.toIntegral(entt);
|
|
3914
|
+
}
|
|
3915
|
+
map(entt) {
|
|
3916
|
+
const record = this.remloc.get(TraitsType.toEntity(entt));
|
|
3917
|
+
if (record !== void 0 && TraitsType.toIntegral(record[0]) === TraitsType.toIntegral(entt)) return record[1];
|
|
3918
|
+
return TraitsType.null;
|
|
3919
|
+
}
|
|
3920
|
+
}
|
|
3921
|
+
return BasicContinuousLoader;
|
|
3922
|
+
});
|
|
3923
|
+
const Snapshot = /* @__PURE__ */ (() => basicSnapshotTemplate.instantiate(Registry))();
|
|
3924
|
+
const SnapshotLoader = /* @__PURE__ */ (() => basicSnapshotLoaderTemplate.instantiate(Registry))();
|
|
3925
|
+
const ContinuousLoader = /* @__PURE__ */ (() => basicContinuousLoaderTemplate.instantiate(Registry))();
|
|
3926
|
+
|
|
3927
|
+
//#endregion
|
|
3928
|
+
//#region src/index.ts
|
|
3929
|
+
const version = "0.0.0";
|
|
3930
|
+
|
|
3931
|
+
//#endregion
|
|
3932
|
+
exports.AggregatePointer = AggregatePointer;
|
|
3933
|
+
exports.ArrayPointer = ArrayPointer;
|
|
3934
|
+
exports.ArrayRange = ArrayRange;
|
|
3935
|
+
exports.BasicDispatcher = BasicDispatcher;
|
|
3936
|
+
exports.Connection = Connection;
|
|
3937
|
+
exports.ContinuousLoader = ContinuousLoader;
|
|
3938
|
+
exports.Delegate = Delegate;
|
|
3939
|
+
exports.DeletionPolicy = DeletionPolicy;
|
|
3940
|
+
exports.Disposable = Disposable;
|
|
3941
|
+
exports.Emitter = Emitter;
|
|
3942
|
+
exports.EmptyTypeOptimization = EmptyTypeOptimization;
|
|
3943
|
+
exports.Entity = Entity;
|
|
3944
|
+
exports.Float32 = Float32;
|
|
3945
|
+
exports.Float64 = Float64;
|
|
3946
|
+
exports.GroupDescriptor = GroupDescriptor;
|
|
3947
|
+
exports.Int16 = Int16;
|
|
3948
|
+
exports.Int32 = Int32;
|
|
3949
|
+
exports.Int64 = Int64;
|
|
3950
|
+
exports.Int8 = Int8;
|
|
3951
|
+
exports.NotConstructorError = NotConstructorError;
|
|
3952
|
+
exports.RangeIterator = RangeIterator;
|
|
3953
|
+
exports.Registry = Registry;
|
|
3954
|
+
exports.ReversePointer = ReversePointer;
|
|
3955
|
+
exports.RuntimeView = RuntimeView;
|
|
3956
|
+
exports.RuntimeViewIterator = RuntimeViewIterator;
|
|
3957
|
+
exports.ScopedConnection = ScopedConnection;
|
|
3958
|
+
exports.Sigh = Sigh;
|
|
3959
|
+
exports.Sink = Sink;
|
|
3960
|
+
exports.Snapshot = Snapshot;
|
|
3961
|
+
exports.SnapshotLoader = SnapshotLoader;
|
|
3962
|
+
exports.SparseSet = SparseSet;
|
|
3963
|
+
exports.SparseSetPointer = SparseSetPointer;
|
|
3964
|
+
exports.StoragePointer = StoragePointer;
|
|
3965
|
+
exports.Template = Template;
|
|
3966
|
+
exports.Uint16 = Uint16;
|
|
3967
|
+
exports.Uint32 = Uint32;
|
|
3968
|
+
exports.Uint64 = Uint64;
|
|
3969
|
+
exports.Uint8 = Uint8;
|
|
3970
|
+
exports.basicContinuousLoaderTemplate = basicContinuousLoaderTemplate;
|
|
3971
|
+
exports.basicEnttTraitsTemplate = basicEnttTraitsTemplate;
|
|
3972
|
+
exports.basicGroupTemplate = basicGroupTemplate;
|
|
3973
|
+
exports.basicRegistryTemplate = basicRegistryTemplate;
|
|
3974
|
+
exports.basicRuntimeViewTemplate = basicRuntimeViewTemplate;
|
|
3975
|
+
exports.basicSighMixinTemplate = basicSighMixinTemplate;
|
|
3976
|
+
exports.basicSnapshotLoaderTemplate = basicSnapshotLoaderTemplate;
|
|
3977
|
+
exports.basicSnapshotTemplate = basicSnapshotTemplate;
|
|
3978
|
+
exports.basicSparseSetTemplate = basicSparseSetTemplate;
|
|
3979
|
+
exports.basicStorageTemplate = basicStorageTemplate;
|
|
3980
|
+
exports.basicViewTemplate = basicViewTemplate;
|
|
3981
|
+
exports.commonType = commonType;
|
|
3982
|
+
exports.componentTraitsTemplate = componentTraitsTemplate;
|
|
3983
|
+
exports.config = config;
|
|
3984
|
+
exports.createSafeNew = createSafeNew;
|
|
3985
|
+
exports.defineTemplate = defineTemplate;
|
|
3986
|
+
exports.directCall = directCall;
|
|
3987
|
+
exports.distance = distance;
|
|
3988
|
+
exports.enttTraitsTemplate = enttTraitsTemplate;
|
|
3989
|
+
exports.insertionSort = insertionSort;
|
|
3990
|
+
exports.internalEnttTraits = internalEnttTraits;
|
|
3991
|
+
exports.isEmptyClass = isEmptyClass;
|
|
3992
|
+
exports.makeGroup = makeGroup;
|
|
3993
|
+
exports.makeRangePointer = makeRangePointer;
|
|
3994
|
+
exports.makeReversePointer = makeReversePointer;
|
|
3995
|
+
exports.makeView = makeView;
|
|
3996
|
+
exports.stdSort = defaultSort;
|
|
3997
|
+
exports.storageTemplate = storageTemplate;
|
|
3998
|
+
exports.storageTypeTTemplate = storageTypeTTemplate;
|
|
3999
|
+
exports.storageTypeTemplate = storageTypeTemplate;
|
|
4000
|
+
exports.toIterator = toIterator;
|
|
4001
|
+
exports.toRange = toRange;
|
|
4002
|
+
exports.version = version;
|
|
4003
|
+
return exports;
|
|
4004
|
+
})({});
|