63 lines
1.7 KiB
TypeScript
63 lines
1.7 KiB
TypeScript
import { useEffect, useRef } from 'react';
|
|
|
|
import { RpgRuntimeShell } from './components/rpg-runtime-shell/RpgRuntimeShell';
|
|
import { useRpgRuntimeSession } from './hooks/rpg-session/useRpgRuntimeSession';
|
|
import type { HydratedSavedGameSnapshot } from './persistence/runtimeSnapshotTypes';
|
|
import type { CustomWorldProfile } from './types';
|
|
|
|
export type RpgRuntimeAppIntent =
|
|
| {
|
|
token: number;
|
|
kind: 'custom-world';
|
|
profile: CustomWorldProfile;
|
|
mode?: 'play';
|
|
disablePersistence?: boolean;
|
|
exitToResult?: boolean;
|
|
}
|
|
| {
|
|
token: number;
|
|
kind: 'snapshot';
|
|
snapshot: HydratedSavedGameSnapshot | null;
|
|
};
|
|
|
|
export function RpgRuntimeApp({
|
|
initialIntent,
|
|
onExitRuntime,
|
|
}: {
|
|
initialIntent: RpgRuntimeAppIntent | null;
|
|
onExitRuntime?: () => void;
|
|
}) {
|
|
const gameShellProps = useRpgRuntimeSession();
|
|
const handledIntentTokenRef = useRef<number | null>(null);
|
|
|
|
useEffect(() => {
|
|
if (!initialIntent || handledIntentTokenRef.current === initialIntent.token) {
|
|
return;
|
|
}
|
|
|
|
handledIntentTokenRef.current = initialIntent.token;
|
|
if (initialIntent.kind === 'custom-world') {
|
|
gameShellProps.entry.handleCustomWorldSelect(initialIntent.profile, {
|
|
mode: initialIntent.mode ?? 'play',
|
|
disablePersistence: initialIntent.disablePersistence,
|
|
});
|
|
return;
|
|
}
|
|
|
|
gameShellProps.entry.handleContinueGame(initialIntent.snapshot);
|
|
}, [gameShellProps.entry, initialIntent]);
|
|
|
|
return (
|
|
<RpgRuntimeShell
|
|
{...gameShellProps}
|
|
onExitRuntimePreview={onExitRuntime}
|
|
showRuntimePreviewExit={
|
|
initialIntent?.kind === 'custom-world' &&
|
|
initialIntent.exitToResult === true
|
|
}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export default RpgRuntimeApp;
|