forked from nikita/muzika-gromche
57 lines
1.6 KiB
C#
57 lines
1.6 KiB
C#
using System.Collections.Generic;
|
|
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
|
|
{
|
|
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<bool> 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;
|
|
}
|
|
}
|
|
}
|