using System.Collections.Generic; using System.Threading.Tasks; namespace MuzikaGromche.Via; interface ILightshow { /// /// Override or reset brightness (value) for flickering animation. /// void SetBrightnessOverride(byte? brightness); void SetColor(byte hue, byte saturation, byte value); } class Animations { public static void Flicker(ILightshow lightshow) { _ = Task.Run(() => FlickerAsync(lightshow)); } static async ValueTask FlickerAsync(ILightshow lightshow) { await foreach (var on in FlickerAnimationAsync()) { byte brightness = on ? (byte)0xFF : (byte)0x00; lightshow.SetBrightnessOverride(brightness); } lightshow.SetBrightnessOverride(null); } // Timestamps (in frames of 60 fps) of state switches, starting with 0 => OFF. private static readonly int[] MansionWallLampFlicker = [ 0, 4, 8, 26, 28, 32, 37, 41, 42, 58, 60, 71, ]; public static async IAsyncEnumerable FlickerAnimationAsync() { bool lastState = true; int lastFrame = 0; const int initialMillisecondsDelay = 100; await Task.Delay(initialMillisecondsDelay); foreach (int frame in MansionWallLampFlicker) { // convert difference in frames into milliseconds int millisecondsDelay = (int)((frame - lastFrame) / 60f * 1000f); lastState = !lastState; lastFrame = frame; await Task.Delay(millisecondsDelay); yield return lastState; } } }