Beispiel #1
0
        /// <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());
            }
        }
Beispiel #2
0
        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;
        }
Beispiel #3
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;
        }
Beispiel #4
0
        private void DecodeHeader(RailBitBuffer buffer)
        {
            // Read: [LocalTick]
            this.senderTick = buffer.ReadTick();

            // Read: [AckTick]
            this.ackTick = buffer.ReadTick();

            // Read: [AckReliableEventId]
            this.ackEventId = buffer.ReadSequenceId();
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
 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;
 }
Beispiel #7
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;
        }
Beispiel #8
0
        /// <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);
                }
            }
        }
Beispiel #9
0
        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;
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
 public static SequenceId PeekSequenceId(this RailBitBuffer buffer)
 {
     return(SequenceId.Peek(buffer));
 }
Beispiel #12
0
 public static SequenceId ReadSequenceId(this RailBitBuffer buffer)
 {
     return(SequenceId.Read(buffer));
 }
Beispiel #13
0
 public static void WriteSequenceId(
     this RailBitBuffer buffer,
     SequenceId sequenceId)
 {
     sequenceId.Write(buffer);
 }
Beispiel #14
0
        public static bool operator <=(SequenceId a, SequenceId b)
        {
            int difference = SequenceId.GetDifference(a, b);

            return(difference <= 0);
        }
Beispiel #15
0
 public static SequenceId operator -(SequenceId a, int b)
 {
     RailDebug.Assert(a.IsValid);
     return(new SequenceId((uint)SequenceId.WrapValue((int)a.rawValue - b)));
 }