Files
dmxconnect/hardware/hardware.go
Valentin Boulanger 4fbb75ad19 34-midi (#35)
Closes #34 Implement MIDI peripherals
Implement device concept
Cleaning project

Reviewed-on: #35
2025-12-02 18:02:17 +00:00

91 lines
2.4 KiB
Go

package hardware
import (
"context"
"errors"
"fmt"
"sync"
"github.com/rs/zerolog/log"
)
// Manager is the class who manages the hardware
type Manager struct {
mu sync.Mutex
wg sync.WaitGroup
providers map[string]Provider // The map of endpoints providers
devices map[string]*Device // The map of devices
DetectedEndpoints map[string]Endpoint // The current list of endpoints
SavedEndpoints map[string]EndpointInfo // The list of stored endpoints
}
// NewManager creates a new hardware manager
func NewManager() *Manager {
log.Trace().Str("package", "hardware").Msg("Hardware instance created")
return &Manager{
providers: make(map[string]Provider, 0),
devices: make(map[string]*Device, 0),
DetectedEndpoints: make(map[string]Endpoint, 0),
SavedEndpoints: make(map[string]EndpointInfo, 0),
}
}
// Start starts to find new endpoint events
func (h *Manager) Start(ctx context.Context) error {
for providerName, provider := range h.providers {
// Initialize the provider
err := provider.Initialize()
if err != nil {
log.Err(err).Str("file", "hardware").Str("providerName", providerName).Msg("unable to initialize provider")
return err
}
// Set callback functions
provider.OnArrival(h.OnEndpointArrival)
provider.OnRemoval(h.OnEndpointRemoval)
// Start the provider
err = provider.Start(ctx)
if err != nil {
log.Err(err).Str("file", "hardware").Str("providerName", providerName).Msg("unable to start provider")
return err
}
}
return nil
}
// WaitStop stops the hardware manager
func (h *Manager) WaitStop() error {
log.Trace().Str("file", "hardware").Msg("closing the hardware manager")
// Stop each provider
var errs []error
for name, f := range h.providers {
if err := f.WaitStop(); err != nil {
errs = append(errs, fmt.Errorf("%s: %w", name, err))
}
}
// Wait for all the endpoints to close
log.Trace().Str("file", "MIDIProvider").Msg("closing all MIDI endpoints")
for registeredEndpointSN, registeredEndpoint := range h.DetectedEndpoints {
err := registeredEndpoint.WaitStop()
if err != nil {
errs = append(errs, fmt.Errorf("%s: %w", registeredEndpointSN, err))
}
}
// Wait for goroutines to finish
h.wg.Wait()
// Returning errors
if len(errs) > 0 {
return errors.Join(errs...)
}
log.Info().Str("file", "hardware").Msg("hardware manager stopped")
return nil
}