mirror of
https://github.com/Noratrieb/brainfuck.git
synced 2026-01-14 13:35:00 +01:00
blocking mode
This commit is contained in:
parent
2202c79521
commit
e9d3a88bb6
7 changed files with 63 additions and 27 deletions
|
|
@ -34,6 +34,10 @@ $medium-color: #78787f;
|
|||
height: 400px;
|
||||
font-size: 100px;
|
||||
}
|
||||
|
||||
.code-options-wrapper > * {
|
||||
margin: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.code-display-wrapper {
|
||||
|
|
@ -67,12 +71,18 @@ $medium-color: #78787f;
|
|||
}
|
||||
}
|
||||
|
||||
.run-button {
|
||||
height: 50px;
|
||||
width: 200px;
|
||||
|
||||
}
|
||||
|
||||
.bf-run {
|
||||
margin: 20px;
|
||||
|
||||
button {
|
||||
height: 50px;
|
||||
width: 200px;
|
||||
|
||||
.speed-control-wrapper > * {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.small-speed-button {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import './App.scss';
|
||||
import CodeInput, {CodeOptions} from "./components/CodeInput";
|
||||
import ProgramOutput from "./components/ProgramOutput";
|
||||
import '../App.scss';
|
||||
import CodeInput, {CodeOptions} from "./CodeInput";
|
||||
import ProgramOutput from "./ProgramOutput";
|
||||
import React, {useCallback, useState} from "react";
|
||||
import Runner from "./components/Runner";
|
||||
import Runner from "./Runner";
|
||||
|
||||
export const OptionContext = React.createContext<CodeOptions>({});
|
||||
|
||||
|
||||
function App() {
|
||||
const [out, setOut] = useState("");
|
||||
const [input, setInput] = useState<[string, CodeOptions]>(["", {}]);
|
||||
|
|
@ -4,6 +4,7 @@ import presets from "../presets.json";
|
|||
export interface CodeOptions {
|
||||
minify?: boolean,
|
||||
directStart?: boolean,
|
||||
startSuperSpeed?: boolean,
|
||||
enableBreakpoints?: boolean
|
||||
asciiView?: boolean
|
||||
}
|
||||
|
|
@ -26,7 +27,7 @@ const CodeInput = ({input: [code, options], setInput}: CodeInputProps) => {
|
|||
|
||||
return (
|
||||
<div className="bf-input">
|
||||
<div>
|
||||
<div className="code-options-wrapper">
|
||||
<div>
|
||||
<label htmlFor="bf-input-fontsize-range">Font Size</label>
|
||||
<input type="range" id="bf-input-fontsize-range" onChange={v => setFontSize(+v.target.value)}/>
|
||||
|
|
@ -35,6 +36,8 @@ const CodeInput = ({input: [code, options], setInput}: CodeInputProps) => {
|
|||
<CodeOption displayName="Minify Code" name="minify" options={options} onChange={changeHandler}/>
|
||||
<CodeOption displayName="Start Directly" name="directStart" options={options}
|
||||
onChange={changeHandler}/>
|
||||
<CodeOption displayName="Start in blocking mode" name="startSuperSpeed" options={options}
|
||||
onChange={changeHandler}/>
|
||||
<CodeOption displayName="Breakpoints (•)" name="enableBreakpoints" options={options}
|
||||
onChange={changeHandler}/>
|
||||
<CodeOption displayName="Show ASCII in memory" name="asciiView" options={options}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React, {useContext, useRef, useState} from 'react';
|
||||
import Interpreter from "../brainfuck/Interpreter";
|
||||
import {OptionContext} from "../App";
|
||||
import {OptionContext} from "./App";
|
||||
|
||||
const MAX_TABLE_COLUMNS = 20;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,13 @@ import React, {useCallback, useContext, useEffect, useRef, useState} from 'react
|
|||
import Interpreter from "../brainfuck/Interpreter";
|
||||
import CodeDisplay from "./CodeDisplay";
|
||||
import RunDisplay from "./RunDisplay";
|
||||
import {OptionContext} from "../App";
|
||||
import {OptionContext} from "./App";
|
||||
|
||||
|
||||
interface RunInfoProps {
|
||||
code: string,
|
||||
running: boolean,
|
||||
setRunning: (running: boolean) => void,
|
||||
running: boolean
|
||||
code: string,
|
||||
outHandler: (char: number) => void,
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +42,11 @@ const Runner = ({setRunning, running, outHandler, code}: RunInfoProps) => {
|
|||
|
||||
const startHandler = useCallback(() => {
|
||||
if (options.directStart) {
|
||||
setSpeed(100);
|
||||
if (options.startSuperSpeed) {
|
||||
setSpeed(-1);
|
||||
} else {
|
||||
setSpeed(100);
|
||||
}
|
||||
} else {
|
||||
setSpeed(0);
|
||||
}
|
||||
|
|
@ -72,20 +77,35 @@ const Runner = ({setRunning, running, outHandler, code}: RunInfoProps) => {
|
|||
rerender();
|
||||
}, [interpreter, startTime]);
|
||||
|
||||
const runBlocking = useCallback(() => {
|
||||
try {
|
||||
while (speed === -1 && !interpreter?.reachedEnd) {
|
||||
interpreter?.next();
|
||||
}
|
||||
setSpeed(0);
|
||||
setInfo(`Finished Execution. Took ${(Date.now() - startTime) / 1000}s`)
|
||||
} catch (e) {
|
||||
setInfo(e.message);
|
||||
setSpeed(0);
|
||||
}
|
||||
}, [speed, interpreter, startTime]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (running) {
|
||||
if (speed === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const interval = setInterval(() => {
|
||||
nextHandler();
|
||||
}, 1000 / (speed * 10));
|
||||
|
||||
return () => clearInterval(interval);
|
||||
if (speed > 0) {
|
||||
const interval = setInterval(() => {
|
||||
nextHandler();
|
||||
}, 1000 / (speed * 10));
|
||||
return () => clearInterval(interval);
|
||||
}
|
||||
runBlocking();
|
||||
}
|
||||
}, [running, nextHandler, speed]);
|
||||
|
||||
}, [runBlocking, running, nextHandler, speed]);
|
||||
|
||||
return (
|
||||
<div className="bf-run">
|
||||
|
|
@ -96,9 +116,9 @@ const Runner = ({setRunning, running, outHandler, code}: RunInfoProps) => {
|
|||
</>
|
||||
}
|
||||
<div>
|
||||
{running && <button onClick={stopHandler}>Back</button>}
|
||||
<button onClick={startHandler}>{running ? "Restart" : "Start"}</button>
|
||||
{running && <button onClick={nextHandler}>Next</button>}
|
||||
{running && <button className="run-button" onClick={stopHandler}>Back</button>}
|
||||
<button className="run-button" onClick={startHandler}>{running ? "Restart" : "Start"}</button>
|
||||
{running && <button className="run-button" onClick={nextHandler}>Next</button>}
|
||||
</div>
|
||||
{
|
||||
running && interpreter &&
|
||||
|
|
@ -126,7 +146,7 @@ interface SpeedControlProps {
|
|||
const SpeedControl = ({speed, setSpeed}: SpeedControlProps) => {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="speed-control-wrapper">
|
||||
<label htmlFor="run-info-speed-range">Speed</label>
|
||||
<input type="range" id="run-info-speed-range" value={speed}
|
||||
onChange={e => setSpeed(+e.target.value)}/>
|
||||
|
|
@ -139,6 +159,10 @@ const SpeedControl = ({speed, setSpeed}: SpeedControlProps) => {
|
|||
<button onClick={() => setSpeed(s => s === 100 ? 100 : s + 1)}
|
||||
className="small-speed-button">+</button>
|
||||
</span>
|
||||
<span>
|
||||
<label>Superspeed Mode (blocking)</label>
|
||||
<input id="superspeed-mode-check" type="checkbox" checked={speed === -1} onChange={() => setSpeed(-1)}/>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import App from './components/App';
|
||||
|
||||
ReactDOM.render(
|
||||
<React.StrictMode>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue