Ereigniszustellung und Hostgrenzen korrigieren und Change archivieren

This commit is contained in:
2026-09-05 19:15:31 +02:00
parent 57d6386a5a
commit 644a86212f
39 changed files with 2013 additions and 271 deletions

View File

@@ -55,15 +55,76 @@ enum Value {
## Ausführungsmodell / Unterbrechbarkeit
- Die Interpreterschleife läuft in **Ticks**: nach jeder Anweisung (Grenze
aus der Zeilentabelle) prüft sie ein Flag-Set: Breakpoint? Einzelschritt?
Strg+Untbr? Ereignis-Queue nicht leer und Zustellung erlaubt?
- Ereigniszustellung (Forms, Timer) erfolgt kooperativ: nur an
Zustellpunkten (`DOEVENTS`, `SLEEP`, blockierende Eingabe, Ende einer
Ereignisprozedur) — wie im Vorbild.
- Die VM ist eine gewöhnliche zustandsbehaftete Struktur, `step()`-basiert;
die einbettende Schleife (IDE-Debugger oder Runner) treibt sie. Kein
eigener Thread nötig; Terminal-Events werden zwischen Ticks gepollt.
Die VM läuft auf dem aufrufenden Thread. `Vm::run` liefert bei STOP,
Breakpoint, Einzelschritt, Programmende oder Fehler ein `RunEvent` an den
Runner zurück. `Stmt` markiert Anweisungsgrenzen; es gibt keine Prüfung
nach jedem Opcode.
Die gemeinsame Zustellentscheidung gilt an Anweisungsgrenzen, bei
`DOEVENTS`, während `SLEEP` und während blockierender Konsoleneingabe. Eine
zugestellte Ereignisprozedur beginnt ihre erste Anweisung, bevor ein
weiterer Handler sie unterbrechen darf. Forms-Handler laufen normalerweise
bis zur Rückkehr; explizites DOEVENTS und blockierendes Warten können andere
Handler verschachteln, aber nie dieselbe laufende Forms-Ereignisprozedur.
Die Rückkehr aus dem äußersten normalen Forms-Handler arbeitet wartende
Forms-Ereignisse geordnet ab. Objekt-Opcodes stellen nur erforderliche
synchrone LOAD-Handler zu; deren Rückkehr zieht keine unabhängigen Ereignisse
mitten in eine Anweisung vor. Ein offenes
Menü sperrt klassische Traps und Forms-Timer, ohne ON/OFF/STOP zu verändern.
Beim Menüschließen wird die Zustellbarkeit vor erneutem Warten geprüft.
INPUT, LINE INPUT, INPUT$ und RANDOMIZE ohne Argument teilen einen
fortsetzbaren Konsolenleser. Teiltext und Restlänge liegen im aufrufenden
Frame; Referenzen und Ausdrucksoperanden bleiben bis zum Abschluss auf dem
Stack. Nach jedem Hostereignis kann die VM einen Handler ausführen und
danach am Eingabe-Opcode fortsetzen, auch über STOP/CONT und verschachtelte
Eingaben hinweg. Fehler-Unwinding und RETURN label verwerfen die abgebrochene
Eingabe. Während dieses Lesens gehören ungetrappte Tasten der Konsole.
`RtState::eingaben` hält Tasten und Maus in Hostreihenfolge, auch beim
Übergeben an Dialoge. Die VM nimmt eine Forms-Eingabe samt ihren Handlern
vor der nächsten Eingabe an. Konsolentasten bleiben lesbar; Maus ohne
Formular oder außerhalb der Bildschirmfläche wird verworfen. KEY ON
entnimmt getrappte Tasten. KEY STOP merkt höchstens einen Trap, markiert die
betroffenen Eingaben als bereits gemerkt und lässt sie lesbar, auch nach ON.
Vor der klassischen Quellenauswahl wird der getrappte Tastenanfang der Queue
gemeldet: KEY behält seine Priorität vor TIMER/UEVENT/SIGNAL, ohne eine davor
wartende Mauseingabe zu überholen. EOF beendet die Quelle; modale und
modellose Formularschleifen arbeiten schon angenommene Ereignisse noch ab.
`Host::jetzt_ms` ist die einzige Uhr für Ereignisfristen. Die VM fragt sie
nur für aktive Zeitquellen, SLEEP-Fristen und zeitabhängige Mausauswertung
ab. Der klassische TIMER wird weiterhin bei Anzeigen, expliziter
Kooperation und ansonsten alle 64 Anweisungsgrenzen geprüft.
`Host::warten(Option<u64>)` wartet auf ein Ereignis oder die absolute
Deadline derselben Uhr; `None` als Ergebnis meldet eine erreichte Deadline.
Ohne Deadline liefert der Host erst ein Ereignis oder explizites
`Ereignis::Ende`. Die VM verwendet weder Instant noch Sleep/Yield als
Rückfallebene. Auch modale und nach Programmende sichtbare Forms verwenden
diesen Wartepfad. CaptureHost liefert vorbereitete Ereignisse zuerst und
rückt beim Warten andernfalls bis zur Deadline vor; ohne Deadline meldet
er Eingabeende. Seine Uhr bleibt außerhalb dieser ausdrücklichen
Warteoperation oder manueller Zeitänderungen stehen.
`tb-ui` hat standardmäßig keine Terminalabhängigkeiten. Das Feature
`terminal` schaltet die Module `host`, `screen`, `signale` und die optionalen
Dependencies crossterm, ratatui und signal-hook ein. `tb-cli` aktiviert es
explizit; VM, Forms-Modell, FRM-Reader und Dialoge brauchen es nicht. Einbetter
müssen die neue Host-Wartemethode implementieren. Dialog-Eingabequeues tragen
`Eingabe` statt nackter `Ereignis`-Werte, damit KEY-STOP-Markierungen erhalten
bleiben; Ereignisse lassen sich mit `.into()` einreihen.
Der separate Workspace `tests/terminalfrei` prüft Einbettung ohne
Feature-Unifikation mit CLI oder IDE:
```sh
cargo run --manifest-path tests/terminalfrei/Cargo.toml --offline
cargo tree --manifest-path tests/terminalfrei/Cargo.toml --edges normal
```
Der erste Befehl lädt ein FRM-Korpusprogramm und prüft dessen `KM`-Ausgabe
mit CaptureHost. Der zweite Baum darf crossterm, ratatui und signal-hook
nicht enthalten.
## `.tbc`-Container (Stand Phase 2, Formatversion 1)