Implement basic execution system and UI
This is a rather large commit that includes all of the following: - React UI with code editor, runtime renderer and input-output panes - Language providers for a sample language and Brainfuck - Implementation of code execution in a web worker - All-at-once unabortable execution of program fully functional
This commit is contained in:
60
engines/execution-controller.ts
Normal file
60
engines/execution-controller.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { LanguageEngine, StepExecutionResult } from "./types";
|
||||
|
||||
type ExecuteAllArgs<RS> = {
|
||||
/** Interval between two execution steps, in milliseconds */
|
||||
interval?: number;
|
||||
/**
|
||||
* Pass to run in streaming-response mode.
|
||||
* Callback is called with exeuction result on every execution step.
|
||||
*/
|
||||
onResult?: (result: StepExecutionResult<RS>) => void;
|
||||
};
|
||||
|
||||
class ExecutionController<RS> {
|
||||
private _engine: LanguageEngine<RS>;
|
||||
private _result: StepExecutionResult<RS> | null;
|
||||
|
||||
/**
|
||||
* Create a new ExecutionController.
|
||||
* @param engine Language engine to use for execution
|
||||
*/
|
||||
constructor(engine: LanguageEngine<RS>) {
|
||||
this._engine = engine;
|
||||
this._engine.resetState();
|
||||
this._result = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset execution state in controller and engine.
|
||||
* Clears out state from the current execution cycle.
|
||||
*/
|
||||
resetState() {
|
||||
this._engine.resetState();
|
||||
this._result = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load code and user input into the engine to prepare for execution.
|
||||
* @param code Code content, lines separated by `\n`
|
||||
* @param input User input, lines separated by '\n'
|
||||
*/
|
||||
prepare(code: string, input: string) {
|
||||
this._engine.prepare(code, input);
|
||||
}
|
||||
|
||||
async executeAll({ interval, onResult }: ExecuteAllArgs<RS>) {
|
||||
while (true) {
|
||||
this._result = this._engine.executeStep();
|
||||
onResult && onResult(this._result);
|
||||
if (!this._result.nextStepLocation) break;
|
||||
if (interval) await this.sleep(interval);
|
||||
}
|
||||
return this._result;
|
||||
}
|
||||
|
||||
private async sleep(millis: number) {
|
||||
return new Promise<void>((resolve) => setTimeout(resolve, millis));
|
||||
}
|
||||
}
|
||||
|
||||
export default ExecutionController;
|
||||
Reference in New Issue
Block a user