Windows-Client mit funktionierender Fyne-GUI und Rotor-Startcode
This commit is contained in:
parent
c9e3ba052a
commit
3a85b17422
3 changed files with 134 additions and 29 deletions
|
|
@ -23,10 +23,11 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"image/color"
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/app"
|
||||
"fyne.io/fyne/v2/theme"
|
||||
"image/color"
|
||||
|
||||
"git.lang-dieter.de/rs2322tcp/internal/gui"
|
||||
"git.lang-dieter.de/rs2322tcp/internal/version"
|
||||
|
|
@ -113,11 +114,6 @@ func main() {
|
|||
return
|
||||
}
|
||||
|
||||
// Das technische Client-System wird nach dem Erzeugen des Fensters
|
||||
// asynchron gestartet. Dadurch bleibt die GUI auch während des
|
||||
// Verbindungsaufbaus sofort sichtbar und bedienbar.
|
||||
guiApplication.Start()
|
||||
|
||||
// SetOnClosed gehört zum Fyne-Fenster, nicht zur Fyne-Anwendung.
|
||||
//
|
||||
// Beim Schließen des Hauptfensters wird die technische Client-
|
||||
|
|
@ -129,6 +125,16 @@ func main() {
|
|||
},
|
||||
)
|
||||
|
||||
// ShowAndRun zeigt das Fenster und startet den Fyne-Eventloop.
|
||||
guiApplication.ShowAndRun()
|
||||
// Zuerst das GUI-Fenster erzeugen und anzeigen.
|
||||
//
|
||||
// Dadurch wird ein möglicher Fehler beim Start von Fyne/GLFW erkannt,
|
||||
// bevor die technische Client-Kommunikation gestartet wird.
|
||||
guiApplication.Window().Show()
|
||||
|
||||
// Erst nachdem das Fenster erfolgreich erzeugt wurde, wird das
|
||||
// technische Client-System asynchron gestartet.
|
||||
guiApplication.Start()
|
||||
|
||||
// Den Fyne-Eventloop starten.
|
||||
application.Run()
|
||||
}
|
||||
|
|
@ -11,8 +11,8 @@
|
|||
* Beschreibung:
|
||||
* Windows-spezifische Erzeugung eines verwalteten virtuellen rs2322tcp-Ports.
|
||||
*
|
||||
* Der konfigurierte virtuelle COM-Port wird über die bereits vorhandene
|
||||
* serielle Infrastruktur geöffnet.
|
||||
* Der konfigurierte virtuelle COM-Port wird einmal geöffnet und anschließend
|
||||
* über dasselbe Handle für Lese- und Schreiboperationen verwendet.
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
|
|
@ -36,6 +36,9 @@ import (
|
|||
// The visible COM port is provided by the platform-specific PortPath()
|
||||
// implementation. The actual COM-port pair configuration is managed
|
||||
// externally by the Windows virtual COM-port driver.
|
||||
//
|
||||
// The COM port is opened exactly once. The resulting handle is used for
|
||||
// parallel read and write operations.
|
||||
func openVirtualPort(
|
||||
manager *VirtualPortManager,
|
||||
number int,
|
||||
|
|
@ -59,7 +62,7 @@ func openVirtualPort(
|
|||
StopBits: bugserial.OneStopBit,
|
||||
}
|
||||
|
||||
serial, err := bugserial.Open(portPath, mode)
|
||||
port, err := bugserial.Open(portPath, mode)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"open virtual serial port %s: %w",
|
||||
|
|
@ -71,7 +74,7 @@ func openVirtualPort(
|
|||
virtualPort := NewVirtualPort(
|
||||
portPath,
|
||||
&windowsSerial{
|
||||
port: serial,
|
||||
port: port,
|
||||
path: portPath,
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -12,8 +12,9 @@
|
|||
* Windows-spezifische Implementierung der virtuellen seriellen Schnittstelle
|
||||
* über go.bug.st/serial.
|
||||
*
|
||||
* Der konfigurierte COM-Port wird direkt geöffnet. Die Zuordnung eines
|
||||
* virtuellen COM-Port-Paares erfolgt außerhalb des rs2322tcp-Clients.
|
||||
* Ein COM-Port wird unter Windows nur einmal geöffnet. Dasselbe Handle wird
|
||||
* parallel für Lese- und Schreiboperationen verwendet. Damit kann eine
|
||||
* Goroutine blockierend lesen, während eine andere Goroutine Daten schreibt.
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
|
|
@ -30,9 +31,11 @@ import (
|
|||
// windowsSerial
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// windowsSerial implements VirtualSerial using a Windows COM port.
|
||||
// windowsSerial implements VirtualSerial using one Windows COM-port handle
|
||||
// for both reading and writing.
|
||||
type windowsSerial struct {
|
||||
mu sync.Mutex
|
||||
|
||||
port bugserial.Port
|
||||
path string
|
||||
}
|
||||
|
|
@ -51,10 +54,10 @@ func (p *windowsSerial) Path() string {
|
|||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Read / Write
|
||||
// Read
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Read reads raw bytes from the COM port.
|
||||
// Read reads raw bytes from the Windows COM-port handle.
|
||||
func (p *windowsSerial) Read(b []byte) (int, error) {
|
||||
if p == nil {
|
||||
return 0, fmt.Errorf("virtual serial port is nil")
|
||||
|
|
@ -62,16 +65,41 @@ func (p *windowsSerial) Read(b []byte) (int, error) {
|
|||
|
||||
p.mu.Lock()
|
||||
port := p.port
|
||||
path := p.path
|
||||
p.mu.Unlock()
|
||||
|
||||
if port == nil {
|
||||
return 0, fmt.Errorf("virtual serial port is closed")
|
||||
}
|
||||
|
||||
return port.Read(b)
|
||||
n, err := port.Read(b)
|
||||
|
||||
if n > 0 {
|
||||
fmt.Printf(
|
||||
"WINDOWS SERIAL RX [%s]: %d Bytes\n% X\n",
|
||||
path,
|
||||
n,
|
||||
b[:n],
|
||||
)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf(
|
||||
"WINDOWS SERIAL RX FEHLER [%s]: nach %d Bytes: %v\n",
|
||||
path,
|
||||
n,
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
return n, err
|
||||
}
|
||||
|
||||
// Write writes raw bytes to the COM port.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Write
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Write writes raw bytes to the Windows COM-port handle.
|
||||
func (p *windowsSerial) Write(b []byte) (int, error) {
|
||||
if p == nil {
|
||||
return 0, fmt.Errorf("virtual serial port is nil")
|
||||
|
|
@ -79,20 +107,67 @@ func (p *windowsSerial) Write(b []byte) (int, error) {
|
|||
|
||||
p.mu.Lock()
|
||||
port := p.port
|
||||
path := p.path
|
||||
p.mu.Unlock()
|
||||
|
||||
if port == nil {
|
||||
return 0, fmt.Errorf("virtual serial port is closed")
|
||||
}
|
||||
|
||||
return port.Write(b)
|
||||
fmt.Printf(
|
||||
"WINDOWS SERIAL TX [%s]: %d Bytes\n% X\n",
|
||||
path,
|
||||
len(b),
|
||||
b,
|
||||
)
|
||||
|
||||
fmt.Printf(
|
||||
"WINDOWS SERIAL TX [%s]: Rufe port.Write() auf ...\n",
|
||||
path,
|
||||
)
|
||||
|
||||
n, err := port.Write(b)
|
||||
|
||||
fmt.Printf(
|
||||
"WINDOWS SERIAL TX [%s]: port.Write() zurückgekehrt: %d von %d Bytes\n",
|
||||
path,
|
||||
n,
|
||||
len(b),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf(
|
||||
"WINDOWS SERIAL TX FEHLER [%s]: %v\n",
|
||||
path,
|
||||
err,
|
||||
)
|
||||
|
||||
return n, err
|
||||
}
|
||||
|
||||
if n != len(b) {
|
||||
fmt.Printf(
|
||||
"WINDOWS SERIAL TX UNVOLLSTÄNDIG [%s]: %d von %d Bytes\n",
|
||||
path,
|
||||
n,
|
||||
len(b),
|
||||
)
|
||||
} else {
|
||||
fmt.Printf(
|
||||
"WINDOWS SERIAL TX ERFOLGREICH [%s]: %d Bytes\n",
|
||||
path,
|
||||
n,
|
||||
)
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Close
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Close closes the Windows COM port.
|
||||
// Close closes the Windows COM-port handle.
|
||||
func (p *windowsSerial) Close() error {
|
||||
if p == nil {
|
||||
return nil
|
||||
|
|
@ -100,15 +175,36 @@ func (p *windowsSerial) Close() error {
|
|||
|
||||
p.mu.Lock()
|
||||
|
||||
if p.port == nil {
|
||||
p.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
port := p.port
|
||||
path := p.path
|
||||
|
||||
p.port = nil
|
||||
|
||||
p.mu.Unlock()
|
||||
|
||||
return port.Close()
|
||||
if port == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Printf(
|
||||
"WINDOWS SERIAL [%s]: Schließe COM-Port ...\n",
|
||||
path,
|
||||
)
|
||||
|
||||
if err := port.Close(); err != nil {
|
||||
fmt.Printf(
|
||||
"WINDOWS SERIAL [%s]: Fehler beim Schließen des COM-Ports: %v\n",
|
||||
path,
|
||||
err,
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf(
|
||||
"WINDOWS SERIAL [%s]: COM-Port geschlossen.\n",
|
||||
path,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue