public unsafe bool GetDelayedPacket(ref NetworkPipelineContext ctx, ref NativeSlice<byte> delayedPacket, ref bool needsResume, ref bool needsUpdate, long currentTimestamp) { needsUpdate = needsResume = false; var dataSize = UnsafeUtility.SizeOf<DelayedPacket>(); byte* processBufferPtr = (byte*) ctx.internalProcessBuffer.GetUnsafePtr(); var simCtx = (Context*) ctx.internalSharedProcessBuffer.GetUnsafePtr(); int oldestPacketIndex = -1; long oldestTime = long.MaxValue; int readyPackets = 0; int packetsInQueue = 0; for (int i = 0; i < m_PacketCount; i++) { DelayedPacket* packet = (DelayedPacket*) (processBufferPtr + dataSize * i); if ((int) packet->delayUntil == 0) continue; packetsInQueue++; if (packet->delayUntil > currentTimestamp) continue; readyPackets++; if (oldestTime <= packet->delayUntil) continue; oldestPacketIndex = i; oldestTime = packet->delayUntil; } simCtx->ReadyPackets = readyPackets; simCtx->WaitingPackets = packetsInQueue; simCtx->NextPacketTime = oldestTime; simCtx->StatsTime = currentTimestamp; // If more than one item has expired timer we need to resume this pipeline stage if (readyPackets > 1) { needsUpdate = false; needsResume = true; } // If more than one item is present (but doesn't have expired timer) we need to re-run the pipeline // in a later update call else if (packetsInQueue > 0) { needsUpdate = true; needsResume = false; } if (oldestPacketIndex >= 0) { DelayedPacket* packet = (DelayedPacket*) (processBufferPtr + dataSize * oldestPacketIndex); packet->delayUntil = 0; delayedPacket = new NativeSlice<byte>(ctx.internalProcessBuffer, packet->processBufferOffset, packet->packetSize); return true; } return false; }
public unsafe bool GetEmptyDataSlot(byte* processBufferPtr, ref int packetPayloadOffset, ref int packetDataOffset) { var dataSize = UnsafeUtility.SizeOf<DelayedPacket>(); var packetPayloadStartOffset = m_PacketCount * dataSize; bool foundSlot = false; for (int i = 0; i < m_PacketCount; i++) { packetDataOffset = dataSize * i; DelayedPacket* packetData = (DelayedPacket*) (processBufferPtr + packetDataOffset); // Check if this slot is empty if (packetData->delayUntil == 0) { foundSlot = true; packetPayloadOffset = packetPayloadStartOffset + m_MaxPacketSize * i; break; } } return foundSlot; }
public unsafe bool GetDelayedPacket(ref NetworkPipelineContext ctx, ref InboundSendBuffer delayedPacket, ref NetworkPipelineStage.Requests requests, long currentTimestamp) { requests = NetworkPipelineStage.Requests.None; var dataSize = UnsafeUtility.SizeOf <DelayedPacket>(); byte *processBufferPtr = (byte *)ctx.internalProcessBuffer; var simCtx = (Context *)ctx.internalSharedProcessBuffer; int oldestPacketIndex = -1; long oldestTime = long.MaxValue; int readyPackets = 0; int packetsInQueue = 0; for (int i = 0; i < m_PacketCount; i++) { DelayedPacket *packet = (DelayedPacket *)(processBufferPtr + dataSize * i); if ((int)packet->delayUntil == 0) { continue; } packetsInQueue++; if (packet->delayUntil > currentTimestamp) { continue; } readyPackets++; if (oldestTime <= packet->delayUntil) { continue; } oldestPacketIndex = i; oldestTime = packet->delayUntil; } simCtx->ReadyPackets = readyPackets; simCtx->WaitingPackets = packetsInQueue; simCtx->NextPacketTime = oldestTime; simCtx->StatsTime = currentTimestamp; // If more than one item has expired timer we need to resume this pipeline stage if (readyPackets > 1) { requests |= NetworkPipelineStage.Requests.Resume; } // If more than one item is present (but doesn't have expired timer) we need to re-run the pipeline // in a later update call else if (packetsInQueue > 0) { requests |= NetworkPipelineStage.Requests.Update; } if (oldestPacketIndex >= 0) { DelayedPacket *packet = (DelayedPacket *)(processBufferPtr + dataSize * oldestPacketIndex); packet->delayUntil = 0; delayedPacket.bufferWithHeaders = ctx.internalProcessBuffer + packet->processBufferOffset; delayedPacket.bufferWithHeadersLength = packet->packetSize; delayedPacket.headerPadding = packet->packetHeaderPadding; delayedPacket.SetBufferFrombufferWithHeaders(); return(true); } return(false); }