using System; using System.Collections.Generic; using PepperDash.Core; using PepperDash.Core.Logging; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Routing; using Serilog.Events; namespace PepperDash.Essentials.Devices.Common.Generic { /// /// Represents a GenericSink /// public class GenericSink : EssentialsDevice, IRoutingSinkWithSwitchingWithInputPort, ICurrentSources { /// public Dictionary CurrentSources { get; private set; } /// public Dictionary CurrentSourceKeys { get; private set; } /// public event EventHandler CurrentSourcesChanged; /// /// Initializes a new instance of the GenericSink class /// /// The device key /// The device name public GenericSink(string key, string name) : base(key, name) { InputPorts = new RoutingPortCollection(); var inputPort = new RoutingInputPort(RoutingPortNames.AnyVideoIn, eRoutingSignalType.AudioVideo | eRoutingSignalType.SecondaryAudio, eRoutingPortConnectionType.Hdmi, null, this); InputPorts.Add(inputPort); CurrentSources = new Dictionary { { eRoutingSignalType.Audio, null }, { eRoutingSignalType.Video, null }, }; CurrentSourceKeys = new Dictionary { { eRoutingSignalType.Audio, string.Empty }, { eRoutingSignalType.Video, string.Empty }, }; } /// public void SetCurrentSource(eRoutingSignalType signalType, string sourceListKey, SourceListItem sourceListItem) { foreach (eRoutingSignalType type in Enum.GetValues(typeof(eRoutingSignalType))) { var flagValue = Convert.ToInt32(type); // Skip if flagValue is 0 or not a power of two (i.e., not a single-bit flag). // (flagValue & (flagValue - 1)) != 0 checks if more than one bit is set. if (flagValue == 0 || (flagValue & (flagValue - 1)) != 0) { this.LogDebug("Skipping {type}", type); continue; } this.LogDebug("setting {type}", type); if (signalType.HasFlag(type)) { UpdateCurrentSources(type, sourceListKey, sourceListItem); } } // Raise the CurrentSourcesChanged event CurrentSourcesChanged?.Invoke(this, EventArgs.Empty); } private void UpdateCurrentSources(eRoutingSignalType signalType, string sourceListKey, SourceListItem sourceListItem) { if (CurrentSources.ContainsKey(signalType)) { CurrentSources[signalType] = sourceListItem; } else { CurrentSources.Add(signalType, sourceListItem); } // Update the current source key for the specified signal type if (CurrentSourceKeys.ContainsKey(signalType)) { CurrentSourceKeys[signalType] = sourceListKey; } else { CurrentSourceKeys.Add(signalType, sourceListKey); } } /// /// Gets or sets the InputPorts /// public RoutingPortCollection InputPorts { get; private set; } /// /// Gets or sets the CurrentSourceInfoKey /// public string CurrentSourceInfoKey { get; set; } private SourceListItem _currentSource; /// /// Gets or sets the CurrentSourceInfo /// public SourceListItem CurrentSourceInfo { get => _currentSource; set { if (value == _currentSource) { return; } CurrentSourceChange?.Invoke(_currentSource, ChangeType.WillChange); _currentSource = value; CurrentSourceChange?.Invoke(_currentSource, ChangeType.DidChange); } } /// /// Gets the current input port /// public RoutingInputPort CurrentInputPort => InputPorts[0]; /// /// Event fired when the current source changes /// public event SourceInfoChangeHandler CurrentSourceChange; /// public event InputChangedEventHandler InputChanged; /// public void ExecuteSwitch(object inputSelector) { this.LogDebug("GenericSink Executing Switch to: {inputSelector}", inputSelector); } } /// /// Represents a GenericSinkFactory /// public class GenericSinkFactory : EssentialsDeviceFactory { /// /// Initializes a new instance of the GenericSinkFactory class /// public GenericSinkFactory() { TypeNames = new List() { "genericsink", "genericdestination" }; } /// /// BuildDevice method /// /// public override EssentialsDevice BuildDevice(DeviceConfig dc) { Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Generic Sink Device"); return new GenericSink(dc.Key, dc.Name); } } }