// batch as many messages as possible into writer // returns true if any batch was made. public bool MakeNextBatch(NetworkWriter writer, double timeStamp) { // if we have no messages then there's nothing to do if (messages.Count == 0) { return(false); } // make sure the writer is fresh to avoid uncertain situations if (writer.Position != 0) { throw new ArgumentException($"MakeNextBatch needs a fresh writer!"); } // write timestamp first // -> double precision for accuracy over long periods of time writer.WriteDouble(timeStamp); // do start no matter what do { // add next message no matter what. even if > threshold. // (we do allow > threshold sized messages as single batch) NetworkWriterPooled message = messages.Dequeue(); ArraySegment <byte> segment = message.ToArraySegment(); writer.WriteBytes(segment.Array, segment.Offset, segment.Count); // return the writer to pool NetworkWriterPool.Return(message); } // keep going as long as we have more messages, // AND the next one would fit into threshold. while (messages.Count > 0 && writer.Position + messages.Peek().Position <= threshold); // we had messages, so a batch was made return(true); }
// get next message, unpacked from batch (if any) // timestamp is the REMOTE time when the batch was created remotely. public bool GetNextMessage(out NetworkReader message, out double remoteTimeStamp) { // getting messages would be easy via // <<size, message, size, message, ...>> // but to save A LOT of bandwidth, we use // <<message, message, ...> // in other words, we don't know where the current message ends // // BUT: it doesn't matter! // -> we simply return the reader // * if we have one yet // * and if there's more to read // -> the caller can then read one message from it // -> when the end is reached, we retire the batch! // // for example: // while (GetNextMessage(out message)) // ProcessMessage(message); // message = null; // do nothing if we don't have any batches. // otherwise the below queue.Dequeue() would throw an // InvalidOperationException if operating on empty queue. if (batches.Count == 0) { remoteTimeStamp = 0; return(false); } // was our reader pointed to anything yet? if (reader.Length == 0) { remoteTimeStamp = 0; return(false); } // no more data to read? if (reader.Remaining == 0) { // retire the batch NetworkWriterPooled writer = batches.Dequeue(); NetworkWriterPool.Return(writer); // do we have another batch? if (batches.Count > 0) { // point reader to the next batch. // we'll return the reader below. NetworkWriterPooled next = batches.Peek(); StartReadingBatch(next); } // otherwise there's nothing more to read else { remoteTimeStamp = 0; return(false); } } // use the current batch's remote timestamp // AFTER potentially moving to the next batch ABOVE! remoteTimeStamp = readerRemoteTimeStamp; // if we got here, then we have more data to read. message = reader; return(true); }
public static void Return(NetworkWriterPooled writer) { Pool.Return(writer); }
public static void Recycle(NetworkWriterPooled writer) => Return(writer);