tone 15.1.6 → 15.1.8

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.
@@ -217,6 +217,21 @@ describe("Context", () => {
217
217
  }, 0.01);
218
218
  }, 0.05);
219
219
  });
220
+
221
+ it("is robust against altering the timeline within the callback fn", (done) => {
222
+ let invokeCount = 0;
223
+ function checkDone(id: number) {
224
+ // clearing the current event alters the timeline and should not cause an issue
225
+ ctx.clearTimeout(id);
226
+ invokeCount++;
227
+ if (invokeCount === 3) {
228
+ done();
229
+ }
230
+ }
231
+ const id0 = ctx.setTimeout(() => checkDone(id0), 0.01);
232
+ const id1 = ctx.setTimeout(() => checkDone(id1), 0.01);
233
+ const id2 = ctx.setTimeout(() => checkDone(id2), 0.01);
234
+ });
220
235
  });
221
236
 
222
237
  context("setInterval", () => {
@@ -558,15 +558,11 @@ export class Context extends BaseContext {
558
558
  */
559
559
  private _timeoutLoop(): void {
560
560
  const now = this.now();
561
- let firstEvent = this._timeouts.peek();
562
- while (this._timeouts.length && firstEvent && firstEvent.time <= now) {
561
+ this._timeouts.forEachBefore(now, (event) => {
563
562
  // invoke the callback
564
- firstEvent.callback();
565
- // shift the first event off
566
- this._timeouts.shift();
567
- // get the next one
568
- firstEvent = this._timeouts.peek();
569
- }
563
+ event.callback();
564
+ this._timeouts.remove(event);
565
+ });
570
566
  }
571
567
 
572
568
  /**
@@ -8,6 +8,10 @@ describe("Draw", () => {
8
8
  draw.dispose();
9
9
  });
10
10
 
11
+ afterEach(() => {
12
+ draw.cancel(0);
13
+ });
14
+
11
15
  it("can schedule a callback at a AudioContext time", (done) => {
12
16
  const scheduledTime = draw.now() + 0.2;
13
17
  draw.schedule(() => {
@@ -98,15 +98,12 @@ export class DrawClass extends ToneWithContext<ToneWithContextOptions> {
98
98
  */
99
99
  private _drawLoop(): void {
100
100
  const now = this.context.currentTime;
101
- while (
102
- this._events.length &&
103
- (this._events.peek() as DrawEvent).time - this.anticipation <= now
104
- ) {
105
- const event = this._events.shift();
106
- if (event && now - event.time <= this.expiration) {
101
+ this._events.forEachBefore(now + this.anticipation, (event) => {
102
+ if (now - event.time <= this.expiration) {
107
103
  event.callback();
108
104
  }
109
- }
105
+ this._events.remove(event);
106
+ });
110
107
  if (this._events.length > 0) {
111
108
  this._animationFrame = requestAnimationFrame(this._boundDrawLoop);
112
109
  }
@@ -141,6 +141,7 @@ export class Timeline<GenericEvent extends TimelineEvent> extends Tone {
141
141
  /**
142
142
  * Return the first event in the timeline without removing it
143
143
  * @returns {Object} The first event object
144
+ * @deprecated
144
145
  */
145
146
  peek(): GenericEvent | undefined {
146
147
  return this._timeline[0];
@@ -148,6 +149,7 @@ export class Timeline<GenericEvent extends TimelineEvent> extends Tone {
148
149
 
149
150
  /**
150
151
  * Return the first event in the timeline and remove it
152
+ * @deprecated
151
153
  */
152
154
  shift(): GenericEvent | undefined {
153
155
  return this._timeline.shift();
@@ -196,20 +196,20 @@ export abstract class OneShotSource<
196
196
  * Invoke the onended callback
197
197
  */
198
198
  protected _onended(): void {
199
- if (this.onended !== noOp) {
200
- this.onended(this);
201
- // overwrite onended to make sure it only is called once
202
- this.onended = noOp;
203
- // dispose when it's ended to free up for garbage collection only in the online context
204
- if (!this.context.isOffline) {
205
- const disposeCallback = () => this.dispose();
206
- // @ts-ignore
207
- if (typeof window.requestIdleCallback !== "undefined") {
208
- // @ts-ignore
209
- window.requestIdleCallback(disposeCallback);
210
- } else {
211
- setTimeout(disposeCallback, 1000);
212
- }
199
+ if (this.onended === noOp) {
200
+ return;
201
+ }
202
+
203
+ this.onended(this);
204
+ // overwrite onended to make sure it only is called once
205
+ this.onended = noOp;
206
+ // dispose when it's ended to free up for garbage collection only in the online context
207
+ if (!this.context.isOffline) {
208
+ const disposeCallback = () => this.dispose();
209
+ if (typeof requestIdleCallback !== "undefined") {
210
+ requestIdleCallback(disposeCallback);
211
+ } else {
212
+ setTimeout(disposeCallback, 10);
213
213
  }
214
214
  }
215
215
  }
package/Tone/version.ts CHANGED
@@ -1 +1 @@
1
- export const version: string = "15.1.6";
1
+ export const version: string = "15.1.8";