Files
mdg-filius/tools/java-oracle/src/TerminalWindowRun.java
T
julian.kiedaischandClaude Opus 5.5 ac48e969f4 feat(editor): F4.6b the command line on a computer's desktop
A new oracle, TerminalWindowRun, types into Java's own command line
window: the window writes each line after its prompt, takes a blank
line, cls, reset and exit itself, keeps the lines for the arrow keys,
and keeps its text, history and working directory over a stop and a
start.

The room now holds a command line window per computer for everyone
(TerminalWindow), kept over stops; the protocol carries its lines and
the one way to read them (terminalScreen); the core goes on in the
working directory of the run before (continueIn). The desktop opens
programs in Java's frame, and the command line works with keyboard and
finger: grey on black, the prompt hidden while a command runs, history,
chips for the commands, Ctrl+C. The room's failure is now tested in the
browser.

Fixed: the room handed the engine the wall clock with fractions of a
millisecond, and a ping hung after its first timeout. The engine and
the room count whole milliseconds, as Java's clock does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:22:49 +00:00

109 lines
4.8 KiB
Java

// Types into FILIUS' own command line window (GUIApplicationTerminalWindow on
// a GUIDesktopPanel) of a computer without a network, key by key as its key
// listener hears them, and writes after each key what the window shows: its
// text, its prompt and whether the prompt is shown, the input line. Then the
// simulation is stopped and started again (beenden, starten), as a change of
// mode does, and the window and the working directory are read again: the
// reference for the editor's command line window (packages/sim/test/
// terminalWindow.test.ts).
//
// Usage: java -cp filius.jar:lib/*:classes TerminalWindowRun <output json>
import filius.gui.anwendungssicht.GUIApplicationTerminalWindow;
import filius.gui.anwendungssicht.GUIDesktopPanel;
import filius.hardware.knoten.Rechner;
import filius.software.system.Betriebssystem;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class TerminalWindowRun {
static final String TERMINAL = "filius.software.lokal.Terminal";
static Object field(Object owner, String name) throws Exception {
Field field = GUIApplicationTerminalWindow.class.getDeclaredField(name);
field.setAccessible(true);
return field.get(owner);
}
static Map<String, Object> shown(GUIApplicationTerminalWindow window, String step) throws Exception {
Map<String, Object> result = new LinkedHashMap<>();
result.put("step", step);
result.put("text", ((JTextArea) field(window, "terminalField")).getText());
JLabel label = (JLabel) field(window, "inputLabel");
result.put("prompt", label.getText());
result.put("promptShown", label.isVisible());
result.put("input", ((JTextField) field(window, "inputField")).getText());
return result;
}
static void press(JTextField input, int key, int modifiers) {
KeyEvent event = new KeyEvent(input, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), modifiers, key, KeyEvent.CHAR_UNDEFINED);
for (KeyListener listener : input.getKeyListeners()) listener.keyPressed(event);
}
/** Waits until the program has answered: the prompt is shown again (or a second passed). */
static void settle(GUIApplicationTerminalWindow window) throws Exception {
JLabel label = (JLabel) field(window, "inputLabel");
for (int waited = 0; waited < 2000 && !label.isVisible(); waited += 20) Thread.sleep(20);
Thread.sleep(200);
}
public static void main(String[] args) throws Exception {
try {
run(args);
} catch (Throwable error) {
error.printStackTrace();
System.exit(1);
}
System.exit(0);
}
static void run(String[] args) throws Exception {
Rechner host = new Rechner();
Betriebssystem system = (Betriebssystem) host.getSystemSoftware();
system.installApp(TERMINAL, true);
system.starten();
GUIDesktopPanel desktop = new GUIDesktopPanel(system);
GUIApplicationTerminalWindow window = (GUIApplicationTerminalWindow) desktop.starteAnwendung(TERMINAL);
JTextField input = (JTextField) field(window, "inputField");
List<Object> steps = new ArrayList<>();
steps.add(shown(window, "open"));
// A line typed and entered ("type:<line>"), a key ("up", "down", "ctrl+c"), a stop and start ("restart").
String[] keys = { "enter:", "enter: ", "enter:pwd", "enter:mkdir dir", "enter:cd dir", "enter:pwd", "enter:nosuchcommand", "up", "up", "up", "down", "down", "down",
"enter:cls", "enter:ls", "restart", "enter:pwd", "up", "enter:exit" };
for (String key : keys) {
if (key.startsWith("enter:")) {
input.setText(key.substring("enter:".length()));
press(input, KeyEvent.VK_ENTER, 0);
settle(window);
} else if (key.equals("up")) {
press(input, KeyEvent.VK_UP, 0);
} else if (key.equals("down")) {
press(input, KeyEvent.VK_DOWN, 0);
} else if (key.equals("restart")) {
system.beenden();
system.starten();
Thread.sleep(300);
}
steps.add(shown(window, key));
}
Map<String, Object> output = new LinkedHashMap<>();
output.put("steps", steps);
try (FileOutputStream out = new FileOutputStream(args[0])) {
out.write((FlsOracle.Json.write(output, "") + "\n").getBytes(StandardCharsets.UTF_8));
}
System.out.println("terminal window steps: " + steps.size());
}
}