@vworlds/vecs 1.0.30 → 1.0.32
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/filter.d.ts +10 -9
- package/dist/filter.js +6 -7
- package/dist/filter.js.map +1 -1
- package/dist/inject.d.ts +20 -9
- package/dist/inject.js +33 -18
- package/dist/inject.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/query/callbacks.d.ts +9 -9
- package/dist/query/callbacks.js +52 -28
- package/dist/query/callbacks.js.map +1 -1
- package/dist/query/group.d.ts +3 -2
- package/dist/query/group.js +2 -2
- package/dist/query/group.js.map +1 -1
- package/dist/query/options.d.ts +29 -0
- package/dist/query/options.js +2 -0
- package/dist/query/options.js.map +1 -0
- package/dist/query/query.d.ts +34 -19
- package/dist/query/query.js +29 -13
- package/dist/query/query.js.map +1 -1
- package/dist/system.d.ts +10 -9
- package/dist/system.js +15 -20
- package/dist/system.js.map +1 -1
- package/docs/README.md +2 -2
- package/docs/design-guide.md +4 -4
- package/docs/queries-and-filters.md +7 -6
- package/docs/systems.md +35 -17
- package/package.json +1 -1
package/docs/systems.md
CHANGED
|
@@ -18,7 +18,7 @@ world
|
|
|
18
18
|
.system("Render")
|
|
19
19
|
.with(Sprite, Position)
|
|
20
20
|
.enter([Sprite, Position], (e, [sprite, pos]) => sprite.show(pos))
|
|
21
|
-
.update(Position, [Sprite], (e, pos, [sprite]) => sprite.moveTo(pos.x, pos.y))
|
|
21
|
+
.update({ watch: Position, inject: [Sprite] }, (e, pos, [sprite]) => sprite.moveTo(pos.x, pos.y))
|
|
22
22
|
.exit([Sprite], (e, [sprite]) => sprite.hide());
|
|
23
23
|
```
|
|
24
24
|
|
|
@@ -77,16 +77,17 @@ taxonomy, ordering rules, and custom phases are covered in
|
|
|
77
77
|
Mutation events are routed into the system's inbox as the world applies commands; the inbox is
|
|
78
78
|
replayed in arrival order at the top of the system's next run, inside a deferred scope.
|
|
79
79
|
|
|
80
|
-
### `.enter(callback)` / `.enter(inject, callback)`
|
|
80
|
+
### `.enter(callback)` / `.enter(inject, callback)` / `.enter(options, callback)`
|
|
81
81
|
|
|
82
82
|
Fires once when an entity starts matching the system:
|
|
83
83
|
|
|
84
84
|
```ts
|
|
85
85
|
.enter((e) => { ... })
|
|
86
86
|
.enter([Position, Sprite], (e, [pos, sprite]) => sprite.setPosition(pos.x, pos.y))
|
|
87
|
+
.enter({ inject: [Position, Sprite] }, (e, [pos, sprite]) => sprite.setPosition(pos.x, pos.y))
|
|
87
88
|
```
|
|
88
89
|
|
|
89
|
-
### `.update(ComponentClass, callback)` / `.update(
|
|
90
|
+
### `.update(ComponentClass, callback)` / `.update(options, callback)`
|
|
90
91
|
|
|
91
92
|
Fires when the watched component is set or marked modified on a tracked entity — and **on entry**
|
|
92
93
|
for each watched component the entity already has. `update(ComponentClass, ...)` also adds
|
|
@@ -96,7 +97,9 @@ reference:
|
|
|
96
97
|
|
|
97
98
|
```ts
|
|
98
99
|
.update(Position, (entity, pos) => renderer.setPosition(entity.eid, pos.x, pos.y))
|
|
99
|
-
.update(Position, [Sprite], (entity, pos, [sprite]) =>
|
|
100
|
+
.update({ watch: Position, inject: [Sprite] }, (entity, pos, [sprite]) =>
|
|
101
|
+
sprite.setPosition(pos.x, pos.y)
|
|
102
|
+
)
|
|
100
103
|
```
|
|
101
104
|
|
|
102
105
|
Because `update` fires on entry, a separate `enter` that applies the same value is redundant —
|
|
@@ -108,7 +111,7 @@ Use `.update(C, ...)` by itself when `C` is the membership shape and watched val
|
|
|
108
111
|
A query or system can register only one `update(C, ...)` callback for each component. A duplicate
|
|
109
112
|
registration throws instead of replacing the existing callback.
|
|
110
113
|
|
|
111
|
-
### `.exit(callback)` / `.exit(inject, callback)`
|
|
114
|
+
### `.exit(callback)` / `.exit(inject, callback)` / `.exit(options, callback)`
|
|
112
115
|
|
|
113
116
|
Fires when an entity stops matching (component removed, or entity destroyed). Directly injected
|
|
114
117
|
components are read from a **snapshot captured at exit time**, so they are still resolvable even
|
|
@@ -117,11 +120,12 @@ be `undefined`:
|
|
|
117
120
|
|
|
118
121
|
```ts
|
|
119
122
|
.exit([Sprite], (e, [sprite]) => sprite.destroy());
|
|
123
|
+
.exit({ inject: [Sprite] }, (e, [sprite]) => sprite.destroy());
|
|
120
124
|
```
|
|
121
125
|
|
|
122
126
|
## Per-tick callbacks: `each` and `run`
|
|
123
127
|
|
|
124
|
-
### `.each(components, callback)`
|
|
128
|
+
### `.each(components, callback)` / `.each(options, callback)`
|
|
125
129
|
|
|
126
130
|
Fires every tick the system runs, once per tracked entity, regardless of change. Use it only for
|
|
127
131
|
genuinely per-frame sweeps — when reacting to change suffices, prefer `update` (see
|
|
@@ -132,6 +136,10 @@ genuinely per-frame sweeps — when reacting to change suffices, prefer `update`
|
|
|
132
136
|
.each([Position, Velocity], (e, [pos, vel]) => {
|
|
133
137
|
pos.x += vel.vx;
|
|
134
138
|
});
|
|
139
|
+
|
|
140
|
+
.each({ inject: [Position, Velocity] }, (e, [pos, vel]) => {
|
|
141
|
+
pos.x += vel.vx;
|
|
142
|
+
});
|
|
135
143
|
```
|
|
136
144
|
|
|
137
145
|
`each` implies `.track()`. Only one `each` per system — a second call throws. The resolved tuple
|
|
@@ -157,11 +165,12 @@ then `each`.
|
|
|
157
165
|
|
|
158
166
|
## Component injection
|
|
159
167
|
|
|
160
|
-
`enter`, `exit`, `update`, `each`, `orderBy`, and `forEach` accept
|
|
161
|
-
|
|
168
|
+
`enter`, `exit`, `update`, `each`, `orderBy`, and `forEach` accept either a short injection list or
|
|
169
|
+
an options object with `inject`, resolved per entity and passed as a typed tuple:
|
|
162
170
|
|
|
163
171
|
```ts
|
|
164
172
|
.each([Position, Sprite], (e, [pos, sprite]) => { ... })
|
|
173
|
+
.each({ inject: [Position, Sprite] }, (e, [pos, sprite]) => { ... })
|
|
165
174
|
```
|
|
166
175
|
|
|
167
176
|
Nullability follows membership: components guaranteed by `with` (or `hint`) are non-nullable;
|
|
@@ -199,17 +208,20 @@ in `each` and `forEach`, at most once per tuple, and entities with zero children
|
|
|
199
208
|
|
|
200
209
|
### The `Iter` cursor
|
|
201
210
|
|
|
202
|
-
Pass `Iter
|
|
203
|
-
|
|
211
|
+
Pass `{ cursor: Iter, ... }` to `each`, `forEach`, `enter`, `exit`, `update`, or `orderBy` to receive
|
|
212
|
+
a reusable cursor instead of the bare entity:
|
|
204
213
|
|
|
205
214
|
```ts
|
|
206
215
|
import { Iter } from "@vworlds/vecs";
|
|
207
216
|
|
|
208
|
-
system.each(
|
|
209
|
-
|
|
210
|
-
it
|
|
211
|
-
|
|
212
|
-
|
|
217
|
+
system.each(
|
|
218
|
+
{ cursor: Iter, inject: [Body, { target: [ChildOf, [Position]] }] },
|
|
219
|
+
(it, [body, pos]) => {
|
|
220
|
+
it.entity; // the visited entity
|
|
221
|
+
it.src[0]; // entity body was read from (the visited entity)
|
|
222
|
+
it.src[1]; // entity pos was read from (the ChildOf target), or undefined
|
|
223
|
+
}
|
|
224
|
+
);
|
|
213
225
|
```
|
|
214
226
|
|
|
215
227
|
`it.src` holds the source entity per tuple slot: the visited entity for direct components, the
|
|
@@ -217,11 +229,11 @@ relationship target for `target` slots, the specific child for `down` slots. Whe
|
|
|
217
229
|
requested, the non-cursor path runs with zero per-entity overhead — dispatch happens once at setup
|
|
218
230
|
time. `each`/`forEach`/`update`/`orderBy` reuse cursor and tuple instances across the pass, so
|
|
219
231
|
snapshot what you need before triggering further mutations from inside a callback. Passing
|
|
220
|
-
`
|
|
232
|
+
`{ cursor: Entity, ... }` is also accepted and means the default entity-first signature.
|
|
221
233
|
|
|
222
234
|
## Ordering and tracking
|
|
223
235
|
|
|
224
|
-
### `.orderBy(components, compare)`
|
|
236
|
+
### `.orderBy(components, compare)` / `.orderBy(options, compare)`
|
|
225
237
|
|
|
226
238
|
Keep matched entities in a custom order. Iteration, `forEach`, and `each` then walk entities in
|
|
227
239
|
sorted order. Implies tracking:
|
|
@@ -232,6 +244,12 @@ world
|
|
|
232
244
|
.with(Position, Sprite)
|
|
233
245
|
.orderBy([Position], (_ea, [a], _eb, [b]) => a.y - b.y)
|
|
234
246
|
.each([Position, Sprite], (e, [pos, sprite]) => sprite.draw(pos.x, pos.y));
|
|
247
|
+
|
|
248
|
+
world
|
|
249
|
+
.system("Render")
|
|
250
|
+
.with(Position, Sprite)
|
|
251
|
+
.orderBy({ inject: [Position] }, (_ea, [a], _eb, [b]) => a.y - b.y)
|
|
252
|
+
.each({ inject: [Position, Sprite] }, (e, [pos, sprite]) => sprite.draw(pos.x, pos.y));
|
|
235
253
|
```
|
|
236
254
|
|
|
237
255
|
Ties break by entity id, so the order is deterministic.
|