public void ManualBeat(IteratorEffectFunc effectFunction = null) { if (effectFunction != null) { EffectFunction = effectFunction; } if (sw.IsRunning && sw.Elapsed < TimeSpan.FromSeconds(5)) { LastManualBeat = sw.Elapsed; sw.Reset(); } sw.Start(); _timer.Stop(); if (LastManualBeat.HasValue) { StartAutoTimer(LastManualBeat.Value); } _timer_Elapsed(null, null); }
/// <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 <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 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; } } }