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)
{
CurrentSources[signalType] = sourceListItem;
CurrentSourceKeys[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);
}
}
}