internal void Parse() { CodeLine.LineStr = DefineTable.Dealias(CodeLine.LineStr); // Perform regex: const string instrPattern = "glowramp"; const string gap = @"[\s|\t]*"; const string ledsPattern = @"\[(.*?)]"; const string colorPattern = @"\((.*?)\)"; const string timePattern = @"(\d+)"; const string timeUnitPattern = @"(ms|s|m|h|t)"; var pattern = $@"^{instrPattern}{gap}:{gap}{ledsPattern}{gap}{colorPattern}{gap}to{gap}{colorPattern}{gap}in{gap}{timePattern}{timeUnitPattern}$"; var match = Regex.Match(CodeLine.LineStr, pattern); if (!match.Success) { Console.WriteLine("Invalid 'glowRamp' instruction"); throw new Exception(); } // Get zero-based led list: try { LedIdxList = match.Groups[1].Value.GetLeds(); } catch { Console.WriteLine("Invalid LED(s) in 'glowRamp' instruction"); throw new Exception(); } // Get color: try { // Get start color: LedColorFrom = match.Groups[2].Value.GetColor(); // Get end color: LedColorTo = match.Groups[3].Value.GetColor(); } catch { Console.WriteLine("Invalid color in 'glowRamp' instruction"); throw new Exception(); } // Get ramp duration in millisecs: long millisecs = match.Groups[4].Value.GetDuration(match.Groups[5].Value); if (millisecs > 3888000000) // 45-day upper limit. { Console.WriteLine("Pause duration exceed 45-days (3888000-seconds)"); throw new Exception(); } RampMs = (uint)millisecs; // Calculate from-to delta (negative values indicate decrement): LedColorDiff.Red = LedColorTo.Red - LedColorFrom.Red; LedColorDiff.Green = LedColorTo.Green - LedColorFrom.Green; LedColorDiff.Blue = LedColorTo.Blue - LedColorFrom.Blue; LedColorDiff.Bright = LedColorTo.Bright - LedColorFrom.Bright; // Calculate red tick/color step to get as close as possible to target color in ramp ticks: if (LedColorDiff.Red != 0 && RampTicks >= Math.Abs(LedColorDiff.Red)) { TickStep.Red = (int)Math.Floor((double)RampTicks / Math.Abs(LedColorDiff.Red)); ColorStep.Red = 1; } else if (LedColorDiff.Red != 0 && RampTicks < Math.Abs(LedColorDiff.Red)) { TickStep.Red = 1; ColorStep.Red = (int)Math.Floor((double)Math.Abs(LedColorDiff.Red) / RampTicks); } // Calculate green tick/color step to get as close as possible to target color in ramp ticks: if (LedColorDiff.Green != 0 && RampTicks >= Math.Abs(LedColorDiff.Green)) { TickStep.Green = (int)Math.Floor((double)RampTicks / Math.Abs(LedColorDiff.Green)); ColorStep.Green = 1; } else if (LedColorDiff.Green != 0 && RampTicks < Math.Abs(LedColorDiff.Green)) { TickStep.Green = 1; ColorStep.Green = (int)Math.Floor((double)Math.Abs(LedColorDiff.Green) / RampTicks); } // Calculate blue tick/color step to get as close as possible to target color in ramp ticks: if (LedColorDiff.Blue != 0 && RampTicks >= Math.Abs(LedColorDiff.Blue)) { TickStep.Blue = (int)Math.Floor((double)RampTicks / Math.Abs(LedColorDiff.Blue)); ColorStep.Blue = 1; } else if (LedColorDiff.Blue != 0 && RampTicks < Math.Abs(LedColorDiff.Blue)) { TickStep.Blue = 1; ColorStep.Blue = (int)Math.Floor((double)Math.Abs(LedColorDiff.Blue) / RampTicks); } // Calculate bright tick/color step to get as close as possible to target color in ramp ticks: if (LedColorDiff.Bright != 0 && RampTicks >= Math.Abs(LedColorDiff.Bright)) { TickStep.Bright = (int)Math.Floor((double)RampTicks / Math.Abs(LedColorDiff.Bright)); ColorStep.Bright = 1; } else if (LedColorDiff.Bright != 0 && RampTicks < Math.Abs(LedColorDiff.Bright)) { TickStep.Bright = 1; ColorStep.Bright = (int)Math.Floor((double)Math.Abs(LedColorDiff.Bright) / RampTicks); } // Generate pre glow immediate instruction to initialize glow ramp: PreGlowImmediateInstruction = new GlowImmediateInstruction { LedIdxList = new List <int>(LedIdxList), LedColor = LedColorFrom.DeepCopy(), Path = Path, ZOrder = ZOrder }; // Generate post glow immediate instruction to finalize glow ramp: PostGlowImmediateInstruction = new GlowImmediateInstruction { LedIdxList = new List <int>(LedIdxList), LedColor = LedColorTo.DeepCopy(), Path = Path, ZOrder = ZOrder }; // Generate post-ramp ledstrip state: foreach (var ledIdx in LedIdxList) { LedstripPostState.LedStateList[ledIdx] = LedColorTo; } }
internal bool Equals(GlowImmediateInstruction mi) { return(LedIdxList.OrderBy(x => x).SequenceEqual(mi.LedIdxList.OrderBy(x => x)) && LedColor.Equals(mi.LedColor)); }
internal static List <Instruction> ConvertToInstructions(List <CodeLine> codeLines, int path, int zOrder) { var instrSet = new List <Instruction>(); var funcGuid = Guid.NewGuid(); var currLineNb = 1; try { foreach (var codeLine in codeLines) { currLineNb = codeLine.LineNb; if (codeLine.LineStr.IsGlowImmediateInstruction()) { var instr = new GlowImmediateInstruction(codeLine, path, zOrder); instrSet.Add(instr); } else if (codeLine.LineStr.IsGlowRampInstruction()) { var instr = new GlowRampInstruction(codeLine, path, zOrder); instrSet.Add(instr.PreGlowImmediateInstruction); instrSet.Add(instr); instrSet.Add(instr.PostGlowImmediateInstruction); } else if (codeLine.LineStr.IsCallInstruction(out var repeatCount)) { while (repeatCount-- > 0) { var instr = new CallInstruction(codeLine, path, zOrder); instrSet.AddRange(instr.InstrList); } } else if (codeLine.LineStr.IsCallAsyncInstruction(zOrder, out int newZOrder)) { var nextExecutionPathIndex = ++ExecutionPathIndex; var pathActivateInstruction = new PathActivateInstruction(path, zOrder) // use prev zOrder as this instruction is not in new path. { TargetPathIdx = (uint)nextExecutionPathIndex }; var callInstruction = new CallInstruction(codeLine, nextExecutionPathIndex, newZOrder); var pathEndInstruction = new PathEndInstruction(nextExecutionPathIndex, newZOrder); instrSet.Add(pathActivateInstruction); instrSet.AddRange(callInstruction.InstrList); instrSet.Add(pathEndInstruction); } else if (codeLine.LineStr.IsPauseInstruction()) { var instr = new PauseInstruction(codeLine, path, zOrder); instrSet.Add(instr); } else if (codeLine.LineStr.IsHereInstruction()) { var instr = new HereInstruction(codeLine, path, zOrder, funcGuid); instrSet.Add(instr); } else if (codeLine.LineStr.IsGotoInstruction()) { var instr = new GotoInstruction(codeLine, path, zOrder, funcGuid); instrSet.Add(instr); } else { Console.WriteLine($"Unknown instruction"); throw new Exception(); } } } catch { if (recursiveTip) { recursiveTip = false; Console.Write($"Error parsing line {currLineNb}"); } throw new Exception(); } return(instrSet); }