Example #1
0
        public async Task ReadMessages(PipeReader reader, PacketSource packetSource, CancellationToken ct = default)
        {
            try
            {
                while (!ct.IsCancellationRequested)
                {
                    var msg = await reader.ReadAsync(ct).ConfigureAwait(false);

                    if (msg.IsCompleted || msg.IsCanceled || ct.IsCancellationRequested)
                    {
                        break;
                    }

                    if (!TryReadFromBuffer(msg.Buffer, out PacketHeader header, out int headerBytesRead))
                    {
                        reader.AdvanceTo(msg.Buffer.Start, msg.Buffer.End);
                    }
                    else
                    {
                        switch (header.PacketId)
                        {
                        case PacketHeader.PacketType.Session:
                            if (HandleMessageAndAdvanceBuffer <PacketSessionData>(out var pSessionData))
                            {
                                _packetHandler.OnPacketSessionData(ref pSessionData, packetSource);
                            }
                            break;

                        case PacketHeader.PacketType.CarSetups:
                            HandleMessageAndAdvanceBuffer <PacketCarSetupData>(out var pCarSetup);
                            {
                                _packetHandler.OnPacketCarSetupData(ref pCarSetup, packetSource);
                            }
                            break;

                        case PacketHeader.PacketType.CarStatus:
                            HandleMessageAndAdvanceBuffer <PacketCarStatusData>(out var pCarStatus);
                            {
                                _packetHandler.OnPacketCarStatusData(ref pCarStatus, packetSource);
                            }
                            break;

                        case PacketHeader.PacketType.CarTelemetry:
                            HandleMessageAndAdvanceBuffer <PacketCarTelemetryData>(out var pTelemetry);
                            {
                                _packetHandler.OnPacketCarTelemetryData(ref pTelemetry, packetSource);
                            }
                            break;

                        case PacketHeader.PacketType.Event:
                            if (HandleMessageAndAdvanceBuffer <PacketEventData>(out var pEvent))
                            {
                                _packetHandler.OnPacketEventData(ref pEvent, packetSource);
                            }
                            break;

                        case PacketHeader.PacketType.LapData:
                            HandleMessageAndAdvanceBuffer <PacketLapData>(out var pLap);
                            {
                                _packetHandler.OnPacketLapData(ref pLap, packetSource);
                            }
                            break;

                        case PacketHeader.PacketType.Motion:
                            HandleMessageAndAdvanceBuffer <PacketMotionData>(out var pMotion);
                            {
                                _packetHandler.OnPacketMotionData(ref pMotion, packetSource);
                            }
                            break;

                        case PacketHeader.PacketType.Participants:
                            HandleMessageAndAdvanceBuffer <PacketParticipantsData>(out var pParticipants);
                            {
                                _packetHandler.OnPacketParticipantsData(ref pParticipants, packetSource);
                            }
                            break;

                        default:
                            throw new InvalidOperationException(
                                      $"Unsupported packet id {header.PacketId}, message should have been filtered before");
                        }
                    }

                    bool HandleMessageAndAdvanceBuffer <T>(out T sessionData) where T : struct
                    {
                        if (!TryReadFromBuffer <T>(msg.Buffer, out sessionData, out int bytesRead))
                        {
                            reader.AdvanceTo(msg.Buffer.Start, msg.Buffer.End);
                            return(false);
                        }

                        if (Logger.IsDebugEnabled)
                        {
                            Logger.DebugFormat("Successfully parsed {0}: {1}", typeof(T).Name, sessionData);
                        }

                        reader.AdvanceTo(msg.Buffer.GetPosition(bytesRead));
                        return(true);
                    }
                }