/// <summary> /// Removes any acked or expired outgoing events. /// </summary> private void CleanOutgoingEvents( SequenceId ackedEventId) { if (ackedEventId.IsValid == false) { return; } while (this.outgoingEvents.Count > 0) { RailEvent top = this.outgoingEvents.Peek(); // Stop if we hit an un-acked reliable event if (top.IsReliable) { if (top.EventId > ackedEventId) { break; } } // Stop if we hit an unreliable event with remaining attempts else { if (top.Attempts > 0) { break; } } RailPool.Free(this.outgoingEvents.Dequeue()); } }
public RailPacket() { this.senderTick = Tick.INVALID; this.ackTick = Tick.INVALID; this.ackEventId = SequenceId.INVALID; this.pendingEvents = new List <RailEvent>(); this.events = new List <RailEvent>(); this.eventsWritten = 0; }
internal virtual void Reset() { this.senderTick = Tick.INVALID; this.ackTick = Tick.INVALID; this.ackEventId = SequenceId.INVALID; this.pendingEvents.Clear(); this.events.Clear(); this.eventsWritten = 0; }
private void DecodeHeader(RailBitBuffer buffer) { // Read: [LocalTick] this.senderTick = buffer.ReadTick(); // Read: [AckTick] this.ackTick = buffer.ReadTick(); // Read: [AckReliableEventId] this.ackEventId = buffer.ReadSequenceId(); }
private static int GetDifference(SequenceId a, SequenceId b) { RailDebug.Assert(a.IsValid); RailDebug.Assert(b.IsValid); int difference = (int)((a.rawValue << SequenceId.BIT_SHIFT) - (b.rawValue << SequenceId.BIT_SHIFT)); return(difference); }
internal void Initialize( Tick senderTick, Tick ackTick, SequenceId ackEventId, IEnumerable <RailEvent> events) { this.senderTick = senderTick; this.ackTick = ackTick; this.ackEventId = ackEventId; this.pendingEvents.AddRange(events); this.eventsWritten = 0; }
/// <summary> /// Queues an event to send directly to this peer. /// </summary> public void QueueEvent(RailEvent evnt, int attempts) { // TODO: Event scoping // All global events are sent reliably RailEvent clone = evnt.Clone(); clone.EventId = this.lastQueuedEventId; clone.Attempts = attempts; this.outgoingEvents.Enqueue(clone); this.lastQueuedEventId = this.lastQueuedEventId.Next; }
/// <summary> /// Selects outgoing events to send. /// </summary> private IEnumerable <RailEvent> FilterOutgoingEvents() { // The receiving client can only store SequenceWindow.HISTORY_LENGTH // events in its received buffer, and will skip any events older than // its latest received minus that history length, including reliable // events. In order to make sure we don't force the client to skip a // reliable event, we will throttle the outgoing events if we've been // sending them too fast. For example, if we have a reliable event // with ID 3 pending, the highest ID we can send would be ID 67. If we // send an event with ID 68, then the client may ignore ID 3 when it // comes in for being too old, even though it's reliable. // // In practice this shouldn't be a problem unless we're sending way // more events than is reasonable(/possible) in a single packet, or // something is wrong with reliable event acking. SequenceId firstReliable = SequenceId.INVALID; foreach (RailEvent evnt in this.outgoingEvents) { if (evnt.IsReliable) { if (firstReliable.IsValid == false) { firstReliable = evnt.EventId; } RailDebug.Assert(firstReliable <= evnt.EventId); } if (firstReliable.IsValid) { if (SequenceWindow.AreInRange(firstReliable, evnt.EventId) == false) { string current = "Throttling events due to unacked reliable\n"; foreach (RailEvent evnt2 in this.outgoingEvents) { current += evnt2.EventId + " "; } RailDebug.LogWarning(current); break; } } if (evnt.CanSend) { yield return(evnt); } } }
protected RailPeer( IRailNetPeer netPeer, RailInterpreter interpreter, RailPacket reusableIncoming, RailPacket reusableOutgoing) { this.netPeer = netPeer; this.interpreter = interpreter; this.controlledEntities = new HashSet <RailEntity>(); this.remoteClock = new RailClock(); this.outgoingEvents = new Queue <RailEvent>(); this.reusableIncoming = reusableIncoming; this.reusableOutgoing = reusableOutgoing; this.lastQueuedEventId = SequenceId.START.Next; this.processedEventHistory = new SequenceWindow(SequenceId.START); this.netPeer.PayloadReceived += this.OnPayloadReceived; }
public static int operator -(SequenceId a, SequenceId b) { int difference = SequenceId.GetDifference(a, b) >> SequenceId.BIT_SHIFT; // We need to skip 0 since it's not a valid number if (a.rawValue < b.rawValue) { if (difference > 0) { difference--; } } else { if (difference < 0) { difference++; } } return(difference); }
public static SequenceId PeekSequenceId(this RailBitBuffer buffer) { return(SequenceId.Peek(buffer)); }
public static SequenceId ReadSequenceId(this RailBitBuffer buffer) { return(SequenceId.Read(buffer)); }
public static void WriteSequenceId( this RailBitBuffer buffer, SequenceId sequenceId) { sequenceId.Write(buffer); }
public static bool operator <=(SequenceId a, SequenceId b) { int difference = SequenceId.GetDifference(a, b); return(difference <= 0); }
public static SequenceId operator -(SequenceId a, int b) { RailDebug.Assert(a.IsValid); return(new SequenceId((uint)SequenceId.WrapValue((int)a.rawValue - b))); }