Skip to content

Default timer doesn't stop when calling .stop() #64

@theseamusjames

Description

@theseamusjames

Issue:
At run time, from a system, I'm calling engine.stop() but the timer doesn't stop.

Expected behavior:
The timer and subsequently all the systems should stop.

Digging into this problem I found that this.loopId in stop() and this.loopId in loop() were exactly one apart, ie. 2047 in stop and 2048 in loop.

There's some issue with the callback passed into requestAnimationFrame. It seems to preserve the state from one iteration before, and thus, even though we set loopId to null in stop, the previous state is executed on the next call of 'loop' and loopId is reset at the end of the function.

You can see this by setting breakpoints in stop and loop and watching the loopId.

Remedy:
I added a flag called this.stopOnNextFrame. Code below:

export default class DefaultTimer {
  constructor() {
    this.subscribers = [];
    this.loopId = null;
    this.stopOnNextFrame = false;
  }

  loop = time => {
    if (this.stopOnNextFrame ) {
      this.stopOnNextFrame = false;
      return;
    }

    if (this.loopId) {
      this.subscribers.forEach(callback => {
        callback(time);
      });
    }

    this.loopId = requestAnimationFrame(this.loop);
  };

  start() {
    if (!this.loopId) {
      this.loop();
    }
  }

  stop() {
    if (this.loopId) {
      this.stopOnNextFrame = true;
      cancelAnimationFrame(this.loopId);
    }
  }

  subscribe(callback) {
    if (this.subscribers.indexOf(callback) === -1)
      this.subscribers.push(callback);
  }

  unsubscribe(callback) {
    this.subscribers = this.subscribers.filter(s => s !== callback)
  }
}```

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions