Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | 28x 28x 28x 28x 65x 65x 65x 18x 16x 16x 16x 16x 16x 5x 4x 4x 4x 4x 4x 17x 17x 17x 30x 17x 40x | /**
* Circular buffer of emulator state snapshots for rewind functionality.
* Snapshots are stored directly without deep-copying, since
* snapshotState() already clones all TypedArrays via .slice().
*/
export class RewindBuffer {
/**
* @param {number} maxSnapshots - maximum number of snapshots to retain
*/
constructor(maxSnapshots = 30) {
this.maxSnapshots = maxSnapshots;
this.snapshots = new Array(maxSnapshots);
this.count = 0;
this.writeIndex = 0;
}
/**
* Push a snapshot into the buffer.
* The caller must ensure the snapshot's typed arrays are already
* independent copies (e.g. from snapshotState() which uses .slice()).
* Overwrites the oldest snapshot when full.
* @param {object} snapshot - emulator state snapshot (already cloned)
*/
push(snapshot) {
this.snapshots[this.writeIndex] = snapshot;
this.writeIndex = (this.writeIndex + 1) % this.maxSnapshots;
if (this.count < this.maxSnapshots) this.count++;
}
/**
* Pop the most recent snapshot from the buffer.
* @returns {object|null} the most recent snapshot, or null if empty
*/
pop() {
if (this.count === 0) return null;
this.writeIndex = (this.writeIndex - 1 + this.maxSnapshots) % this.maxSnapshots;
this.count--;
const snapshot = this.snapshots[this.writeIndex];
this.snapshots[this.writeIndex] = null;
return snapshot;
}
/**
* Peek at the most recent snapshot without removing it.
* @returns {object|null} the most recent snapshot, or null if empty
*/
peek() {
if (this.count === 0) return null;
const index = (this.writeIndex - 1 + this.maxSnapshots) % this.maxSnapshots;
return this.snapshots[index];
}
/**
* Clear all snapshots from the buffer.
*/
clear() {
this.snapshots.fill(null);
this.count = 0;
this.writeIndex = 0;
}
/**
* Return all snapshots in order from oldest to newest.
* @returns {object[]} array of snapshots
*/
getAll() {
const result = new Array(this.count);
const start = (this.writeIndex - this.count + this.maxSnapshots) % this.maxSnapshots;
for (let i = 0; i < this.count; i++) {
result[i] = this.snapshots[(start + i) % this.maxSnapshots];
}
return result;
}
/**
* Number of snapshots currently stored.
* @returns {number}
*/
get length() {
return this.count;
}
}
|