A test that waits for a deadline somebody guessed is waiting for the wrong thing, so it waits for the editor (#93)
game-maker / suite (push) Successful in 6m48s
game-maker / suite (push) Successful in 6m48s
The suite spent 88% of its step time asleep: 564 s of steps, 496 s of
them in sleep(n) - fixed spans estimated by hand and then copied from
step to step. That is why it was slow, and why it flickered.
The signal is afterFrames(count, timeout) in ui/render.ts, exposed as
__gm.afterFrames(). It wakes the loop itself, because an editor that
draws nothing would never redeem a promise of a frame, and it gives up
after a timeout instead of hanging the run. settle() in the harness
waits two drawn frames (~32 ms) instead of 150-300 ms and falls back to
sleep(150) when the hook is missing (an old build): silently not
waiting would make every later check a coin toss.
Every action goes through it now - click, doubleClick, wheel, drag,
dragAsset, press, typeText, select, mutate, undo, redo - and with that
about 550 sleep() calls behind those actions became redundant, helpers
that are nothing but a mutate in a coat included. What a frame cannot
answer got its own condition instead: waitUntil(expr), play()/stop()
waiting on __gm.state.mode rather than on 300 ms, saved() for the
autosave (the two hand-written polling loops sampled at 300 ms for
something that arrives after a second), and showTab() as a real tool -
47 places called evaluate("__gm.showTab(...)") raw, and 24 of them
waited for nothing at all and read the old panel.
564 s -> 243 s of step time, the waiting share 88% -> 76%. Three kinds
of wait were kept, and each one bit when it was taken away: loading
bytes (textures, fonts), game time that a repaint cannot stand in for
(time scale, shader and particle clocks, the live values a running
graph carries), and the inertia the scroll step measures on purpose.
Two things the new speed uncovered, both real: 25-animation read the
frame menu unfiltered and had frozen an incomplete list (the CI failure
on c990dbc), and 33-render-on-change measured idleness while the
autosave of the step before was still painting - it waits for
saveStatus to leave dirty/saving now, so it measures that nothing
happens any more instead of that it waited long enough.
This commit is contained in:
1 parent
c990dbcb26
commit
7e5003b590
41 files changed
+362
-732
No files matched your search
@@ -33,6 +33,7 @@ export async function transform(t) {
|
||||
entity,
|
||||
stop,
|
||||
shot,
|
||||
showTab,
|
||||
} = t;
|
||||
const field = (label) => json(`__gm.inspectorField(${JSON.stringify(label)})`);
|
||||
const rect = (id) => json(`__gm.objectRect(${JSON.stringify(id)})`);
|
||||
@@ -47,7 +48,6 @@ export async function transform(t) {
|
||||
);
|
||||
const selectObject = async (id) => {
|
||||
await select({ kind: 'object', holderId: 'scene1', objectIds: [id], objectId: id });
|
||||
await sleep(300);
|
||||
};
|
||||
const remove = (ids) =>
|
||||
mutate(`
|
||||
@@ -57,8 +57,7 @@ export async function transform(t) {
|
||||
|
||||
await press('Escape');
|
||||
await evaluate('__gm.state.select(null)');
|
||||
await evaluate("__gm.showTab('scene')");
|
||||
await sleep(200);
|
||||
await showTab('scene');
|
||||
|
||||
// 29a. A plain red 100×40 sprite in its lane, and a second camera to read the inspector off;
|
||||
// a sprite object has the transform rows, a camera object has not.
|
||||
@@ -118,7 +117,6 @@ export async function transform(t) {
|
||||
|
||||
// 29c. Rotation 90: the box stands up – its frame swaps sides, the pixels move with it.
|
||||
await override(BOX, { rotation: 90 });
|
||||
await sleep(300);
|
||||
const turned = await rect(BOX);
|
||||
const turnedPx = { right: await px(40, 0), below: await px(0, 40) };
|
||||
check(
|
||||
@@ -132,7 +130,6 @@ export async function transform(t) {
|
||||
|
||||
// 29d. Scale 2 on top: twice the frame, red where the upright box would have ended long ago.
|
||||
await override(BOX, { scale: 2 });
|
||||
await sleep(300);
|
||||
const grown = await rect(BOX);
|
||||
const far = await px(0, 90);
|
||||
check(
|
||||
@@ -159,7 +156,6 @@ export async function transform(t) {
|
||||
JSON.stringify(plain),
|
||||
);
|
||||
await override(BOX, { mirrorX: true });
|
||||
await sleep(300);
|
||||
const mirrored = { left: await px(-30, 0), right: await px(30, 0) };
|
||||
check(
|
||||
'Mirror X swaps the halves: green left, red right',
|
||||
@@ -167,7 +163,6 @@ export async function transform(t) {
|
||||
JSON.stringify(mirrored),
|
||||
);
|
||||
await override(BOX, { mirrorY: true });
|
||||
await sleep(300);
|
||||
const both = { left: await px(-30, 0), right: await px(30, 0) };
|
||||
check(
|
||||
'Mirror Y on top leaves the halves where Mirror X put them',
|
||||
@@ -176,17 +171,14 @@ export async function transform(t) {
|
||||
);
|
||||
await override(BOX, { mirrorX: false, mirrorY: false });
|
||||
await spriteProps({ texture: '', color: 0xff0000 });
|
||||
await sleep(300);
|
||||
|
||||
// 29f. A child 100 to the right of its parent: once the parent turns a quarter, the child hangs
|
||||
// 100 below it – and is drawn turned itself.
|
||||
await mutate(`
|
||||
const scene = __gm.state.activeScene;
|
||||
scene.objects.push({ id: ${JSON.stringify(CHILD)}, assetId: ${JSON.stringify(SPRITE)}, name: '', position: { x: 100, y: 0, z: 1 }, editorOffset: { x: 0, y: 0 }, overrides: {}, parentId: ${JSON.stringify(BOX)}, instanceEdits: {} });`);
|
||||
await sleep(300);
|
||||
const flat = { parent: await screen(BOX), child: await screen(CHILD) };
|
||||
await override(BOX, { rotation: 90 });
|
||||
await sleep(300);
|
||||
const hung = { parent: await screen(BOX), child: await screen(CHILD), childRect: await rect(CHILD) };
|
||||
check(
|
||||
'a child follows its parent’s turn: 100 to the right becomes 100 below, drawn turned',
|
||||
@@ -202,7 +194,6 @@ export async function transform(t) {
|
||||
// 29g. Dragging the child 30 screen pixels down moves it along the parent's x axis – which now
|
||||
// points down – so its local x grows by 30 / scale and y stays.
|
||||
await drag(hung.child.x, hung.child.y, hung.child.x, hung.child.y + 30, { steps: 8 });
|
||||
await sleep(300);
|
||||
const dragged = await object(CHILD);
|
||||
check(
|
||||
'a drag under a turned parent lands in the parent’s frame: local x + 30 / scale, y unchanged',
|
||||
@@ -210,7 +201,6 @@ export async function transform(t) {
|
||||
JSON.stringify({ position: dragged.position, expected: 100 + 30 / s }),
|
||||
);
|
||||
await undo();
|
||||
await sleep(200);
|
||||
check('undo puts the child back', (await object(CHILD)).position.x === 100);
|
||||
await selectObject(CHILD);
|
||||
const gizmos = await json('__gm.gizmos()');
|
||||
@@ -236,7 +226,6 @@ export async function transform(t) {
|
||||
);
|
||||
__gm.state.select(null)`);
|
||||
await press('Enter', { ctrl: true });
|
||||
await sleep(300);
|
||||
await holdKey('ArrowRight', 1000);
|
||||
const body = await entity('otf-body');
|
||||
await stop();
|
||||
@@ -255,7 +244,6 @@ export async function transform(t) {
|
||||
project.assets = project.assets.filter((a) => !gone.has(a.id));
|
||||
__gm.lookAt(0, 0)`);
|
||||
await evaluate('__gm.state.select(null)');
|
||||
await sleep(200);
|
||||
check(
|
||||
'the step leaves nothing behind',
|
||||
(await json(`__gm.state.project.assets.some((a) => a.id === ${JSON.stringify(SPRITE)})`)) === false &&
|
||||
|
||||
Reference in new issue
Block a user