Skip to content

Commit a258088

Browse files
committed
Reset millis() after setup
1 parent b858de8 commit a258088

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

src/core/main.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,8 @@ class p5 {
238238
constants.P2D
239239
);
240240

241-
// Record the time when sketch starts
241+
// Record the time when setup starts. millis() will start at 0 within
242+
// setup, but this isn't documented, locked-in behavior yet.
242243
this._millisStart = window.performance.now();
243244

244245
const context = this._isGlobal ? window : this;
@@ -274,6 +275,10 @@ class p5 {
274275

275276
// Run `postsetup` hooks
276277
await this._runLifecycleHook('postsetup');
278+
279+
// Record the time when the draw loop starts so that millis() starts at 0
280+
// when the draw loop begins.
281+
this._millisStart = window.performance.now();
277282
}
278283

279284
// While '#_draw' here is async, it is not awaited as 'requestAnimationFrame'
@@ -468,11 +473,11 @@ for (const k in constants) {
468473
* If `setup()` is declared `async` (e.g. `async function setup()`),
469474
* execution pauses at each `await` until its promise resolves.
470475
* For example, `font = await loadFont(...)` waits for the font asset
471-
* to load because `loadFont()` function returns a promise, and the await
476+
* to load because `loadFont()` function returns a promise, and the await
472477
* keyword means the program will wait for the promise to resolve.
473478
* This ensures that all assets are fully loaded before the sketch continues.
474479
475-
*
480+
*
476481
* loading assets.
477482
*
478483
* Note: `setup()` doesn’t have to be declared, but it’s common practice to do so.

test/unit/core/main.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,4 +179,36 @@ suite('Core', function () {
179179
assert.isUndefined(logMsg);
180180
});
181181
});
182+
183+
suite('millis()', () => {
184+
let myp5
185+
186+
beforeEach(() => {
187+
vi.useFakeTimers();
188+
});
189+
afterEach(() => {
190+
vi.useRealTimers();
191+
if (myp5) {
192+
myp5.remove();
193+
myp5 = undefined;
194+
}
195+
});
196+
197+
test('millis() starts at 0 when the draw loop begins', async () => {
198+
const t = await new Promise((resolve) => {
199+
myp5 = new p5((p) => {
200+
p.setup = () => {
201+
// Pretend setup takes 1s
202+
vi.advanceTimersByTime(1000);
203+
};
204+
p.draw = () => {
205+
// Pretend draw() happens 50ms after setup
206+
vi.advanceTimersByTime(50);
207+
resolve(p.millis());
208+
};
209+
});
210+
});
211+
expect(t).toEqual(50);
212+
});
213+
});
182214
});

vitest.workspace.mjs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { defineWorkspace } from 'vitest/config';
1+
import { defineWorkspace, configDefaults } from 'vitest/config';
22
import vitePluginString from 'vite-plugin-string';
33

44
const plugins = [
@@ -38,7 +38,10 @@ export default defineWorkspace([
3838
name: 'chrome',
3939
provider: 'webdriverio',
4040
screenshotFailures: false
41-
}
41+
},
42+
fakeTimers: {
43+
toFake: [...(configDefaults.fakeTimers.toFake ?? []), 'performance'],
44+
},
4245
}
4346
}
4447
]);

0 commit comments

Comments
 (0)