Files
Archduino/internal/module/registry.go

57 lines
1.2 KiB
Go

package module
import (
"fmt"
"sort"
"sync"
)
// Registry holds all known modules keyed by Meta.ID.
type Registry struct {
mu sync.RWMutex
modules map[string]Module
}
// NewRegistry returns an empty registry.
func NewRegistry() *Registry {
return &Registry{modules: make(map[string]Module)}
}
// Register adds a module. Returns an error if the ID is already present
// or empty. Safe for concurrent use.
func (r *Registry) Register(m Module) error {
id := m.Meta().ID
if id == "" {
return fmt.Errorf("module has empty ID")
}
r.mu.Lock()
defer r.mu.Unlock()
if _, dup := r.modules[id]; dup {
return fmt.Errorf("module %q already registered", id)
}
r.modules[id] = m
return nil
}
// Get returns the module with the given ID, or (nil, false) if absent.
func (r *Registry) Get(id string) (Module, bool) {
r.mu.RLock()
defer r.mu.RUnlock()
m, ok := r.modules[id]
return m, ok
}
// All returns all registered modules sorted by ID for determinism.
func (r *Registry) All() []Module {
r.mu.RLock()
defer r.mu.RUnlock()
out := make([]Module, 0, len(r.modules))
for _, m := range r.modules {
out = append(out, m)
}
sort.Slice(out, func(i, j int) bool {
return out[i].Meta().ID < out[j].Meta().ID
})
return out
}