@oasys/oecs 0.3.0 → 0.4.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 +196 -267
- package/dist/array-CxbPyiHO.cjs +1 -0
- package/dist/array-uFR7Q8fU.js +132 -0
- package/dist/core/ecs/access_check.d.ts +77 -0
- package/dist/core/ecs/access_check.d.ts.map +1 -0
- package/dist/core/ecs/archetype.d.ts +474 -0
- package/dist/core/ecs/archetype.d.ts.map +1 -0
- package/dist/core/ecs/builtin_relations.d.ts +43 -0
- package/dist/core/ecs/builtin_relations.d.ts.map +1 -0
- package/dist/core/ecs/command_log.d.ts +113 -0
- package/dist/core/ecs/command_log.d.ts.map +1 -0
- package/dist/core/ecs/component.d.ts +106 -0
- package/dist/core/ecs/component.d.ts.map +1 -0
- package/dist/core/ecs/compute_backend.d.ts +37 -0
- package/dist/core/ecs/compute_backend.d.ts.map +1 -0
- package/dist/core/ecs/dispatch_trace.d.ts +93 -0
- package/dist/core/ecs/dispatch_trace.d.ts.map +1 -0
- package/dist/core/ecs/ecs.d.ts +533 -0
- package/dist/core/ecs/ecs.d.ts.map +1 -0
- package/dist/core/ecs/ecs_memory.d.ts +179 -0
- package/dist/core/ecs/ecs_memory.d.ts.map +1 -0
- package/dist/core/ecs/entity.d.ts +28 -0
- package/dist/core/ecs/entity.d.ts.map +1 -0
- package/dist/core/ecs/event.d.ts +54 -0
- package/dist/core/ecs/event.d.ts.map +1 -0
- package/dist/core/ecs/frame_trace.d.ts +133 -0
- package/dist/core/ecs/frame_trace.d.ts.map +1 -0
- package/dist/core/ecs/host_commands.d.ts +252 -0
- package/dist/core/ecs/host_commands.d.ts.map +1 -0
- package/dist/core/ecs/index.d.ts +41 -0
- package/dist/core/ecs/index.d.ts.map +1 -0
- package/dist/core/ecs/observer.d.ts +142 -0
- package/dist/core/ecs/observer.d.ts.map +1 -0
- package/dist/core/ecs/query.d.ts +557 -0
- package/dist/core/ecs/query.d.ts.map +1 -0
- package/dist/core/ecs/ref.d.ts +31 -0
- package/dist/core/ecs/ref.d.ts.map +1 -0
- package/dist/core/ecs/relation.d.ts +231 -0
- package/dist/core/ecs/relation.d.ts.map +1 -0
- package/dist/core/ecs/resource.d.ts +33 -0
- package/dist/core/ecs/resource.d.ts.map +1 -0
- package/dist/core/ecs/resume.d.ts +85 -0
- package/dist/core/ecs/resume.d.ts.map +1 -0
- package/dist/core/ecs/run_condition.d.ts +75 -0
- package/dist/core/ecs/run_condition.d.ts.map +1 -0
- package/dist/core/ecs/schedule.d.ts +133 -0
- package/dist/core/ecs/schedule.d.ts.map +1 -0
- package/dist/core/ecs/sparse_store.d.ts +107 -0
- package/dist/core/ecs/sparse_store.d.ts.map +1 -0
- package/dist/core/ecs/store.d.ts +1149 -0
- package/dist/core/ecs/store.d.ts.map +1 -0
- package/dist/core/ecs/store_layout_listener.d.ts +23 -0
- package/dist/core/ecs/store_layout_listener.d.ts.map +1 -0
- package/dist/core/ecs/system.d.ts +134 -0
- package/dist/core/ecs/system.d.ts.map +1 -0
- package/dist/core/ecs/utils/arrays.d.ts +7 -0
- package/dist/core/ecs/utils/arrays.d.ts.map +1 -0
- package/dist/core/ecs/utils/constants.d.ts +12 -0
- package/dist/core/ecs/utils/constants.d.ts.map +1 -0
- package/dist/core/ecs/utils/error.d.ts +51 -0
- package/dist/core/ecs/utils/error.d.ts.map +1 -0
- package/dist/core/reactive/array.d.ts +24 -0
- package/dist/core/reactive/array.d.ts.map +1 -0
- package/dist/core/reactive/index.cjs +1 -0
- package/dist/core/reactive/index.d.ts +10 -0
- package/dist/core/reactive/index.d.ts.map +1 -0
- package/dist/core/reactive/index.js +17 -0
- package/dist/core/reactive/interop.d.ts +19 -0
- package/dist/core/reactive/interop.d.ts.map +1 -0
- package/dist/core/reactive/kernel.d.ts +71 -0
- package/dist/core/reactive/kernel.d.ts.map +1 -0
- package/dist/core/reactive/map.d.ts +16 -0
- package/dist/core/reactive/map.d.ts.map +1 -0
- package/dist/core/reactive/struct.d.ts +10 -0
- package/dist/core/reactive/struct.d.ts.map +1 -0
- package/dist/core/store/__generated__/abi.d.ts +43 -0
- package/dist/core/store/__generated__/abi.d.ts.map +1 -0
- package/dist/core/store/action_ring.d.ts +136 -0
- package/dist/core/store/action_ring.d.ts.map +1 -0
- package/dist/core/store/allocator.d.ts +238 -0
- package/dist/core/store/allocator.d.ts.map +1 -0
- package/dist/core/store/buffer_backed_column.d.ts +69 -0
- package/dist/core/store/buffer_backed_column.d.ts.map +1 -0
- package/dist/core/store/column_store.d.ts +265 -0
- package/dist/core/store/column_store.d.ts.map +1 -0
- package/dist/core/store/command_dispatch.d.ts +52 -0
- package/dist/core/store/command_dispatch.d.ts.map +1 -0
- package/dist/core/store/command_ring.d.ts +107 -0
- package/dist/core/store/command_ring.d.ts.map +1 -0
- package/dist/core/store/descriptor.d.ts +80 -0
- package/dist/core/store/descriptor.d.ts.map +1 -0
- package/dist/core/store/entity_index.d.ts +108 -0
- package/dist/core/store/entity_index.d.ts.map +1 -0
- package/dist/core/store/event_ring.d.ts +95 -0
- package/dist/core/store/event_ring.d.ts.map +1 -0
- package/dist/core/store/extend.d.ts +109 -0
- package/dist/core/store/extend.d.ts.map +1 -0
- package/dist/core/store/grow.d.ts +39 -0
- package/dist/core/store/grow.d.ts.map +1 -0
- package/dist/core/store/header.d.ts +64 -0
- package/dist/core/store/header.d.ts.map +1 -0
- package/dist/core/store/index.d.ts +16 -0
- package/dist/core/store/index.d.ts.map +1 -0
- package/dist/core/store/region_table.d.ts +74 -0
- package/dist/core/store/region_table.d.ts.map +1 -0
- package/dist/core/store/snapshot.d.ts +43 -0
- package/dist/core/store/snapshot.d.ts.map +1 -0
- package/dist/core/store/state_hash.d.ts +38 -0
- package/dist/core/store/state_hash.d.ts.map +1 -0
- package/dist/core/store/store_regions.d.ts +38 -0
- package/dist/core/store/store_regions.d.ts.map +1 -0
- package/dist/extensions/editor/editor.d.ts +149 -0
- package/dist/extensions/editor/editor.d.ts.map +1 -0
- package/dist/extensions/editor/field_handle.d.ts +35 -0
- package/dist/extensions/editor/field_handle.d.ts.map +1 -0
- package/dist/extensions/editor/index.cjs +1 -0
- package/dist/extensions/editor/index.d.ts +21 -0
- package/dist/extensions/editor/index.d.ts.map +1 -0
- package/dist/extensions/editor/index.js +209 -0
- package/dist/extensions/reactive/ecs_sync.d.ts +210 -0
- package/dist/extensions/reactive/ecs_sync.d.ts.map +1 -0
- package/dist/extensions/reactive/index.cjs +1 -0
- package/dist/extensions/reactive/index.d.ts +23 -0
- package/dist/extensions/reactive/index.d.ts.map +1 -0
- package/dist/extensions/reactive/index.js +225 -0
- package/dist/extensions/solid/index.cjs +1 -0
- package/dist/extensions/solid/index.d.ts +6 -0
- package/dist/extensions/solid/index.d.ts.map +1 -0
- package/dist/extensions/solid/index.js +32 -0
- package/dist/extensions/solid/kernel_solid.d.ts +42 -0
- package/dist/extensions/solid/kernel_solid.d.ts.map +1 -0
- package/dist/index.cjs +2 -1
- package/dist/index.d.ts +16 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8563 -1233
- package/dist/interop-CT-REx0W.cjs +1 -0
- package/dist/interop-CcY6ASQc.js +18 -0
- package/dist/kernel-DgyrLFjW.js +227 -0
- package/dist/kernel-yWV3XnAb.cjs +1 -0
- package/dist/log/console_sink.d.ts +4 -0
- package/dist/log/console_sink.d.ts.map +1 -0
- package/dist/log/index.d.ts +3 -0
- package/dist/log/index.d.ts.map +1 -0
- package/dist/log/logger.d.ts +27 -0
- package/dist/log/logger.d.ts.map +1 -0
- package/dist/primitives.cjs +1 -0
- package/dist/primitives.d.ts +18 -0
- package/dist/primitives.d.ts.map +1 -0
- package/dist/primitives.js +44 -0
- package/dist/shared-BXSZnxx4.cjs +1 -0
- package/dist/shared-C678TAPY.js +99 -0
- package/dist/shared.cjs +1 -0
- package/dist/shared.d.ts +22 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +7 -0
- package/dist/topological_sort-DlRpSrxu.js +391 -0
- package/dist/topological_sort-WAT-VHb-.cjs +1 -0
- package/dist/type_primitives/assertions.d.ts +12 -8
- package/dist/type_primitives/assertions.d.ts.map +1 -1
- package/dist/type_primitives/binary_heap/binary_heap.d.ts +6 -2
- package/dist/type_primitives/binary_heap/binary_heap.d.ts.map +1 -1
- package/dist/type_primitives/bitset/bitset.d.ts +16 -4
- package/dist/type_primitives/bitset/bitset.d.ts.map +1 -1
- package/dist/type_primitives/brand.d.ts +6 -1
- package/dist/type_primitives/brand.d.ts.map +1 -1
- package/dist/type_primitives/error.d.ts +4 -0
- package/dist/type_primitives/error.d.ts.map +1 -1
- package/dist/type_primitives/index.d.ts +3 -0
- package/dist/type_primitives/index.d.ts.map +1 -1
- package/dist/type_primitives/sparse_map/sparse_map.d.ts +7 -3
- package/dist/type_primitives/sparse_map/sparse_map.d.ts.map +1 -1
- package/dist/type_primitives/sparse_set/sparse_set.d.ts +4 -0
- package/dist/type_primitives/sparse_set/sparse_set.d.ts.map +1 -1
- package/dist/type_primitives/topological_sort/topological_sort.d.ts +7 -3
- package/dist/type_primitives/topological_sort/topological_sort.d.ts.map +1 -1
- package/dist/type_primitives/typed_arrays/typed_arrays.d.ts +53 -16
- package/dist/type_primitives/typed_arrays/typed_arrays.d.ts.map +1 -1
- package/dist/utils/arrays.d.ts +1 -1
- package/dist/utils/arrays.d.ts.map +1 -1
- package/dist/utils/error.d.ts +2 -20
- package/dist/utils/error.d.ts.map +1 -1
- package/package.json +36 -9
- package/dist/archetype.d.ts +0 -101
- package/dist/archetype.d.ts.map +0 -1
- package/dist/component.d.ts +0 -45
- package/dist/component.d.ts.map +0 -1
- package/dist/ecs.d.ts +0 -104
- package/dist/ecs.d.ts.map +0 -1
- package/dist/entity.d.ts +0 -11
- package/dist/entity.d.ts.map +0 -1
- package/dist/event.d.ts +0 -30
- package/dist/event.d.ts.map +0 -1
- package/dist/query.d.ts +0 -90
- package/dist/query.d.ts.map +0 -1
- package/dist/ref.d.ts +0 -23
- package/dist/ref.d.ts.map +0 -1
- package/dist/resource.d.ts +0 -23
- package/dist/resource.d.ts.map +0 -1
- package/dist/schedule.d.ts +0 -45
- package/dist/schedule.d.ts.map +0 -1
- package/dist/store.d.ts +0 -118
- package/dist/store.d.ts.map +0 -1
- package/dist/system.d.ts +0 -16
- package/dist/system.d.ts.map +0 -1
|
@@ -0,0 +1,557 @@
|
|
|
1
|
+
import { Store } from './store';
|
|
2
|
+
import { FrameTraceSink } from './frame_trace';
|
|
3
|
+
import { Archetype, ArchetypeView } from './archetype';
|
|
4
|
+
import { EntityID } from './entity';
|
|
5
|
+
import { ComponentDef, ComponentID, ComponentSchema, FieldValues, MutableColumnsForSchema, ColumnsForSchema, BundleOrDef } from './component';
|
|
6
|
+
import { SparseComponentDef, SparseComponentID } from './sparse_store';
|
|
7
|
+
import { RelationDef } from './relation';
|
|
8
|
+
import { ComponentRef, ReadonlyComponentRef } from './ref';
|
|
9
|
+
import { EventKey, EventReader, EventSchema, SignalKey } from './event';
|
|
10
|
+
import { ResourceKey } from './resource';
|
|
11
|
+
import { BitSet } from '../../type_primitives';
|
|
12
|
+
export interface QueryCacheEntry {
|
|
13
|
+
includeMask: BitSet;
|
|
14
|
+
excludeMask: BitSet | null;
|
|
15
|
+
anyOfMask: BitSet | null;
|
|
16
|
+
query: Query<any>;
|
|
17
|
+
}
|
|
18
|
+
export interface QueryResolver {
|
|
19
|
+
_resolveQuery(include: BitSet, exclude: BitSet | null, anyOf: BitSet | null, defs: readonly ComponentDef[]): Query<any>;
|
|
20
|
+
_getLastRunTick(): number;
|
|
21
|
+
/** Current ECS write tick — the tick `eachChunk` stamps via `cols.mut` (§eachChunk). */
|
|
22
|
+
_getCurrentTick(): number;
|
|
23
|
+
_getQueryDirtyEpoch(): number;
|
|
24
|
+
_nextQueryId(): number;
|
|
25
|
+
_andSingleCache: Map<number, Query<any>>;
|
|
26
|
+
_notSingleCache: Map<number, Query<any>>;
|
|
27
|
+
_anyOfSingleCache: Map<number, Query<any>>;
|
|
28
|
+
_changedSingleCache: Map<number, ChangedQuery<any>>;
|
|
29
|
+
_optionalSingleCache: Map<number, Query<any>>;
|
|
30
|
+
_withSparseSingleCache: Map<number, Query<any>>;
|
|
31
|
+
_withoutSparseSingleCache: Map<number, Query<any>>;
|
|
32
|
+
_withRelationSingleCache: Map<number, Query<any>>;
|
|
33
|
+
_withoutRelationSingleCache: Map<number, Query<any>>;
|
|
34
|
+
_includeDisabledSingleCache: Map<number, Query<any>>;
|
|
35
|
+
_hierarchySingleCache: Map<number, Query<any>>;
|
|
36
|
+
/** Second query-match path (#469 / ADR-0011): drive iteration by sparse
|
|
37
|
+
* membership rather than the archetype mask, yielding entities — sparse
|
|
38
|
+
* members are scattered across archetypes, so there is no archetype-column
|
|
39
|
+
* span to hand back. With a sparse require term, drive from the smallest
|
|
40
|
+
* required store and filter; with only sparse excludes, drive the dense
|
|
41
|
+
* archetype list and skip excluded rows; with neither, walk dense entities.
|
|
42
|
+
* Only entered via `Query.forEachEntity`, so dense `forEach` never pays.
|
|
43
|
+
* `includeDisabled` widens the per-archetype row scan from enabled rows to
|
|
44
|
+
* all rows (#577). */
|
|
45
|
+
_forEachSparseMatch(include: BitSet, exclude: BitSet | null, anyOf: BitSet | null, sparseInclude: readonly SparseComponentID[], sparseExclude: readonly SparseComponentID[], denseArchetypes: readonly Archetype[], cb: (entityId: EntityID) => void, includeDisabled: boolean): void;
|
|
46
|
+
/** Backing sparse id of a relation — resolves a `(R, *)` wildcard term
|
|
47
|
+
* (`withRelation`, #579) to the membership store the sparse-match path
|
|
48
|
+
* already drives. */
|
|
49
|
+
_relationBackingSparseId(def: RelationDef): SparseComponentID;
|
|
50
|
+
/** Third query-match path (#579): `(*, T)` — drive iteration from the union of
|
|
51
|
+
* every relation's `sourcesOf(target)` (dedup + canonical sort), intersected
|
|
52
|
+
* with the dense mask + sparse terms + the enabled-row filter. Only entered via
|
|
53
|
+
* `Query.forEachRelatedTo`. */
|
|
54
|
+
_forEachRelationTargetMatch(target: EntityID, include: BitSet, exclude: BitSet | null, anyOf: BitSet | null, sparseInclude: readonly SparseComponentID[], sparseExclude: readonly SparseComponentID[], includeDisabled: boolean, cb: (entityId: EntityID) => void): void;
|
|
55
|
+
/** Fourth query-match path (#581): yield the matched entities (dense mask +
|
|
56
|
+
* sparse terms + enabled-row filter, exactly the `_forEachSparseMatch`
|
|
57
|
+
* intersection) in canonical **hierarchy depth order** over exclusive relation
|
|
58
|
+
* `relation` — depth ascending (parents before children), entity index
|
|
59
|
+
* ascending within a depth band. Entities deeper than `maxDepth` are skipped
|
|
60
|
+
* (`HIERARCHY_UNBOUNDED` = no limit). Only entered via `Query.forEachEntity`
|
|
61
|
+
* on a query carrying a `.hierarchy(R)` term. */
|
|
62
|
+
_forEachHierarchyMatch(include: BitSet, exclude: BitSet | null, anyOf: BitSet | null, sparseInclude: readonly SparseComponentID[], sparseExclude: readonly SparseComponentID[], denseArchetypes: readonly Archetype[], relation: RelationDef, maxDepth: number, includeDisabled: boolean, cb: (entityId: EntityID) => void): void;
|
|
63
|
+
}
|
|
64
|
+
/** No depth limit on a `.hierarchy(R)` term (#581) — yield every matched entity
|
|
65
|
+
* regardless of its depth in the tree. The default `maxDepth`. */
|
|
66
|
+
export declare const HIERARCHY_UNBOUNDED: number;
|
|
67
|
+
/** A `.hierarchy(R)` depth-ordering term (#581). Records the exclusive relation
|
|
68
|
+
* whose tree defines the order and the (optional) max depth to yield. Stored on
|
|
69
|
+
* the Query and consumed by the `forEachEntity` hierarchy match path; absent
|
|
70
|
+
* (`null`) for the common case. */
|
|
71
|
+
export interface HierarchyTerm {
|
|
72
|
+
/** The exclusive relation whose chain/tree defines the depth ordering. */
|
|
73
|
+
readonly relation: RelationDef;
|
|
74
|
+
/** Inclusive max depth to yield (root = 0); entities deeper than this are
|
|
75
|
+
* skipped. `HIERARCHY_UNBOUNDED` for no limit (bitECS `Hierarchy()` depth arg). */
|
|
76
|
+
readonly maxDepth: number;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* eachChunk cursor (§eachChunk). One instance is allocated per `eachChunk`
|
|
80
|
+
* pass and reused across every matched archetype in that pass — only `_arch`/
|
|
81
|
+
* `_tick` are re-pointed per archetype, so the inner loop allocates nothing.
|
|
82
|
+
* Per-call (not cached on the query) so a nested `eachChunk` on the same query
|
|
83
|
+
* gets its own cursor and can't re-point an outer pass's position. `.mut(def)` /
|
|
84
|
+
* `.read(def)` resolve a whole component's columns at once into a field-keyed
|
|
85
|
+
* object (a per-archetype-per-component cache refreshed in place), hiding the
|
|
86
|
+
* change tick. Destructure the group immediately; don't retain it across calls.
|
|
87
|
+
*/
|
|
88
|
+
export declare class ChunkColumns {
|
|
89
|
+
/** @internal */ _arch: Archetype;
|
|
90
|
+
/** @internal */ _tick: number;
|
|
91
|
+
/** Mutable column group — `const { x, y } = cols.mut(Pos)`. Stamps the tick. */
|
|
92
|
+
mut<S extends ComponentSchema>(def: ComponentDef<S>): MutableColumnsForSchema<S>;
|
|
93
|
+
/** Read-only column group — `const { vx, vy } = cols.read(Vel)`. No tick bump. */
|
|
94
|
+
read<S extends ComponentSchema>(def: ComponentDef<S>): ColumnsForSchema<S>;
|
|
95
|
+
}
|
|
96
|
+
export declare class Query<Defs extends readonly ComponentDef[]> {
|
|
97
|
+
private readonly _archetypes;
|
|
98
|
+
readonly _defs: Defs;
|
|
99
|
+
private readonly _resolver;
|
|
100
|
+
readonly _include: BitSet;
|
|
101
|
+
private readonly _exclude;
|
|
102
|
+
private readonly _anyOf;
|
|
103
|
+
private _nonEmptyArchetypes;
|
|
104
|
+
private _lastSeenEpoch;
|
|
105
|
+
readonly _id: number;
|
|
106
|
+
readonly _sparseInclude: readonly SparseComponentID[];
|
|
107
|
+
readonly _sparseExclude: readonly SparseComponentID[];
|
|
108
|
+
readonly _optional: readonly ComponentID[];
|
|
109
|
+
readonly _includeDisabled: boolean;
|
|
110
|
+
readonly _relationIncludes: readonly RelationDef[];
|
|
111
|
+
readonly _relationExcludes: readonly RelationDef[];
|
|
112
|
+
readonly _hierarchy: HierarchyTerm | null;
|
|
113
|
+
constructor(archetypes: Archetype[], defs: Defs, resolver: QueryResolver, include: BitSet, exclude: BitSet | null, anyOf: BitSet | null, id: number, sparseInclude?: readonly SparseComponentID[], sparseExclude?: readonly SparseComponentID[], optional?: readonly ComponentID[], includeDisabled?: boolean, relationIncludes?: readonly RelationDef[], relationExcludes?: readonly RelationDef[], hierarchy?: HierarchyTerm | null);
|
|
114
|
+
/** Guard the dense-only methods (`count` / `forEach` / `archetype_count`)
|
|
115
|
+
* against a query carrying sparse terms. These walk the dense archetype
|
|
116
|
+
* list and never consult `_sparseInclude` / `_sparseExclude`, so on a
|
|
117
|
+
* sparse-derived query they'd **fail open** — returning the unfiltered dense
|
|
118
|
+
* result instead of the sparse-filtered one. Throw in `__DEV__` (compiled
|
|
119
|
+
* out of prod) steering the caller to `forEachEntity`, the only path that
|
|
120
|
+
* honors sparse membership (#469). Mirrors `ChangedQuery`'s dev-guard on its
|
|
121
|
+
* include-mask invariant. */
|
|
122
|
+
private _assertDenseOnly;
|
|
123
|
+
/** Number of matching archetypes (including empty ones). */
|
|
124
|
+
get archetypeCount(): number;
|
|
125
|
+
/** Total entity count across all matching archetypes — enabled rows only by
|
|
126
|
+
* default, or all rows when `includeDisabled()` (#577). Reads the partition
|
|
127
|
+
* fields directly (not the flag-dependent `entityCount` getter). */
|
|
128
|
+
count(): number;
|
|
129
|
+
get archetypes(): readonly ArchetypeView[];
|
|
130
|
+
/** Carry this query's non-dense terms — optional fetch-if-present (#575) and
|
|
131
|
+
* sparse membership (#469) — onto a freshly composed dense query. `and` /
|
|
132
|
+
* `not` / `anyOf` build the new dense mask via `_resolveQuery`, which is
|
|
133
|
+
* keyed on the mask alone and so hands back a query carrying NONE of these
|
|
134
|
+
* terms; before #592 that silently dropped them, making composition
|
|
135
|
+
* order-dependent (`q.optional(V).and(H)` lost `V`; `q.and(H).optional(V)`
|
|
136
|
+
* kept it). When this query carries no non-dense terms (the common case)
|
|
137
|
+
* `base` is already correct and returned as-is, preserving the mask-cached
|
|
138
|
+
* singleton with zero allocation. Otherwise re-derive on top of `base`'s dense
|
|
139
|
+
* state, threading the terms forward so composition is symmetric regardless of
|
|
140
|
+
* order. Reading `base`'s private fields is allowed — same-class instance. */
|
|
141
|
+
private _carryNondense;
|
|
142
|
+
/** Extend required component set. Returns a new (cached) Query. */
|
|
143
|
+
and<D extends ComponentDef[]>(...comps: D): Query<[...Defs, ...D]>;
|
|
144
|
+
/** @internal — cold cache-miss path for single-arg `and`, split out (#649) so
|
|
145
|
+
* the hot `and` body is just key-compute + cache hit. The miss path runs once
|
|
146
|
+
* per unique composition, then every repeat is a cache hit; keeping it out of
|
|
147
|
+
* line shrinks `and`'s inlined footprint when several composes share one hot
|
|
148
|
+
* function (the `query_compose` shape). Same rationale for `_notMiss` /
|
|
149
|
+
* `_anyOfMiss` / `_changedMiss`. */
|
|
150
|
+
private _andMiss;
|
|
151
|
+
/** Exclude archetypes that have any of these components. */
|
|
152
|
+
without(...comps: ComponentDef[]): Query<Defs>;
|
|
153
|
+
/** @internal — cold cache-miss path for single-arg `not` (#649); see `_andMiss`. */
|
|
154
|
+
private _notMiss;
|
|
155
|
+
/** Require a sparse component (#469): match only entities that hold it,
|
|
156
|
+
* across every archetype. A sparse term doesn't touch the dense mask, so
|
|
157
|
+
* the returned (cached) query reuses this one's live archetype list; it is
|
|
158
|
+
* iterated via `forEachEntity`, never `forEach` (sparse members are
|
|
159
|
+
* scattered within archetypes, so there is no SoA column span to yield). */
|
|
160
|
+
withSparse(...defs: SparseComponentDef[]): Query<Defs>;
|
|
161
|
+
/** One-id `withSparse` composition, cached on `(parent_id, sparseId)` in
|
|
162
|
+
* the resolver's shared single-term map. Both the single- and multi-arg public
|
|
163
|
+
* forms fold over this, so all sparse-require composition is deduplicated. */
|
|
164
|
+
private _withSparseOne;
|
|
165
|
+
/** Exclude a sparse component (#469): drop entities that hold it. Same
|
|
166
|
+
* dense-list reuse and `forEachEntity` iteration as `withSparse`. */
|
|
167
|
+
withoutSparse(...defs: SparseComponentDef[]): Query<Defs>;
|
|
168
|
+
/** One-id `withoutSparse` composition, cached on `(parent_id, sparseId)`. The
|
|
169
|
+
* multi-arg form folds over this (#497) — mirrors `_withSparseOne`. */
|
|
170
|
+
private _withoutSparseOne;
|
|
171
|
+
/** Build a derived query carrying new sparse terms. Reuses this query's
|
|
172
|
+
* dense state by reference — the masks are never mutated in place (`and` /
|
|
173
|
+
* `not` / `anyOf` copy before mutating), and `_archetypes` is the same
|
|
174
|
+
* live array the store appends to, so the derived query stays live too.
|
|
175
|
+
* Carries the existing `_optional` terms through unchanged (the two axes
|
|
176
|
+
* compose). */
|
|
177
|
+
private _deriveSparse;
|
|
178
|
+
/** Require the `(R, *)` wildcard (#579): match only sources that hold **any**
|
|
179
|
+
* target under relation `R`. "Has any `(R, *)` pair" is exactly membership in
|
|
180
|
+
* R's backing sparse store (exclusive `{target}` row / multi tag), so this is a
|
|
181
|
+
* relation-typed front door over `withSparse` — it pushes R's backing sparse
|
|
182
|
+
* id onto `_sparseInclude` and reuses the `forEachEntity` sparse-match path
|
|
183
|
+
* (insertion order; canonical sorting is reserved for `stateHash`/snapshot, and
|
|
184
|
+
* costs 4–5× here for no determinism benefit — see the §579 bench report).
|
|
185
|
+
* Membership semantics: each source once; fetch its targets with
|
|
186
|
+
* `ctx.targetsOf(e, R)`. Requires `relationReads: [R]` (checked at iteration).
|
|
187
|
+
* Cached per `(parent_id, relation_id)` like the sparse terms (#497). */
|
|
188
|
+
withRelation(...defs: RelationDef[]): Query<Defs>;
|
|
189
|
+
private _withRelationOne;
|
|
190
|
+
/** Exclude the `(R, *)` wildcard (#579): drop sources that hold any target
|
|
191
|
+
* under `R`. Mirror of `withRelation` on the exclude side (pushes R's
|
|
192
|
+
* backing sparse id onto `_sparseExclude`). */
|
|
193
|
+
withoutRelation(...defs: RelationDef[]): Query<Defs>;
|
|
194
|
+
private _withoutRelationOne;
|
|
195
|
+
/** Build a derived query carrying new relation-wildcard terms. Threads the
|
|
196
|
+
* backing-sparse ids (which the driver actually consumes) plus the relation
|
|
197
|
+
* ids (which only the `__DEV__` access check consumes), reusing the dense /
|
|
198
|
+
* optional / disabled state by reference — same rationale as `_deriveSparse`. */
|
|
199
|
+
private _deriveRelation;
|
|
200
|
+
/** Order this query's matched entities in **hierarchy depth order** over the
|
|
201
|
+
* exclusive relation `R` — parents before children — and (optionally) drop any
|
|
202
|
+
* deeper than `maxDepth` (#581; flecs `cascade` / bitECS `Hierarchy()`). The
|
|
203
|
+
* matched *set* is unchanged (still the dense mask + sparse + `(R, *)` + disabled
|
|
204
|
+
* terms); `.hierarchy(R)` only **reorders** + depth-limits it, so an entity with
|
|
205
|
+
* no `R`-parent is a root at depth 0 and still yielded (first). The canonical
|
|
206
|
+
* order is depth ascending, then **entity index ascending within each depth
|
|
207
|
+
* band** — a total, insertion-order-independent order (identical across lockstep
|
|
208
|
+
* peers), produced by an O(K) radix on the entity index, never a comparator sort.
|
|
209
|
+
*
|
|
210
|
+
* Iterate with `forEachEntity`: members scatter across archetypes, so there is
|
|
211
|
+
* no SoA column span — `forEach` / `count` reject a hierarchy query (like a
|
|
212
|
+
* sparse term). **Exclusive relations only** (matches the traversal constraint
|
|
213
|
+
* #474); a multi relation throws `RELATION_MODE_MISMATCH` at iteration, and a
|
|
214
|
+
* cycle is a loud `RELATION_CYCLE` in `__DEV__` (a safe break in production).
|
|
215
|
+
* Requires `relationReads: [R]` (checked at iteration). Carried through
|
|
216
|
+
* `and`/`not`/`anyOf` like the sparse terms (`_carryNondense`).
|
|
217
|
+
*
|
|
218
|
+
* `Defs` is unchanged — `R` is an ordering, not a required component (like
|
|
219
|
+
* `not` / `anyOf`). Returns a new query; the unbounded form is cached. */
|
|
220
|
+
hierarchy(relation: RelationDef, maxDepth?: number): Query<Defs>;
|
|
221
|
+
/** Build a derived query carrying a hierarchy ordering term. Reuses this
|
|
222
|
+
* query's dense / sparse / optional / disabled / relation-wildcard state by
|
|
223
|
+
* reference (the matched set is unchanged) — same rationale as `_deriveSparse`. */
|
|
224
|
+
private _deriveHierarchy;
|
|
225
|
+
/** Assert every `(R, *)` wildcard term on this query was declared in the
|
|
226
|
+
* system's `relationReads` (#579 / #496). Iteration-time (`forEachEntity` /
|
|
227
|
+
* `forEachRelatedTo`), not construction-time, so it is robust to queries
|
|
228
|
+
* built outside a system — same rationale as the data-op checks. `__DEV__` only;
|
|
229
|
+
* outside a system `checkRelationRead` is a no-op. */
|
|
230
|
+
private _checkRelationAccess;
|
|
231
|
+
/** Iterate every source related to `target` under **any** relation — the
|
|
232
|
+
* `(*, T)` wildcard (#579) — intersected with this query's dense + sparse +
|
|
233
|
+
* `(R, *)` + disabled predicate, each source yielded once in ascending-EntityID
|
|
234
|
+
* order (the `sourcesOf` / `sourcesOfAny` convention). `target` is supplied
|
|
235
|
+
* here rather than as a chained term because it is a runtime `EntityID`: baking
|
|
236
|
+
* it into a cached `Query` would key the cache on a recycled value and churn
|
|
237
|
+
* query-ids, and `(*, T)` is the rare/cold shape. Composes with
|
|
238
|
+
* `withRelation` / `withSparse` / dense terms on the receiver. Reads
|
|
239
|
+
* every relation's reverse index, so the system must declare
|
|
240
|
+
* `relationReads: [ANY_RELATION]` (plus `[R]` for any composed `withRelation`).
|
|
241
|
+
* Cold/structural — not a per-tick hot loop over many targets. */
|
|
242
|
+
forEachRelatedTo(target: EntityID, cb: (entityId: EntityID) => void): void;
|
|
243
|
+
/** Add optional fetch-if-present terms (#575). Does NOT narrow the matched
|
|
244
|
+
* set — the dense mask is untouched, so iteration still spans archetypes with
|
|
245
|
+
* and without each `T`. Read each column per archetype span via
|
|
246
|
+
* `arch.getOptionalColumnRead(T, field)` (column when present, `undefined`
|
|
247
|
+
* when absent). `.optional(T)` is the *declaration* that authorizes that fetch:
|
|
248
|
+
* inside `forEach`, `getOptionalColumnRead` throws in `__DEV__` if `T` was
|
|
249
|
+
* not declared here (#592) — the read-side analog of `reads:[T]`, which is also
|
|
250
|
+
* still required for access coverage (both checks fire, even on the absent
|
|
251
|
+
* span). The term is carried through `and`/`not`/`anyOf` (see
|
|
252
|
+
* `_carryNondense`), so it survives composition in any order. Returns a new
|
|
253
|
+
* (cached) Query.
|
|
254
|
+
*
|
|
255
|
+
* `Defs` is unchanged (the optional `T` is not a required component, like
|
|
256
|
+
* `not` / `anyOf`); column types come from the accessor's own generics. */
|
|
257
|
+
optional(...defs: ComponentDef[]): Query<Defs>;
|
|
258
|
+
/** One-id `optional` composition, cached on `(parent_id << 16) | cid` in the
|
|
259
|
+
* resolver's shared single-term map (dense cid <= 128, same packing as the
|
|
260
|
+
* `and` / `not` / `anyOf` caches). */
|
|
261
|
+
private _optionalOne;
|
|
262
|
+
/** Build a derived query carrying new optional terms. Reuses this query's
|
|
263
|
+
* dense state by reference (the matched set is unchanged) and carries the
|
|
264
|
+
* existing sparse terms through unchanged — same rationale as `_deriveSparse`. */
|
|
265
|
+
private _deriveOptional;
|
|
266
|
+
/** Opt this query back in to disabled entities (#577). By default a query
|
|
267
|
+
* excludes disabled entities (the iteration bound `arch.entityCount` is the
|
|
268
|
+
* enabled-row count). The returned (cached) query spans disabled rows too:
|
|
269
|
+
* `forEach` publishes the all-rows flag so the SoA loop's `arch.entityCount`
|
|
270
|
+
* reports `length`, and `count`/`forEachEntity` widen accordingly. Does NOT
|
|
271
|
+
* touch the dense mask, so it reuses this query's live archetype list and is
|
|
272
|
+
* carried through `and`/`not`/`anyOf` like the sparse/optional terms. */
|
|
273
|
+
includeDisabled(): Query<Defs>;
|
|
274
|
+
forEach(cb: (arch: ArchetypeView) => void): void;
|
|
275
|
+
/** @internal — cold `includeDisabled` wrapper for `forEach` (#577), split out
|
|
276
|
+
* (#649) so the all-rows flag dance (`_setIterAllRows` + try/finally) stays
|
|
277
|
+
* out of `forEach`'s inlined hot body. The default (enabled-only) query never
|
|
278
|
+
* reaches here, so V8 leaves this uninlined and `forEach` shrinks accordingly. */
|
|
279
|
+
private _forEachIncludeDisabled;
|
|
280
|
+
/**
|
|
281
|
+
* Per-archetype destructured column iteration (§eachChunk) — the flecs
|
|
282
|
+
* `run()` / koota `useStores` model, and the recommended hot-path default for
|
|
283
|
+
* mutating systems:
|
|
284
|
+
*
|
|
285
|
+
* q.eachChunk((cols, count) => {
|
|
286
|
+
* const { x, y } = cols.mut(Pos); // whole group, tick stamped inside
|
|
287
|
+
* const { vx, vy } = cols.read(Vel); // read-only group
|
|
288
|
+
* for (let i = 0; i < count; i++) { x[i] += vx[i] * dt; y[i] += vy[i] * dt; }
|
|
289
|
+
* });
|
|
290
|
+
*
|
|
291
|
+
* vs the raw path it replaces (per-field `getColumn` + manual `ecsTick`
|
|
292
|
+
* thread + `entityCount` loop). It folds away: per-field fetches (one call
|
|
293
|
+
* per component), the `getColumn`/`getColumnRead` choice (→ `.mut`/`.read`),
|
|
294
|
+
* the manual tick arg (hidden in `.mut`), and the `.length`-vs-`entityCount`
|
|
295
|
+
* corruption trap (`count` is `entityCount`). It is also the only mutable
|
|
296
|
+
* column accessor reachable through the iteration path — the read-only
|
|
297
|
+
* `ArchetypeView` from `forEach` deliberately omits the mutable `getColumn`.
|
|
298
|
+
* The SoA inner loop is byte-identical, and the per-archetype group objects
|
|
299
|
+
* are cached (zero per-archetype allocation). One `ChunkColumns` cursor is
|
|
300
|
+
* allocated per pass and reused across that pass's archetypes. Honours
|
|
301
|
+
* `includeDisabled()` exactly like `forEach` (the bound widens to the
|
|
302
|
+
* disabled tail); dense-only like `forEach` (sparse/relation/hierarchy terms
|
|
303
|
+
* throw in `__DEV__` — iterate those with `forEachEntity`).
|
|
304
|
+
*/
|
|
305
|
+
eachChunk(cb: (cols: ChunkColumns, count: number) => void): void;
|
|
306
|
+
/** @internal — shared body for `eachChunk`'s default and `includeDisabled`
|
|
307
|
+
* paths. The `ChunkColumns` cursor is allocated per call (a 2-field object whose
|
|
308
|
+
* cost doesn't scale with the per-row work) rather than cached on the query, so
|
|
309
|
+
* a nested `eachChunk` on the SAME query gets its own cursor instead of
|
|
310
|
+
* re-pointing the outer pass's `_arch`/`_tick`. The per-(archetype, component)
|
|
311
|
+
* column-group caches that actually matter for allocation live on the
|
|
312
|
+
* `Archetype`, untouched. */
|
|
313
|
+
private _eachChunkInner;
|
|
314
|
+
/**
|
|
315
|
+
* Early-exit iteration: like `forEach`, but stops as soon as `cb` returns
|
|
316
|
+
* `true`, and returns whether any callback did. The predicate analog for
|
|
317
|
+
* "does any matching row satisfy X?" — without it, callers hand-rolled a
|
|
318
|
+
* `query.archetypes` walk (re-implementing the empty-archetype skip) just
|
|
319
|
+
* to be able to `return` mid-scan. Deliberately a separate method:
|
|
320
|
+
* honouring return values on `forEach`'s existing `=> void` callback
|
|
321
|
+
* would silently change behaviour for arrow-expression bodies that happen
|
|
322
|
+
* to return a truthy value.
|
|
323
|
+
*/
|
|
324
|
+
forEachUntil(cb: (arch: ArchetypeView) => boolean): boolean;
|
|
325
|
+
/** @internal — shared body for `forEachUntil`'s default and
|
|
326
|
+
* `includeDisabled` paths. Same dev-mode optional-term scope as
|
|
327
|
+
* `forEach` (#592). */
|
|
328
|
+
private _forEachUntilInner;
|
|
329
|
+
/** @internal — the `includeDisabled` delegate for `forEach` (#577). The
|
|
330
|
+
* default (enabled-only) path inlines this body directly into `forEach`
|
|
331
|
+
* (#608) to dodge a megamorphic delegate hop; this copy survives only for the
|
|
332
|
+
* rare all-rows path, which needs the `_setIterAllRows` try/finally wrap. */
|
|
333
|
+
private _forEachInner;
|
|
334
|
+
/** Iterate the entities this query matches, yielding each `EntityID`
|
|
335
|
+
* (#469 — the sparse-membership match path). Use this whenever the query
|
|
336
|
+
* carries a `withSparse` / `withoutSparse` term: members are scattered
|
|
337
|
+
* across archetypes, so there is no SoA column span to hand back — read
|
|
338
|
+
* fields via `ctx.getField` (dense) or `ctx.getSparseField` (sparse) on
|
|
339
|
+
* the yielded entity. A dense-only query also works here (it walks its
|
|
340
|
+
* archetypes' entity ids), but prefer `forEach` for the SoA hot loop.
|
|
341
|
+
*
|
|
342
|
+
* Iteration is read-mostly: mutating the *driving* sparse component's
|
|
343
|
+
* membership mid-iteration is unsafe. The walk drives off the store's live
|
|
344
|
+
* key array, so **adding** the driving component (the store `push`es a new
|
|
345
|
+
* key, which the `i < length` loop then visits) and **removing** it (the
|
|
346
|
+
* store swap-pops, shifting the index list under the walk) both corrupt the
|
|
347
|
+
* traversal. This is sharper than for dense `forEach`: `ctx.addSparse` /
|
|
348
|
+
* `ctx.addRelation` apply *immediately* (no archetype transition to defer),
|
|
349
|
+
* so unlike a deferred dense `addComponent` the mutation lands in the live
|
|
350
|
+
* array at once. Buffer such edits and apply them after the walk. */
|
|
351
|
+
forEachEntity(cb: (entityId: EntityID) => void): void;
|
|
352
|
+
/** @internal — used by ChangedQuery. Rebuild non-empty archetype list if the
|
|
353
|
+
* Store has bumped its dirty epoch since our last rebuild, return cached result.
|
|
354
|
+
*
|
|
355
|
+
* Rebuild allocates a *fresh* array and swaps it in rather than truncating
|
|
356
|
+
* the cached one in place (#431). `forEach`/`count`/`ChangedQuery.forEach`
|
|
357
|
+
* bind the returned array once and walk it; an in-place `dst.length = 0` +
|
|
358
|
+
* re-push would corrupt that walk if the query is re-entrantly iterated —
|
|
359
|
+
* i.e. the callback runs an immediate-mode mutation that crosses a
|
|
360
|
+
* 0↔non-zero entity boundary on the *same* Query (bumping the epoch) and
|
|
361
|
+
* then re-enters here via a nested `forEach`/`count`. Building fresh hands
|
|
362
|
+
* the inner call its own array and leaves the outer iterator's snapshot
|
|
363
|
+
* intact, so each archetype is visited exactly once. Cost is one array
|
|
364
|
+
* allocation per epoch advance (rare — only on boundary crossings); the
|
|
365
|
+
* steady-state path returns the cached array with zero allocation. In-system
|
|
366
|
+
* iteration never triggers a rebuild mid-loop: deferred mutations settle the
|
|
367
|
+
* epoch during `flushStructural`, between systems. */
|
|
368
|
+
_nonEmpty(): Archetype[];
|
|
369
|
+
/** @internal — cold rebuild path for `_nonEmpty`, split out (#649) so the
|
|
370
|
+
* hot `_nonEmpty` body is just an epoch check + cached return. Keeping the
|
|
371
|
+
* filter loops here shrinks `_nonEmpty`'s inlined bytecode footprint, which
|
|
372
|
+
* matters when several composed queries iterate inside one hot function (the
|
|
373
|
+
* `query_compose` shape): the leaner `_nonEmpty` keeps `forEach` under V8's
|
|
374
|
+
* per-function cumulative inlining budget. */
|
|
375
|
+
private _rebuildNonEmpty;
|
|
376
|
+
/** Require at least one of these components. */
|
|
377
|
+
anyOf(...comps: ComponentDef[]): Query<Defs>;
|
|
378
|
+
/** @internal — cold cache-miss path for single-arg `anyOf` (#649); see `_andMiss`. */
|
|
379
|
+
private _anyOfMiss;
|
|
380
|
+
/** Create a ChangedQuery that filters archetypes by change tick.
|
|
381
|
+
*
|
|
382
|
+
* Granularity is **archetype**, not row: the `_changedTick[cid]` is
|
|
383
|
+
* bumped per archetype on any write into that component's column
|
|
384
|
+
* (`Archetype._changedTick` in archetype.ts). A 1-row write in a
|
|
385
|
+
* 1000-row archetype trips `forEach` on the whole archetype next tick.
|
|
386
|
+
* Use cases that need row-level granularity should compare per-row
|
|
387
|
+
* state explicitly inside the callback.
|
|
388
|
+
*
|
|
389
|
+
* The returned ChangedQuery is composable (M6): `and`/`without`/`anyOf`/
|
|
390
|
+
* `optional` refine it further, so `q.changed(Pos).without(Dead)` works — and
|
|
391
|
+
* is the same set as `q.without(Dead).changed(Pos)`. */
|
|
392
|
+
changed(...defs: ComponentDef[]): ChangedQuery<Defs>;
|
|
393
|
+
/** @internal — cold cache-miss path for single-arg `changed` (#649); see `_andMiss`. */
|
|
394
|
+
private _changedMiss;
|
|
395
|
+
/** @internal — reads lastRunTick from the resolver (ECS). */
|
|
396
|
+
_ctxLastRunTick(): number;
|
|
397
|
+
}
|
|
398
|
+
export declare class QueryBuilder {
|
|
399
|
+
private readonly _resolver;
|
|
400
|
+
constructor(_resolver: QueryResolver);
|
|
401
|
+
with<T extends ComponentDef[]>(...defs: T): Query<T>;
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Deferred structural-command facade (§ctx.commands — Bevy `Commands`).
|
|
405
|
+
* Namespaces the deferred structural ops so the call site is self-documenting:
|
|
406
|
+
* `ctx.commands.add(e, …)` is *always* deferred (applied at the phase flush),
|
|
407
|
+
* ending the collision where `ecs.addComponent` (immediate) and the bare
|
|
408
|
+
* `ctx.addComponent` (deferred) share a name with opposite timing. Takes
|
|
409
|
+
* varargs callable bundles, so one shape — `commands.spawn(bundle(Pos,{x,y}), bundle(Vel,{vx:1}))`
|
|
410
|
+
* — serves spawn and add. The legacy `ctx.addComponent`/etc. stay for now;
|
|
411
|
+
* the intent is for `ctx.commands.*` to become the only deferred surface.
|
|
412
|
+
*/
|
|
413
|
+
export declare class Commands {
|
|
414
|
+
private readonly store;
|
|
415
|
+
constructor(store: Store);
|
|
416
|
+
/** Spawn from bundles. Create is immediate (the id is returned now); the
|
|
417
|
+
* component attaches are deferred to the phase flush — so until that flush the
|
|
418
|
+
* entity exists in its empty/partial archetype and a query running later in
|
|
419
|
+
* the same phase can observe it half-built. (Same semantics as
|
|
420
|
+
* `ctx.createEntity` + `ctx.addComponent`; fully-deferred id-reservation
|
|
421
|
+
* spawn, à la Bevy, is a separate follow-up.) */
|
|
422
|
+
spawn(...items: BundleOrDef[]): EntityID;
|
|
423
|
+
/** Attach bundles to an existing entity (deferred). */
|
|
424
|
+
add(entityId: EntityID, ...items: BundleOrDef[]): this;
|
|
425
|
+
/** Remove a component (deferred). */
|
|
426
|
+
remove(entityId: EntityID, def: ComponentDef): this;
|
|
427
|
+
/** Destroy an entity (deferred). */
|
|
428
|
+
despawn(entityId: EntityID): this;
|
|
429
|
+
/** Disable an entity (deferred). */
|
|
430
|
+
disable(entityId: EntityID): this;
|
|
431
|
+
/** Re-enable an entity (deferred). */
|
|
432
|
+
enable(entityId: EntityID): this;
|
|
433
|
+
}
|
|
434
|
+
export declare class SystemContext {
|
|
435
|
+
private readonly store;
|
|
436
|
+
lastRunTick: number;
|
|
437
|
+
/** Deferred structural-command facade (§ctx.commands). */
|
|
438
|
+
readonly commands: Commands;
|
|
439
|
+
/** Current ECS tick. Use this for write ticks in getColumn. */
|
|
440
|
+
get ecsTick(): number;
|
|
441
|
+
/** The world's frame-trace sink (ADR-0030), or `null`. Lets the schedule
|
|
442
|
+
* fire `systemStart`/`flush*` without reaching into the private store.
|
|
443
|
+
* Read only under `if (__DEV__)`; the seam is dead-code-eliminated in prod. */
|
|
444
|
+
get _trace(): FrameTraceSink | null;
|
|
445
|
+
constructor(store: Store);
|
|
446
|
+
createEntity(): EntityID;
|
|
447
|
+
isAlive(entityId: EntityID): boolean;
|
|
448
|
+
hasComponent(entityId: EntityID, def: ComponentDef): boolean;
|
|
449
|
+
getField<S extends ComponentSchema>(entityId: EntityID, def: ComponentDef<S>, field: string & keyof S): number;
|
|
450
|
+
setField<S extends ComponentSchema>(entityId: EntityID, def: ComponentDef<S>, field: string & keyof S, value: number): void;
|
|
451
|
+
/** Read-modify-write one field: `updateField(e, Gold, "value", v => v - cost)`
|
|
452
|
+
* is the one-line form of the `getField` → compute → `setField` round trip.
|
|
453
|
+
* Returns the written value. Same access-check and observer semantics as the
|
|
454
|
+
* two calls it composes. */
|
|
455
|
+
updateField<S extends ComponentSchema>(entityId: EntityID, def: ComponentDef<S>, field: string & keyof S, fn: (current: number) => number): number;
|
|
456
|
+
/**
|
|
457
|
+
* Record an entity as changed for a component's per-entity `onSet` observer
|
|
458
|
+
* (#517 §1 / ADR-0013). The SoA write idiom — `const col = arch.getColumn(D,
|
|
459
|
+
* f, tick); col[i] = v` in a tight loop — bypasses the deferred buffer and the
|
|
460
|
+
* engine never sees the per-element writes, so a per-entity `onSet` consumer
|
|
461
|
+
* pushes the row here (the bench's winning `tick+list`: raw write + an int
|
|
462
|
+
* push, fired batched at the post-update detection point — never a per-element
|
|
463
|
+
* observable setter). No-op for components without a per-entity onSet observer.
|
|
464
|
+
* `setField` records automatically; this is for the hot `getColumn` loop.
|
|
465
|
+
*/
|
|
466
|
+
markChanged(entityId: EntityID, def: ComponentDef): void;
|
|
467
|
+
/**
|
|
468
|
+
* Create a cached component reference for a single entity. Marks the
|
|
469
|
+
* component as changed (the mutable default — see `refRead` for the
|
|
470
|
+
* read-only variant to reach for when you are not mutating). See ref.ts.
|
|
471
|
+
*/
|
|
472
|
+
ref<S extends ComponentSchema>(def: ComponentDef<S>, entityId: EntityID): ComponentRef<S>;
|
|
473
|
+
/**
|
|
474
|
+
* Create a cached read-only component reference for a single entity. Use
|
|
475
|
+
* this when you are not mutating. The returned `ReadonlyComponentRef<S>`
|
|
476
|
+
* is an *advisory* compile-time barrier (no `_changedTick` bump): the
|
|
477
|
+
* `readonly` typing blocks field writes at the type layer, but the
|
|
478
|
+
* underlying accessor shares its prototype with `ref()` and can still be
|
|
479
|
+
* written through a §10c-policed cast. See ref.ts.
|
|
480
|
+
*/
|
|
481
|
+
refRead<S extends ComponentSchema>(def: ComponentDef<S>, entityId: EntityID): ReadonlyComponentRef<S>;
|
|
482
|
+
/** Buffer an entity for deferred destruction (applied at phase flush). */
|
|
483
|
+
destroyEntity(id: EntityID): this;
|
|
484
|
+
addComponent(entityId: EntityID, def: ComponentDef<Record<string, never>>): this;
|
|
485
|
+
addComponent<S extends ComponentSchema>(entityId: EntityID, def: ComponentDef<S>, values: FieldValues<S>): this;
|
|
486
|
+
removeComponent(entityId: EntityID, def: ComponentDef): this;
|
|
487
|
+
/** Buffer `entityId` to be disabled at the phase flush (idempotent). */
|
|
488
|
+
disable(entityId: EntityID): this;
|
|
489
|
+
/** Buffer `entityId` to be re-enabled at the phase flush (idempotent). */
|
|
490
|
+
enable(entityId: EntityID): this;
|
|
491
|
+
/** Whether `entityId` is currently disabled (immediate read). */
|
|
492
|
+
isDisabled(entityId: EntityID): boolean;
|
|
493
|
+
addSparse(entityId: EntityID, def: SparseComponentDef<Record<string, never>>): this;
|
|
494
|
+
addSparse<S extends ComponentSchema>(entityId: EntityID, def: SparseComponentDef<S>, values: FieldValues<S>): this;
|
|
495
|
+
removeSparse(entityId: EntityID, def: SparseComponentDef): this;
|
|
496
|
+
hasSparse(entityId: EntityID, def: SparseComponentDef): boolean;
|
|
497
|
+
getSparseField<S extends ComponentSchema>(entityId: EntityID, def: SparseComponentDef<S>, field: string & keyof S): number;
|
|
498
|
+
setSparseField<S extends ComponentSchema>(entityId: EntityID, def: SparseComponentDef<S>, field: string & keyof S, value: number): void;
|
|
499
|
+
/** Add a `(R, tgt)` pair to `src` (exclusive replaces, multi adds). */
|
|
500
|
+
addRelation(src: EntityID, def: RelationDef, tgt: EntityID): this;
|
|
501
|
+
/** Remove a `(R, tgt)` pair from `src`; for multi, omitting `tgt` removes all. */
|
|
502
|
+
removeRelation(src: EntityID, def: RelationDef, tgt?: EntityID): this;
|
|
503
|
+
/** The single target of `src` under an exclusive relation, or `undefined`. */
|
|
504
|
+
targetOf(src: EntityID, def: RelationDef): EntityID | undefined;
|
|
505
|
+
/** All targets of `src` under `R`, ascending by id. */
|
|
506
|
+
targetsOf(src: EntityID, def: RelationDef): EntityID[];
|
|
507
|
+
/** Sources pointing at `tgt` under `R` (the reverse index), ascending by id. */
|
|
508
|
+
sourcesOf(def: RelationDef, tgt: EntityID): EntityID[];
|
|
509
|
+
/** Whether `src` holds any pair under `R`. */
|
|
510
|
+
hasRelation(src: EntityID, def: RelationDef): boolean;
|
|
511
|
+
/** Flush all deferred changes: structural (add/remove) first, then
|
|
512
|
+
* destructions. Republishes archetype row counts into the SAB
|
|
513
|
+
* descriptor at the end so any WASM scan running in the next phase
|
|
514
|
+
* sees fresh `row_count` fields. This is one of two publish sites —
|
|
515
|
+
* `ECS.update()` also republishes once at tick start (see PATTERNS.md
|
|
516
|
+
* §60), covering host-side mutations between updates. The publish walks
|
|
517
|
+
* descriptors only — it doesn't touch column data — and benches at
|
|
518
|
+
* sub-microsecond per archetype, so paying it once per phase boundary
|
|
519
|
+
* is materially cheaper than the pre-#306 pattern of paying it per
|
|
520
|
+
* WASM-using system per tick. After #336 the descriptor walk is gated
|
|
521
|
+
* on a dirty flag, so read-only phases skip the walk entirely. */
|
|
522
|
+
flush(): void;
|
|
523
|
+
emit(key: SignalKey): void;
|
|
524
|
+
emit<S extends EventSchema>(key: EventKey<S>, values: S): void;
|
|
525
|
+
read<S extends EventSchema>(key: EventKey<S>): EventReader<S>;
|
|
526
|
+
resource<T>(key: ResourceKey<T>): T;
|
|
527
|
+
setResource<T>(key: ResourceKey<T>, value: T): void;
|
|
528
|
+
/** Drop a resource mid-tick (#798). A lifecycle mutation, so it is access-
|
|
529
|
+
* checked as a *write* — the system must declare the key in `resourceWrites`,
|
|
530
|
+
* which serialises it against readers/writers of the same resource. Fails
|
|
531
|
+
* closed on a missing key. */
|
|
532
|
+
removeResource<T>(key: ResourceKey<T>): void;
|
|
533
|
+
hasResource<T>(key: ResourceKey<T>): boolean;
|
|
534
|
+
}
|
|
535
|
+
export declare class ChangedQuery<Defs extends readonly ComponentDef[]> {
|
|
536
|
+
private readonly _query;
|
|
537
|
+
private readonly _changedIds;
|
|
538
|
+
constructor(query: Query<Defs>, changedIds: number[]);
|
|
539
|
+
/** Also require these components (mirrors `Query.and`). */
|
|
540
|
+
and<D extends ComponentDef[]>(...comps: D): ChangedQuery<[...Defs, ...D]>;
|
|
541
|
+
/** Exclude archetypes holding any of these (mirrors `Query.without`). */
|
|
542
|
+
without(...comps: ComponentDef[]): ChangedQuery<Defs>;
|
|
543
|
+
/** Require at least one of these (mirrors `Query.anyOf`). */
|
|
544
|
+
anyOf(...comps: ComponentDef[]): ChangedQuery<Defs>;
|
|
545
|
+
/** Permit optional-component data access in the loop (mirrors `Query.optional`). */
|
|
546
|
+
optional(...defs: ComponentDef[]): ChangedQuery<Defs>;
|
|
547
|
+
forEach(cb: (arch: ArchetypeView) => void): void;
|
|
548
|
+
/** @internal — cold `includeDisabled` wrapper (#577), split out of `forEach`
|
|
549
|
+
* (#649) so the all-rows flag dance stays out of the inlined hot body. */
|
|
550
|
+
private _forEachIncludeDisabled;
|
|
551
|
+
/** @internal — the `includeDisabled` delegate for `forEach` (#577). The
|
|
552
|
+
* default path inlines this body directly into `forEach` (#608) to dodge a
|
|
553
|
+
* megamorphic delegate hop; this copy survives only for the rare all-rows
|
|
554
|
+
* path, which needs the `_setIterAllRows` try/finally wrap. */
|
|
555
|
+
private _forEachInner;
|
|
556
|
+
}
|
|
557
|
+
//# sourceMappingURL=query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/core/ecs/query.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ComponentSchema } from './component';
|
|
2
|
+
import { ArchetypeColumnLayout } from './archetype';
|
|
3
|
+
import { AnyTypedArray, ColumnBacking } from '../../type_primitives';
|
|
4
|
+
/** Maps component schema to scalar get/set properties: { x: number, y: number }. */
|
|
5
|
+
export type ComponentRef<S extends ComponentSchema> = {
|
|
6
|
+
-readonly [K in keyof S]: number;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Read-only view of a component reference. This is an **advisory** barrier,
|
|
10
|
+
* not a runtime safety boundary: the `readonly` properties block field writes
|
|
11
|
+
* at the type layer, but `createRef` installs working get/set on the shared
|
|
12
|
+
* prototype for both `ref()` and `refRead()`, so a §10c-policed cast can
|
|
13
|
+
* still write through (and would skip the change-tick bump `ref()` performs).
|
|
14
|
+
* Treat it as "I promise I am only reading," enforced by the escape-hatch lint
|
|
15
|
+
* (`bun run lint:escape-hatches`), not by the runtime.
|
|
16
|
+
*/
|
|
17
|
+
export type ReadonlyComponentRef<S extends ComponentSchema> = {
|
|
18
|
+
readonly [K in keyof S]: number;
|
|
19
|
+
};
|
|
20
|
+
/** Minimal column group shape needed by createRef. */
|
|
21
|
+
export interface RefColumnGroup {
|
|
22
|
+
readonly layout: ArchetypeColumnLayout;
|
|
23
|
+
readonly columns: ColumnBacking<AnyTypedArray>[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create a ComponentRef bound to a specific row in a column group.
|
|
27
|
+
* The prototype is built once per column group and cached; subsequent
|
|
28
|
+
* calls for the same group only allocate the lightweight ref object.
|
|
29
|
+
*/
|
|
30
|
+
export declare function createRef<S extends ComponentSchema>(group: RefColumnGroup, row: number): ComponentRef<S>;
|
|
31
|
+
//# sourceMappingURL=ref.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ref.d.ts","sourceRoot":"","sources":["../../../src/core/ecs/ref.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;KA2BK;AAEL,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE1E,oFAAoF;AACpF,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,eAAe,IAAI;IACrD,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM;CAChC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,eAAe,IAAI;IAC7D,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM;CAC/B,CAAC;AAMF,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,aAAa,CAAC,EAAE,CAAC;CACjD;AAWD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,eAAe,EAClD,KAAK,EAAE,cAAc,EACrB,GAAG,EAAE,MAAM,GACT,YAAY,CAAC,CAAC,CAAC,CAwBjB"}
|