Beispiel #1
0
        /// <summary>
        /// Resume or play back a packet we had received earlier out of order. When an out of order packet is received
        /// it is stored since we need to first return the packet with the next sequence ID. When that packet finally
        /// arrives it is returned but a pipeline resume is requested since we already have the next packet stored
        /// and it can be processed immediately after.
        /// </summary>
        /// <param name="context">Pipeline context, we'll use both the shared reliability context and receive context.</param>
        /// <param name="startSequence">The first packet which we need to retrieve now, there could be more after that.</param>
        /// <param name="needsResume">Indicates if we need the pipeline to resume again.</param>
        /// <returns></returns>
        public static unsafe NativeSlice <byte> ResumeReceive(NetworkPipelineContext context, int startSequence, ref bool needsResume)
        {
            if (startSequence == NullEntry)
            {
                return(default(NativeSlice <byte>));
            }

            SharedContext *shared   = (SharedContext *)context.internalSharedProcessBuffer.GetUnsafePtr();
            Context *      reliable = (Context *)context.internalProcessBuffer.GetUnsafePtr();

            reliable->Resume = NullEntry;

            PacketInformation *info  = GetPacketInformation(context.internalProcessBuffer, startSequence);
            var latestReceivedPacket = shared->ReceivedPackets.Sequence;

            if (info->SequenceId == startSequence)
            {
                var offset = reliable->DataPtrOffset + ((startSequence % reliable->Capacity) * reliable->DataStride);
                NativeSlice <byte> slice = new NativeSlice <byte>(context.internalProcessBuffer, offset, info->Size);
                reliable->Delivered = startSequence;

                if ((ushort)(startSequence + 1) <= latestReceivedPacket)
                {
                    reliable->Resume = (ushort)(startSequence + 1);
                    needsResume      = true;
                }
                return(slice);
            }
            return(default(NativeSlice <byte>));
        }
Beispiel #2
0
        /// <summary>
        /// Write packet, packet header and tracking information to the given buffer space. This buffer
        /// should contain the reliability Context at the front, that contains the capacity of the buffer
        /// and pointer offsets needed to find the slots we can copy the packet to.
        /// </summary>
        /// <param name="self">Buffer space where we can store packets.</param>
        /// <param name="sequence">The sequence ID of the packet, this is used to find a slot inside the buffer.</param>
        /// <param name="header">The packet header which we'll store with the packet payload.</param>
        /// <param name="data">The packet data which we're storing.</param>
        /// <exception cref="OverflowException"></exception>
        public static unsafe void SetHeaderAndPacket(NativeSlice <byte> self, int sequence, PacketHeader header, InboundBufferVec data, long timestamp)
        {
            byte *   ptr       = (byte *)self.GetUnsafePtr();
            Context *ctx       = (Context *)ptr;
            int      totalSize = data.buffer1.Length + data.buffer2.Length;

            if (totalSize > ctx->DataStride)
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            { throw new OverflowException(); }
#else
            { return; }
#endif
            var index = sequence % ctx->Capacity;

            PacketInformation *info = GetPacketInformation(self, sequence);
            info->SequenceId = sequence;
            info->Size       = totalSize;
            info->SendTime   = timestamp;

            Packet *packet = GetPacket(self, sequence);
            packet->Header = header;
            var   offset  = (ctx->DataPtrOffset + (index * ctx->DataStride)) + UnsafeUtility.SizeOf <PacketHeader>();
            void *dataPtr = (ptr + offset);

            if (data.buffer1.Length > 0)
            {
                UnsafeUtility.MemCpy(dataPtr, data.buffer1.GetUnsafeReadOnlyPtr(), data.buffer1.Length);
            }
            if (data.buffer2.Length > 0)
            {
                UnsafeUtility.MemCpy(&dataPtr + data.buffer1.Length, data.buffer2.GetUnsafeReadOnlyPtr(), data.buffer2.Length);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Write packet, packet header and tracking information to the given buffer space. This buffer
        /// should contain the reliability Context at the front, that contains the capacity of the buffer
        /// and pointer offsets needed to find the slots we can copy the packet to.
        /// </summary>
        /// <param name="self">Buffer space where we can store packets.</param>
        /// <param name="sequence">The sequence ID of the packet, this is used to find a slot inside the buffer.</param>
        /// <param name="header">The packet header which we'll store with the packet payload.</param>
        /// <param name="data">The packet data which we're storing.</param>
        /// <exception cref="OverflowException"></exception>
        public static unsafe void SetHeaderAndPacket(byte *self, int sequence, PacketHeader header, InboundSendBuffer data, long timestamp)
        {
            Context *ctx       = (Context *)self;
            int      totalSize = data.bufferLength + data.headerPadding;

            if (totalSize + UnsafeUtility.SizeOf <PacketHeader>() > ctx->DataStride)
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            { throw new OverflowException(); }
#else
            { return; }
#endif
            var index = sequence % ctx->Capacity;

            PacketInformation *info = GetPacketInformation(self, sequence);
            info->SequenceId    = sequence;
            info->Size          = (ushort)totalSize;
            info->HeaderPadding = (ushort)data.headerPadding;
            info->SendTime      = timestamp;

            Packet *packet = GetPacket(self, sequence);
            packet->Header = header;
            var   offset  = (ctx->DataPtrOffset + (index * ctx->DataStride)) + UnsafeUtility.SizeOf <PacketHeader>();
            void *dataPtr = (self + offset);

            if (data.bufferLength > 0)
            {
                UnsafeUtility.MemCpy((byte *)dataPtr + data.headerPadding, data.buffer, data.bufferLength);
            }
        }
Beispiel #4
0
        public static unsafe void SetPacket(NativeSlice <byte> self, int sequence, void *data, int length)
        {
            byte *   ptr = (byte *)self.GetUnsafePtr();
            Context *ctx = (Context *)ptr;

            if (length > ctx->DataStride)
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            { throw new OverflowException(); }
#else
            { return; }
#endif

            var index = sequence % ctx->Capacity;

            PacketInformation *info = GetPacketInformation(self, sequence);
            info->SequenceId = sequence;
            info->Size       = length;
            info->SendTime   = -1;        // Not used for packets queued for resume receive

            var   offset  = ctx->DataPtrOffset + (index * ctx->DataStride);
            void *dataPtr = (ptr + offset);

            UnsafeUtility.MemCpy(dataPtr, data, length);
        }