xros-shell / SpatialShellTerminal.cs
LoveLogicAI's picture
unity terminal
8272517 verified
Raw History Blame Contribute Delete
2.46 kB
// SpatialShellTerminal.cs — the terminal panel: a command line inside VR.
//
// A TextMeshPro input field + output log. Typing a command and submitting it
// sends the text to the backend shell and prints the returned output. This is
// the "terminal" element of the spatial OS.
//
// Setup: attach to a GameObject with a TMP_InputField (input) and a TMP_Text
// (output) as children, and a reference to the XrosClient. Wire the input
// field's OnSubmit event to Submit(), or call Submit() from your own handler.
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using TMPro;
using UnityEngine;
public class SpatialShellTerminal : MonoBehaviour
{
public XrosClient client;
public TMP_InputField input;
public TMP_Text output;
[Tooltip("Maximum number of output lines kept in the log.")]
public int maxLines = 200;
private readonly List<string> history = new List<string>();
private int historyIndex = -1;
private void OnEnable()
{
if (client != null) client.OnMessage += HandleMessage;
}
private void OnDisable()
{
if (client != null) client.OnMessage -= HandleMessage;
}
private void HandleMessage(JObject msg)
{
// Only the terminal cares about "output" (command results).
if (msg["op"]?.ToString() == "output")
{
Append(msg["text"]?.ToString() ?? "");
}
}
public void Submit()
{
if (string.IsNullOrWhiteSpace(input.text)) return;
string line = input.text.Trim();
history.Add(line);
historyIndex = history.Count;
Append("> " + line);
input.text = "";
input.ActivateInputField();
client?.SendCommand(line);
}
public void ScrollHistory(int direction)
{
if (history.Count == 0) return;
historyIndex = Mathf.Clamp(historyIndex + direction, 0, history.Count);
input.text = historyIndex < history.Count ? history[historyIndex] : "";
input.caretPosition = input.text.Length;
}
private void Append(string line)
{
output.text += line + "\n";
// Trim old lines to keep the log bounded.
var lines = output.text.Split('\n');
if (lines.Length > maxLines)
{
var kept = new string[maxLines];
System.Array.Copy(lines, lines.Length - maxLines, kept, 0, maxLines);
output.text = string.Join("\n", kept);
}
}
}