internal void Parse()
        {
            CodeLine.LineStr = DefineTable.Dealias(CodeLine.LineStr);

            // Perform regex:
            const string instrPattern    = "pause";
            const string gap             = @"[\s|\t]*";
            const string timePattern     = @"(\d+)";
            const string timeUnitPattern = @"(ms|s|m|h|t)";
            var          pattern         = $@"^{instrPattern}{gap}:{gap}{timePattern}{timeUnitPattern}$";
            var          match           = Regex.Match(CodeLine.LineStr, pattern);

            if (!match.Success)
            {
                Console.WriteLine("Invalid 'pause' instruction");
                throw new Exception();
            }

            // Get pause duration in millisecs:
            long millisecs = match.Groups[1].Value.GetDuration(match.Groups[2].Value);

            if (millisecs > 3888000000)    // 45-day upper limit.
            {
                Console.WriteLine("Pause duration exceed 45-days (3888000-seconds)");
                throw new Exception();
            }
            Millisecs = (uint)millisecs;
        }
Пример #2
0
        internal void Parse()
        {
            CodeLine.LineStr = DefineTable.Dealias(CodeLine.LineStr);

            // Perform regex:
            const string instrPattern = "here";
            const string gap          = @"[\s|\t]*";
            const string funcPattern  = "([a-z][a-z_0-9]*)";
            var          pattern      = $"^{instrPattern}{gap}:{gap}{funcPattern}$";
            var          match        = Regex.Match(CodeLine.LineStr, pattern);

            if (!match.Success)
            {
                Console.WriteLine("Invalid 'here' instruction");
                throw new Exception();
            }

            // Get bookmark name:
            _name = match.Groups[1].Value;
        }
        internal void Parse()
        {
            CodeLine.LineStr = DefineTable.Dealias(CodeLine.LineStr);

            // Perform regex:
            const string instrPattern = "glowimmediate";
            const string gap          = @"[\s|\t]*";
            const string ledsPattern  = @"\[(.*?)]";
            const string colorPattern = @"\((.*?)\)";
            var          pattern      = $"^{instrPattern}{gap}:{gap}{ledsPattern}{gap}{colorPattern}$";
            var          match        = Regex.Match(CodeLine.LineStr, pattern);

            if (!match.Success)
            {
                Console.WriteLine("Invalid 'glowImmediate' instruction");
                throw new Exception();
            }

            // Get zero-based led list:
            try
            {
                LedIdxList = match.Groups[1].Value.GetLeds();
            }
            catch
            {
                Console.WriteLine("Invalid LED(s) in 'glowImmediate' instruction");
                throw new Exception();
            }

            // Get color:
            try
            {
                LedColor = match.Groups[2].Value.GetColor();
            }
            catch
            {
                Console.WriteLine("Invalid color in 'glowImmediate' instruction");
                throw new Exception();
            }
        }
Пример #4
0
        private static int Main(string[] userArgs)
        {
            Console.WriteLine("Starting build...");

            try
            {
                // Handle args:
                var args = new ArgHandler(userArgs);

                if (args.Lines == null && args.Lines.Count() == 0)
                {
                    Console.WriteLine($"Empty or invalid code file.");
                    throw new Exception();
                }

                // Remove comments, extra whitespace, tabs, empty lines, etc:
                var codeLines = CodeCleanup(args.Lines);

                // Store code lines in their respective table:
                PopulateCodeTables(codeLines);

                // Build tables:
                DeviceTable.Build();
                DefineTable.Build();
                FunctionTable.Build();

                // Compile/link start function:
                var compiler     = new Compiler(args);
                var isSuccessful = compiler.Compile(out byte[] lightshowByteArray, out uint contextRegionByteSize, out uint maxInstrPathByteSize, out int threadCount);
                if (lightshowByteArray == null)
                {
                    Console.WriteLine("No build data generated.");
                    throw new Exception();
                }
                if (DeviceTable.Dev.SimulatorBrightnessCoeff == 0)
                {
                    Console.WriteLine("Invalid simulator brightness coefficient.");
                    throw new Exception();
                }
                Console.WriteLine($"Device threads usage: {Math.Round(100f * threadCount / DeviceTable.Proto.MaxThreads, 1):F1}% ({threadCount} of {DeviceTable.Proto.MaxThreads} threads).");
                CheckMemoryUsage(lightshowByteArray, contextRegionByteSize, maxInstrPathByteSize);

                Console.WriteLine("Build completed successfully.");

                // Generate output files (xml/bin):
                var controlPacketGenerator     = new ControlPacketGenerator(args);
                var downloadLightshowByteArray = controlPacketGenerator.GetDownloadLightshowPackets(lightshowByteArray);
                var startLightshowByteArray    = controlPacketGenerator.GetStartLightshowPacket();
                var pauseLightshowByteArray    = controlPacketGenerator.GetPauseLightshowPacket();
                var resumeLightshowByteArray   = controlPacketGenerator.GetResumeLightshowPacket();
                var outputXmlFilePath          = Path.Combine(Path.GetDirectoryName(args.InputFilePath), Path.GetFileNameWithoutExtension(args.InputFilePath) + ".xml");
                var outputBinFilePath          = Path.Combine(Path.GetDirectoryName(args.InputFilePath), Path.GetFileNameWithoutExtension(args.InputFilePath) + ".bin");
                PrintOutput(
                    lightshowByteArray, downloadLightshowByteArray, startLightshowByteArray, pauseLightshowByteArray, resumeLightshowByteArray,
                    outputXmlFilePath, outputBinFilePath);

                return((int)ExitCode.Success);
            }
            catch
            {
                return((int)ExitCode.Fail);
            }
        }
        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;
            }
        }