Last active
April 4, 2023 11:21
-
-
Save timsonner/bcd60dceb4389ae514f77e18c2074757 to your computer and use it in GitHub Desktop.
C#. Unity. System.Diagnostics library. Spawn system processes, TMP_InputField and TMP_Text. Mock Terminal.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System.Diagnostics; | |
| using System.IO; | |
| using System.Threading; | |
| using TMPro; | |
| using UnityEngine; | |
| public class Terminal : MonoBehaviour | |
| { | |
| public TMP_InputField inputField; | |
| public TMP_Text outputText; | |
| public TMP_Text outputTextCurrentDirectory; | |
| public TMP_Text outputTextCommandEntered; | |
| private string currentDirectory = Directory.GetCurrentDirectory(); | |
| private Process process; | |
| private SynchronizationContext mainThreadContext; | |
| private Process processToKill; | |
| private void Awake() | |
| { | |
| mainThreadContext = SynchronizationContext.Current; | |
| } | |
| private void Start() | |
| { | |
| inputField.onEndEdit.AddListener(SendCommand); | |
| outputTextCurrentDirectory.text = currentDirectory; | |
| } | |
| private void Update() | |
| { | |
| if (Input.GetKey(KeyCode.LeftControl) && Input.GetKeyDown(KeyCode.C)) | |
| { | |
| // Plus 1 hack... | |
| string killCommand = "kill " + (processToKill.Id + 1); | |
| SendCommand(killCommand); | |
| mainThreadContext.Post(_ => outputTextCommandEntered.text += "\n" + killCommand, null); | |
| } | |
| } | |
| private void SendCommand(string command) | |
| { | |
| Thread thread = new(() => | |
| { | |
| process = new Process(); | |
| processToKill = process; | |
| // Handle directory changes | |
| if (command.Split(' ')[0] == "cd") | |
| { | |
| currentDirectory = command[3..]; | |
| print("Changing directory to: " + currentDirectory); | |
| mainThreadContext.Post(_ => outputTextCurrentDirectory.text = currentDirectory, null); | |
| mainThreadContext.Post(_ => inputField.text = "", null); | |
| } | |
| process.StartInfo.FileName = "/bin/bash"; | |
| process.StartInfo.Arguments = "-c \"cd " + currentDirectory + " && " + command + "\""; | |
| process.StartInfo.UseShellExecute = false; | |
| process.StartInfo.RedirectStandardOutput = true; | |
| process.StartInfo.RedirectStandardError = true; | |
| process.OutputDataReceived += (sender, args) => | |
| { | |
| if (args.Data != null) | |
| { | |
| mainThreadContext.Post(_ => outputText.text += "\n" + args.Data, null); | |
| mainThreadContext.Post(_ => outputTextCurrentDirectory.text = currentDirectory, null); | |
| mainThreadContext.Post(_ => inputField.text = "", null); | |
| mainThreadContext.Post(_ => outputTextCommandEntered.text += "\n" + command + " " + process.Id, null); | |
| } | |
| }; | |
| process.ErrorDataReceived += (sender, args) => | |
| { | |
| if (args.Data != null) | |
| { | |
| mainThreadContext.Post(_ => outputText.text += "\n" + args.Data, null); | |
| mainThreadContext.Post(_ => outputTextCurrentDirectory.text = currentDirectory, null); | |
| mainThreadContext.Post(_ => inputField.text = "", null); | |
| mainThreadContext.Post(_ => outputTextCommandEntered.text += "\n" + command + " " + process.Id, null); | |
| } | |
| }; | |
| process.Start(); | |
| process.BeginOutputReadLine(); | |
| process.BeginErrorReadLine(); | |
| process.WaitForExit(); | |
| }); | |
| thread.Start(); | |
| } | |
| } |
Author
Author
all items complete
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Todo:
- IO stream handling for commands like ping or top.
- Keyboard interupt handlers; ctrl-c for instance.
- Clear input field "On End Edit", eg. when user hits enter.
- Handle directory changes, eg. "cd ~/"
- Fix the way user input is parsed. A command like echo "foo" > bar breaks command call.
- Backround image and green text, because its kewl.