using System; using System.Collections.Generic; using RGB.NET.Core; namespace RGB.NET.Devices.WS281X; /// /// /// Represents a update queue for serial devices. /// /// The type of data sent through the serial connection. public abstract class SerialConnectionUpdateQueue : UpdateQueue { #region Properties & Fields /// /// Gets or sets the prompt to wait for between sending commands. /// // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global protected char Prompt { get; set; } = '>'; /// /// Gets the serial port used by this queue. /// protected ISerialConnection SerialConnection { get; } #endregion #region Constructors /// /// /// Initializes a new instance of the class. /// /// The update trigger used by this queue. /// The serial connection used to access the device. internal SerialConnectionUpdateQueue(IDeviceUpdateTrigger updateTrigger, ISerialConnection serialConnection) : base(updateTrigger) { SerialConnection = serialConnection; } #endregion #region Methods /// protected override void OnStartup(object? sender, CustomUpdateData customData) { base.OnStartup(sender, customData); if (!SerialConnection.IsOpen) SerialConnection.Open(); SerialConnection.DiscardInBuffer(); } /// protected override bool Update(ReadOnlySpan<(object key, Color color)> dataSet) { try { foreach (TData command in GetCommands(dataSet.ToArray())) { SerialConnection.ReadTo(Prompt); SendCommand(command); } return true; } catch (Exception ex) { WS281XDeviceProvider.Instance.Throw(ex); } return false; } /// /// Gets the commands that need to be sent to the device to update the requested colors. /// /// The set of data that needs to be updated. /// The commands to be sent. protected abstract IEnumerable GetCommands(IList<(object key, Color color)> dataSet); /// /// Sends a command as a string followed by a line-break to the device. /// This most likely needs to be overwritten if the data-type isn't string. /// /// The command to be sent. protected virtual void SendCommand(TData command) => SerialConnection.WriteLine((command as string) ?? string.Empty); #endregion }