using System; using System.Collections.Generic; using System.Linq; namespace RGB.NET.Core { /// /// Represents a generic update queue. /// /// The type of the key used to identify some data. /// The type of the data. public abstract class UpdateQueue : IDisposable { #region Properties & Fields private readonly object _dataLock = new object(); private readonly IDeviceUpdateTrigger _updateTrigger; private Dictionary _currentDataSet; #endregion #region Constructors /// /// Initializes a new instance of the class. /// /// The causing this queue to update. protected UpdateQueue(IDeviceUpdateTrigger updateTrigger) { this._updateTrigger = updateTrigger; _updateTrigger.Starting += OnStartup; _updateTrigger.Update += OnUpdate; } #endregion #region Methods /// /// Event handler for the -event. /// /// The causing this update. /// provided by the trigger. protected virtual void OnUpdate(object sender, CustomUpdateData customData) { Dictionary dataSet; lock (_dataLock) { dataSet = _currentDataSet; _currentDataSet = null; } if ((dataSet != null) && (dataSet.Count != 0)) Update(dataSet); } /// /// Event handler for the -event. /// /// The starting . /// provided by the trigger. protected virtual void OnStartup(object sender, CustomUpdateData customData) { } /// /// Performs the update this queue is responsible for. /// /// The set of data that needs to be updated. protected abstract void Update(Dictionary dataSet); /// /// Sets or merges the provided data set in the current dataset and notifies the trigger that there is new data available. /// /// The set of data. // ReSharper disable once MemberCanBeProtected.Global public virtual void SetData(Dictionary dataSet) { if ((dataSet == null) || (dataSet.Count == 0)) return; lock (_dataLock) { if (_currentDataSet == null) _currentDataSet = dataSet; else { foreach (KeyValuePair command in dataSet) _currentDataSet[command.Key] = command.Value; } } _updateTrigger.TriggerHasData(); } /// /// Resets the current data set. /// public virtual void Reset() { lock (_dataLock) _currentDataSet = null; } /// public virtual void Dispose() { _updateTrigger.Starting -= OnStartup; _updateTrigger.Update -= OnUpdate; Reset(); } #endregion } /// /// Represents a generic using an object as the key and a color as the value. /// public abstract class UpdateQueue : UpdateQueue { #region Constructors /// protected UpdateQueue(IDeviceUpdateTrigger updateTrigger) : base(updateTrigger) { } #endregion #region Methods /// /// Calls for a data set created out of the provided list of . /// /// public void SetData(IEnumerable leds) => SetData(leds?.ToDictionary(x => x.CustomData ?? x.Id, x => x.Color)); #endregion } }