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>)); } }
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); } }
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>); } }