From 7f6c8e6a709a55d9672bef5602293be8a3b662b6 Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Wed, 25 Jan 2017 20:51:08 +0100 Subject: [PATCH] Added auto-update functionality --- RGB.NET.Core/RGB.NET.Core.csproj | 2 + RGB.NET.Core/RGBSurfaceUpdater.cs | 89 +++++++++++++++++++++++++++++++ RGB.NET.Core/UpdateMode.cs | 18 +++++++ 3 files changed, 109 insertions(+) create mode 100644 RGB.NET.Core/RGBSurfaceUpdater.cs create mode 100644 RGB.NET.Core/UpdateMode.cs diff --git a/RGB.NET.Core/RGB.NET.Core.csproj b/RGB.NET.Core/RGB.NET.Core.csproj index f3dad45..db842ba 100644 --- a/RGB.NET.Core/RGB.NET.Core.csproj +++ b/RGB.NET.Core/RGB.NET.Core.csproj @@ -75,6 +75,8 @@ + + diff --git a/RGB.NET.Core/RGBSurfaceUpdater.cs b/RGB.NET.Core/RGBSurfaceUpdater.cs new file mode 100644 index 0000000..c040acc --- /dev/null +++ b/RGB.NET.Core/RGBSurfaceUpdater.cs @@ -0,0 +1,89 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace RGB.NET.Core +{ + public static partial class RGBSurface + { + #region Properties & Fields + + private static CancellationTokenSource _updateTokenSource; + private static CancellationToken _updateToken; + private static Task _updateTask; + + /// + /// Gets or sets the update-frequency in seconds. (Calculate by using '1.0 / updates per second') + /// + public static double UpdateFrequency { get; set; } = 1.0 / 30.0; + + private static UpdateMode _updateMode = UpdateMode.Manual; + /// + /// Gets or sets the update-mode. + /// + public static UpdateMode UpdateMode + { + get { return _updateMode; } + set + { + _updateMode = value; + CheckUpdateLoop(); + } + } + + #endregion + + #region Methods + + /// + /// Checks if automatic updates should occur and starts/stops the update-loop if needed. + /// + /// Thrown if the requested update-mode is not available. + private static async void CheckUpdateLoop() + { + bool shouldRun; + switch (UpdateMode) + { + case UpdateMode.Manual: + shouldRun = false; + break; + case UpdateMode.Continuous: + shouldRun = true; + break; + default: + throw new ArgumentOutOfRangeException(); + } + + if (shouldRun && (_updateTask == null)) // Start task + { + _updateTokenSource?.Dispose(); + _updateTokenSource = new CancellationTokenSource(); + _updateTask = Task.Factory.StartNew(UpdateLoop, (_updateToken = _updateTokenSource.Token)); + } + else if (!shouldRun && (_updateTask != null)) // Stop task + { + _updateTokenSource.Cancel(); + await _updateTask; + _updateTask.Dispose(); + _updateTask = null; + } + } + + private static void UpdateLoop() + { + while (!_updateToken.IsCancellationRequested) + { + long preUpdateTicks = DateTime.Now.Ticks; + + foreach (IRGBDevice device in _devices) + device.Update(); + + int sleep = (int)((UpdateFrequency * 1000.0) - ((DateTime.Now.Ticks - preUpdateTicks) / 10000.0)); + if (sleep > 0) + Thread.Sleep(sleep); + } + } + + #endregion + } +} diff --git a/RGB.NET.Core/UpdateMode.cs b/RGB.NET.Core/UpdateMode.cs new file mode 100644 index 0000000..960a03b --- /dev/null +++ b/RGB.NET.Core/UpdateMode.cs @@ -0,0 +1,18 @@ +namespace RGB.NET.Core +{ + /// + /// Contains list of available update modes. + /// + public enum UpdateMode + { + /// + /// The will not perform automatic updates. Updates will only occur if is called. + /// + Manual, + + /// + /// The will perform automatic updates at the rate set in . + /// + Continuous + } +}