Exemplo n.º 1
0
        private void OnAnimationRequestReceived(byte[] message)
        {
            // The frame might be split up into multiple packages.
            // We keep a buffer (FrameProtocol for each frame) to wait for all packages.
            // When the frame is complete, we call FrameReceived.
            int frameIndex          = FrameProtocol.GetFrameIndex(message);
            FrameWithoutDelta frame = null;

            lock (_resourceLock)
            {
                if (_frameSectionBuffer == null)
                {
                    _frameSectionBuffer = new Dictionary <int, FrameProtocol>();
                }

                if (!_frameSectionBuffer.ContainsKey(frameIndex))
                {
                    _frameSectionBuffer.Add(frameIndex, new FrameProtocol());
                }

                if (_frameSectionBuffer[frameIndex].TryDeserialize(message, out frame))
                {
                    _frameSectionBuffer.Remove(frameIndex);
                }
            }

            if (frame != null)
            {
                OnFrameReceived(frame);
            }
        }
Exemplo n.º 2
0
        public void TryDeserialize_frameWithThreeFrameSetsOutOfOrder_DeserializesCorrectly()
        {
            int maxPackageSize              = 1016;
            int timeUnitsPerFrame           = 100;
            int frameIndex                  = 9;
            FrameWithoutDelta expectedFrame = new FrameWithoutDelta(frameIndex, timeUnitsPerFrame, 900);

            for (int i = 0; i < 900; i++)
            {
                expectedFrame[i] = new PixelInstruction(1, 2, 3);
            }

            // RUN
            byte[][] packages = FrameProtocol.SerializeFrame(expectedFrame, maxPackageSize);

            Assert.AreEqual(3, packages.Length);

            FrameProtocol     protocol = new FrameProtocol();
            FrameWithoutDelta frame;

            Assert.AreEqual(false, protocol.TryDeserialize(packages[0], out frame));
            Assert.AreEqual(false, protocol.TryDeserialize(packages[2], out frame));
            Assert.AreEqual(true, protocol.TryDeserialize(packages[1], out frame));
            Assert.IsNotNull(frame);
            Assert.AreEqual(expectedFrame.Index, frame.Index);
            Assert.AreEqual(expectedFrame.TimeStampRelative, frame.TimeStampRelative);
            Assert.AreEqual(expectedFrame.Count, frame.Count);
            CollectionAssert.AreEquivalent(expectedFrame.Items, frame.Items);
        }
Exemplo n.º 3
0
        public void SerializeFrame_FrameTooBigForASinglePackage_CreatesCorrectByteArray()
        {
            int maxPackageSize      = 1016;
            int timeUnitsPerFrame   = 100;
            int frameIndex          = 9;
            FrameWithoutDelta frame = new FrameWithoutDelta(frameIndex, timeUnitsPerFrame, 900);

            for (int i = 0; i < 900; i++)
            {
                frame[i] = new PixelInstruction(1, 2, 3);
            }

            // RUN
            byte[][] packages = FrameProtocol.SerializeFrame(frame, maxPackageSize);

            // Deserialize
            FrameProtocol     frameProtocol     = new FrameProtocol();
            FrameWithoutDelta deserializedFrame = null;

            foreach (byte[] package in packages)
            {
                if (frameProtocol.TryDeserialize(package, out FrameWithoutDelta returnFrame))
                {
                    deserializedFrame = returnFrame;
                }
            }

            // Assert
            Assert.AreEqual(3, packages.Length);
            Assert.IsNotNull(deserializedFrame);
            CollectionAssert.AreEqual(frame.Items, deserializedFrame.Items);
        }
Exemplo n.º 4
0
        private void OnFrameReceived(FrameWithoutDelta frame)
        {
            EventHandler <FrameWithoutDelta> handler = RenderFrameReceived;

            if (handler != null)
            {
                handler(this, frame);
            }
        }
Exemplo n.º 5
0
        public static byte[][] SerializeFrame(FrameWithoutDelta frame, int maxSizePerPackage)
        {
            int bytesNeeded = HEADER_BYTES_NEEDED + frame.Items.Length * PixelInstructionProtocol.BYTES_NEEDED;

            byte[][] packages;

            if (bytesNeeded <= maxSizePerPackage)
            {
                // The frame is small enough to fit in a single packet.
                // No FrameSectionPackage is needed.
                packages    = new byte[1][];
                packages[0] = new byte[bytesNeeded];
                BitConverter.GetBytes(frame.Index).CopyTo(packages[0], 0);             // Sequence index
                BitConverter.GetBytes(frame.TimeStampRelative).CopyTo(packages[0], 4); // TimeStamp (relative)
                BitConverter.GetBytes(frame.Count).CopyTo(packages[0], 8);             // Number of PixelInstructions
                BitConverter.GetBytes(false).CopyTo(packages[0], 12);                  // Has FrameSections

                for (int i = 0; i < frame.Count; i++)
                {
                    int bufferStartIndex = HEADER_BYTES_NEEDED + i * PixelInstructionProtocol.BYTES_NEEDED;
                    PixelInstructionProtocol.Serialize(frame[i], packages[0], bufferStartIndex);
                }
                return(packages);
            }

            // This frame is too big to send as one packet.
            // Create multiple packages with the help of FrameSectionPackage

            // First, calculate the inital package
            int headerBytesNeeded          = HEADER_BYTES_NEEDED + FrameSectionProtocol.HEADER_BYTES_NEEDED;
            int instructionsInFirstSection = (maxSizePerPackage - headerBytesNeeded) / PixelInstructionProtocol.BYTES_NEEDED;

            // Second, calculate how many FrameSections are needed
            int instructionsThatFitInOtherSections = (maxSizePerPackage - FrameSectionProtocol.HEADER_BYTES_NEEDED) / PixelInstructionProtocol.BYTES_NEEDED;
            int frameSectionsNeeded = (int)Math.Ceiling((double)(frame.Count - instructionsInFirstSection) / instructionsThatFitInOtherSections) + 1; // +1 for the first section

            packages = new byte[frameSectionsNeeded][];

            // Third, create the Frame header and its first section
            packages[0] = new byte[headerBytesNeeded + instructionsInFirstSection * PixelInstructionProtocol.BYTES_NEEDED];

            BitConverter.GetBytes(frame.Index).CopyTo(packages[0], 0);             // Sequence index
            BitConverter.GetBytes(frame.TimeStampRelative).CopyTo(packages[0], 4); // TimeStamp (relative)
            BitConverter.GetBytes(frameSectionsNeeded).CopyTo(packages[0], 8);     // Number of FrameSets
            BitConverter.GetBytes(true).CopyTo(packages[0], 12);                   // Has FrameSections
            CreateFrameSection(packages[0], 13, frame, frame.Index, 0, 0, instructionsInFirstSection);

            // Lastely, create the other frame sections. A new byte array (package) for each FrameSection.
            for (int i = 0; i < frameSectionsNeeded - 1; i++)
            {
                int instructionStartIndex     = instructionsInFirstSection + i * instructionsThatFitInOtherSections;
                int instructionsInThisSection = Math.Min(instructionsThatFitInOtherSections, frame.Count - instructionStartIndex);
                packages[i + 1] = new byte[FrameSectionProtocol.HEADER_BYTES_NEEDED + PixelInstructionProtocol.BYTES_NEEDED * instructionsInThisSection];
                CreateFrameSection(packages[i + 1], 0, frame, frame.Index, i + 1, instructionStartIndex, instructionsInThisSection);
            }
            return(packages);
        }
Exemplo n.º 6
0
        private static void CreateFrameSection(byte[] buffer, int bufferStartIndex, FrameWithoutDelta frame,
                                               int frameIndex, int sectionIndex, int instructionStartIndex, int numberOfInstructions)
        {
            FrameSectionPackage package = new FrameSectionPackage();

            package.FrameSequenceIndex = frameIndex;
            package.Index             = sectionIndex;
            package.pixelInstructions = new List <PixelInstruction>();
            for (int i = instructionStartIndex; i < instructionStartIndex + numberOfInstructions; i++)
            {
                package.pixelInstructions.Add(frame[i]);
            }

            FrameSectionProtocol.Serialize(package, buffer, bufferStartIndex);
        }
Exemplo n.º 7
0
        public void Render__LedStripRenderGetsCalled()
        {
            FrameWithoutDelta frame = new FrameWithoutDelta(0, 100, 1);

            frame[0] = new PixelInstruction(10, 20, 30);
            var mock = new Mock <ILEDStrip>();

            mock.Setup(x => x.Render());

            LedController controller = new LedController(mock.Object);

            controller.RenderFrame(frame);

            mock.Verify(x => x.Render(), Times.Once);
        }
Exemplo n.º 8
0
        public void GetFrameIndex_FrameAndFrameSection_GetsCorrectIndex()
        {
            int maxPackageSize              = 1016;
            int timeUnitsPerFrame           = 100;
            int frameIndex                  = 9;
            FrameWithoutDelta expectedFrame = new FrameWithoutDelta(frameIndex, timeUnitsPerFrame, 900);

            for (int i = 0; i < 900; i++)
            {
                expectedFrame[i] = new PixelInstruction(1, 2, 3);
            }

            // RUN
            byte[][] packages = FrameProtocol.SerializeFrame(expectedFrame, maxPackageSize);

            Assert.AreEqual(3, packages.Length);
            Assert.AreEqual(frameIndex, FrameProtocol.GetFrameIndex(packages[0]));
            Assert.AreEqual(frameIndex, FrameProtocol.GetFrameIndex(packages[1]));
            Assert.AreEqual(frameIndex, FrameProtocol.GetFrameIndex(packages[2]));
        }
Exemplo n.º 9
0
        public void RenderFrame(FrameWithoutDelta frame)
        {
            if (Monitor.TryEnter(lockObject))
            {
                try
                {
                    for (int i = 0; i < frame.Count; i++)
                    {
                        PixelInstruction instruction = frame[i];

                        _ledStrip.SetLEDColor(0, i, System.Drawing.Color.FromArgb(instruction.R, instruction.G, instruction.B));
                    }

                    _ledStrip.Render();
                }
                finally
                {
                    Monitor.Exit(lockObject);
                }
            }
        }
Exemplo n.º 10
0
        public void TryDeserialize_frameWithNoFrameSets_DeserializesCorrectly()
        {
            int timeUnitsPerFrame           = 100;
            FrameWithoutDelta expectedFrame = new FrameWithoutDelta(1, timeUnitsPerFrame, 3);

            expectedFrame[0] = new PixelInstruction(1, 2, 3);
            expectedFrame[1] = new PixelInstruction(4, 5, 6);
            expectedFrame[2] = new PixelInstruction(7, 8, 9);

            byte[] bytes      = new byte[sizeof(int) + sizeof(int) + sizeof(int) + sizeof(bool) + PixelInstructionProtocol.BYTES_NEEDED * 3];
            int    startIndex = 0;

            BitConverter.GetBytes(1).CopyTo(bytes, startIndex);                        // Frame index
            BitConverter.GetBytes(timeUnitsPerFrame).CopyTo(bytes, startIndex   += 4); // Timestamp (relative)
            BitConverter.GetBytes(expectedFrame.Count).CopyTo(bytes, startIndex += 4); // Number of PixelInstructions
            BitConverter.GetBytes(false).CopyTo(bytes, startIndex += 4);               // Has FrameSections
            // instruction 1
            bytes[startIndex += 1] = 1;
            bytes[startIndex += 1] = 2;
            bytes[startIndex += 1] = 3;
            // instruction 2
            bytes[startIndex += 1] = 4;
            bytes[startIndex += 1] = 5;
            bytes[startIndex += 1] = 6;
            // instruction 3
            bytes[startIndex += 1] = 7;
            bytes[startIndex += 1] = 8;
            bytes[startIndex += 1] = 9;

            FrameProtocol     protocol = new FrameProtocol();
            FrameWithoutDelta frame;

            Assert.AreEqual(true, protocol.TryDeserialize(bytes, out frame));
            Assert.IsNotNull(frame);
            Assert.AreEqual(expectedFrame.Index, frame.Index);
            Assert.AreEqual(expectedFrame.TimeStampRelative, frame.TimeStampRelative);
            Assert.AreEqual(expectedFrame.Count, frame.Count);
            CollectionAssert.AreEqual(expectedFrame.Items, frame.Items);
        }
Exemplo n.º 11
0
        public void PrepareFrame_Frame_FrameGetsDrawnToStrip()
        {
            FrameWithoutDelta frame = new FrameWithoutDelta(0, 100, 1);

            frame[0] = new PixelInstruction(10, 20, 30);

            var mock = new Mock <ILEDStrip>();

            int   index = -1;
            Color color = new Color();

            mock.Setup(x => x.SetLEDColor(It.IsAny <int>(), It.IsAny <int>(), It.IsAny <Color>())).Callback <int, int, Color>((i, j, c) =>
            {
                index = j;
                color = c;
            });

            LedController controller = new LedController(mock.Object);

            controller.RenderFrame(frame);
            Assert.AreEqual(0, index);
            Assert.AreEqual(Color.FromArgb(10, 20, 30), color);
        }
Exemplo n.º 12
0
        public void SerializeFrame_Frame_CreatesCorrectByteArray()
        {
            int maxPackageSize      = 1016;
            int timeUnitsPerFrame   = 100;
            int frameIndex          = 9;
            FrameWithoutDelta frame = new FrameWithoutDelta(frameIndex, timeUnitsPerFrame, 3);

            frame[0] = new PixelInstruction(1, 2, 3);
            frame[1] = new PixelInstruction(4, 5, 6);
            frame[2] = new PixelInstruction(7, 8, 9);

            byte[] expectedBytes = new byte[sizeof(int) + sizeof(int) + sizeof(int) + sizeof(bool) + 3 + 3 + 3];
            int    startIndex    = 0;

            BitConverter.GetBytes(frameIndex).CopyTo(expectedBytes, startIndex);             // Frame index
            BitConverter.GetBytes(timeUnitsPerFrame).CopyTo(expectedBytes, startIndex += 4);
            BitConverter.GetBytes(frame.Count).CopyTo(expectedBytes, startIndex       += 4); // Number of PixelInstructions
            BitConverter.GetBytes(false).CopyTo(expectedBytes, startIndex             += 4); // Has FrameSections
            // instruction 1
            expectedBytes[startIndex += 1] = 1;
            expectedBytes[startIndex += 1] = 2;
            expectedBytes[startIndex += 1] = 3;
            // instruction 2
            expectedBytes[startIndex += 1] = 4;
            expectedBytes[startIndex += 1] = 5;
            expectedBytes[startIndex += 1] = 6;
            // instruction 3
            expectedBytes[startIndex += 1] = 7;
            expectedBytes[startIndex += 1] = 8;
            expectedBytes[startIndex += 1] = 9;

            byte[][] packages = FrameProtocol.SerializeFrame(frame, maxPackageSize);

            Assert.AreEqual(1, packages.Length);
            Assert.AreEqual(expectedBytes, packages[0]);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Deserialize a package
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns>True if the frame has been deserialized, False if not all packages have been received.</returns>
        public bool TryDeserialize(byte[] bytes, out FrameWithoutDelta frame)
        {
            frame = null;
            if (_frameSectionPackages == null)
            {
                // First package.
                // Read Frame header
                int startIndex = 0;
                _frameIndex        = BitConverter.ToInt32(bytes, startIndex);
                _timeStampRelative = BitConverter.ToInt32(bytes, startIndex += 4);
                int  itemCount        = BitConverter.ToInt32(bytes, startIndex += 4);
                bool hasFrameSections = BitConverter.ToBoolean(bytes, startIndex += 4);
                startIndex += 1;

                if (hasFrameSections)
                {
                    _frameSectionPackages     = new FrameSectionPackage[itemCount];
                    _frameSectionsReceived    = new bool[itemCount];
                    _frameSectionsReceived[0] = true;
                    // The rest of the package is a FrameSection
                    _frameSectionPackages[0] = FrameSectionProtocol.Deserialize(bytes, startIndex);
                    return(false);
                }
                else
                {
                    frame = new FrameWithoutDelta(_frameIndex, _timeStampRelative, itemCount);
                    // The rest of the package contains PixelInstructions
                    for (int i = 0; i < itemCount; i++)
                    {
                        int instructionStartIndex = startIndex + i * PixelInstructionProtocol.BYTES_NEEDED;
                        frame[i] = PixelInstructionProtocol.Deserialize(bytes, instructionStartIndex);
                    }
                    return(true);
                }
            }
            else
            {
                // Subsequent package. Always starts with a FrameSection.
                FrameSectionPackage package = FrameSectionProtocol.Deserialize(bytes, 0);
                if (package.FrameSequenceIndex != _frameIndex)
                {
                    throw new System.Net.ProtocolViolationException(
                              $"The frameIndex of the frameSection does not match with the Frame's index. Expected :{_frameIndex}, Received: {package.FrameSequenceIndex}");
                }

                _frameSectionPackages[package.Index]  = package;
                _frameSectionsReceived[package.Index] = true;

                if (_frameSectionsReceived.All(x => x))
                {
                    // TODO add totalNumberOfPixelInstructions to frame header
                    int totalPixelInstructions = _frameSectionPackages.Sum(x => x.NumberOfPixelInstructions);
                    frame = new FrameWithoutDelta(_frameIndex, _timeStampRelative, totalPixelInstructions);
                    int index = 0;
                    for (int i = 0; i < _frameSectionPackages.Length; i++)
                    {
                        for (int j = 0; j < _frameSectionPackages[i].NumberOfPixelInstructions; j++)
                        {
                            frame[index++] = _frameSectionPackages[i].pixelInstructions[j];
                        }
                    }

                    return(true);
                }

                return(false);
            }
        }