69 lines
1.9 KiB
C#
69 lines
1.9 KiB
C#
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace MuzikaGromche.Via;
|
|
|
|
interface ILightshow
|
|
{
|
|
/// <summary>
|
|
/// Override or reset brightness (value) for flickering animation.
|
|
/// </summary>
|
|
void SetBrightnessOverride(byte? brightness);
|
|
void SetColor(byte hue, byte saturation, byte value);
|
|
}
|
|
|
|
class Animations
|
|
{
|
|
private static CancellationTokenSource? cts;
|
|
|
|
public static void Flicker(ILightshow lightshow)
|
|
{
|
|
if (cts != null)
|
|
{
|
|
cts.Cancel();
|
|
}
|
|
cts = new();
|
|
_ = Task.Run(async () => await FlickerAsync(lightshow, cts.Token), cts.Token);
|
|
}
|
|
|
|
static async ValueTask FlickerAsync(ILightshow lightshow, CancellationToken cancellationToken)
|
|
{
|
|
await foreach (var on in FlickerAnimationAsync())
|
|
{
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
break;
|
|
}
|
|
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 => ON.
|
|
private static readonly int[] MansionWallLampFlicker = [
|
|
0, 4, 8, 26, 28, 32, 37, 41, 42, 58, 60, 71,
|
|
];
|
|
|
|
public static async IAsyncEnumerable<bool> FlickerAnimationAsync()
|
|
{
|
|
bool lastState = false;
|
|
int lastFrame = 0;
|
|
|
|
const int initialMillisecondsDelay = 4 * 1000 / 60;
|
|
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;
|
|
}
|
|
}
|
|
}
|