// ReSharper disable MemberCanBePrivate.Global using System.Threading; using System.Threading.Tasks; namespace RGB.NET.Core; /// /// /// Represents an update trigger that is manully triggered by calling . /// public sealed class ManualUpdateTrigger : AbstractUpdateTrigger { #region Properties & Fields private readonly AutoResetEvent _mutex = new(false); private Task? UpdateTask { get; set; } private CancellationTokenSource? UpdateTokenSource { get; set; } private CancellationToken UpdateToken { get; set; } private CustomUpdateData? _customUpdateData; /// /// Gets the time it took the last update-loop cycle to run. /// public override double LastUpdateTime { get; protected set; } #endregion #region Constructors /// /// Initializes a new instance of the class. /// public ManualUpdateTrigger() { Start(); } #endregion #region Methods /// /// Starts the trigger if needed, causing it to performing updates. /// public override void Start() { if (UpdateTask == null) { UpdateTokenSource?.Dispose(); UpdateTokenSource = new CancellationTokenSource(); UpdateTask = Task.Factory.StartNew(UpdateLoop, (UpdateToken = UpdateTokenSource.Token), TaskCreationOptions.LongRunning, TaskScheduler.Default); } } /// /// Stops the trigger if running, causing it to stop performing updates. /// private void Stop() { if (UpdateTask != null) { UpdateTokenSource?.Cancel(); // ReSharper disable once MethodSupportsCancellation UpdateTask.Wait(); UpdateTask.Dispose(); UpdateTask = null; } } /// /// Triggers an update. /// public void TriggerUpdate(CustomUpdateData? updateData = null) { _customUpdateData = updateData; _mutex.Set(); } private void UpdateLoop() { OnStartup(); while (!UpdateToken.IsCancellationRequested) if (_mutex.WaitOne(100)) LastUpdateTime = TimerHelper.Execute(TimerExecute); } private void TimerExecute() => OnUpdate(_customUpdateData); /// public override void Dispose() => Stop(); #endregion }