mirror of
https://github.com/onyx-and-iris/xair-cli.git
synced 2026-04-09 02:13:35 +00:00
move lower level logic into engine
This commit is contained in:
97
internal/xair/engine.go
Normal file
97
internal/xair/engine.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package xair
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/hypebeast/go-osc/osc"
|
||||
)
|
||||
|
||||
type engine struct {
|
||||
Kind MixerKind
|
||||
conn *net.UDPConn
|
||||
mixerAddr *net.UDPAddr
|
||||
|
||||
parser parser
|
||||
addressMap map[string]string
|
||||
|
||||
done chan bool
|
||||
respChan chan *osc.Message
|
||||
}
|
||||
|
||||
// receiveLoop handles incoming OSC messages
|
||||
func (e *engine) receiveLoop() {
|
||||
buffer := make([]byte, 4096)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-e.done:
|
||||
return
|
||||
default:
|
||||
// Set read timeout to avoid blocking forever
|
||||
e.conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
|
||||
n, _, err := e.conn.ReadFromUDP(buffer)
|
||||
if err != nil {
|
||||
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
|
||||
// Timeout is expected, continue loop
|
||||
continue
|
||||
}
|
||||
// Check if we're shutting down to avoid logging expected errors
|
||||
select {
|
||||
case <-e.done:
|
||||
return
|
||||
default:
|
||||
log.Errorf("Read error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
msg, err := e.parseOSCMessage(buffer[:n])
|
||||
if err != nil {
|
||||
log.Errorf("Failed to parse OSC message: %v", err)
|
||||
continue
|
||||
}
|
||||
e.respChan <- msg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parseOSCMessage parses raw bytes into an OSC message with improved error handling
|
||||
func (e *engine) parseOSCMessage(data []byte) (*osc.Message, error) {
|
||||
msg, err := e.parser.Parse(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
// sendToAddress sends an OSC message to a specific address (enables replying to different ports)
|
||||
func (e *engine) sendToAddress(addr *net.UDPAddr, oscAddress string, args ...any) error {
|
||||
msg := osc.NewMessage(oscAddress)
|
||||
for _, arg := range args {
|
||||
msg.Append(arg)
|
||||
}
|
||||
|
||||
log.Debugf("Sending to %v: %s", addr, msg.String())
|
||||
if len(args) > 0 {
|
||||
log.Debug(" - Arguments: ")
|
||||
for i, arg := range args {
|
||||
if i > 0 {
|
||||
log.Debug(", ")
|
||||
}
|
||||
log.Debugf("%v", arg)
|
||||
}
|
||||
}
|
||||
log.Debug("")
|
||||
|
||||
data, err := msg.MarshalBinary()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal message: %v", err)
|
||||
}
|
||||
|
||||
_, err = e.conn.WriteToUDP(data, addr)
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user