add onNextPhase and advance to phaseInterceptor

This commit is contained in:
snoozbuster 2024-08-13 21:10:11 -07:00
parent eb11b951e6
commit d45ed3d9d3
1 changed files with 32 additions and 0 deletions

View File

@ -38,6 +38,9 @@ import UI, { Mode } from "#app/ui/ui";
import { Phase } from "#app/phase"; import { Phase } from "#app/phase";
import ErrorInterceptor from "#app/test/utils/errorInterceptor"; import ErrorInterceptor from "#app/test/utils/errorInterceptor";
import { QuietFormChangePhase } from "#app/form-change-phase"; import { QuietFormChangePhase } from "#app/form-change-phase";
import { expect } from "vitest";
type PhaseClassType = (abstract new (...args: any) => Phase); // `typeof Phase` does not work here because of some issue with ctor signatures
export default class PhaseInterceptor { export default class PhaseInterceptor {
public scene; public scene;
@ -173,6 +176,14 @@ export default class PhaseInterceptor {
}); });
} }
/**
* Advance a single phase
* @returns A promise that resolves when the next phase has started
*/
advance(): Promise<void> {
return this.run(this.onHold[0]);
}
/** /**
* Method to run a phase with an optional skip function. * Method to run a phase with an optional skip function.
* @param phaseTarget - The phase to run. * @param phaseTarget - The phase to run.
@ -213,6 +224,27 @@ export default class PhaseInterceptor {
}); });
} }
/**
* The next time a phase of the given type would be run, first run the provided callback.
* The phase instance is passed to the callback, for easier mocking.
*
* This function does not actually start running phases - for that, see {@linkcode to()}.
* @param phaseType Class type of the phase you want to tap
* @param cb callback to run when the phase next arrives
*/
onNextPhase<T extends PhaseClassType>(phaseType: T, cb: (phase: InstanceType<T>) => void) {
const targetName = phaseType.name;
this.scene.moveAnimations = null; // Mandatory to avoid crash
ErrorInterceptor.getInstance().add(this);
const interval = setInterval(async () => {
const currentPhase = this.onHold[0];
if (currentPhase?.name === targetName) {
clearInterval(interval);
cb(currentPhase);
}
});
}
pop() { pop() {
this.onHold.pop(); this.onHold.pop();
this.scene.shiftPhase(); this.scene.shiftPhase();