private static void GenerateRandomEffectSettings(out RGBColor hexColor, out IteratorEffectMode iteratorMode, out IteratorEffectMode iteratorSecondaryMode) { Random r = new Random(); hexColor = RGBColor.Random(r); while (hexColor.R < 0.15 && hexColor.G < 0.15 && hexColor.B < 0.15) { hexColor = RGBColor.Random(r); } Array values = Enum.GetValues(typeof(IteratorEffectMode)); iteratorMode = (IteratorEffectMode)values.GetValue(r.Next(values.Length)); iteratorSecondaryMode = (IteratorEffectMode)values.GetValue(r.Next(values.Length)); //Bounce and Single are no fun for random mode if (iteratorMode == IteratorEffectMode.Bounce || iteratorMode == IteratorEffectMode.Single) { iteratorMode = IteratorEffectMode.Cycle; } else if (iteratorMode == IteratorEffectMode.RandomOrdered) //RandomOrdered only runs once { iteratorMode = IteratorEffectMode.Random; } }
public static Task SetRandomColor(this IEnumerable <StreamingLight> group, IteratorEffectMode mode = IteratorEffectMode.Cycle, Ref <TimeSpan?> waitTime = null, Ref <TimeSpan?> transitionTime = null, TimeSpan?duration = null, CancellationToken cancellationToken = new CancellationToken()) { if (waitTime == null) { waitTime = TimeSpan.FromMilliseconds(50); } if (transitionTime == null) { transitionTime = TimeSpan.FromMilliseconds(0); } return(group.IteratorEffect(async(current, t) => { var r = new Random(); var color = new RGBColor(r.NextDouble(), r.NextDouble(), r.NextDouble()); current.SetState(color, 1, transitionTime.Value.Value); }, mode, waitTime, duration, cancellationToken)); }
/// <summary> /// Does not wait for the previous flash to end /// NOTE: Can not be used with mode All or AllIndividual /// </summary> /// <param name="group"></param> /// <param name="color"></param> /// <param name="mode"></param> /// <param name="waitTime"></param> /// <param name="onTime"></param> /// <param name="transitionTimeOn"></param> /// <param name="transitionTimeOff"></param> /// <param name="duration"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public static Task FlashQuick(this IEnumerable <IEnumerable <EntertainmentLight> > group, CancellationToken cancellationToken, RGBColor?color, IteratorEffectMode mode = IteratorEffectMode.Cycle, IteratorEffectMode secondaryIteratorMode = IteratorEffectMode.All, Func <TimeSpan> waitTime = null, Func <TimeSpan> onTime = null, Func <TimeSpan> transitionTimeOn = null, Func <TimeSpan> transitionTimeOff = null, TimeSpan?duration = null) { if (!color.HasValue) { color = RGBColor.Random(); } if (mode == IteratorEffectMode.All || mode == IteratorEffectMode.AllIndividual) { return(group.Flash(cancellationToken, color.Value, mode, secondaryIteratorMode, waitTime, onTime, transitionTimeOn, transitionTimeOff, true, duration)); } else { if (waitTime == null) { waitTime = () => TimeSpan.FromMilliseconds(50); } if (onTime == null) { onTime = waitTime; } if (transitionTimeOn == null) { transitionTimeOn = () => TimeSpan.FromMilliseconds(0); } if (transitionTimeOff == null) { transitionTimeOff = () => TimeSpan.FromMilliseconds(0); } Func <TimeSpan> actualWaitTime = () => onTime() + transitionTimeOn(); return(group.IteratorEffect(cancellationToken, async(current, ct, t) => { current.SetState(ct, color, 1, transitionTimeOn()); Task.Run(async() => { await Task.Delay(onTime() + transitionTimeOn(), ct).ConfigureAwait(false); current.SetBrightness(ct, 0, transitionTimeOff()); }, ct); }, mode, secondaryIteratorMode, actualWaitTime, duration)); } }
public static Task SetRandomColor(this IEnumerable <IEnumerable <EntertainmentLight> > group, CancellationToken cancellationToken, IteratorEffectMode mode = IteratorEffectMode.Cycle, IteratorEffectMode secondaryIteratorMode = IteratorEffectMode.All, Func <TimeSpan> waitTime = null, Func <TimeSpan> transitionTime = null, TimeSpan?duration = null) { if (waitTime == null) { waitTime = () => TimeSpan.FromMilliseconds(50); } if (transitionTime == null) { transitionTime = () => TimeSpan.FromMilliseconds(0); } return(group.IteratorEffect(cancellationToken, async(current, ct, t) => { var color = RGBColor.Random(); current.SetState(ct, color, 1, transitionTime()); }, mode, secondaryIteratorMode, waitTime, duration)); }
public static Task SetColor(this IEnumerable <IEnumerable <EntertainmentLight> > group, CancellationToken cancellationToken, RGBColor color, IteratorEffectMode mode = IteratorEffectMode.Cycle, IteratorEffectMode secondaryIteratorMode = IteratorEffectMode.All, Func <TimeSpan> waitTime = null, Func <TimeSpan> transitionTime = null, TimeSpan?duration = null) { var list = new List <RGBColor>() { color }; return(SetRandomColorFromList(group, cancellationToken, list, mode, secondaryIteratorMode, waitTime, transitionTime, duration)); }
private static void StartEffect(CancellationToken ctsToken, TypeInfo selectedEffect, IEnumerable <IEnumerable <EntertainmentLight> > group, string groupName, Func <TimeSpan> waitTime, RGBColor?color, IteratorEffectMode iteratorMode = IteratorEffectMode.All, IteratorEffectMode secondaryIteratorMode = IteratorEffectMode.All) { MethodInfo?methodInfo = selectedEffect.GetMethod("Start"); if (methodInfo == null) { return; } //get group if (group == null) { group = GroupService.GetRandomGroup(); } object[] parametersArray = new object[] { group, waitTime, color, iteratorMode, secondaryIteratorMode, ctsToken }; object?classInstance = Activator.CreateInstance(selectedEffect, null); methodInfo.Invoke(classInstance, parametersArray); var hub = (IHubContext <StatusHub>)Startup.ServiceProvider.GetService(typeof(IHubContext <StatusHub>)); hub.Clients.All.SendAsync("StartingEffect", $"Starting: {selectedEffect.Name} {groupName}, {iteratorMode}-{secondaryIteratorMode} {color?.ToHex()}", new EffectLogMsg() { EffectType = "group", Name = selectedEffect.Name, RGBColor = color?.ToHex(), Group = groupName, IteratorMode = iteratorMode.ToString(), SecondaryIteratorMode = secondaryIteratorMode.ToString(), }); }
public static void StartEffect(string typeName, string colorHex, string?group = null, IteratorEffectMode iteratorMode = IteratorEffectMode.All, IteratorEffectMode secondaryIteratorMode = IteratorEffectMode.All) { var hub = (IHubContext <StatusHub>)Startup.ServiceProvider.GetService(typeof(IHubContext <StatusHub>)); var all = GetEffectTypes(); var allGroup = GetGroupEffectTypes(); var effectType = all.Where(x => x.Name == typeName).FirstOrDefault(); var groupEffectType = allGroup.Where(x => x.Name == typeName).FirstOrDefault(); bool isGroupEffect = groupEffectType != null && !string.IsNullOrEmpty(group); var selectedEffect = isGroupEffect ? groupEffectType : effectType; if (selectedEffect != null) { var hueEffectAtt = selectedEffect.GetCustomAttribute <HueEffectAttribute>(); if (hueEffectAtt == null) { return; } var isBaseLayer = hueEffectAtt.IsBaseEffect && iteratorMode != IteratorEffectMode.Single && iteratorMode != IteratorEffectMode.RandomOrdered; var layer = GetLayer(isBaseLayer); if (layerInfo.ContainsKey(layer)) { //Cancel currently running job layerInfo[layer].CancellationTokenSource?.Cancel(); } CancellationTokenSource cts = new CancellationTokenSource(); layerInfo[layer] = new RunningEffectInfo() { Name = hueEffectAtt.Name, CancellationTokenSource = cts }; Func <TimeSpan> waitTime = () => StreamingSetup.WaitTime; RGBColor? color = null; if (!string.IsNullOrEmpty(colorHex)) { color = new RGBColor(colorHex); } if (isGroupEffect) { //get group var selectedGroup = GroupService.GetAll(layer).Where(x => x.Name == group).Select(x => x.Lights).FirstOrDefault(); StartEffect(cts.Token, selectedEffect, selectedGroup.SelectMany(x => x), group, waitTime, color, iteratorMode, secondaryIteratorMode); } else { StartEffect(cts.Token, selectedEffect, layer, waitTime, color); } } }
/// <summary> /// Does not wait for the previous flash to end /// NOTE: Can not be used with mode All or AllIndividual /// </summary> /// <param name="group"></param> /// <param name="color"></param> /// <param name="mode"></param> /// <param name="waitTime"></param> /// <param name="onTime"></param> /// <param name="transitionTimeOn"></param> /// <param name="transitionTimeOff"></param> /// <param name="duration"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public static Task FlashQuick(this IEnumerable <StreamingLight> group, RGBColor?color, IteratorEffectMode mode = IteratorEffectMode.Cycle, Ref <TimeSpan?> waitTime = null, Ref <TimeSpan?> onTime = null, Ref <TimeSpan?> transitionTimeOn = null, Ref <TimeSpan?> transitionTimeOff = null, TimeSpan?duration = null, CancellationToken cancellationToken = new CancellationToken()) { if (!color.HasValue) { var r = new Random(); color = new RGBColor(r.NextDouble(), r.NextDouble(), r.NextDouble()); } if (mode == IteratorEffectMode.All || mode == IteratorEffectMode.AllIndividual) { return(group.Flash(color.Value, mode, waitTime, onTime, transitionTimeOn, transitionTimeOff, duration, cancellationToken)); } else { if (waitTime == null) { waitTime = TimeSpan.FromMilliseconds(50); } if (onTime == null) { onTime = waitTime; } if (transitionTimeOn == null) { transitionTimeOn = TimeSpan.FromMilliseconds(0); } if (transitionTimeOff == null) { transitionTimeOff = TimeSpan.FromMilliseconds(0); } Ref <TimeSpan?> actualWaitTime = onTime.Value + transitionTimeOn.Value; return(group.IteratorEffect(async(current, t) => { actualWaitTime.Value = onTime.Value.Value + transitionTimeOn.Value.Value; current.SetState(color, 1, transitionTimeOn.Value.Value); Task.Run(async() => { await Task.Delay(onTime.Value.Value + transitionTimeOn.Value.Value); current.SetBrightness(0, transitionTimeOff.Value.Value); }, cancellationToken); }, mode, actualWaitTime, duration, cancellationToken)); } }
public static Task Flash(this IEnumerable <IEnumerable <EntertainmentLight> > group, CancellationToken cancellationToken, RGBColor?color, IteratorEffectMode mode = IteratorEffectMode.Cycle, IteratorEffectMode secondaryIteratorMode = IteratorEffectMode.All, Ref <TimeSpan?> waitTime = null, Ref <TimeSpan?> onTime = null, Ref <TimeSpan?> transitionTimeOn = null, Ref <TimeSpan?> transitionTimeOff = null, bool waitTillFinished = true, TimeSpan?duration = null) { if (!color.HasValue) { var r = new Random(); color = new RGBColor(r.NextDouble(), r.NextDouble(), r.NextDouble()); } if (waitTime == null) { waitTime = TimeSpan.FromMilliseconds(50); } if (onTime == null) { onTime = waitTime; } if (transitionTimeOn == null) { transitionTimeOn = TimeSpan.FromMilliseconds(0); } if (transitionTimeOff == null) { transitionTimeOff = TimeSpan.FromMilliseconds(0); } Ref <TimeSpan?> actualWaitTime = waitTime.Value + onTime.Value + transitionTimeOn.Value + transitionTimeOff.Value; if (!waitTillFinished) { actualWaitTime = waitTime.Value; } return(group.IteratorEffect(cancellationToken, async(current, ct, t) => { if (!waitTillFinished) { actualWaitTime.Value = waitTime.Value; } else { actualWaitTime.Value = waitTime.Value.Value + onTime.Value.Value + transitionTimeOn.Value.Value + transitionTimeOff.Value.Value; } current.SetState(ct, color, 1, transitionTimeOn.Value.Value); Task.Run(async() => { await Task.Delay(onTime.Value.Value + transitionTimeOn.Value.Value, ct).ConfigureAwait(false); current.SetBrightness(ct, 0, transitionTimeOff.Value.Value); }, ct); }, mode, secondaryIteratorMode, actualWaitTime, duration)); }
public static Task SetRandomColorFromList(this IEnumerable <StreamingLight> group, List <RGBColor> colors, IteratorEffectMode mode = IteratorEffectMode.Cycle, Ref <TimeSpan?> waitTime = null, Ref <TimeSpan?> transitionTime = null, TimeSpan?duration = null, CancellationToken cancellationToken = new CancellationToken()) { if (waitTime == null) { waitTime = TimeSpan.FromMilliseconds(50); } if (transitionTime == null) { transitionTime = TimeSpan.FromMilliseconds(0); } return(group.IteratorEffect(async(current, t) => { var color = colors.OrderBy(x => new Guid()).First(); current.SetState(color, 1, transitionTime.Value.Value); }, mode, waitTime, duration, cancellationToken)); }
/// <summary> /// Apply the effectFunction repeatedly to a group of lights /// </summary> /// <param name="group"></param> /// <param name="effectFunction"></param> /// <param name="mode"></param> /// <param name="waitTime"></param> /// <param name="duration"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public static async Task IteratorEffect(this IEnumerable <EntertainmentLight> group, CancellationToken cancellationToken, IteratorEffectFunc effectFunction, IteratorEffectMode mode, Func <TimeSpan> waitTime, TimeSpan?duration = null, int maxIterations = int.MaxValue) { if (waitTime == null) { waitTime = () => TimeSpan.FromSeconds(1); } if (duration == null) { duration = TimeSpan.MaxValue; } bool keepGoing = true; var lights = group.ToList(); bool reverse = false; Stopwatch sw = new Stopwatch(); sw.Start(); int i = 0; while (keepGoing && !cancellationToken.IsCancellationRequested && !(sw.Elapsed > duration) && i < maxIterations) { //Apply to whole group if mode is all if (mode == IteratorEffectMode.All) { effectFunction(group, cancellationToken, waitTime()); await Task.Delay(waitTime(), cancellationToken).ConfigureAwait(false); i++; continue; } if (reverse) { lights.Reverse(); } if (mode == IteratorEffectMode.Random || mode == IteratorEffectMode.RandomOrdered) { lights = lights.OrderBy(x => Guid.NewGuid()).ToList(); } foreach (var light in lights.Skip(reverse ? 1 : 0)) { if (!cancellationToken.IsCancellationRequested) { effectFunction(new List <EntertainmentLight>() { light }, cancellationToken, waitTime()); if (mode != IteratorEffectMode.AllIndividual) { await Task.Delay(waitTime(), cancellationToken).ConfigureAwait(false); } } } if (mode == IteratorEffectMode.AllIndividual) { await Task.Delay(waitTime(), cancellationToken).ConfigureAwait(false); } keepGoing = mode == IteratorEffectMode.Single ? false : true; if (mode == IteratorEffectMode.Bounce) { reverse = true; } i++; } }
/// <summary> /// Apply the groupFunction repeatedly to a list of groups of lights /// </summary> /// <param name="list"></param> /// <param name="groupFunction"></param> /// <param name="mode"></param> /// <param name="waitTime"></param> /// <param name="duration"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public static async Task IteratorEffect(this IEnumerable <IEnumerable <EntertainmentLight> > list, CancellationToken cancellationToken, IteratorEffectFunc groupFunction, IteratorEffectMode mode, IteratorEffectMode secondaryMode, Func <TimeSpan> waitTime, TimeSpan?duration = null, int maxIterations = int.MaxValue) { if (waitTime == null) { waitTime = () => TimeSpan.FromSeconds(1); } if (duration == null) { duration = TimeSpan.MaxValue; } int secondaryMaxIterations = 1; //Normalize secondary iterator mode switch (secondaryMode) { case IteratorEffectMode.Bounce: secondaryMaxIterations = 2; break; case IteratorEffectMode.Cycle: case IteratorEffectMode.Single: secondaryMode = IteratorEffectMode.Single; break; case IteratorEffectMode.Random: case IteratorEffectMode.RandomOrdered: secondaryMode = IteratorEffectMode.RandomOrdered; break; case IteratorEffectMode.All: case IteratorEffectMode.AllIndividual: default: break; } bool keepGoing = true; var groups = list.ToList(); bool reverse = false; if (mode == IteratorEffectMode.RandomOrdered) { groups = groups.OrderBy(x => Guid.NewGuid()).ToList(); } Stopwatch sw = new Stopwatch(); sw.Start(); int i = 0; while (keepGoing && !cancellationToken.IsCancellationRequested && !(sw.Elapsed > duration) && i < maxIterations) { //Apply to all groups if mode is all if (mode == IteratorEffectMode.All) { var flatGroup = list.SelectMany(x => x); if (!cancellationToken.IsCancellationRequested) { groupFunction(flatGroup, cancellationToken, waitTime()); } //foreach (var group in list) //{ // if (!cancellationToken.IsCancellationRequested) // await groupFunction(group, waitTime); //} await Task.Delay(waitTime(), cancellationToken).ConfigureAwait(false); i++; continue; } if (reverse) { groups.Reverse(); } if (mode == IteratorEffectMode.Random) { groups = groups.OrderBy(x => Guid.NewGuid()).ToList(); } if (mode == IteratorEffectMode.AllIndividual) { List <Task> allIndividualTasks = new List <Task>(); foreach (var group in groups.Skip(reverse ? 1 : 0).Where(x => x.Any())) { //Do not await, AllIndividual runs them all at the same time var t = group.IteratorEffect(cancellationToken, groupFunction, secondaryMode, waitTime, maxIterations: secondaryMaxIterations); allIndividualTasks.Add(t); } await Task.WhenAll(allIndividualTasks).ConfigureAwait(false); } else { foreach (var group in groups.Skip(reverse ? 1 : 0).Where(x => x.Any())) { await group.IteratorEffect(cancellationToken, groupFunction, secondaryMode, waitTime, maxIterations : secondaryMaxIterations).ConfigureAwait(false); } } keepGoing = mode == IteratorEffectMode.Single || mode == IteratorEffectMode.RandomOrdered ? false : true; if (mode == IteratorEffectMode.Bounce) { reverse = true; } i++; } }
/// <summary> /// Apply the effectFunction repeatedly to a group of lights /// </summary> /// <param name="group"></param> /// <param name="effectFunction"></param> /// <param name="mode"></param> /// <param name="waitTime"></param> /// <param name="duration"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public static async Task IteratorEffect(this IEnumerable <StreamingLight> group, IteratorEffectFunc effectFunction, IteratorEffectMode mode, Ref <TimeSpan?> waitTime, TimeSpan?duration = null, CancellationToken cancellationToken = new CancellationToken()) { if (waitTime == null) { waitTime = TimeSpan.FromSeconds(1); } if (duration == null) { duration = TimeSpan.MaxValue; } bool keepGoing = true; var lights = group.ToList(); bool reverse = false; Stopwatch sw = new Stopwatch(); sw.Start(); while (keepGoing && !cancellationToken.IsCancellationRequested && !(sw.Elapsed > duration)) { //Apply to whole group if mode is all if (mode == IteratorEffectMode.All) { await effectFunction(group, waitTime); await Task.Delay(waitTime.Value.Value); continue; } if (reverse) { lights.Reverse(); } if (mode == IteratorEffectMode.Random) { lights = lights.OrderBy(x => Guid.NewGuid()).ToList(); } foreach (var light in lights.Skip(reverse ? 1 : 0)) { await effectFunction(new List <StreamingLight>() { light }, waitTime); if (mode != IteratorEffectMode.AllIndividual) { await Task.Delay(waitTime.Value.Value); } } if (mode == IteratorEffectMode.AllIndividual) { await Task.Delay(waitTime.Value.Value); } keepGoing = mode == IteratorEffectMode.Single ? false : true; if (mode == IteratorEffectMode.Bounce) { reverse = true; } } }
public Task Start(IEnumerable <IEnumerable <EntertainmentLight> > layer, Func <TimeSpan> waitTime, RGBColor?color, IteratorEffectMode iteratorMode, IteratorEffectMode secondaryIteratorMode, CancellationToken cancellationToken) { if (!color.HasValue) { color = RGBColor.Random(); } if (iteratorMode != IteratorEffectMode.All) { if (secondaryIteratorMode == IteratorEffectMode.Bounce || secondaryIteratorMode == IteratorEffectMode.Cycle || secondaryIteratorMode == IteratorEffectMode.Random || secondaryIteratorMode == IteratorEffectMode.RandomOrdered || secondaryIteratorMode == IteratorEffectMode.Single) { Func <TimeSpan> customWaitMS = () => TimeSpan.FromMilliseconds((waitTime().TotalMilliseconds *layer.Count()) / layer.SelectMany(x => x).Count()); return(layer.FlashQuick(cancellationToken, color, iteratorMode, secondaryIteratorMode, waitTime: customWaitMS)); } } return(layer.FlashQuick(cancellationToken, color, iteratorMode, secondaryIteratorMode, waitTime: waitTime)); }
public Task Start(IEnumerable <IEnumerable <EntertainmentLight> > layer, Func <TimeSpan> waitTime, RGBColor?color, IteratorEffectMode iteratorMode, IteratorEffectMode secondaryIteratorMode, CancellationToken cancellationToken) { if (!color.HasValue) { color = RGBColor.Random(); } if (iteratorMode == IteratorEffectMode.All) { iteratorMode = IteratorEffectMode.AllIndividual; } //This is no fun, no action, change it to cycle if (iteratorMode == IteratorEffectMode.AllIndividual && (secondaryIteratorMode == IteratorEffectMode.All || secondaryIteratorMode == IteratorEffectMode.AllIndividual)) { secondaryIteratorMode = IteratorEffectMode.Cycle; } if (iteratorMode != IteratorEffectMode.AllIndividual) { if (secondaryIteratorMode == IteratorEffectMode.Bounce || secondaryIteratorMode == IteratorEffectMode.Cycle || secondaryIteratorMode == IteratorEffectMode.Random || secondaryIteratorMode == IteratorEffectMode.RandomOrdered || secondaryIteratorMode == IteratorEffectMode.Single) { Func <TimeSpan> customWaitMS = () => TimeSpan.FromMilliseconds((waitTime().TotalMilliseconds *layer.Count()) / layer.SelectMany(x => x).Count()); Func <TimeSpan> customOnTime = () => customWaitMS() / 2; Func <TimeSpan> customOffTime = () => customWaitMS() * 2; return(layer.Flash(cancellationToken, color, iteratorMode, secondaryIteratorMode, waitTime: customWaitMS, transitionTimeOn: customOnTime, transitionTimeOff: customOffTime, waitTillFinished: false)); } } Func <TimeSpan> onTime = () => waitTime() / 2; Func <TimeSpan> offTime = () => waitTime() * 2; return(layer.Flash(cancellationToken, color, iteratorMode, secondaryIteratorMode, waitTime: waitTime, transitionTimeOn: onTime, transitionTimeOff: offTime, waitTillFinished: false)); }