Beispiel #1
0
        /// <summary>
        ///     Override to provide new behavior for a receipt of a complete PosiStageNet data frame
        /// </summary>
        /// <param name="header"></param>
        /// <param name="dataPackets"></param>
        protected virtual void OnCompleteDataFrameReceived(PsnDataHeaderChunk header,
                                                           IReadOnlyCollection <PsnDataPacketChunk> dataPackets)
        {
            var dataTrackerChunks = dataPackets.SelectMany(p =>
                                                           ((PsnDataTrackerListChunk)p.SubChunks.Single(c => c.ChunkId == PsnDataPacketChunkId.PsnDataTrackerList))
                                                           .SubChunks)
                                    .ToList();

            if (dataTrackerChunks.Select(c => c.TrackerId).Distinct().Count() != dataTrackerChunks.Count)
            {
                InvalidPacketReceived?.Invoke(this,
                                              new InvalidPacketsReceivedEventArgs(dataPackets, false, "Duplicate tracker IDs in frame"));
                return;
            }

            foreach (var chunk in dataTrackerChunks)
            {
                if (!_trackers.TryGetValue(chunk.TrackerId, out var tracker))
                {
                    tracker = new PsnTracker(chunk.TrackerId);
                }

                Tuple <float, float, float> position       = null;
                Tuple <float, float, float> speed          = null;
                Tuple <float, float, float> orientation    = null;
                Tuple <float, float, float> acceleration   = null;
                Tuple <float, float, float> targetPosition = null;
                float?validity = null;

                foreach (var subchunk in chunk.SubChunks)
                {
                    switch (subchunk.ChunkId)
                    {
                    case PsnDataTrackerChunkId.PsnDataTrackerPos:
                        position = ((PsnDataTrackerPosChunk)subchunk).Vector;
                        break;

                    case PsnDataTrackerChunkId.PsnDataTrackerSpeed:
                        speed = ((PsnDataTrackerSpeedChunk)subchunk).Vector;
                        break;

                    case PsnDataTrackerChunkId.PsnDataTrackerOri:
                        orientation = ((PsnDataTrackerOriChunk)subchunk).Vector;
                        break;

                    case PsnDataTrackerChunkId.PsnDataTrackerStatus:
                        validity = ((PsnDataTrackerStatusChunk)subchunk).Validity;
                        break;

                    case PsnDataTrackerChunkId.PsnDataTrackerAccel:
                        acceleration = ((PsnDataTrackerAccelChunk)subchunk).Vector;
                        break;

                    case PsnDataTrackerChunkId.PsnDataTrackerTrgtPos:
                        targetPosition = ((PsnDataTrackerTrgtPosChunk)subchunk).Vector;
                        break;

                    default:
                        throw new ArgumentOutOfRangeException(nameof(subchunk.ChunkId));
                    }
                }

                tracker = PsnTracker.CloneInternal(tracker, dataTimeStamp: header.TimeStamp,
                                                   position: position, clearPosition: position == null,
                                                   speed: speed, clearSpeed: speed == null,
                                                   orientation: orientation, clearOrientation: orientation == null,
                                                   acceleration: acceleration, clearAcceleration: acceleration == null,
                                                   targetposition: targetPosition, clearTargetPosition: targetPosition == null,
                                                   validity: validity, clearValidity: validity == null);

                _trackers[chunk.TrackerId] = tracker;
            }

            TrackersUpdated?.Invoke(this, Trackers);
        }
Beispiel #2
0
        /// <summary>
        ///     Override to provide new behavior for receipt of a complete PosiStageNet info frame
        /// </summary>
        /// <param name="header"></param>
        /// <param name="systemName"></param>
        /// <param name="infoPackets"></param>
        protected virtual void OnCompleteInfoFrameReceived(PsnInfoHeaderChunk header, string systemName,
                                                           IReadOnlyCollection <PsnInfoPacketChunk> infoPackets)
        {
            var infoTrackerChunks = infoPackets.SelectMany(p =>
                                                           ((PsnInfoTrackerListChunk)p.SubChunks.Single(c => c.ChunkId == PsnInfoPacketChunkId.PsnInfoTrackerList))
                                                           .SubChunks)
                                    .ToList();

            if (infoTrackerChunks.Select(c => c.TrackerId).Distinct().Count() != infoTrackerChunks.Count)
            {
                InvalidPacketReceived?.Invoke(this,
                                              new InvalidPacketsReceivedEventArgs(infoPackets, false, "Duplicate tracker IDs in frame"));
                return;
            }

            if (RemoteSystemName != systemName)
            {
                RemoteSystemName = systemName;
                RemoteSystemNameUpdated?.Invoke(this, RemoteSystemName);
            }

            foreach (var chunk in infoTrackerChunks)
            {
                PsnInfoTrackerNameChunk trackerNameChunk = null;

                foreach (var subchunk in chunk.SubChunks)
                {
                    switch (subchunk.ChunkId)
                    {
                    case PsnInfoTrackerChunkId.PsnInfoTrackerName:

                        if (trackerNameChunk != null)
                        {
                            InvalidPacketReceived?.Invoke(this,
                                                          new InvalidPacketsReceivedEventArgs(infoPackets, !IsStrict,
                                                                                              $"Tracker ID {chunk.TrackerId} has multiple tracker name chunks"));

                            if (IsStrict)
                            {
                                return;
                            }
                        }

                        trackerNameChunk = (PsnInfoTrackerNameChunk)subchunk;

                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }

                if (trackerNameChunk == null)
                {
                    InvalidPacketReceived?.Invoke(this,
                                                  new InvalidPacketsReceivedEventArgs(infoPackets, !IsStrict,
                                                                                      $"Tracker ID {chunk.TrackerId} has no tracker name chunk"));

                    if (IsStrict)
                    {
                        return;
                    }

                    continue;
                }

                if (!_trackers.TryGetValue(chunk.TrackerId, out var tracker))
                {
                    tracker = new PsnTracker(chunk.TrackerId, trackerNameChunk.TrackerName, null, header.TimeStamp);
                    _trackers.TryAdd(chunk.TrackerId, tracker);
                }
                else
                {
                    tracker = tracker.SetTrackerName(trackerNameChunk.TrackerName);
                    tracker = tracker.SetInfoTimeStamp(header.TimeStamp);
                }

                _trackers[chunk.TrackerId] = tracker;
            }

            TrackersUpdated?.Invoke(this, Trackers);
        }