feat(doc): F4.4a devices and cables in the document, undo per person; NewDeviceRun

A new device is what Java's palette makes, measured with the new oracle
NewDeviceRun (every kind and router size saved as FILIUS saves). Devices
move to whole pixels and go with their cables; a cable takes the first free
port, a home router's WAN port unless its LAN port is asked for, a wireless
host only joins a switch, two devices join once, each refusal named with
Java's message. Each person's undo takes back their own changes only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 09:18:14 +00:00
co-authored by Claude Opus 5.5
parent 63273916b5
commit 27ab7a1f49
9 changed files with 595 additions and 9 deletions
+33
View File
@@ -1062,3 +1062,36 @@ Gemessen (03.10.2026):
dazwischen um wenige Millisekunden je Sekunde: In der E-Mail-Geschichte
folgt die Weitergabe gmx → webmail auf herberts Verbindung, ihre Frames
liegen bis zu 272 ms hinter dem Kern.
## Neue Geräte aus der Palette (F4.4a)
`NewDeviceRun` legt jede Geräteart so an wie Filius' Palette
(`GUIContainer.neuerKnoten`: Konstruktor, beim Vermittlungsrechner die
Schnittstellenzahl seines Dialogs, Beschriftung, `setProperty`, das die
Einstellungen des Geräts öffnet) und speichert sie wie Filius
(`SzenarioVerwaltung.speichern`) nach
`packages/doc/test/fixtures/new-devices.fls`: Rechner, Notebook, Switch,
Vermittlungsrechner mit 2 bis 8 Schnittstellen, Heimrouter, Modem.
Gemessen (03.10.2026):
* Rechner und Notebook: eine Karte 192.168.0.10/255.255.255.0, kein
Gateway, kein DNS, leeres Dateisystem, keine Programme.
* Switch: 24 Ports, SSID gewürfelt (sechs Hexziffern).
* Vermittlungsrechner: so viele Karten wie gewählt, alle 192.168.0.10/24,
Firewall aus (Standardregeln), kein Eintrag als Gerät; schließt man den
Dialog, sind es 2.
* Heimrouter: WAN 42.0.0.10/255.0.0.0, LAN 192.168.0.10/24, Firewall aus.
* Modem: ein Port, Port 12345.
* MAC-Adressen gewürfelt. Der Name ist der Typ der Geräteart in der
Sprache der Oberfläche (`Knoten.TYPE`).
* Ablegen: Die Vorschau hängt mittig am Zeiger; nach dem Setzen der
Beschriftung rückt Java den Knopf so, dass das Symbol bleibt, wo die
Vorschau war (`initTextAndUpdateLocation`).
* Kabel (`GUIEvents`): der erste freie Port; am Heimrouter WAN, wenn man
die linke Hälfte des Knopfs trifft, sonst LAN; ein Funkgerät nur an einen
Switch; zwei Geräte nur einmal verbunden. Javas Meldungen:
`guievents_msg1` (kein freier Port), `msg22`/`msg23` (WAN/LAN belegt),
`msg26` (drahtlos nicht möglich), `msg12` (bereits verbunden).
* Ein Wettlauf im Swing-Thread wirft beim Speichern gelegentlich eine
Ausnahme; die Datei wird trotzdem vollständig geschrieben.
+8 -1
View File
@@ -21,7 +21,7 @@ if [ ! -f "$upstream/target/filius.jar" ]; then
fi
classpath="$upstream/target/filius.jar:$upstream/target/lib/*"
mkdir -p "$here/.build"
javac -encoding UTF-8 -d "$here/.build" -cp "$classpath" "$here/src/FlsOracle.java" "$here/src/GetterDefaults.java" "$here/src/IpCheckCases.java" "$here/src/DnsHostsCases.java" "$here/src/EmailFileCases.java" "$here/src/BeansDump.java" "$here/src/Base64Cases.java" "$here/src/ScenarioNetwork.java" "$here/src/DhcpRun.java" "$here/src/TcpRun.java" "$here/src/DnsRun.java" "$here/src/ArpRun.java" "$here/src/RipRun.java" "$here/src/NatRun.java" "$here/src/WlanRun.java" "$here/src/ExampleRun.java" "$here/src/EchoRun.java" "$here/src/WebRun.java" "$here/src/RouterWebRun.java" "$here/src/KonfigCases.java" "$here/src/EmailRun.java" "$here/src/MailCases.java" "$here/src/EmailClientRun.java" "$here/src/TerminalCases.java" "$here/src/TerminalRun.java" "$here/src/FileCases.java" "$here/src/GnutellaRun.java"
javac -encoding UTF-8 -d "$here/.build" -cp "$classpath" "$here/src/FlsOracle.java" "$here/src/GetterDefaults.java" "$here/src/IpCheckCases.java" "$here/src/DnsHostsCases.java" "$here/src/EmailFileCases.java" "$here/src/BeansDump.java" "$here/src/Base64Cases.java" "$here/src/ScenarioNetwork.java" "$here/src/DhcpRun.java" "$here/src/TcpRun.java" "$here/src/DnsRun.java" "$here/src/ArpRun.java" "$here/src/RipRun.java" "$here/src/NatRun.java" "$here/src/WlanRun.java" "$here/src/ExampleRun.java" "$here/src/EchoRun.java" "$here/src/WebRun.java" "$here/src/RouterWebRun.java" "$here/src/KonfigCases.java" "$here/src/EmailRun.java" "$here/src/MailCases.java" "$here/src/EmailClientRun.java" "$here/src/TerminalCases.java" "$here/src/TerminalRun.java" "$here/src/FileCases.java" "$here/src/GnutellaRun.java" "$here/src/NewDeviceRun.java"
# FILIUS writes its settings below $HOME; keep them out of the real one.
mkdir -p "$here/.build/home"
# Removed first: a crashed run must not leave the previous result standing.
@@ -321,6 +321,13 @@ for run in pingLan:8000 pingRouted:13000 pingNobody:49000 pingUnreachable:45000
test -s "$output"
done
# Every kind of device as FILIUS' palette makes it, saved as FILIUS saves
# (NewDeviceRun): what the editor's new devices must be (packages/doc/test/devices.test.ts).
output="$root/packages/doc/test/fixtures/new-devices.fls"
rm -f "$output"
HOME="$here/.build/home" xvfb-run -a java -cp "$classpath:$here/.build" NewDeviceRun "$output" 2>&1 | grep -v 'logback\|^$' || true
test -s "$output"
# FILIUS' own examples as Java FILIUS runs them, opened and started as FILIUS
# does (ExampleRun): the acceptance of F2 (packages/fls/test/examplesJava.test.ts)
# and the classics of F3 (web, email, gnutella; packages/fls/test/classicsJava.test.ts).
+62
View File
@@ -0,0 +1,62 @@
// Makes every kind of device as FILIUS' palette makes it
// (GUIContainer.neuerKnoten: the constructor, a router's number of interfaces
// from its dialog, the label, setProperty, which opens the device's settings)
// and saves them in one project, as FILIUS saves (SzenarioVerwaltung.speichern).
// The editor's new devices must be what this file holds once read
// (packages/doc/test/devices.test.ts).
//
// NewDeviceRun <out.fls>
//
// In the file's order: Rechner, Notebook, Switch, Vermittlungsrechner with 2
// to 8 interfaces, Gateway (Heimrouter), Modem.
import filius.gui.GUIContainer;
import filius.gui.netzwerksicht.GUIDesignSidebar;
import filius.gui.netzwerksicht.GUIKabelItem;
import filius.gui.netzwerksicht.GUIKnotenItem;
import filius.gui.netzwerksicht.JSidebarButton;
import filius.gui.netzwerksicht.GUIDocuItem;
import filius.hardware.knoten.Gateway;
import filius.hardware.knoten.Knoten;
import filius.hardware.knoten.Modem;
import filius.hardware.knoten.Notebook;
import filius.hardware.knoten.Rechner;
import filius.hardware.knoten.Switch;
import filius.hardware.knoten.Vermittlungsrechner;
import filius.rahmenprogramm.SzenarioVerwaltung;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
public class NewDeviceRun {
static void add(List<GUIKnotenItem> items, Knoten device, String icon, int x, int y) {
JSidebarButton label = new JSidebarButton(new ImageIcon(NewDeviceRun.class.getResource("/" + icon + ".png")), device.holeHardwareTyp());
label.setBounds(x, y, label.getWidth(), label.getHeight());
label.initTextAndUpdateLocation(device.holeAnzeigeName());
GUIKnotenItem item = new GUIKnotenItem();
item.setKnoten(device);
item.setImageLabel(label);
GUIContainer.getGUIContainer().setProperty(device);
items.add(item);
}
public static void main(String[] args) throws Exception {
GUIContainer.getGUIContainer();
List<GUIKnotenItem> items = new ArrayList<>();
add(items, new Rechner(), GUIDesignSidebar.RECHNER, 100, 100);
add(items, new Notebook(), GUIDesignSidebar.NOTEBOOK, 300, 100);
add(items, new Switch(), GUIDesignSidebar.SWITCH, 500, 100);
for (int interfaces = 2; interfaces <= 8; interfaces++) {
Vermittlungsrechner router = new Vermittlungsrechner();
router.setzeAnzahlAnschluesse(interfaces);
add(items, router, GUIDesignSidebar.VERMITTLUNGSRECHNER, 100 * interfaces, 300);
}
add(items, new Gateway(), GUIDesignSidebar.GATEWAY, 100, 500);
add(items, new Modem(), GUIDesignSidebar.MODEM, 300, 500);
if (!SzenarioVerwaltung.getInstance().speichern(args[0], items, new ArrayList<GUIKabelItem>(), new ArrayList<GUIDocuItem>())) {
throw new IllegalStateException("FILIUS could not save " + args[0]);
}
System.exit(0);
}
}