import React from "react"; import { CodeEditor, CodeEditorRef } from "../ui/code-editor"; import { InputEditor, InputEditorRef } from "../ui/input-editor"; import { MainLayout } from "../ui/MainLayout"; import { useExecController } from "../ui/use-exec-controller"; import { DocumentRange, LanguageProvider } from "../engines/types"; import SampleLangProvider from "../engines/sample-lang"; import BrainfuckProvider from "../engines/brainfuck"; import { OutputViewer } from "../ui/output-viewer"; export const Mainframe = () => { const codeEditorRef = React.useRef(null); const inputEditorRef = React.useRef(null); // const providerRef = React.useRef>(SampleLangProvider); const providerRef = React.useRef>(BrainfuckProvider); const execController = useExecController(); // UI states used in execution time const [rendererState, setRendererState] = React.useState(null); const [output, setOutput] = React.useState(null); const [codeHighlights, setCodeHighlights] = React.useState< DocumentRange | undefined >(); const testDrive = React.useCallback(async () => { console.info("=== RUNNING TEST DRIVE ==="); // Check that controller is ready to execute const readyStates = ["empty", "ready", "done"]; if (!readyStates.includes(execController.state)) { console.error(`Controller not ready: state is ${execController.state}`); return; } // Prepare for execution setOutput(""); await execController.resetState(); await execController.prepare( codeEditorRef.current!.getValue(), inputEditorRef.current!.getValue() ); // Begin execution await execController.executeAll((result) => { setRendererState(result.rendererState); setCodeHighlights(result.nextStepLocation || undefined); setOutput((o) => (o || "") + (result.output || "")); }, 20); }, [execController.state]); React.useEffect(() => { const handler = (ev: KeyboardEvent) => { if (!(ev.ctrlKey && ev.code === "KeyY")) return; testDrive(); }; document.addEventListener("keydown", handler); return () => document.removeEventListener("keydown", handler); }, [testDrive]); return ( ( )} renderRenderer={() => ( )} renderInput={() => } renderOutput={() => } /> ); };