/// <summary>
        /// Gets the size of the incoming <see cref="Quaternion"/> array.
        /// </summary>
        /// <param name="serialPort">The communication port.</param>
        /// <param name="cancellationToken">Optional cancel token.</param>
        /// <returns>Awaitable byte future.</returns>
        protected virtual async Task <byte> GetQuaternionCountAsync(ICommunicationPort serialPort, CancellationToken cancellationToken)
        {
            await serialPort.ReadAsync(SingleByteBuffer, 0, 1, cancellationToken);

            byte quaternionCount = SingleByteBuffer[0];

            return(quaternionCount);
        }
        /// <inheritdoc />
        public async Task <RecyclableArraySegment <Quaternion> > ReadMessageAsync(ICommunicationPort serialPort, CancellationToken cancellationToken = default(CancellationToken))
        {
            byte quaternionCount = await GetQuaternionCountAsync(serialPort, cancellationToken);

            if (quaternionCount == 0)
            {
                return(RecyclableArraySegment <Quaternion> .Empty);
            }

            //Now we should read the quats based on the provided count
            var quatArray = ArrayPool <Quaternion> .Shared.Rent(quaternionCount);

            try
            {
                for (int i = 0; i < quaternionCount && !cancellationToken.IsCancellationRequested; i++)
                {
                    await serialPort.ReadAsync(SingleQuatBuffer, 0, SingleQuatBuffer.Length, cancellationToken);

                    //Just return whatever we have if cancelled.
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return(new RecyclableArraySegment <Quaternion>(quatArray, 0, quaternionCount));
                    }

                    //quatArray[i] = new Quaternion(GetFloatFromQuatBuffer(1), GetFloatFromQuatBuffer(2), GetFloatFromQuatBuffer(3), GetFloatFromQuatBuffer(0));
                    quatArray[i] = new Quaternion(GetFloatFromQuatBuffer(0), GetFloatFromQuatBuffer(1), GetFloatFromQuatBuffer(2), GetFloatFromQuatBuffer(3));

                    if (GlardunioStaticConfig.DebugLogging)
                    {
                        Debug.Log($"Quat log: {quatArray[i].x} {quatArray[i].y} {quatArray[i].z} {quatArray[i].w}");
                    }
                }

                return(new RecyclableArraySegment <Quaternion>(quatArray, 0, quaternionCount));
            }
            catch (Exception e)
            {
                throw;
            }
            finally
            {
                //If exceptions happen let's dipose of the array
                ArrayPool <Quaternion> .Shared.Return(quatArray);
            }
        }
Пример #3
0
        /// <summary>
        /// Read a line from the SerialPort asynchronously
        /// </summary>
        /// <param name="serialPort">The port to read data from</param>
        /// <returns>A line read from the input</returns>
        public static async Task <string> ReadLineAsync(this ICommunicationPort serialPort)
        {
            if (!serialPort.Encoding.IsSingleByte)
            {
                throw new InvalidOperationException($"TODO: Cannot support {serialPort.Encoding.EncodingName}. Only supports 1 byte ASCII right now.");
            }

            int charSizeCount = serialPort.Encoding.IsSingleByte ? 1 : serialPort.Encoding.GetMaxByteCount(1);

            byte[] _singleCharBuffer = ArrayPool <byte> .Shared.Rent(charSizeCount);

            StringBuilder builder = new StringBuilder();

            try
            {
                // Read the input one byte at a time, convert the
                // byte into a char, add that char to the overall
                // response string, once the response string ends
                // with the line ending then stop reading
                while (true)
                {
                    await serialPort.ReadAsync(_singleCharBuffer, 0, 1)
                    .ConfigureAwait(false);

                    builder.Append((char)_singleCharBuffer[0]);

                    if (builder[builder.Length - 1] == DefaultNewLine)
                    {
                        // Truncate the line ending
                        return(builder.ToString(0, builder.Length - 1));
                    }
                }
            }
            catch (Exception e)
            {
                throw;
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(_singleCharBuffer, true);
            }
        }
        /// <inheritdoc />
        public async Task <int> ReadMessageAsync(ICommunicationPort serialPort, CancellationToken cancellationToken = default(CancellationToken))
        {
            await serialPort.ReadAsync(IntBuffer, 0, sizeof(int), cancellationToken);

            return(Unsafe.ReadUnaligned <int>(ref IntBuffer[0]));
        }