VersaGUI/doc/00_architecture.md
2026-03-30 19:51:38 +02:00

70 lines
3.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# VersaGUI Architektur-Übersicht
## Technologie-Stack
| Merkmal | Wert |
|---|---|
| Sprache | C# / .NET 7 |
| UI-Framework | WinForms (`[STAThread]`) |
| Einstiegspunkt | `Program.cs``Application.Run(new TrayApp())` |
| Laufzeitmodell | `ApplicationContext` (kein `Form` als Hauptfenster) |
| Threading | UI-Thread + 1 Hintergrund-Lese-Thread + Timer-Thread |
## Komponentenübersicht
| Datei | Verantwortung |
|---|---|
| `TrayApp` | `ApplicationContext`; hält Tray-Icon, öffnet ConfigForm, verarbeitet Board-Events |
| `SerialManager` | Verbindungsverwaltung, WMI-Erkennung, Lese-Thread, Sende-Methoden |
| `ConfigForm` | Hauptfenster (Grid + Encoder-Panel + Footer); öffnet ActionDialog |
| `ActionDialog` | Modaler Dialog zum Bearbeiten einer Aktion + LED-Einstellungen |
| `DeviceConfig` | C#-Spiegel von `SDeviceConfig`; Serialisierung/Deserialisierung (223 B) |
| `MacroTable` | C#-Spiegel von `SMacroTable`; Serialisierung/Deserialisierung (256 B) |
| `ConfigJson` | JSON-Import/Export für `DeviceConfig` |
| `Protocol` | Konstanten für alle Command/Event-IDs (spiegelt `usb_serial.h`) |
## Datenfluss
```
Board → SerialManager (ReadLoop, BG-Thread)
→ SynchronizationContext.Post (→ UI-Thread)
→ TrayApp.OnPacket()
├── Config-Dump: _rxConfigBuf aufbauen → DeviceConfig.FromBytes()
├── Makro-Dump: _rxMacroBuf aufbauen → MacroTable.FromBytes()
└── HOST_COMMAND-Events: (TODO: Aktion ausführen)
Benutzer → ConfigForm → ActionDialog
→ DeviceConfig / MacroTable (in-memory ändern)
→ SerialManager.SendConfig() + SendMacros() (BG-Task)
→ Board (chunked, 6 B/Paket)
```
## Threading-Modell
```
UI-Thread : TrayApp, ConfigForm, ActionDialog, alle WinForms-Controls
BG-Thread : SerialManager.ReadLoop() blockiert auf ReadByte()
Timer-Thread : SerialManager._reconnectTimer → TryConnect() alle 3 s
Sende-Task : ConfigForm.OnSave() → Task.Run() (blockiert ~400 ms für Transfer)
```
Alle Board-Events werden per `SynchronizationContext.Post` auf den UI-Thread gepostet. Controls dürfen nie vom BG-Thread angefasst werden.
## Verbindungslebenszyklus
```
Start → Timer feuert → TryConnect() → WMI-Suche (VID 0x239A / PID 0x0042)
→ SerialPort öffnen (DtrEnable=true VOR Open()!)
→ 200 ms warten → ReadLoop starten → Connected-Event → RequestConfig() + RequestMacros()
Disconnect → ReadLoop bricht ab → Disconnected-Event → 5 s Backoff → Timer läuft weiter
```
## Invarianten / Constraints
- **DtrEnable=true muss VOR `Open()` gesetzt werden**: SAMD21 prüft DTR für `usb_serial_send()`. Der Default-Wert false würde alle Board→PC-Antworten still verwerfen.
- **IOException ≠ Disconnect**: .NET 7 wirft `IOException` statt `TimeoutException` bei `ReadByte()`-Timeout. Nur als echten Fehler behandeln wenn `_port.IsOpen == false`.
- **Packed-kompatible Serialisierung**: `DeviceConfig.ToBytes()` muss exakt 223 B in derselben Reihenfolge wie `SDeviceConfig` (packed C++) erzeugen. Jede Änderung am Firmware-Layout muss hier gespiegelt werden.
- **Config-Version**: `DeviceConfig.Version == 2`. `FromBytes()` prüft Magic + Version + CRC; schlägt einer fehl → Methode gibt `false` zurück, Config bleibt unverändert.
- **Debug-Log**: `versapad_rx.txt` in `%TEMP%` vor Release-Nutzung entfernen (TODO).