@typeonce/ritmo 0.8.0 → 0.9.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 +3 -2
- package/dist/Clock.d.ts +19 -4
- package/dist/Clock.d.ts.map +1 -1
- package/dist/Clock.js +18 -2
- package/dist/Clock.js.map +1 -1
- package/dist/Command.d.ts +101 -45
- package/dist/Command.d.ts.map +1 -1
- package/dist/Command.js +22 -4
- package/dist/Command.js.map +1 -1
- package/dist/Debug.d.ts +66 -8
- package/dist/Debug.d.ts.map +1 -1
- package/dist/Descriptor.d.ts +27 -9
- package/dist/Descriptor.d.ts.map +1 -1
- package/dist/Descriptor.js +13 -9
- package/dist/Descriptor.js.map +1 -1
- package/dist/Entity.d.ts +15 -8
- package/dist/Entity.d.ts.map +1 -1
- package/dist/Entity.js.map +1 -1
- package/dist/FixedLoop.d.ts +106 -0
- package/dist/FixedLoop.d.ts.map +1 -0
- package/dist/FixedLoop.js +97 -0
- package/dist/FixedLoop.js.map +1 -0
- package/dist/HostClock.d.ts +1 -1
- package/dist/HostClock.d.ts.map +1 -1
- package/dist/HostClock.js +2 -1
- package/dist/HostClock.js.map +1 -1
- package/dist/Machine.d.ts +4 -1
- package/dist/Machine.d.ts.map +1 -1
- package/dist/Machine.js +4 -1
- package/dist/Machine.js.map +1 -1
- package/dist/Query.d.ts +52 -10
- package/dist/Query.d.ts.map +1 -1
- package/dist/Query.js +2 -1
- package/dist/Query.js.map +1 -1
- package/dist/Relation.d.ts +5 -14
- package/dist/Relation.d.ts.map +1 -1
- package/dist/Relation.js +0 -32
- package/dist/Relation.js.map +1 -1
- package/dist/Runtime.d.ts +58 -15
- package/dist/Runtime.d.ts.map +1 -1
- package/dist/Runtime.js +288 -70
- package/dist/Runtime.js.map +1 -1
- package/dist/Schedule.d.ts +24 -15
- package/dist/Schedule.d.ts.map +1 -1
- package/dist/Schedule.js +2 -1
- package/dist/Schedule.js.map +1 -1
- package/dist/Schema.d.ts +98 -29
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +4 -4
- package/dist/Schema.js.map +1 -1
- package/dist/Snapshot.d.ts +76 -1
- package/dist/Snapshot.d.ts.map +1 -1
- package/dist/Snapshot.js +42 -1
- package/dist/Snapshot.js.map +1 -1
- package/dist/System.d.ts +68 -24
- package/dist/System.d.ts.map +1 -1
- package/dist/System.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/cells.d.ts +2 -0
- package/dist/internal/cells.d.ts.map +1 -1
- package/dist/internal/cells.js +34 -8
- package/dist/internal/cells.js.map +1 -1
- package/dist/internal/debug.d.ts +3 -0
- package/dist/internal/debug.d.ts.map +1 -1
- package/dist/internal/debug.js +83 -15
- package/dist/internal/debug.js.map +1 -1
- package/dist/internal/fragments.d.ts +2 -6
- package/dist/internal/fragments.d.ts.map +1 -1
- package/dist/internal/fragments.js +25 -2
- package/dist/internal/fragments.js.map +1 -1
- package/dist/internal/game.d.ts +2 -0
- package/dist/internal/game.d.ts.map +1 -1
- package/dist/internal/game.js +16 -3
- package/dist/internal/game.js.map +1 -1
- package/dist/internal/queries.d.ts.map +1 -1
- package/dist/internal/queries.js +27 -18
- package/dist/internal/queries.js.map +1 -1
- package/dist/internal/relations.d.ts +10 -0
- package/dist/internal/relations.d.ts.map +1 -0
- package/dist/internal/relations.js +32 -0
- package/dist/internal/relations.js.map +1 -0
- package/dist/internal/streams.d.ts +2 -0
- package/dist/internal/streams.d.ts.map +1 -1
- package/dist/internal/streams.js +10 -0
- package/dist/internal/streams.js.map +1 -1
- package/dist/internal/world.d.ts +7 -1
- package/dist/internal/world.d.ts.map +1 -1
- package/dist/internal/world.js +53 -3
- package/dist/internal/world.js.map +1 -1
- package/package.json +1 -1
- package/src/Clock.ts +29 -4
- package/src/Command.ts +161 -67
- package/src/Debug.ts +61 -9
- package/src/Descriptor.ts +43 -17
- package/src/Entity.ts +16 -9
- package/src/FixedLoop.ts +218 -0
- package/src/HostClock.ts +2 -1
- package/src/Machine.ts +4 -1
- package/src/Query.ts +47 -10
- package/src/Relation.ts +5 -67
- package/src/Runtime.ts +345 -85
- package/src/Schedule.ts +31 -19
- package/src/Schema.ts +118 -35
- package/src/Snapshot.ts +90 -2
- package/src/System.ts +76 -23
- package/src/index.ts +4 -0
- package/src/internal/cells.ts +42 -10
- package/src/internal/debug.ts +84 -15
- package/src/internal/fragments.ts +23 -3
- package/src/internal/game.ts +19 -3
- package/src/internal/queries.ts +28 -2
- package/src/internal/relations.ts +52 -0
- package/src/internal/streams.ts +11 -0
- package/src/internal/world.ts +60 -4
package/src/internal/streams.ts
CHANGED
|
@@ -59,6 +59,8 @@ export interface Streams<T> {
|
|
|
59
59
|
* reader has read, then enforces the capacity.
|
|
60
60
|
*/
|
|
61
61
|
trim(windowBoundary: number): void
|
|
62
|
+
/** Drops every batch stamped after `tick` (what a rolled-back phase published). */
|
|
63
|
+
retract(tick: number): void
|
|
62
64
|
/** Clears simulation messages; unread host messages survive world restore. */
|
|
63
65
|
clear(): void
|
|
64
66
|
/** Every key with retained entries or registered readers. */
|
|
@@ -151,6 +153,15 @@ export const make = <T>(capacity: number): Streams<T> => {
|
|
|
151
153
|
dropFront(log, overflow)
|
|
152
154
|
}
|
|
153
155
|
},
|
|
156
|
+
retract(tick) {
|
|
157
|
+
for (const log of logs.values()) {
|
|
158
|
+
const start = firstAfter(log.ticks, tick)
|
|
159
|
+
for (let index = start; index < log.batches.length; index++) log.size -= log.batches[index]!.length
|
|
160
|
+
log.ticks.length = start
|
|
161
|
+
log.batches.length = start
|
|
162
|
+
log.surviveRestore.length = start
|
|
163
|
+
}
|
|
164
|
+
},
|
|
154
165
|
clear() {
|
|
155
166
|
for (const [key, log] of logs) {
|
|
156
167
|
const ticks: Array<number> = []
|
package/src/internal/world.ts
CHANGED
|
@@ -48,6 +48,8 @@ export interface EntityRecord {
|
|
|
48
48
|
* Cached query matches by query ordinal, reused while the entity matches.
|
|
49
49
|
*/
|
|
50
50
|
readonly matches: Array<unknown>
|
|
51
|
+
/** The name of the component at an ordinal, for error messages (shared by the world's records). */
|
|
52
|
+
readonly nameAt: (ordinal: number) => string
|
|
51
53
|
alive: boolean
|
|
52
54
|
}
|
|
53
55
|
|
|
@@ -227,6 +229,16 @@ export const makeWorld = <S extends Schema.Any>(schema: S, lifecycleCapacity: nu
|
|
|
227
229
|
const journalRecords: Array<EntityRecord> = []
|
|
228
230
|
const journalOrdinals: Array<number> = []
|
|
229
231
|
const journalValues: Array<unknown> = []
|
|
232
|
+
/**
|
|
233
|
+
* Journal of a phase: several system transactions undone together (a
|
|
234
|
+
* transition's exit schedules). Each committed write keeps its value and
|
|
235
|
+
* change tick from before it, so rollback restores both, newest first.
|
|
236
|
+
*/
|
|
237
|
+
let inPhase = false
|
|
238
|
+
const phaseRecords: Array<EntityRecord> = []
|
|
239
|
+
const phaseOrdinals: Array<number> = []
|
|
240
|
+
const phaseValues: Array<unknown> = []
|
|
241
|
+
const phaseChanged: Array<number> = []
|
|
230
242
|
|
|
231
243
|
/**
|
|
232
244
|
* Entity ownership used by scene and level lifetime scopes.
|
|
@@ -238,6 +250,8 @@ export const makeWorld = <S extends Schema.Any>(schema: S, lifecycleCapacity: nu
|
|
|
238
250
|
/** Suppresses per-component and relation hooks inside spawns and despawns. */
|
|
239
251
|
let hookDepth = 0
|
|
240
252
|
|
|
253
|
+
const nameAt = (ordinal: number): string => descriptors[ordinal]?.name ?? `component #${ordinal}`
|
|
254
|
+
|
|
241
255
|
const ordinalOf = (descriptor: ComponentDescriptor): number => {
|
|
242
256
|
const known = ordinals.get(descriptor.key)
|
|
243
257
|
if (known !== undefined) {
|
|
@@ -337,6 +351,7 @@ export const makeWorld = <S extends Schema.Any>(schema: S, lifecycleCapacity: nu
|
|
|
337
351
|
values,
|
|
338
352
|
marks,
|
|
339
353
|
matches: [],
|
|
354
|
+
nameAt,
|
|
340
355
|
alive: true
|
|
341
356
|
}
|
|
342
357
|
records.set(record.id, record)
|
|
@@ -363,14 +378,19 @@ export const makeWorld = <S extends Schema.Any>(schema: S, lifecycleCapacity: nu
|
|
|
363
378
|
/**
|
|
364
379
|
* Writes an existing component value in place and records the change.
|
|
365
380
|
*/
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
381
|
+
/**
|
|
382
|
+
* Writes a component the entity holds. Returns `false`, writing nothing,
|
|
383
|
+
* when it does not (despawned records hold nothing): only a stale query
|
|
384
|
+
* cell gets here, and it reports the misuse.
|
|
385
|
+
*/
|
|
386
|
+
const setComponentValue = (record: EntityRecord, ordinal: number, value: unknown): boolean => {
|
|
387
|
+
if (record.values[ordinal] === ABSENT) {
|
|
388
|
+
return false
|
|
369
389
|
}
|
|
370
390
|
if (!inTransaction) {
|
|
371
391
|
record.values[ordinal] = value
|
|
372
392
|
markChanged(record, ordinal)
|
|
373
|
-
return
|
|
393
|
+
return true
|
|
374
394
|
}
|
|
375
395
|
const slot = ordinal * MARK_STRIDE + JOURNALED
|
|
376
396
|
if (record.marks[slot] !== transaction) {
|
|
@@ -380,6 +400,7 @@ export const makeWorld = <S extends Schema.Any>(schema: S, lifecycleCapacity: nu
|
|
|
380
400
|
journalValues.push(record.values[ordinal])
|
|
381
401
|
}
|
|
382
402
|
record.values[ordinal] = value
|
|
403
|
+
return true
|
|
383
404
|
}
|
|
384
405
|
|
|
385
406
|
const clearJournal = (): void => {
|
|
@@ -403,6 +424,13 @@ export const makeWorld = <S extends Schema.Any>(schema: S, lifecycleCapacity: nu
|
|
|
403
424
|
inTransaction = false
|
|
404
425
|
for (let index = 0; index < journalRecords.length; index++) {
|
|
405
426
|
const record = journalRecords[index]!
|
|
427
|
+
if (inPhase) {
|
|
428
|
+
const ordinal = journalOrdinals[index]!
|
|
429
|
+
phaseRecords.push(record)
|
|
430
|
+
phaseOrdinals.push(ordinal)
|
|
431
|
+
phaseValues.push(journalValues[index])
|
|
432
|
+
phaseChanged.push(record.marks[ordinal * MARK_STRIDE + CHANGED]!)
|
|
433
|
+
}
|
|
406
434
|
if (record.alive) {
|
|
407
435
|
markChanged(record, journalOrdinals[index]!)
|
|
408
436
|
}
|
|
@@ -421,6 +449,30 @@ export const makeWorld = <S extends Schema.Any>(schema: S, lifecycleCapacity: nu
|
|
|
421
449
|
clearJournal()
|
|
422
450
|
}
|
|
423
451
|
|
|
452
|
+
const clearPhase = (): void => {
|
|
453
|
+
inPhase = false
|
|
454
|
+
phaseRecords.length = 0
|
|
455
|
+
phaseOrdinals.length = 0
|
|
456
|
+
phaseValues.length = 0
|
|
457
|
+
phaseChanged.length = 0
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/** Starts a phase: the transactions committed until it ends can be undone together. */
|
|
461
|
+
const beginPhase = (): void => {
|
|
462
|
+
inPhase = true
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/** Restores every write committed in the phase, with its change tick. */
|
|
466
|
+
const rollbackPhase = (): void => {
|
|
467
|
+
for (let index = phaseRecords.length - 1; index >= 0; index--) {
|
|
468
|
+
const record = phaseRecords[index]!
|
|
469
|
+
const ordinal = phaseOrdinals[index]!
|
|
470
|
+
record.values[ordinal] = phaseValues[index]
|
|
471
|
+
record.marks[ordinal * MARK_STRIDE + CHANGED] = phaseChanged[index]!
|
|
472
|
+
}
|
|
473
|
+
clearPhase()
|
|
474
|
+
}
|
|
475
|
+
|
|
424
476
|
const clearEntityScope = (id: number): void => {
|
|
425
477
|
const scopeKey = scopeByEntity.get(id)
|
|
426
478
|
if (scopeKey === undefined) {
|
|
@@ -779,6 +831,7 @@ export const makeWorld = <S extends Schema.Any>(schema: S, lifecycleCapacity: nu
|
|
|
779
831
|
records,
|
|
780
832
|
relationDefinitions,
|
|
781
833
|
ordinalOf,
|
|
834
|
+
nameAt,
|
|
782
835
|
has,
|
|
783
836
|
entityIdOf,
|
|
784
837
|
allocateEntity,
|
|
@@ -792,6 +845,9 @@ export const makeWorld = <S extends Schema.Any>(schema: S, lifecycleCapacity: nu
|
|
|
792
845
|
beginTransaction,
|
|
793
846
|
commitTransaction,
|
|
794
847
|
rollbackTransaction,
|
|
848
|
+
beginPhase,
|
|
849
|
+
commitPhase: clearPhase,
|
|
850
|
+
rollbackPhase,
|
|
795
851
|
tryRelate,
|
|
796
852
|
unrelate,
|
|
797
853
|
reorderChildren,
|