Files
go-mxl-player/internal/playback/session_plan.go
T
2026-09-01 01:28:36 +03:00

90 lines
1.8 KiB
Go

package playback
import "fmt"
type SessionTopology uint8
const (
TopologyIdle SessionTopology = iota
TopologyIndependent
TopologySynchronized
)
func (t SessionTopology) String() string {
switch t {
case TopologyIdle:
return "idle"
case TopologyIndependent:
return "independent"
case TopologySynchronized:
return "synchronized"
default:
return fmt.Sprintf("SessionTopology(%d)", uint8(t))
}
}
type SyncPredicate func(video, audio FeedConfig) bool
type SessionPlan struct {
Topology SessionTopology
// Desired states for independent slots.
Video FeedConfig
Audio FeedConfig
// Desired state for the synchronized slot.
Sync SyncPairConfig
}
func BuildSessionPlan(
desired SessionConfig,
canSync SyncPredicate,
) (SessionPlan, error) {
if err := desired.Validate(); err != nil {
return SessionPlan{}, fmt.Errorf("validate desired session: %w", err)
}
if desired.SyncRequested &&
desired.Video.Active &&
desired.Audio.Active &&
canSync != nil &&
canSync(desired.Video, desired.Audio) {
return SessionPlan{
Topology: TopologySynchronized,
Video: stoppedFeed(desired.Video),
Audio: stoppedFeed(desired.Audio),
Sync: SyncPairConfig{
Video: desired.Video,
Audio: desired.Audio,
},
}, nil
}
if desired.Video.Active || desired.Audio.Active {
return SessionPlan{
Topology: TopologyIndependent,
Video: desired.Video,
Audio: desired.Audio,
Sync: SyncPairConfig{
Video: stoppedFeed(desired.Video),
Audio: stoppedFeed(desired.Audio),
},
}, nil
}
return SessionPlan{
Topology: TopologyIdle,
Video: stoppedFeed(desired.Video),
Audio: stoppedFeed(desired.Audio),
Sync: SyncPairConfig{
Video: stoppedFeed(desired.Video),
Audio: stoppedFeed(desired.Audio),
},
}, nil
}
func stoppedFeed(config FeedConfig) FeedConfig {
config.Active = false
return config
}