Beispiel #1
0
        protected void PumpSendQueue()
        {
            lock (queueLock)
            {
                while (!sendQueue.IsEmpty)
                {
                    QueueEntry entry = sendQueue.Front();

                    if (sendLatency > 0)
                    {
                        // Should really come up with a gaussian distribution based on the configured
                        // value, but this will do for now.
                        int jitter = (sendLatency * 2 / 3) + ((random.Next() % sendLatency) / 3);
                        if (Utility.GetCurrentTime() < sendQueue.Front().queueTime + jitter)
                        {
                            break;
                        }
                    }

                    if (oopPercent > 0 && ooPacket.message != null && random.Next() % 100 < oopPercent)
                    {
                        uint delay = (uint)(random.Next() % (sendLatency * 10 + 1000));
                        Log($"creating rogue oop (seq: {entry.message.SequenceNumber}  delay: {delay})");
                        ooPacket.queueTime   = Utility.GetCurrentTime() + delay;
                        ooPacket.message     = entry.message;
                        ooPacket.destAddress = entry.destAddress;
                    }
                    else
                    {
                        var byteMsg = Utility.GetByteArray(entry.message);
                        udpClient.SendTo(byteMsg, udpEndpoint);

                        entry.message = null;
                    }

                    sendQueue.Pop();
                }
            }

            if (ooPacket.message != null && ooPacket.queueTime < Utility.GetCurrentTime())
            {
                Log("sending rogue oop!");
                var ooMsg = Utility.GetByteArray(ooPacket.message);
                udpClient.SendTo(ooMsg, udpEndpoint);

                ooPacket.message = null;
            }
        }
Beispiel #2
0
        public override GGPOErrorCode AdvanceFrame()
        {
            sync.IncrementFrame();
            currentInput.Erase();

            Log($"End of frame({sync.FrameCount})...");

            if (isRollingBack)
            {
                return(GGPOErrorCode.OK);
            }

            int frame = sync.FrameCount;
            // Hold onto the current frame in our queue of saved states.  We'll need
            // the checksum later to verify that our replay of the same frame got the
            // same results.
            var info = new SavedInfo
            {
                frame    = frame,
                input    = lastInput,
                buffer   = sync.GetLastSavedFrame().buffer,
                checksum = sync.GetLastSavedFrame().checksum,
            };

            savedFrames.Push(info);

            if (frame - lastVerified == checkDistance)
            {
                // We've gone far enough ahead and should now start replaying frames.
                // Load the last verified frame and set the rollback flag to true.
                sync.LoadFrame(lastVerified);

                isRollingBack = true;
                while (!savedFrames.IsEmpty)
                {
                    callbacks.AdvanceFrame();

                    // Verify that the checksumn of this frame is the same as the one in our
                    // list.
                    info = savedFrames.Front();
                    savedFrames.Pop();

                    if (info.frame != sync.FrameCount)
                    {
                        RaiseSyncError($"Frame number {info.frame} does not match saved frame number {frame}");
                    }
                    int checksum = sync.GetLastSavedFrame().checksum;
                    if (info.checksum != checksum)
                    {
                        LogSaveStates(info);
                        RaiseSyncError($"Checksum for frame {frame} does not match saved ({checksum} != {info.checksum})");
                    }
                    Log($"Checksum {checksum:D8} for frame {info.frame} matches.");
                }
                lastVerified  = frame;
                isRollingBack = false;
            }

            return(GGPOErrorCode.OK);
        }
Beispiel #3
0
 private void Undo()
 {
     if (!undolog.IsEmpty)
     {
         textBox.Text = undolog.Pop();
     }
 }
Beispiel #4
0
        public bool GetEvent(out UdpProtocolEvent evt)
        {
            if (eventQueue.IsEmpty)
            {
                evt = null;
                return(false);
            }

            evt = eventQueue.Front();
            eventQueue.Pop();
            return(true);
        }
        public void UnderflowTest()
        {
            var buffer = new RingBuffer <int>(1);
            var failed = false;

            try {
                buffer.Pop();
            }
            catch (Exception e) {
                failed = true;
            }

            Assert.IsTrue(failed, "Expected buffer to underflow, but no exception was thrown");
        }
Beispiel #6
0
            public void PushSample(float sample)
            {
                sample = Math.Abs(sample);

                while (indices.Count > 0 && GetSample(indices.Head) <= sample)
                {
                    indices.Pop();
                }
                while (indices.Count > 0 && indices.Tail <= sampleCount - windowSize)
                {
                    indices.PopBack();
                }
                indices.Push(sampleCount++);
                buffer.Push(sample);
            }
Beispiel #7
0
 public T Remove()
 {
     return(_buffer.Pop());
 }
        public void NormalFencePerfTest()
        {
            long numberOfItems = 10000000;

            ManualResetEvent evt = new ManualResetEvent(false);

            RingBuffer<long> buffer = new RingBuffer<long>(1000);

            Thread producer = new Thread(() =>
            {
                evt.WaitOne();

                long count = 0;

                while (count < numberOfItems)
                {
                    bool wasPushed = buffer.Push(1);

                    if (wasPushed)
                    {
                        count++;
                    }
                }
            });

            Thread consumer = new Thread(() =>
            {
                evt.WaitOne();

                long count = 0;

                while (count < numberOfItems)
                {
                    long popped = 0;
                    bool wasPopped = buffer.Pop(ref popped);

                    if (wasPopped)
                    {
                        count += popped;
                    }
                }

            });

            producer.Start();
            consumer.Start();

            Thread.Sleep(1000);

            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            evt.Set();

            producer.Join();
            consumer.Join();

            stopwatch.Stop();

            Console.WriteLine(string.Format("Total time taken: {0}ms", stopwatch.ElapsedMilliseconds));
        }
        public void NormalFencePerfTest()
        {
            long numberOfItems = 10000000;

            ManualResetEvent evt = new ManualResetEvent(false);

            RingBuffer <long> buffer = new RingBuffer <long>(1000);

            Thread producer = new Thread(() =>
            {
                evt.WaitOne();

                long count = 0;

                while (count < numberOfItems)
                {
                    bool wasPushed = buffer.Push(1);

                    if (wasPushed)
                    {
                        count++;
                    }
                }
            });

            Thread consumer = new Thread(() =>
            {
                evt.WaitOne();

                long count = 0;

                while (count < numberOfItems)
                {
                    long popped    = 0;
                    bool wasPopped = buffer.Pop(ref popped);

                    if (wasPopped)
                    {
                        count += popped;
                    }
                }
            });

            producer.Start();
            consumer.Start();

            Thread.Sleep(1000);

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            evt.Set();

            producer.Join();
            consumer.Join();

            stopwatch.Stop();

            Console.WriteLine(string.Format("Total time taken: {0}ms", stopwatch.ElapsedMilliseconds));
        }
Beispiel #10
0
        protected bool OnInput(NetworkMessage msg)
        {
            var inputMsg = msg as InputMessage;

            Log($"[OnInput] Processing sequence {msg.SequenceNumber}");

            // If a disconnect is requested, go ahead and disconnect now.
            bool disconnectRequested = inputMsg.DisconnectRequested;

            if (disconnectRequested)
            {
                if (currentState != State.Disconnected && !disconnectEventSent)
                {
                    Log("Disconnecting endpoint on remote request.");
                    QueueEvent(new UdpProtocolEvent(UdpProtocolEvent.Type.Disconnected));
                    disconnectEventSent = true;
                }
            }
            else
            {
                // Update the peer connection status if this peer is still considered to be part
                // of the network.
                NetworkConnectStatus[] remoteStatus = inputMsg.PeerConnectStatus;
                for (int i = 0; i < peerConnectStatus.Length; i++)
                {
                    if (remoteStatus[i] != null && peerConnectStatus[i] != null)
                    {
                        Debug.Assert(remoteStatus[i].LastFrame >= peerConnectStatus[i].LastFrame);
                        peerConnectStatus[i].Disconnected = peerConnectStatus[i].Disconnected || remoteStatus[i].Disconnected;
                        peerConnectStatus[i].LastFrame    = Math.Max(peerConnectStatus[i].LastFrame, remoteStatus[i].LastFrame);
                    }
                }
            }

            // Decompress the input.
            int lastReceivedFrameNumber = lastReceivedInput.frame;

            if (inputMsg.NumBits > 0)
            {
                int  offset       = 0;
                uint currentFrame = inputMsg.StartFrame;

                lastReceivedInput.size = inputMsg.InputSize;
                if (lastReceivedInput.frame < 0)
                {
                    lastReceivedInput.frame = (int)(inputMsg.StartFrame - 1);
                }

                while (offset < inputMsg.NumBits)
                {
                    // Keep walking through the frames (parsing bits) until we reach
                    // the inputs for the frame right after the one we're on.
                    Debug.Assert(currentFrame <= lastReceivedInput.frame + 1,
                                 $"currentFrame is {currentFrame} and lastRecievedInput.frame is {lastReceivedInput.frame} from sequence {inputMsg.SequenceNumber}");
                    bool useInputs = currentFrame == (lastReceivedInput.frame + 1);

                    while (Bitvector.ReadBit(inputMsg.Bits, ref offset) > 0)
                    {
                        bool on     = Bitvector.ReadBit(inputMsg.Bits, ref offset) > 0;
                        int  button = Bitvector.ReadNibblet(inputMsg.Bits, ref offset);

                        if (useInputs)
                        {
                            if (on)
                            {
                                lastReceivedInput.Set(button);
                            }
                            else
                            {
                                lastReceivedInput.Clear(button);
                            }
                        }
                    }
                    Debug.Assert(offset <= inputMsg.NumBits);

                    // Now if we want to use these inputs, go ahead and send them to
                    // the emulator.
                    if (useInputs)
                    {
                        // Move forward 1 frame in the stream.
                        Debug.Assert(currentFrame == lastReceivedInput.frame + 1,
                                     $"currentFrame is {currentFrame} and lastRecievedInput.frame is {lastReceivedInput.frame} from sequence {inputMsg.SequenceNumber}");
                        lastReceivedInput.frame = (int)currentFrame;

                        // Send the event to the emulator
                        var evt = new InputEvent
                        {
                            Input = lastReceivedInput,
                        };

                        runningState.lastInputPacketReceiveTime = Utility.GetCurrentTime();
                        Log($"Sending frame {lastReceivedInput.frame} to emu queue {queue} ({lastReceivedInput.ToString()}).");
                        QueueEvent(evt);
                    }
                    else
                    {
                        Log($"Skipping past frame:({currentFrame}) current is {lastReceivedInput.frame}.");
                    }

                    // Move forward 1 frame in the input stream.
                    currentFrame++;
                }
            }

            Debug.Assert(lastReceivedInput.frame >= lastReceivedFrameNumber);

            // Get rid of our buffered input
            while (!pendingOutput.IsEmpty && pendingOutput.Front().frame < inputMsg.AckFrame)
            {
                Log($"Throwing away pending output frame {pendingOutput.Front().frame}");
                lastAckedInput = pendingOutput.Front();
                pendingOutput.Pop();
            }

            Log($"[OnInput] Completed sequence {msg.SequenceNumber}");
            return(true);
        }