Example #1
0
        public void UpdateReceive <T>(T driver, out int updateCount) where T : struct, INetworkPipelineReceiver
        {
            updateCount = m_ReceiveStageNeedsUpdate.Length;
            NativeArray <UpdatePipeline> receiveUpdates = new NativeArray <UpdatePipeline>(updateCount, Allocator.Temp);

            // Move current update requests to a new queue
            for (int i = 0; i < updateCount; ++i)
            {
                receiveUpdates[i] = m_ReceiveStageNeedsUpdate[i];
            }
            m_ReceiveStageNeedsUpdate.Clear();

            // Process all current requested updates, new update requests will (possibly) be generated from the pipeline stages
            for (int i = 0; i < receiveUpdates.Length; ++i)
            {
                UpdatePipeline updateItem = receiveUpdates[i];
                ProcessReceiveStagesFrom(driver, updateItem.stage, updateItem.pipeline, updateItem.connection, default(NativeSlice <byte>));
            }
        }
Example #2
0
        private static void AddSendUpdate(NetworkConnection connection, int stageId, NetworkPipeline pipelineId, NativeList <UpdatePipeline> currentUpdates)
        {
            var newUpdate = new UpdatePipeline
            {
                connection = connection, stage = stageId, pipeline = pipelineId
            };
            bool uniqueItem = true;

            for (int j = 0; j < currentUpdates.Length; ++j)
            {
                if (currentUpdates[j].stage == newUpdate.stage &&
                    currentUpdates[j].pipeline.Id == newUpdate.pipeline.Id &&
                    currentUpdates[j].connection == newUpdate.connection)
                {
                    uniqueItem = false;
                }
            }
            if (uniqueItem)
            {
                currentUpdates.Add(newUpdate);
            }
        }
Example #3
0
        private void ProcessReceiveStagesFrom <T>(T driver, int startStage, NetworkPipeline pipeline, NetworkConnection connection, NativeSlice <byte> buffer) where T : struct, INetworkPipelineReceiver
        {
            var p            = m_Pipelines[pipeline.Id - 1];
            var connectionId = connection.m_NetworkId;
            var resumeQ      = new NativeList <int>(16, Allocator.Temp);
            int resumeQStart = 0;

            NetworkPipelineContext ctx = default(NetworkPipelineContext);

            ctx.timestamp = Timestamp;
            var inboundBuffer = new NativeSlice <byte>(buffer, 0, buffer.Length);

            ctx.header = default(DataStreamWriter);
            NativeList <UpdatePipeline> sendUpdates = new NativeList <UpdatePipeline>(128, Allocator.Temp);

            while (true)
            {
                bool needsUpdate                = false;
                bool needsSendUpdate            = false;
                int  internalBufferOffset       = p.receiveBufferOffset + sizePerConnection[RecveiveSizeOffset] * connectionId;
                int  internalSharedBufferOffset = p.sharedBufferOffset + sizePerConnection[SharedSizeOffset] * connectionId;

                // Adjust offset accounting for stages in front of the starting stage, since we're parsing the stages in reverse order
                for (int st = 0; st < startStage; ++st)
                {
                    internalBufferOffset       += m_StageCollection.GetReceiveCapacity(m_StageList[p.FirstStageIndex + st]);
                    internalSharedBufferOffset += m_StageCollection.GetSharedStateCapacity(m_StageList[p.FirstStageIndex + st]);
                }

                for (int i = startStage; i >= 0; --i)
                {
                    ProcessReceiveStage(i, pipeline, internalBufferOffset, internalSharedBufferOffset, ref ctx, ref inboundBuffer, ref resumeQ, ref needsUpdate, ref needsSendUpdate);
                    if (needsUpdate)
                    {
                        var newUpdate = new UpdatePipeline
                        {
                            connection = connection, stage = i, pipeline = pipeline
                        };
                        bool uniqueItem = true;
                        for (int j = 0; j < m_ReceiveStageNeedsUpdate.Length; ++j)
                        {
                            if (m_ReceiveStageNeedsUpdate[j].stage == newUpdate.stage &&
                                m_ReceiveStageNeedsUpdate[j].pipeline.Id == newUpdate.pipeline.Id &&
                                m_ReceiveStageNeedsUpdate[j].connection == newUpdate.connection)
                            {
                                uniqueItem = false;
                            }
                        }
                        if (uniqueItem)
                        {
                            m_ReceiveStageNeedsUpdate.Add(newUpdate);
                        }
                    }

                    if (needsSendUpdate)
                    {
                        AddSendUpdate(connection, i, pipeline, m_SendStageNeedsUpdate);
                    }

                    if (inboundBuffer.Length == 0)
                    {
                        break;
                    }

                    // Offset needs to be adjusted for the next pipeline (the one in front of this one)
                    if (i > 0)
                    {
                        internalBufferOffset -=
                            m_StageCollection.GetReceiveCapacity(m_StageList[p.FirstStageIndex + i - 1]);
                        internalSharedBufferOffset -=
                            m_StageCollection.GetSharedStateCapacity(m_StageList[p.FirstStageIndex + i - 1]);
                    }

                    needsUpdate = false;
                }

                if (inboundBuffer.Length != 0)
                {
                    driver.PushDataEvent(connection, inboundBuffer);
                }

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

                startStage    = resumeQ[resumeQStart++];
                inboundBuffer = default(NativeSlice <byte>);
            }
        }