95 lines
2.2 KiB
Go
95 lines
2.2 KiB
Go
|
|
package remap
|
||
|
|
|
||
|
|
import (
|
||
|
|
"github.com/gopatchy/artmap/artnet"
|
||
|
|
"github.com/gopatchy/artmap/config"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Output represents a remapped DMX output
|
||
|
|
type Output struct {
|
||
|
|
Universe artnet.Universe
|
||
|
|
Data [512]byte
|
||
|
|
}
|
||
|
|
|
||
|
|
// Engine handles DMX channel remapping
|
||
|
|
type Engine struct {
|
||
|
|
mappings []config.NormalizedMapping
|
||
|
|
// Index mappings by source universe for faster lookup
|
||
|
|
bySource map[artnet.Universe][]config.NormalizedMapping
|
||
|
|
}
|
||
|
|
|
||
|
|
// NewEngine creates a new remapping engine
|
||
|
|
func NewEngine(mappings []config.NormalizedMapping) *Engine {
|
||
|
|
bySource := make(map[artnet.Universe][]config.NormalizedMapping)
|
||
|
|
for _, m := range mappings {
|
||
|
|
bySource[m.FromUniverse] = append(bySource[m.FromUniverse], m)
|
||
|
|
}
|
||
|
|
|
||
|
|
return &Engine{
|
||
|
|
mappings: mappings,
|
||
|
|
bySource: bySource,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Remap applies mappings to incoming DMX data and returns outputs
|
||
|
|
func (e *Engine) Remap(srcUniverse artnet.Universe, srcData [512]byte) []Output {
|
||
|
|
mappings, ok := e.bySource[srcUniverse]
|
||
|
|
if !ok {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// Group outputs by destination universe
|
||
|
|
outputs := make(map[artnet.Universe]*Output)
|
||
|
|
|
||
|
|
for _, m := range mappings {
|
||
|
|
// Get or create output for this destination universe
|
||
|
|
out, ok := outputs[m.ToUniverse]
|
||
|
|
if !ok {
|
||
|
|
out = &Output{
|
||
|
|
Universe: m.ToUniverse,
|
||
|
|
}
|
||
|
|
outputs[m.ToUniverse] = out
|
||
|
|
}
|
||
|
|
|
||
|
|
// Copy channels
|
||
|
|
for i := 0; i < m.Count; i++ {
|
||
|
|
srcChan := m.FromChannel + i
|
||
|
|
dstChan := m.ToChannel + i
|
||
|
|
if srcChan < 512 && dstChan < 512 {
|
||
|
|
out.Data[dstChan] = srcData[srcChan]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Convert map to slice
|
||
|
|
result := make([]Output, 0, len(outputs))
|
||
|
|
for _, out := range outputs {
|
||
|
|
result = append(result, *out)
|
||
|
|
}
|
||
|
|
|
||
|
|
return result
|
||
|
|
}
|
||
|
|
|
||
|
|
// SourceUniverses returns all universes that have mappings
|
||
|
|
func (e *Engine) SourceUniverses() []artnet.Universe {
|
||
|
|
result := make([]artnet.Universe, 0, len(e.bySource))
|
||
|
|
for u := range e.bySource {
|
||
|
|
result = append(result, u)
|
||
|
|
}
|
||
|
|
return result
|
||
|
|
}
|
||
|
|
|
||
|
|
// DestUniverses returns all destination universes
|
||
|
|
func (e *Engine) DestUniverses() []artnet.Universe {
|
||
|
|
seen := make(map[artnet.Universe]bool)
|
||
|
|
for _, m := range e.mappings {
|
||
|
|
seen[m.ToUniverse] = true
|
||
|
|
}
|
||
|
|
|
||
|
|
result := make([]artnet.Universe, 0, len(seen))
|
||
|
|
for u := range seen {
|
||
|
|
result = append(result, u)
|
||
|
|
}
|
||
|
|
return result
|
||
|
|
}
|