fix(sdk): release lifecycle validation modules
This commit is contained in:
@@ -34,7 +34,12 @@ export function assertGameEntry(entry: GameEntry): void {
|
||||
if (typeof entry.createModule !== 'function') {
|
||||
throw new Error('GameEntry createModule must be a function');
|
||||
}
|
||||
assertGameModule(entry.createModule());
|
||||
const module = entry.createModule();
|
||||
try {
|
||||
assertGameModule(module);
|
||||
} finally {
|
||||
disposeValidationModule(module);
|
||||
}
|
||||
}
|
||||
|
||||
/** Owns one isolated game module for one room at a time. */
|
||||
@@ -59,15 +64,20 @@ export class GameSessionHost {
|
||||
}
|
||||
|
||||
this.currentState = 'attaching';
|
||||
let module: GameModule | undefined;
|
||||
try {
|
||||
const module = this.entry.createModule();
|
||||
module = this.entry.createModule();
|
||||
assertGameModule(module);
|
||||
this.module = module;
|
||||
module.attach(host);
|
||||
this.currentState = 'active';
|
||||
} catch (error) {
|
||||
this.module = undefined;
|
||||
this.currentState = 'idle';
|
||||
try {
|
||||
module?.dispose();
|
||||
} finally {
|
||||
this.currentState = 'idle';
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -163,3 +173,9 @@ function assertGameModule(module: unknown): asserts module is GameModule {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function disposeValidationModule(module: unknown): void {
|
||||
if (!module || typeof module !== 'object') return;
|
||||
const dispose = (module as Record<string, unknown>).dispose;
|
||||
if (typeof dispose === 'function') dispose.call(module);
|
||||
}
|
||||
|
||||
+10
-2
@@ -9,6 +9,7 @@ import { assertGameEntry, GameSessionHost } from '../runtime/game-session-host.t
|
||||
export interface GameContractHost {
|
||||
readonly host: GameHost;
|
||||
invalidate(): void;
|
||||
assertRestored(deskinfo: unknown): void;
|
||||
}
|
||||
|
||||
export type GameContractHostFactory = () => GameContractHost;
|
||||
@@ -24,8 +25,14 @@ export function assertGameContract(entry: GameEntry, makeHost: GameContractHostF
|
||||
}
|
||||
|
||||
const firstFactoryModule = entry.createModule();
|
||||
const secondFactoryModule = entry.createModule();
|
||||
assert.notEqual(firstFactoryModule, secondFactoryModule, 'createModule must create isolated modules');
|
||||
let secondFactoryModule: ReturnType<GameEntry['createModule']> | undefined;
|
||||
try {
|
||||
secondFactoryModule = entry.createModule();
|
||||
assert.notEqual(firstFactoryModule, secondFactoryModule, 'createModule must create isolated modules');
|
||||
} finally {
|
||||
firstFactoryModule.dispose();
|
||||
if (secondFactoryModule && secondFactoryModule !== firstFactoryModule) secondFactoryModule.dispose();
|
||||
}
|
||||
|
||||
const sessions = new GameSessionHost(entry);
|
||||
runCycle(sessions, makeHost(), entry, 1);
|
||||
@@ -49,6 +56,7 @@ function runCycle(
|
||||
/route/,
|
||||
);
|
||||
sessions.restore(deskinfo);
|
||||
contractHost.assertRestored(deskinfo);
|
||||
sessions.close();
|
||||
contractHost.invalidate();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user