Fix that addAction wouldn't have any effect without a stop and start (#1001)

* Fix that `addAction` wouldn't have any effect without a stop and start - noticed during live mode

* Remove `addActions` as it has a bug-causing replacement of `this.actions` - refactor to reuse `addAction` and add a `push` fast-track to this function for the common case of adding actions in the correct order

* Apply formatting changes

Co-authored-by: eoghanmurray <eoghanmurray@users.noreply.github.com>
This commit is contained in:
Eoghan Murray
2026-04-01 12:00:00 +08:00
committed by GitHub
parent b9516a2759
commit 1afa9fb180
2 changed files with 15 additions and 15 deletions

View File

@@ -188,7 +188,6 @@ export function createPlayerService(
}
const syncEvents = new Array<eventWithTime>();
const actions = new Array<actionWithDelay>();
for (const event of neededEvents) {
if (
lastPlayedTimestamp &&
@@ -202,7 +201,7 @@ export function createPlayerService(
syncEvents.push(event);
} else {
const castFn = getCastFn(event, false);
actions.push({
timer.addAction({
doAction: () => {
castFn();
},
@@ -212,7 +211,6 @@ export function createPlayerService(
}
applyEventsSynchronously(syncEvents);
emitter.emit(ReplayerEvents.Flush);
timer.addActions(actions);
timer.start();
},
pause(ctx) {

View File

@@ -25,38 +25,40 @@ export class Timer {
this.liveMode = config.liveMode;
}
/**
* Add an action after the timer starts.
* Add an action, possibly after the timer starts.
*/
public addAction(action: actionWithDelay) {
if (
!this.actions.length ||
this.actions[this.actions.length - 1].delay <= action.delay
) {
// 'fast track'
this.actions.push(action);
return;
}
// binary search - events can arrive out of order in a realtime context
const index = this.findActionIndex(action);
this.actions.splice(index, 0, action);
}
/**
* Add all actions before the timer starts
*/
public addActions(actions: actionWithDelay[]) {
this.actions = this.actions.concat(actions);
}
public start() {
this.timeOffset = 0;
let lastTimestamp = performance.now();
const { actions } = this;
const check = () => {
const time = performance.now();
this.timeOffset += (time - lastTimestamp) * this.speed;
lastTimestamp = time;
while (actions.length) {
const action = actions[0];
while (this.actions.length) {
const action = this.actions[0];
if (this.timeOffset >= action.delay) {
actions.shift();
this.actions.shift();
action.doAction();
} else {
break;
}
}
if (actions.length > 0 || this.liveMode) {
if (this.actions.length > 0 || this.liveMode) {
this.raf = requestAnimationFrame(check);
}
};