public async Task StartLoop() { void onTextInput(string text) { this.engine.InputReceived(); } TextDisplayStore.TextInput += onTextInput; while (true) { switch (this.engine.State) { case ExecutionState.Running: await TextDisplayStore.SetInputMode(AcceptedInputMode.None).ConfigureAwait(false); await this.engine.Execute().ConfigureAwait(false); this.ExecutedStep?.Invoke(); break; case ExecutionState.BlockedOnNumberInput: await TextDisplayStore.SetInputMode(AcceptedInputMode.Numbers).ConfigureAwait(false); break; case ExecutionState.BlockedOnStringInput: await TextDisplayStore.SetInputMode(AcceptedInputMode.Strings).ConfigureAwait(false); break; case ExecutionState.Paused: await TextDisplayStore.SetInputMode(AcceptedInputMode.None).ConfigureAwait(false); break; case ExecutionState.Terminated: await TextDisplayStore.SetInputMode(AcceptedInputMode.None).ConfigureAwait(false); if (CompilationStore.Compilation.Analysis.UsesTextWindow) { await this.Libraries.TextWindow.WriteLine(EditorResources.TextDisplay_TerminateMessage).ConfigureAwait(false); } this.ExecutedStep?.Invoke(); TextDisplayStore.TextInput -= onTextInput; return; default: throw ExceptionUtilities.UnexpectedValue(this.engine.State); } // Libraries should not call this, so that we actually refresh the UI once every batch GraphicsDisplayStore.UpdateDisplay(); // Important to prevent th UI from freezing await Task.Delay(1).ConfigureAwait(false); } }
public void Set_BackgroundColor(string value) { if (decimal.TryParse(value, out decimal number) && TryGetColorName(number, out string name) && PredefinedColors.TryGetHexColor(name, out string hexColor)) { this.backgroundColorName = name; TextDisplayStore.SetBackgroundColor(hexColor); } else if (PredefinedColors.TryGetHexColor(value, out string hex)) { this.backgroundColorName = value; TextDisplayStore.SetBackgroundColor(hex); } }
public TextDisplay() { this.mode = AcceptedInputMode.None; TextDisplayStore.SetDisplay(this); }
private async Task AcceptInput(string key) { if (this.mode == AcceptedInputMode.None) { return; } switch (key) { case "Backspace": { if (!this.inputBuffer.Any()) { return; } this.inputBuffer = this.inputBuffer.Substring(0, this.inputBuffer.Length - 1); break; } case "Enter": { if (!this.inputBuffer.Any()) { return; } TextDisplayStore.NotifyTextInput(this.inputBuffer); await this.AppendOutput(new OutputChunk(this.inputBuffer, "gray", appendNewLine : true)).ConfigureAwait(false); this.inputBuffer = string.Empty; break; } default: { if (key.Length == 1) { char ch = key[0]; switch (this.mode) { case AcceptedInputMode.Numbers: bool validNumber = char.IsDigit(ch) // first char can be '-' for negative numbers || (ch == '-' && this.inputBuffer.Length < 1) // decimal numbers can contain one '.' || (ch == '.' && !this.inputBuffer.Contains('.')); if (!validNumber) { return; } break; case AcceptedInputMode.Strings: break; default: throw ExceptionUtilities.UnexpectedValue(this.mode); } this.inputBuffer += key; } break; } } this.StateHasChanged(); }
private async Task AcceptInput(string key) { if (this.mode == AcceptedInputMode.None) { return; } switch (key) { case "Backspace": { if (!this.inputBuffer.Any()) { return; } this.inputBuffer = this.inputBuffer.Substring(0, this.inputBuffer.Length - 1); break; } case "Enter": { if (!this.inputBuffer.Any()) { return; } TextDisplayStore.NotifyTextInput(this.inputBuffer); await this.AppendOutput(new OutputChunk(this.inputBuffer, "gray", appendNewLine : true)).ConfigureAwait(false); this.inputBuffer = string.Empty; break; } default: { if (key.Length == 1) { char ch = key[0]; switch (this.mode) { case AcceptedInputMode.Numbers: if (!char.IsDigit(ch) || !decimal.TryParse(this.inputBuffer + key, out _)) { return; } break; case AcceptedInputMode.Strings: break; default: throw ExceptionUtilities.UnexpectedValue(this.mode); } this.inputBuffer += key; } break; } } this.StateHasChanged(); }
public Task WriteLine(string data) { return(TextDisplayStore.AppendOutput(new OutputChunk(data, this.foregroundColorName, appendNewLine: true))); }
public void Clear() => TextDisplayStore.Clear();