import { useEffect, useRef, useState } from 'react'; import styles from './Emulator.module.scss'; type EmulatorSystem = ( 'gb' | 'gbc' | 'gba' ); type EmulatorCore = ( 'gambatte' | 'mgba' ); const EMULATOR_SYSTEM_CORES:{ [key in EmulatorSystem]:EmulatorCore } = { 'gb': 'gambatte', 'gbc': 'gambatte', 'gba': 'mgba' } export type EmulatorProps = { system:EmulatorSystem; }; type SendEmulatorMessageInit = { message:'init'; core:EmulatorCore; system:EmulatorSystem; game:string; gameName:string; } type SendEmulatorMessage = ( SendEmulatorMessageInit ); type ReceiveEmulatorOnGameStart = { message:'start' } type ReceiveEmulatorMessage = ( ReceiveEmulatorOnGameStart ); export const Emulator:React.FC = props => { const iframeRef = useRef(null); const [ hasInit, setHasInit ] = useState(false); const send = (msg:SendEmulatorMessage) => { iframeRef.current?.contentWindow?.postMessage(msg, '*'); }; useEffect(() => { if(hasInit) return; setHasInit(true); send({ message: 'init', core: EMULATOR_SYSTEM_CORES[props.system], system: props.system, game: '/test.gbc', gameName: 'Pokemon - Crystal Version' }); window.onmessage = (e) => { if(!e.data) { console.error('Invalid message received:', e.data); return; } const msg = e.data as ReceiveEmulatorMessage; console.log('recv', msg); switch(msg.message) { case 'start': console.log('Game started!'); break default: console.error('Invalid message received:', msg); break } }; }, [ iframeRef ]); return (