@vworlds/vecs 1.0.15 → 1.0.16
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 +249 -119
- package/dist/component.d.ts +52 -76
- package/dist/component.js +60 -45
- package/dist/component.js.map +1 -1
- package/dist/component_meta.d.ts +98 -0
- package/dist/component_meta.js +65 -0
- package/dist/component_meta.js.map +1 -0
- package/dist/dsl.d.ts +46 -34
- package/dist/dsl.js +459 -61
- package/dist/dsl.js.map +1 -1
- package/dist/entity/entity.base.d.ts +57 -0
- package/dist/entity/entity.base.js +81 -0
- package/dist/entity/entity.base.js.map +1 -0
- package/dist/entity/entity.components.d.ts +117 -0
- package/dist/entity/entity.components.js +244 -0
- package/dist/entity/entity.components.js.map +1 -0
- package/dist/entity/entity.d.ts +35 -0
- package/dist/entity/entity.identity.d.ts +8 -0
- package/dist/entity/entity.identity.js +15 -0
- package/dist/entity/entity.identity.js.map +1 -0
- package/dist/entity/entity.js +33 -0
- package/dist/entity/entity.js.map +1 -0
- package/dist/entity/entity.lifecycle.d.ts +12 -0
- package/dist/entity/entity.lifecycle.js +111 -0
- package/dist/entity/entity.lifecycle.js.map +1 -0
- package/dist/entity/entity.queries.d.ts +3 -0
- package/dist/entity/entity.queries.js +33 -0
- package/dist/entity/entity.queries.js.map +1 -0
- package/dist/entity/entity.relationships.d.ts +9 -0
- package/dist/entity/entity.relationships.js +74 -0
- package/dist/entity/entity.relationships.js.map +1 -0
- package/dist/entity/index.d.ts +2 -0
- package/dist/entity/index.js +3 -0
- package/dist/entity/index.js.map +1 -0
- package/dist/filter.d.ts +27 -8
- package/dist/filter.js +33 -18
- package/dist/filter.js.map +1 -1
- package/dist/index.d.ts +13 -5
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/inject.d.ts +80 -0
- package/dist/inject.js +270 -0
- package/dist/inject.js.map +1 -0
- package/dist/module.d.ts +23 -0
- package/dist/module.js +17 -0
- package/dist/module.js.map +1 -0
- package/dist/modules/identity.d.ts +15 -0
- package/dist/modules/identity.js +41 -0
- package/dist/modules/identity.js.map +1 -0
- package/dist/modules/singleton.d.ts +26 -0
- package/dist/modules/singleton.js +41 -0
- package/dist/modules/singleton.js.map +1 -0
- package/dist/package.json +12 -1
- package/dist/phase.d.ts +2 -2
- package/dist/query/index.d.ts +6 -0
- package/dist/query/index.js +5 -0
- package/dist/query/index.js.map +1 -0
- package/dist/query/query.00.base.d.ts +23 -0
- package/dist/query/query.00.base.js +77 -0
- package/dist/query/query.00.base.js.map +1 -0
- package/dist/query/query.01.reactive.d.ts +7 -0
- package/dist/query/query.01.reactive.js +58 -0
- package/dist/query/query.01.reactive.js.map +1 -0
- package/dist/query/query.02.lifecycle.d.ts +6 -0
- package/dist/query/query.02.lifecycle.js +63 -0
- package/dist/query/query.02.lifecycle.js.map +1 -0
- package/dist/query/query.03.tracking.d.ts +15 -0
- package/dist/query/query.03.tracking.js +31 -0
- package/dist/query/query.03.tracking.js.map +1 -0
- package/dist/query/query.04.callbacks.d.ts +14 -0
- package/dist/query/query.04.callbacks.js +65 -0
- package/dist/query/query.04.callbacks.js.map +1 -0
- package/dist/query/query.05.updates.d.ts +14 -0
- package/dist/query/query.05.updates.js +81 -0
- package/dist/query/query.05.updates.js.map +1 -0
- package/dist/query/query.06.predicate.d.ts +13 -0
- package/dist/query/query.06.predicate.js +40 -0
- package/dist/query/query.06.predicate.js.map +1 -0
- package/dist/query/query.07.groups.d.ts +41 -0
- package/dist/query/query.07.groups.js +110 -0
- package/dist/query/query.07.groups.js.map +1 -0
- package/dist/query/query.d.ts +53 -0
- package/dist/query/query.js +138 -0
- package/dist/query/query.js.map +1 -0
- package/dist/relationship.d.ts +19 -0
- package/dist/relationship.js +18 -0
- package/dist/relationship.js.map +1 -0
- package/dist/system.d.ts +37 -23
- package/dist/system.js +80 -64
- package/dist/system.js.map +1 -1
- package/dist/terms/all_term.d.ts +32 -0
- package/dist/terms/all_term.js +41 -0
- package/dist/terms/all_term.js.map +1 -0
- package/dist/terms/any_term.d.ts +33 -0
- package/dist/terms/any_term.js +42 -0
- package/dist/terms/any_term.js.map +1 -0
- package/dist/terms/build.d.ts +62 -0
- package/dist/terms/build.js +382 -0
- package/dist/terms/build.js.map +1 -0
- package/dist/terms/component_term.d.ts +37 -0
- package/dist/terms/component_term.js +49 -0
- package/dist/terms/component_term.js.map +1 -0
- package/dist/terms/empty_term.d.ts +6 -0
- package/dist/terms/empty_term.js +12 -0
- package/dist/terms/empty_term.js.map +1 -0
- package/dist/terms/index.d.ts +11 -0
- package/dist/terms/index.js +12 -0
- package/dist/terms/index.js.map +1 -0
- package/dist/terms/not_term.d.ts +35 -0
- package/dist/terms/not_term.js +47 -0
- package/dist/terms/not_term.js.map +1 -0
- package/dist/terms/only_term.d.ts +47 -0
- package/dist/terms/only_term.js +79 -0
- package/dist/terms/only_term.js.map +1 -0
- package/dist/terms/predicate_term.d.ts +80 -0
- package/dist/terms/predicate_term.js +109 -0
- package/dist/terms/predicate_term.js.map +1 -0
- package/dist/terms/target_term.d.ts +43 -0
- package/dist/terms/target_term.js +87 -0
- package/dist/terms/target_term.js.map +1 -0
- package/dist/terms/term.d.ts +94 -0
- package/dist/terms/term.js +202 -0
- package/dist/terms/term.js.map +1 -0
- package/dist/terms/world_term.d.ts +68 -0
- package/dist/terms/world_term.js +99 -0
- package/dist/terms/world_term.js.map +1 -0
- package/dist/timer.js +2 -2
- package/dist/timer.js.map +1 -1
- package/dist/util/array_map.js +12 -0
- package/dist/util/array_map.js.map +1 -1
- package/dist/util/bitset.js +107 -22
- package/dist/util/bitset.js.map +1 -1
- package/dist/util/dense_set.d.ts +1 -0
- package/dist/util/dense_set.js +90 -0
- package/dist/util/dense_set.js.map +1 -0
- package/dist/util/id_pool.d.ts +23 -0
- package/dist/util/id_pool.js +194 -0
- package/dist/util/id_pool.js.map +1 -0
- package/dist/world/index.d.ts +3 -0
- package/dist/world/index.js +3 -0
- package/dist/world/index.js.map +1 -0
- package/dist/world/world.base.d.ts +6 -0
- package/dist/world/world.base.js +21 -0
- package/dist/world/world.base.js.map +1 -0
- package/dist/world/world.components.d.ts +67 -0
- package/dist/world/world.components.js +93 -0
- package/dist/world/world.components.js.map +1 -0
- package/dist/world/world.d.ts +29 -0
- package/dist/world/world.deferred.d.ts +13 -0
- package/dist/world/world.deferred.js +93 -0
- package/dist/world/world.deferred.js.map +1 -0
- package/dist/world/world.entities.d.ts +18 -0
- package/dist/world/world.entities.js +97 -0
- package/dist/world/world.entities.js.map +1 -0
- package/dist/world/world.js +39 -0
- package/dist/world/world.js.map +1 -0
- package/dist/world/world.modules.d.ts +12 -0
- package/dist/world/world.modules.js +21 -0
- package/dist/world/world.modules.js.map +1 -0
- package/dist/world/world.pipeline.d.ts +21 -0
- package/dist/world/world.pipeline.js +105 -0
- package/dist/world/world.pipeline.js.map +1 -0
- package/dist/world/world.pools.d.ts +9 -0
- package/dist/world/world.pools.js +59 -0
- package/dist/world/world.pools.js.map +1 -0
- package/dist/world/world.queries.d.ts +18 -0
- package/dist/world/world.queries.js +101 -0
- package/dist/world/world.queries.js.map +1 -0
- package/dist/world/world.storage.d.ts +7 -0
- package/dist/world/world.storage.js +26 -0
- package/dist/world/world.storage.js.map +1 -0
- package/package.json +12 -1
- package/dist/entity.d.ts +0 -215
- package/dist/entity.js +0 -457
- package/dist/entity.js.map +0 -1
- package/dist/query.d.ts +0 -251
- package/dist/query.js +0 -353
- package/dist/query.js.map +0 -1
- package/dist/world.d.ts +0 -389
- package/dist/world.js +0 -631
- package/dist/world.js.map +0 -1
package/dist/component.d.ts
CHANGED
|
@@ -1,86 +1,62 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export type ComponentClass<T extends Component = Component> = new () => T;
|
|
7
|
-
/** A component class constructor or its numeric type id. */
|
|
8
|
-
export type ComponentClassOrType = number | ComponentClass;
|
|
9
|
-
/**
|
|
10
|
-
* Lifecycle hook for a registered component class. Obtained via
|
|
11
|
-
* {@link World.hook}.
|
|
12
|
-
*
|
|
13
|
-
* Hooks are a lightweight alternative to building a {@link System} when all
|
|
14
|
-
* you need is a callback on add / remove / set for a single component type.
|
|
15
|
-
* The same `Hook` is returned on every call to `world.hook(C)`, so registration
|
|
16
|
-
* methods chain:
|
|
17
|
-
*
|
|
18
|
-
* ```ts
|
|
19
|
-
* world.hook(Sprite)
|
|
20
|
-
* .onAdd((e, c) => initSprite(e, c))
|
|
21
|
-
* .onRemove((e, c) => destroySprite(e, c))
|
|
22
|
-
* .onSet((e, c) => syncSprite(e, c));
|
|
23
|
-
* ```
|
|
24
|
-
*
|
|
25
|
-
* Callbacks fire synchronously when the corresponding entity command is
|
|
26
|
-
* applied: inline outside deferred mode, or while the world drains its command
|
|
27
|
-
* queue inside a system / `forEach` / `defer` block.
|
|
28
|
-
*
|
|
29
|
-
* @typeParam C - Component class this hook is bound to.
|
|
30
|
-
*/
|
|
31
|
-
export interface Hook<C extends Component = Component> {
|
|
1
|
+
import { Entity } from "./entity/index.js";
|
|
2
|
+
import type { ComponentType } from "./component_meta.js";
|
|
3
|
+
export { CleanupPolicy, ComponentMeta, type ComponentClass, type ComponentInstance, type ComponentRef, type ComponentRefArray, type ComponentType, type Hook, } from "./component_meta.js";
|
|
4
|
+
/** A component entity created by {@link World.component}. */
|
|
5
|
+
export declare class Component<T extends ComponentType = ComponentType> extends Entity {
|
|
32
6
|
/**
|
|
33
|
-
* Register a
|
|
34
|
-
* to an entity (`entity.add(C)` or `entity.set(C, ...)` on an entity that
|
|
35
|
-
* does not yet have the component).
|
|
7
|
+
* Register a callback fired each time this component is **added** to an entity.
|
|
36
8
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
9
|
+
* The handler is called with the owning entity and the freshly created
|
|
10
|
+
* component instance. Use it to initialise external state (e.g. scene objects)
|
|
11
|
+
* that should exist for the lifetime of the component.
|
|
12
|
+
*
|
|
13
|
+
* @param handler - Callback invoked with `(entity, componentInstance)`.
|
|
14
|
+
* @returns This `Component` entity, for chaining.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* world.component(Sprite).onAdd((entity, sprite) => sprite.initialize(scene));
|
|
19
|
+
* ```
|
|
39
20
|
*/
|
|
40
|
-
onAdd(handler: (entity: Entity, c:
|
|
21
|
+
onAdd(handler: (entity: Entity, c: InstanceType<T>) => void): this;
|
|
41
22
|
/**
|
|
42
|
-
* Register a
|
|
43
|
-
*
|
|
44
|
-
*
|
|
23
|
+
* Register a callback fired each time this component is **removed** from an
|
|
24
|
+
* entity, or when the owning entity is destroyed.
|
|
25
|
+
*
|
|
26
|
+
* The handler is called with the owning entity and the component instance that
|
|
27
|
+
* is about to be detached. Use it to clean up any external state associated
|
|
28
|
+
* with the component.
|
|
29
|
+
*
|
|
30
|
+
* @param handler - Callback invoked with `(entity, componentInstance)`.
|
|
31
|
+
* @returns This `Component` entity, for chaining.
|
|
45
32
|
*
|
|
46
|
-
* @
|
|
47
|
-
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* world.component(Sprite).onRemove((entity, sprite) => sprite.destroy(scene));
|
|
36
|
+
* ```
|
|
48
37
|
*/
|
|
49
|
-
onRemove(handler: (entity: Entity, c:
|
|
38
|
+
onRemove(handler: (entity: Entity, c: InstanceType<T>) => void): this;
|
|
50
39
|
/**
|
|
51
|
-
* Register a
|
|
52
|
-
*
|
|
53
|
-
* `entity.set(C, props)` is called on an entity that already has the
|
|
54
|
-
* component.
|
|
40
|
+
* Register a callback fired each time this component's data is **set or
|
|
41
|
+
* modified**.
|
|
55
42
|
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
43
|
+
* Fires when:
|
|
44
|
+
* - `entity.set(C, props)` applies data to the component.
|
|
45
|
+
* - `entity.attach(instance)` stores an existing instance.
|
|
46
|
+
* - `entity.modified(C)` is called after in-place mutation.
|
|
47
|
+
* - A system's `getMut(C)` marks the component dirty.
|
|
48
|
+
*
|
|
49
|
+
* The handler receives the owning entity and the current component instance.
|
|
50
|
+
* Component instances do not carry entity references, which is why the entity
|
|
51
|
+
* is passed explicitly.
|
|
52
|
+
*
|
|
53
|
+
* @param handler - Callback invoked with `(entity, componentInstance)`.
|
|
54
|
+
* @returns This `Component` entity, for chaining.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* world.component(Transform).onSet((entity, t) => renderer.syncTransform(entity.eid, t));
|
|
59
|
+
* ```
|
|
58
60
|
*/
|
|
59
|
-
onSet(handler: (entity: Entity, c:
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Bookkeeping record produced for each component class registered via
|
|
63
|
-
* {@link World.registerComponent}.
|
|
64
|
-
*
|
|
65
|
-
* Holds the constructor, numeric type id, display name, and pre-computed
|
|
66
|
-
* {@link BitPtr} used by archetype checks. Implements {@link Hook}, so the
|
|
67
|
-
* lifecycle handlers attached via `world.hook(C)` are stored directly on the
|
|
68
|
-
* meta object.
|
|
69
|
-
*/
|
|
70
|
-
export declare class ComponentMeta implements Hook<Component> {
|
|
71
|
-
/** The component class constructor this meta represents. */
|
|
72
|
-
readonly Class: ComponentClass;
|
|
73
|
-
/** Numeric type id assigned at registration time. */
|
|
74
|
-
readonly type: number;
|
|
75
|
-
/** Human-readable name used in logs and serialization lookups. */
|
|
76
|
-
readonly componentName: string;
|
|
77
|
-
/** Pre-computed bit-pointer into the entity archetype {@link Bitset}. */
|
|
78
|
-
readonly bitPtr: BitPtr;
|
|
79
|
-
constructor(Class: ComponentClass, type: number, componentName: string);
|
|
80
|
-
/** @inheritdoc */
|
|
81
|
-
onAdd(handler: (entity: Entity, c: Component) => void): ComponentMeta;
|
|
82
|
-
/** @inheritdoc */
|
|
83
|
-
onRemove(handler: (entity: Entity, c: Component) => void): ComponentMeta;
|
|
84
|
-
/** @inheritdoc */
|
|
85
|
-
onSet(handler: (entity: Entity, c: Component) => void): ComponentMeta;
|
|
61
|
+
onSet(handler: (entity: Entity, c: InstanceType<T>) => void): this;
|
|
86
62
|
}
|
package/dist/component.js
CHANGED
|
@@ -1,56 +1,71 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
this.type = type;
|
|
21
|
-
this.componentName = componentName;
|
|
22
|
-
this.bitPtr = new BitPtr(type);
|
|
23
|
-
}
|
|
24
|
-
/** @inheritdoc */
|
|
1
|
+
import { Entity } from "./entity/index.js";
|
|
2
|
+
export { CleanupPolicy, ComponentMeta, } from "./component_meta.js";
|
|
3
|
+
/** A component entity created by {@link World.component}. */
|
|
4
|
+
export class Component extends Entity {
|
|
5
|
+
/**
|
|
6
|
+
* Register a callback fired each time this component is **added** to an entity.
|
|
7
|
+
*
|
|
8
|
+
* The handler is called with the owning entity and the freshly created
|
|
9
|
+
* component instance. Use it to initialise external state (e.g. scene objects)
|
|
10
|
+
* that should exist for the lifetime of the component.
|
|
11
|
+
*
|
|
12
|
+
* @param handler - Callback invoked with `(entity, componentInstance)`.
|
|
13
|
+
* @returns This `Component` entity, for chaining.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* world.component(Sprite).onAdd((entity, sprite) => sprite.initialize(scene));
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
25
20
|
onAdd(handler) {
|
|
26
|
-
|
|
21
|
+
this.ownMeta.onAdd(handler);
|
|
27
22
|
return this;
|
|
28
23
|
}
|
|
29
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* Register a callback fired each time this component is **removed** from an
|
|
26
|
+
* entity, or when the owning entity is destroyed.
|
|
27
|
+
*
|
|
28
|
+
* The handler is called with the owning entity and the component instance that
|
|
29
|
+
* is about to be detached. Use it to clean up any external state associated
|
|
30
|
+
* with the component.
|
|
31
|
+
*
|
|
32
|
+
* @param handler - Callback invoked with `(entity, componentInstance)`.
|
|
33
|
+
* @returns This `Component` entity, for chaining.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* world.component(Sprite).onRemove((entity, sprite) => sprite.destroy(scene));
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
30
40
|
onRemove(handler) {
|
|
31
|
-
|
|
41
|
+
this.ownMeta.onRemove(handler);
|
|
32
42
|
return this;
|
|
33
43
|
}
|
|
34
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* Register a callback fired each time this component's data is **set or
|
|
46
|
+
* modified**.
|
|
47
|
+
*
|
|
48
|
+
* Fires when:
|
|
49
|
+
* - `entity.set(C, props)` applies data to the component.
|
|
50
|
+
* - `entity.attach(instance)` stores an existing instance.
|
|
51
|
+
* - `entity.modified(C)` is called after in-place mutation.
|
|
52
|
+
* - A system's `getMut(C)` marks the component dirty.
|
|
53
|
+
*
|
|
54
|
+
* The handler receives the owning entity and the current component instance.
|
|
55
|
+
* Component instances do not carry entity references, which is why the entity
|
|
56
|
+
* is passed explicitly.
|
|
57
|
+
*
|
|
58
|
+
* @param handler - Callback invoked with `(entity, componentInstance)`.
|
|
59
|
+
* @returns This `Component` entity, for chaining.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* world.component(Transform).onSet((entity, t) => renderer.syncTransform(entity.eid, t));
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
35
66
|
onSet(handler) {
|
|
36
|
-
|
|
67
|
+
this.ownMeta.onSet(handler);
|
|
37
68
|
return this;
|
|
38
69
|
}
|
|
39
70
|
}
|
|
40
|
-
/**
|
|
41
|
-
* Compute a {@link Bitset} with one bit set for every component class or
|
|
42
|
-
* numeric type id in `classes`.
|
|
43
|
-
*
|
|
44
|
-
* @internal Used to build archetype masks for `HAS` / `HAS_ONLY` queries.
|
|
45
|
-
*
|
|
46
|
-
* @param classes - Component classes or type ids to include.
|
|
47
|
-
* @param world - World used to resolve classes to type ids.
|
|
48
|
-
*/
|
|
49
|
-
export function _calculateComponentBitmask(classes, world) {
|
|
50
|
-
const bitmask = new Bitset();
|
|
51
|
-
classes.forEach((C) => {
|
|
52
|
-
bitmask.add(world.getComponentType(C));
|
|
53
|
-
});
|
|
54
|
-
return bitmask;
|
|
55
|
-
}
|
|
56
71
|
//# sourceMappingURL=component.js.map
|
package/dist/component.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.js","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"component.js","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EACL,aAAa,EACb,aAAa,GAOd,MAAM,qBAAqB,CAAC;AAE7B,6DAA6D;AAC7D,MAAM,OAAO,SAAmD,SAAQ,MAAM;IAC5E;;;;;;;;;;;;;;OAcG;IACI,KAAK,CAAC,OAAqD;QAChE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAyD,CAAC,CAAC;QAC9E,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACI,QAAQ,CAAC,OAAqD;QACnE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAyD,CAAC,CAAC;QACjF,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACI,KAAK,CAAC,OAAqD;QAChE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAyD,CAAC,CAAC;QAC9E,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { BitPtr } from "./util/bitset.js";
|
|
2
|
+
import type { Entity, EntityClass } from "./entity/index.js";
|
|
3
|
+
export declare enum CleanupPolicy {
|
|
4
|
+
Throw = "throw",
|
|
5
|
+
Remove = "remove",
|
|
6
|
+
Delete = "delete"
|
|
7
|
+
}
|
|
8
|
+
/** A component instance. Components are plain objects created with a no-arg constructor. */
|
|
9
|
+
export type ComponentInstance = object;
|
|
10
|
+
/** A component constructor used as a component key. */
|
|
11
|
+
export type ComponentType<T extends ComponentInstance = ComponentInstance> = new (...args: any[]) => T;
|
|
12
|
+
/** A component class constructor that can be instantiated by entity.add/set. */
|
|
13
|
+
export type ComponentClass<T extends ComponentInstance = ComponentInstance> = new () => T;
|
|
14
|
+
/** A component class constructor, component eid, or entity component key. */
|
|
15
|
+
export type ComponentRef = number | ComponentType | EntityClass | Entity;
|
|
16
|
+
/**
|
|
17
|
+
* Lifecycle hook for a registered component class. Exposed by
|
|
18
|
+
* {@link World.component}.
|
|
19
|
+
*
|
|
20
|
+
* Hooks are a lightweight alternative to building a {@link System} when all
|
|
21
|
+
* you need is a callback on add / remove / set for a single component type.
|
|
22
|
+
* Component entities expose the same registration methods, so calls chain:
|
|
23
|
+
*
|
|
24
|
+
* ```ts
|
|
25
|
+
* world.component(Sprite)
|
|
26
|
+
* .onAdd((e, c) => initSprite(e, c))
|
|
27
|
+
* .onRemove((e, c) => destroySprite(e, c))
|
|
28
|
+
* .onSet((e, c) => syncSprite(e, c));
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* Callbacks fire synchronously when the corresponding entity command is
|
|
32
|
+
* applied: inline outside deferred mode, or while the world drains its command
|
|
33
|
+
* queue inside a system / `forEach` / `defer` block.
|
|
34
|
+
*
|
|
35
|
+
* @typeParam C - Component class this hook is bound to.
|
|
36
|
+
*/
|
|
37
|
+
export interface Hook<C extends ComponentInstance = ComponentInstance> {
|
|
38
|
+
/**
|
|
39
|
+
* Register a handler invoked when a component of this type is first attached
|
|
40
|
+
* to an entity (`entity.add(C)` or `entity.set(C, ...)` on an entity that
|
|
41
|
+
* does not yet have the component).
|
|
42
|
+
*
|
|
43
|
+
* @param handler - Receives the entity and freshly created component instance.
|
|
44
|
+
* @returns This hook, for chaining.
|
|
45
|
+
*/
|
|
46
|
+
onAdd(handler: (entity: Entity, c: C) => void): Hook<C>;
|
|
47
|
+
/**
|
|
48
|
+
* Register a handler invoked when a component of this type is removed from
|
|
49
|
+
* an entity (explicit `entity.remove(C)` or implicit removal during
|
|
50
|
+
* `entity.destroy()`).
|
|
51
|
+
*
|
|
52
|
+
* @param handler - Receives the entity and component instance that was removed.
|
|
53
|
+
* @returns This hook, for chaining.
|
|
54
|
+
*/
|
|
55
|
+
onRemove(handler: (entity: Entity, c: C) => void): Hook<C>;
|
|
56
|
+
/**
|
|
57
|
+
* Register a handler invoked when a component's data has been marked as
|
|
58
|
+
* changed (`entity.modified(C)`), and when
|
|
59
|
+
* `entity.set(C, props)` is called on an entity that already has the
|
|
60
|
+
* component.
|
|
61
|
+
*
|
|
62
|
+
* @param handler - Receives the entity and component instance whose data changed.
|
|
63
|
+
* @returns This hook, for chaining.
|
|
64
|
+
*/
|
|
65
|
+
onSet(handler: (entity: Entity, c: C) => void): Hook<C>;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Bookkeeping record produced for each component eid.
|
|
69
|
+
*
|
|
70
|
+
* Holds the constructor, component eid, and pre-computed
|
|
71
|
+
* {@link BitPtr} used by archetype checks. Implements {@link Hook}, so the
|
|
72
|
+
* lifecycle handlers attached via `world.component(C)` are stored directly on
|
|
73
|
+
* the meta object.
|
|
74
|
+
*/
|
|
75
|
+
export declare class ComponentMeta implements Hook<ComponentInstance> {
|
|
76
|
+
/** The component class constructor this meta represents. */
|
|
77
|
+
readonly Class: ComponentType;
|
|
78
|
+
/** Component entity id assigned at registration time. */
|
|
79
|
+
readonly eid: number;
|
|
80
|
+
/** Pre-computed bit-pointer into the entity archetype {@link Bitset}. */
|
|
81
|
+
readonly bitPtr: BitPtr;
|
|
82
|
+
/** Whether this component is a relationship pointing at another entity. */
|
|
83
|
+
readonly isRelationship: boolean;
|
|
84
|
+
/** Applied to entities carrying this component when this component entity is deleted. */
|
|
85
|
+
onDelete: CleanupPolicy;
|
|
86
|
+
/** Applied to entities targeting a deleted entity through this relationship. */
|
|
87
|
+
onDeleteTarget: CleanupPolicy;
|
|
88
|
+
private _usageCount;
|
|
89
|
+
constructor(Class: ComponentType, eid: number);
|
|
90
|
+
/** Number of entities currently carrying this component eid. */
|
|
91
|
+
get usageCount(): number;
|
|
92
|
+
/** @inheritdoc */
|
|
93
|
+
onAdd(handler: (entity: Entity, c: ComponentInstance) => void): ComponentMeta;
|
|
94
|
+
/** @inheritdoc */
|
|
95
|
+
onRemove(handler: (entity: Entity, c: ComponentInstance) => void): ComponentMeta;
|
|
96
|
+
/** @inheritdoc */
|
|
97
|
+
onSet(handler: (entity: Entity, c: ComponentInstance) => void): ComponentMeta;
|
|
98
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { BitPtr } from "./util/bitset.js";
|
|
2
|
+
import { Relationship } from "./relationship.js";
|
|
3
|
+
export var CleanupPolicy;
|
|
4
|
+
(function (CleanupPolicy) {
|
|
5
|
+
CleanupPolicy["Throw"] = "throw";
|
|
6
|
+
CleanupPolicy["Remove"] = "remove";
|
|
7
|
+
CleanupPolicy["Delete"] = "delete";
|
|
8
|
+
})(CleanupPolicy || (CleanupPolicy = {}));
|
|
9
|
+
/**
|
|
10
|
+
* Bookkeeping record produced for each component eid.
|
|
11
|
+
*
|
|
12
|
+
* Holds the constructor, component eid, and pre-computed
|
|
13
|
+
* {@link BitPtr} used by archetype checks. Implements {@link Hook}, so the
|
|
14
|
+
* lifecycle handlers attached via `world.component(C)` are stored directly on
|
|
15
|
+
* the meta object.
|
|
16
|
+
*/
|
|
17
|
+
export class ComponentMeta {
|
|
18
|
+
constructor(Class, eid) {
|
|
19
|
+
/** Applied to entities carrying this component when this component entity is deleted. */
|
|
20
|
+
this.onDelete = CleanupPolicy.Throw;
|
|
21
|
+
/** Applied to entities targeting a deleted entity through this relationship. */
|
|
22
|
+
this.onDeleteTarget = CleanupPolicy.Remove;
|
|
23
|
+
/**
|
|
24
|
+
* @internal Peer metas of components that cannot coexist with this one on
|
|
25
|
+
* the same entity. Set via {@link World.setExclusiveComponents}; `undefined`
|
|
26
|
+
* means no restriction.
|
|
27
|
+
*/
|
|
28
|
+
this._exclusive = undefined;
|
|
29
|
+
this._usageCount = 0;
|
|
30
|
+
this.Class = Class;
|
|
31
|
+
this.eid = eid;
|
|
32
|
+
this.bitPtr = new BitPtr(eid);
|
|
33
|
+
this.isRelationship = Class.prototype instanceof Relationship;
|
|
34
|
+
}
|
|
35
|
+
/** Number of entities currently carrying this component eid. */
|
|
36
|
+
get usageCount() {
|
|
37
|
+
return this._usageCount;
|
|
38
|
+
}
|
|
39
|
+
/** @internal */
|
|
40
|
+
_incrementUsage() {
|
|
41
|
+
this._usageCount++;
|
|
42
|
+
}
|
|
43
|
+
/** @internal */
|
|
44
|
+
_decrementUsage() {
|
|
45
|
+
if (this._usageCount > 0) {
|
|
46
|
+
this._usageCount--;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** @inheritdoc */
|
|
50
|
+
onAdd(handler) {
|
|
51
|
+
(this._onAddHandlers ?? (this._onAddHandlers = [])).unshift(handler);
|
|
52
|
+
return this;
|
|
53
|
+
}
|
|
54
|
+
/** @inheritdoc */
|
|
55
|
+
onRemove(handler) {
|
|
56
|
+
(this._onRemoveHandlers ?? (this._onRemoveHandlers = [])).unshift(handler);
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
/** @inheritdoc */
|
|
60
|
+
onSet(handler) {
|
|
61
|
+
(this._onSetHandlers ?? (this._onSetHandlers = [])).unshift(handler);
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=component_meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component_meta.js","sourceRoot":"","sources":["../src/component_meta.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,CAAN,IAAY,aAIX;AAJD,WAAY,aAAa;IACvB,gCAAe,CAAA;IACf,kCAAiB,CAAA;IACjB,kCAAiB,CAAA;AACnB,CAAC,EAJW,aAAa,KAAb,aAAa,QAIxB;AAsED;;;;;;;GAOG;AACH,MAAM,OAAO,aAAa;IA+BxB,YAAY,KAAoB,EAAE,GAAW;QArB7C,yFAAyF;QAClF,aAAQ,GAAG,aAAa,CAAC,KAAK,CAAC;QACtC,gFAAgF;QACzE,mBAAc,GAAG,aAAa,CAAC,MAAM,CAAC;QAE7C;;;;WAIG;QACI,eAAU,GAAgC,SAAS,CAAC;QASnD,gBAAW,GAAG,CAAC,CAAC;QAGtB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC,SAAS,YAAY,YAAY,CAAC;IAChE,CAAC;IAED,gEAAgE;IAChE,IAAW,UAAU;QACnB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,gBAAgB;IACT,eAAe;QACpB,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED,gBAAgB;IACT,eAAe;QACpB,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;IAED,kBAAkB;IACX,KAAK,CAAC,OAAuD;QAClE,CAAC,IAAI,CAAC,cAAc,KAAnB,IAAI,CAAC,cAAc,GAAK,EAAE,EAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,kBAAkB;IACX,QAAQ,CAAC,OAAuD;QACrE,CAAC,IAAI,CAAC,iBAAiB,KAAtB,IAAI,CAAC,iBAAiB,GAAK,EAAE,EAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,kBAAkB;IACX,KAAK,CAAC,OAAuD;QAClE,CAAC,IAAI,CAAC,cAAc,KAAnB,IAAI,CAAC,cAAc,GAAK,EAAE,EAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
|
package/dist/dsl.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import
|
|
1
|
+
import { type ComponentRef, type ComponentRefArray, type ComponentType } from "./component.js";
|
|
2
|
+
import { Entity } from "./entity/index.js";
|
|
3
|
+
import type { World } from "./world/index.js";
|
|
3
4
|
/**
|
|
4
5
|
* A predicate that decides whether a given entity belongs to a query.
|
|
5
6
|
*
|
|
6
|
-
*
|
|
7
|
+
* Use `{ test: fn }` inside {@link QueryDSL} to express membership rules that
|
|
7
8
|
* the structured operators cannot reach.
|
|
8
9
|
*/
|
|
9
10
|
export type EntityTestFunc = (e: Entity) => boolean;
|
|
@@ -14,38 +15,40 @@ export type EntityTestFunc = (e: Entity) => boolean;
|
|
|
14
15
|
* Operators can be nested arbitrarily:
|
|
15
16
|
*
|
|
16
17
|
* ```ts
|
|
17
|
-
* // Position
|
|
18
|
+
* // Position and either Sprite or Container:
|
|
18
19
|
* world.system("render").query({
|
|
19
|
-
*
|
|
20
|
+
* all: [Position, { any: [Sprite, Container] }],
|
|
20
21
|
* });
|
|
21
22
|
*
|
|
22
|
-
* // Parent has Player AND Container:
|
|
23
|
-
* world.system("attach").query({
|
|
24
|
-
* PARENT: { AND: [Player, Container] },
|
|
25
|
-
* });
|
|
26
|
-
* ```
|
|
27
|
-
*
|
|
28
23
|
* Short forms recognized by `query` / `filter`:
|
|
29
|
-
* -
|
|
30
|
-
* -
|
|
31
|
-
* - An
|
|
24
|
+
* - `true` matches all entities; `false` matches no entities.
|
|
25
|
+
* - A registered component class or numeric type id matches entities with that component.
|
|
26
|
+
* - An array `[A, B]` matches entities with all listed components.
|
|
27
|
+
* - An empty array `[]` is shorthand for `true`.
|
|
28
|
+
* - `{ test: fn, watch: refs }` invokes an arbitrary predicate, rechecked for watched refs.
|
|
32
29
|
*
|
|
33
|
-
* Function values are
|
|
34
|
-
*
|
|
35
|
-
* using them in query DSL expressions.
|
|
30
|
+
* Function values are component classes. Register component classes before using
|
|
31
|
+
* them in query DSL expressions.
|
|
36
32
|
*/
|
|
37
|
-
export type QueryDSL =
|
|
38
|
-
|
|
33
|
+
export type QueryDSL = true | false | ComponentRefArray | ComponentRef | {
|
|
34
|
+
all: readonly QueryDSL[];
|
|
35
|
+
} | {
|
|
36
|
+
any: readonly QueryDSL[];
|
|
37
|
+
} | {
|
|
38
|
+
not: QueryDSL;
|
|
39
|
+
} | {
|
|
40
|
+
only: ComponentRefArray | ComponentRef;
|
|
39
41
|
} | {
|
|
40
|
-
|
|
42
|
+
target: readonly [ComponentRef, QueryDSL];
|
|
41
43
|
} | {
|
|
42
|
-
|
|
44
|
+
source: readonly [ComponentRef, QueryDSL];
|
|
43
45
|
} | {
|
|
44
|
-
|
|
46
|
+
parent: QueryDSL;
|
|
45
47
|
} | {
|
|
46
|
-
|
|
48
|
+
children: QueryDSL;
|
|
47
49
|
} | {
|
|
48
|
-
|
|
50
|
+
test: EntityTestFunc;
|
|
51
|
+
watch?: ComponentRefArray | ComponentRef;
|
|
49
52
|
};
|
|
50
53
|
/**
|
|
51
54
|
* Resolve component nullability based on what was declared in `requires` (or
|
|
@@ -57,7 +60,7 @@ export type QueryDSL = ComponentClassArray | ComponentClassOrType | EntityTestFu
|
|
|
57
60
|
* @typeParam C - Component class being injected.
|
|
58
61
|
* @typeParam R - Tuple of component classes guaranteed present.
|
|
59
62
|
*/
|
|
60
|
-
export type MaybeRequired<C, R extends
|
|
63
|
+
export type MaybeRequired<C, R extends ComponentType[]> = C extends ComponentType ? C extends R[number] ? InstanceType<C> : InstanceType<C> | undefined : never;
|
|
61
64
|
/**
|
|
62
65
|
* Statically extract the component classes that are **guaranteed present** on
|
|
63
66
|
* every entity matched by a {@link QueryDSL} expression.
|
|
@@ -65,22 +68,31 @@ export type MaybeRequired<C, R extends ComponentClass[]> = C extends ComponentCl
|
|
|
65
68
|
* Rules:
|
|
66
69
|
* - Plain component class `C` → `[C]`
|
|
67
70
|
* - Plain array `[A, B]` → `[A, B]`
|
|
68
|
-
* - `
|
|
69
|
-
* - `{
|
|
70
|
-
* - `{
|
|
71
|
-
* - `
|
|
71
|
+
* - `true` / `false` / `[]` → `[]` (no guarantee)
|
|
72
|
+
* - `{ only: ... }` → recurse into the payload
|
|
73
|
+
* - `{ all: [q1, q2, ...] }` → concatenate each branch's extraction
|
|
74
|
+
* - `{ any: ... }` / `{ not: ... }` / `{ test: ... }` → `[]` (no guarantee)
|
|
75
|
+
* - numeric type id → `[]` (opaque)
|
|
72
76
|
*
|
|
73
77
|
* @typeParam Q - Query expression to analyse.
|
|
74
78
|
*/
|
|
75
|
-
export type ExtractRequired<Q> = Q extends
|
|
76
|
-
|
|
79
|
+
export type ExtractRequired<Q> = Q extends ComponentType ? [Q] : Q extends readonly ComponentType[] ? Q : Q extends {
|
|
80
|
+
only: infer H;
|
|
77
81
|
} ? ExtractRequired<H> : Q extends {
|
|
78
|
-
|
|
79
|
-
} ? ExtractRequired<H> : Q extends {
|
|
80
|
-
AND: infer A extends readonly QueryDSL[];
|
|
82
|
+
all: infer A extends readonly QueryDSL[];
|
|
81
83
|
} ? _ExtractAndChain<A> : [];
|
|
82
84
|
type _ExtractAndChain<A extends readonly QueryDSL[]> = A extends readonly [
|
|
83
85
|
infer First,
|
|
84
86
|
...infer Rest extends readonly QueryDSL[]
|
|
85
87
|
] ? [...ExtractRequired<First>, ..._ExtractAndChain<Rest>] : [];
|
|
88
|
+
export declare function _resolveRelationship(ref: ComponentRef, world: World): number;
|
|
89
|
+
export declare function containsDownTerm(q: QueryDSL): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Return a deterministic FNV-1a hash for a query DSL expression.
|
|
92
|
+
*
|
|
93
|
+
* Equivalent expressions hash identically because the DSL is simplified before
|
|
94
|
+
* hashing. Custom predicate functions are represented by process-local function
|
|
95
|
+
* identity ids. Like any 32-bit hash, collisions are theoretically possible.
|
|
96
|
+
*/
|
|
97
|
+
export declare function getDSLKey(q: QueryDSL, world: World): number;
|
|
86
98
|
export {};
|