Ejemplo n.º 1
0
        void InternalUpdate()
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            for (int i = 0; i < m_ConnectionList.Length; ++i)
            {
                int conCount = m_EventQueue.GetCountForConnection(i);
                if (conCount != 0 && m_ConnectionList[i].State != NetworkConnection.State.Disconnected)
                {
                    UnityEngine.Debug.LogError("Resetting event queue with pending events (Count=" +
                                               conCount +
                                               ", ConnectionID=" + i + ") Listening: " + Listening);
                }
            }
#endif
            int free;
            while (m_PendingFree.TryDequeue(out free))
            {
                int ver = m_ConnectionList[free].Version + 1;
                if (ver == 0)
                {
                    ver = 1;
                }
                m_ConnectionList[free] = new Connection {
                    Id = free, Version = ver
                };
                m_FreeList.Enqueue(free);
            }

            m_EventQueue.Clear();
            m_DataStream.Clear();
            CheckTimeouts();
        }
Ejemplo n.º 2
0
            internal unsafe void ProcessPipelineSend <T>(T driver, int startStage, NetworkPipeline pipeline, NetworkConnection connection,
                                                         NativeSlice <byte> payloadBuffer, NativeList <UpdatePipeline> currentUpdates) where T : struct, INetworkPipelineSender
            {
                NetworkPipelineContext ctx = default(NetworkPipelineContext);

                ctx.timestamp = m_timestamp[0];
                var p            = m_Pipelines[pipeline.Id - 1];
                var connectionId = connection.m_NetworkId;

                var resumeQ      = new NativeList <int>(16, Allocator.Temp);
                int resumeQStart = 0;

                ctx.header = new DataStreamWriter(p.headerCapacity, Allocator.Temp);

                var inboundBuffer = default(InboundBufferVec);

                inboundBuffer.buffer1 = payloadBuffer;

                var prevHeader = new DataStreamWriter(p.headerCapacity, Allocator.Temp);

                while (true)
                {
                    int internalBufferOffset       = p.sendBufferOffset + sizePerConnection[SendSizeOffset] * connectionId;
                    int internalSharedBufferOffset = p.sharedBufferOffset + sizePerConnection[SharedSizeOffset] * connectionId;

                    bool needsUpdate = false;
                    // If this is not the first stage we need to fast forward the buffer offset to the correct place
                    if (startStage > 0)
                    {
                        for (int i = 0; i < startStage; ++i)
                        {
                            internalBufferOffset       += m_StageCollection.GetSendCapacity(m_StageList[p.FirstStageIndex + i]);
                            internalSharedBufferOffset += m_StageCollection.GetSharedStateCapacity(m_StageList[p.FirstStageIndex + i]);
                        }
                    }

                    for (int i = startStage; i < p.NumStages; ++i)
                    {
                        var prevInbound = inboundBuffer;
                        ProcessSendStage(i, internalBufferOffset, internalSharedBufferOffset, p, ref resumeQ, ref ctx, ref inboundBuffer, ref needsUpdate);
                        if (inboundBuffer.buffer1 == prevInbound.buffer1 &&
                            inboundBuffer.buffer2 == prevInbound.buffer2)
                        {
                            if (ctx.header.Length > 0)
                            {
                                if (prevHeader.Length > 0)
                                {
                                    ctx.header.WriteBytes(prevHeader.GetUnsafeReadOnlyPtr(), prevHeader.Length);
                                }
                                prevHeader.Clear();
                                var tempHeader = ctx.header;
                                ctx.header = prevHeader;
                                prevHeader = tempHeader;
                                if (inboundBuffer.buffer2.Length == 0)
                                {
                                    inboundBuffer.buffer2 = inboundBuffer.buffer1;
                                }
                                inboundBuffer.buffer1 = prevHeader.GetNativeSlice(0, prevHeader.Length);
                            }
                        }
                        else
                        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                            if (inboundBuffer.buffer2.Length > 0)
                            {
                                throw new InvalidOperationException("Pipeline send stages must return either the unmodified inbound buffers or a consolidated version with a single buffer");
                            }
#endif
                            // Prev header is now part of payload
                            prevHeader.Clear();
                            if (ctx.header.Length > 0)
                            {
                                var tempHeader = ctx.header;
                                ctx.header            = prevHeader;
                                prevHeader            = tempHeader;
                                inboundBuffer.buffer2 = inboundBuffer.buffer1;
                                inboundBuffer.buffer1 = prevHeader.GetNativeSlice(0, prevHeader.Length);
                            }
                        }
                        if (needsUpdate)
                        {
                            AddSendUpdate(connection, i, pipeline, currentUpdates);
                        }
                        if (inboundBuffer.buffer1.Length == 0)
                        {
                            break;
                        }

                        needsUpdate = false;

                        internalBufferOffset       += ctx.internalProcessBuffer.Length;
                        internalSharedBufferOffset += ctx.internalSharedProcessBuffer.Length;
                    }

                    if (inboundBuffer.buffer1.Length != 0)
                    {
                        var iov        = stackalloc network_iovec[4];
                        var pipelineId = pipeline.Id;
                        iov[0].buf = &pipelineId;
                        iov[0].len = 1;
                        iov[1].buf = ctx.header.GetUnsafePtr();
                        iov[1].len = ctx.header.Length;
                        iov[2].buf = inboundBuffer.buffer1.GetUnsafeReadOnlyPtr();
                        iov[2].len = inboundBuffer.buffer1.Length;
                        if (inboundBuffer.buffer2.Length > 0)
                        {
                            iov[3].buf = inboundBuffer.buffer2.GetUnsafeReadOnlyPtr();
                            iov[3].len = inboundBuffer.buffer2.Length;
                            // FIXME: handle send errors
                            driver.Send(connection, iov, 4);
                        }
                        else
                        {
                            driver.Send(connection, iov, 3);
                        }
                    }

                    if (resumeQStart >= resumeQ.Length)
                    {
                        break;
                    }

                    startStage = resumeQ[resumeQStart++];

                    prevHeader.Clear();
                    inboundBuffer = default(InboundBufferVec);
                }
            }