mirror of
https://github.com/Noratrieb/brainfuck.git
synced 2026-01-16 22:35:03 +01:00
better control
This commit is contained in:
parent
d1141cc6a6
commit
2202c79521
7 changed files with 158 additions and 98 deletions
|
|
@ -1,24 +1,27 @@
|
|||
import React, {useCallback, useEffect, useRef, useState} from 'react';
|
||||
import React, {useCallback, useContext, useEffect, useRef, useState} from 'react';
|
||||
import Interpreter from "../brainfuck/Interpreter";
|
||||
import CodeDisplay from "./CodeDisplay";
|
||||
import RunDisplay from "./RunDisplay";
|
||||
import {CodeOptions} from "./CodeInput";
|
||||
import {OptionContext} from "../App";
|
||||
|
||||
interface RunInfoProps {
|
||||
input: [string, CodeOptions],
|
||||
code: string,
|
||||
setRunning: (running: boolean) => void,
|
||||
running: boolean
|
||||
outHandler: (char: number) => void,
|
||||
}
|
||||
|
||||
const Runner = ({setRunning, running, outHandler, input}: RunInfoProps) => {
|
||||
const Runner = ({setRunning, running, outHandler, code}: RunInfoProps) => {
|
||||
const [speed, setSpeed] = useState(0);
|
||||
const [interpreter, setInterpreter] = useState<Interpreter | null>(null);
|
||||
const [info, setInfo] = useState<string | null>(null);
|
||||
const [startTime, setStartTime] = useState(0);
|
||||
|
||||
|
||||
const [, setRerenderNumber] = useState(0);
|
||||
const options = useContext(OptionContext);
|
||||
|
||||
|
||||
const rerender = () => setRerenderNumber(n => n + 1);
|
||||
|
||||
const inputArea = useRef<HTMLTextAreaElement>(null);
|
||||
|
||||
|
|
@ -37,17 +40,17 @@ const Runner = ({setRunning, running, outHandler, input}: RunInfoProps) => {
|
|||
}
|
||||
|
||||
const startHandler = useCallback(() => {
|
||||
if (input[1].directStart) {
|
||||
if (options.directStart) {
|
||||
setSpeed(100);
|
||||
} else {
|
||||
setSpeed(0);
|
||||
}
|
||||
|
||||
setStartTime(Date.now);
|
||||
setInterpreter(new Interpreter(input, outHandler, inputHandler));
|
||||
setInterpreter(new Interpreter([code, options], outHandler, inputHandler));
|
||||
setRunning(false);
|
||||
setRunning(true);
|
||||
}, [input, outHandler, setRunning]);
|
||||
}, [options, code, outHandler, setRunning]);
|
||||
|
||||
const stopHandler = () => {
|
||||
setRunning(false);
|
||||
|
|
@ -66,7 +69,7 @@ const Runner = ({setRunning, running, outHandler, input}: RunInfoProps) => {
|
|||
setSpeed(0);
|
||||
setInfo(`Finished Execution. Took ${(Date.now() - startTime) / 1000}s`)
|
||||
}
|
||||
setRerenderNumber(n => n + 1);
|
||||
rerender();
|
||||
}, [interpreter, startTime]);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -98,21 +101,11 @@ const Runner = ({setRunning, running, outHandler, input}: RunInfoProps) => {
|
|||
{running && <button onClick={nextHandler}>Next</button>}
|
||||
</div>
|
||||
{
|
||||
running &&
|
||||
<div>
|
||||
<label htmlFor="run-info-speed-range">Speed</label>
|
||||
<input type="range" id="run-info-speed-range" value={speed}
|
||||
onChange={e => setSpeed(+e.target.value)}/>
|
||||
<span> {speed}</span>
|
||||
<span>
|
||||
<button onClick={() => setSpeed(s => s === 0 ? 0 : s - 1)}
|
||||
className="small-speed-button">-</button>
|
||||
<button onClick={() => setSpeed(0)}
|
||||
className="small-speed-button">0</button>
|
||||
<button onClick={() => setSpeed(s => s === 100 ? 100 : s + 1)}
|
||||
className="small-speed-button">+</button>
|
||||
</span>
|
||||
</div>
|
||||
running && interpreter &&
|
||||
<>
|
||||
<SpeedControl speed={speed} setSpeed={setSpeed}/>
|
||||
<ManualControlButtons interpreter={interpreter} rerender={rerender}/>
|
||||
</>
|
||||
}
|
||||
{info && <div className="info">{info}</div>}
|
||||
{
|
||||
|
|
@ -125,4 +118,50 @@ const Runner = ({setRunning, running, outHandler, input}: RunInfoProps) => {
|
|||
);
|
||||
};
|
||||
|
||||
interface SpeedControlProps {
|
||||
speed: number,
|
||||
setSpeed: React.Dispatch<React.SetStateAction<number>>,
|
||||
}
|
||||
|
||||
const SpeedControl = ({speed, setSpeed}: SpeedControlProps) => {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<label htmlFor="run-info-speed-range">Speed</label>
|
||||
<input type="range" id="run-info-speed-range" value={speed}
|
||||
onChange={e => setSpeed(+e.target.value)}/>
|
||||
<span> {speed}</span>
|
||||
<span>
|
||||
<button onClick={() => setSpeed(s => s === 0 ? 0 : s - 1)}
|
||||
className="small-speed-button">-</button>
|
||||
<button onClick={() => setSpeed(0)}
|
||||
className="small-speed-button">0</button>
|
||||
<button onClick={() => setSpeed(s => s === 100 ? 100 : s + 1)}
|
||||
className="small-speed-button">+</button>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const ManualControlButtons = ({interpreter, rerender}: { interpreter: Interpreter, rerender: (() => void) }) => {
|
||||
|
||||
const run = (char: string) => {
|
||||
try {
|
||||
interpreter.execute(char);
|
||||
} catch {
|
||||
}
|
||||
rerender();
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button onClick={() => run('<')} className="small-speed-button"><</button>
|
||||
<button onClick={() => run('>')} className="small-speed-button">></button>
|
||||
<button onClick={() => run('-')} className="small-speed-button">-</button>
|
||||
<button onClick={() => run('+')} className="small-speed-button">+</button>
|
||||
<button onClick={() => run('.')} className="small-speed-button">.</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Runner;
|
||||
Loading…
Add table
Add a link
Reference in a new issue