@driftengine/entities 4.8.1 → 4.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/prefab.d.ts +7 -0
- package/dist/prefab.js +15 -0
- package/dist/store.d.ts +2 -0
- package/dist/store.js +13 -0
- package/package.json +2 -2
- package/src/prefab.ts +16 -0
- package/src/store.ts +13 -0
package/dist/prefab.d.ts
CHANGED
|
@@ -16,6 +16,13 @@ export interface Prefab {
|
|
|
16
16
|
readonly name: string;
|
|
17
17
|
readonly components: readonly (readonly [ComponentType, Readonly<Record<string, unknown>>])[];
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* A prefab, refused here if it names a field one of its components does not have.
|
|
21
|
+
*
|
|
22
|
+
* **At definition rather than at the first spawn**, which is the same refusal `World.add` makes,
|
|
23
|
+
* moved to where a game builds its content: a misspelt field found the first time a rare enemy
|
|
24
|
+
* spawns is found by a player.
|
|
25
|
+
*/
|
|
19
26
|
export declare function definePrefab(name: string, components: readonly (readonly [ComponentType, Readonly<Record<string, unknown>>])[]): Prefab;
|
|
20
27
|
/**
|
|
21
28
|
* Make one.
|
package/dist/prefab.js
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A prefab, refused here if it names a field one of its components does not have.
|
|
3
|
+
*
|
|
4
|
+
* **At definition rather than at the first spawn**, which is the same refusal `World.add` makes,
|
|
5
|
+
* moved to where a game builds its content: a misspelt field found the first time a rare enemy
|
|
6
|
+
* spawns is found by a player.
|
|
7
|
+
*/
|
|
1
8
|
export function definePrefab(name, components) {
|
|
9
|
+
for (const [type, values] of components) {
|
|
10
|
+
for (const field of Object.keys(values)) {
|
|
11
|
+
if (type.schema.fields.some((declared) => declared.name === field))
|
|
12
|
+
continue;
|
|
13
|
+
throw new Error(`\`${name}\` gives \`${type.name}\` a field \`${field}\` it does not have. It has ` +
|
|
14
|
+
`${type.schema.fields.map((declared) => `\`${declared.name}\``).join(', ')}.`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
2
17
|
return { name, components };
|
|
3
18
|
}
|
|
4
19
|
/**
|
package/dist/store.d.ts
CHANGED
|
@@ -124,6 +124,8 @@ export declare class ComponentStore {
|
|
|
124
124
|
* not carry an object per field name it will never hand out.
|
|
125
125
|
*/
|
|
126
126
|
private viewObject;
|
|
127
|
+
/** The schema's own field names, which a value handed to `add` must be among. */
|
|
128
|
+
private readonly fieldNames;
|
|
127
129
|
constructor(type: ComponentType, options?: ComponentStoreOptions);
|
|
128
130
|
get size(): number;
|
|
129
131
|
/** The entities this store holds, oldest first. Valid up to `size`; the rest is capacity. */
|
package/dist/store.js
CHANGED
|
@@ -184,12 +184,15 @@ export class ComponentStore {
|
|
|
184
184
|
* not carry an object per field name it will never hand out.
|
|
185
185
|
*/
|
|
186
186
|
viewObject = null;
|
|
187
|
+
/** The schema's own field names, which a value handed to `add` must be among. */
|
|
188
|
+
fieldNames = new Set();
|
|
187
189
|
constructor(type, options = {}) {
|
|
188
190
|
this.type = type;
|
|
189
191
|
const capacity = Math.max(1, options.capacity ?? 16);
|
|
190
192
|
this.denseArray = new Float64Array(capacity);
|
|
191
193
|
this.sparse = new Int32Array(64).fill(-1);
|
|
192
194
|
for (const field of type.schema.fields) {
|
|
195
|
+
this.fieldNames.add(field.name);
|
|
193
196
|
const inner = optionInner(field.type);
|
|
194
197
|
const declared = inner ?? field.type;
|
|
195
198
|
/* A discriminant is an integer, so it takes an integer column rather than being boxed. */
|
|
@@ -247,6 +250,16 @@ export class ComponentStore {
|
|
|
247
250
|
this.write(entity, field, value);
|
|
248
251
|
return;
|
|
249
252
|
}
|
|
253
|
+
/*
|
|
254
|
+
* **A key the schema does not declare is refused before anything is stored**, as `write` and
|
|
255
|
+
* `defineComponent`'s defaults refuse one. The loop below walks the schema and never looked at
|
|
256
|
+
* the other keys, so a misspelt field was dropped without a word and the field it meant took
|
|
257
|
+
* its default; one consumer's had been dropped since the component was written.
|
|
258
|
+
*/
|
|
259
|
+
for (const field in values) {
|
|
260
|
+
if (!this.fieldNames.has(field))
|
|
261
|
+
throw new Error(this.noField(field));
|
|
262
|
+
}
|
|
250
263
|
const at = this.count;
|
|
251
264
|
this.grow(at + 1);
|
|
252
265
|
this.growSparse(entityIndex(entity) + 1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@driftengine/entities",
|
|
3
|
-
"version": "4.8.
|
|
3
|
+
"version": "4.8.3",
|
|
4
4
|
"description": "Entities with generational identity, component storage, systems and scenes",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
],
|
|
28
28
|
"sideEffects": false,
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"driftscript": "1.
|
|
30
|
+
"driftscript": "1.17.0"
|
|
31
31
|
},
|
|
32
32
|
"author": "Drift Technologies",
|
|
33
33
|
"repository": {
|
package/src/prefab.ts
CHANGED
|
@@ -18,10 +18,26 @@ export interface Prefab {
|
|
|
18
18
|
readonly components: readonly (readonly [ComponentType, Readonly<Record<string, unknown>>])[];
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* A prefab, refused here if it names a field one of its components does not have.
|
|
23
|
+
*
|
|
24
|
+
* **At definition rather than at the first spawn**, which is the same refusal `World.add` makes,
|
|
25
|
+
* moved to where a game builds its content: a misspelt field found the first time a rare enemy
|
|
26
|
+
* spawns is found by a player.
|
|
27
|
+
*/
|
|
21
28
|
export function definePrefab(
|
|
22
29
|
name: string,
|
|
23
30
|
components: readonly (readonly [ComponentType, Readonly<Record<string, unknown>>])[],
|
|
24
31
|
): Prefab {
|
|
32
|
+
for (const [type, values] of components) {
|
|
33
|
+
for (const field of Object.keys(values)) {
|
|
34
|
+
if (type.schema.fields.some((declared) => declared.name === field)) continue;
|
|
35
|
+
throw new Error(
|
|
36
|
+
`\`${name}\` gives \`${type.name}\` a field \`${field}\` it does not have. It has ` +
|
|
37
|
+
`${type.schema.fields.map((declared) => `\`${declared.name}\``).join(', ')}.`,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
25
41
|
return { name, components };
|
|
26
42
|
}
|
|
27
43
|
|
package/src/store.ts
CHANGED
|
@@ -312,12 +312,16 @@ export class ComponentStore {
|
|
|
312
312
|
*/
|
|
313
313
|
private viewObject: ComponentView | null = null;
|
|
314
314
|
|
|
315
|
+
/** The schema's own field names, which a value handed to `add` must be among. */
|
|
316
|
+
private readonly fieldNames = new Set<string>();
|
|
317
|
+
|
|
315
318
|
constructor(type: ComponentType, options: ComponentStoreOptions = {}) {
|
|
316
319
|
this.type = type;
|
|
317
320
|
const capacity = Math.max(1, options.capacity ?? 16);
|
|
318
321
|
this.denseArray = new Float64Array(capacity);
|
|
319
322
|
this.sparse = new Int32Array(64).fill(-1);
|
|
320
323
|
for (const field of type.schema.fields) {
|
|
324
|
+
this.fieldNames.add(field.name);
|
|
321
325
|
const inner = optionInner(field.type);
|
|
322
326
|
const declared = inner ?? field.type;
|
|
323
327
|
/* A discriminant is an integer, so it takes an integer column rather than being boxed. */
|
|
@@ -381,6 +385,15 @@ export class ComponentStore {
|
|
|
381
385
|
for (const [field, value] of Object.entries(values)) this.write(entity, field, value);
|
|
382
386
|
return;
|
|
383
387
|
}
|
|
388
|
+
/*
|
|
389
|
+
* **A key the schema does not declare is refused before anything is stored**, as `write` and
|
|
390
|
+
* `defineComponent`'s defaults refuse one. The loop below walks the schema and never looked at
|
|
391
|
+
* the other keys, so a misspelt field was dropped without a word and the field it meant took
|
|
392
|
+
* its default; one consumer's had been dropped since the component was written.
|
|
393
|
+
*/
|
|
394
|
+
for (const field in values) {
|
|
395
|
+
if (!this.fieldNames.has(field)) throw new Error(this.noField(field));
|
|
396
|
+
}
|
|
384
397
|
|
|
385
398
|
const at = this.count;
|
|
386
399
|
this.grow(at + 1);
|