blocking mode

This commit is contained in:
nora 2021-06-25 16:26:54 +02:00
parent 2202c79521
commit e9d3a88bb6
7 changed files with 63 additions and 27 deletions

View file

@ -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 {

View file

@ -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]>(["", {}]);

View file

@ -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}

View file

@ -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;

View file

@ -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>
)
}

View file

@ -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>