private void RunLoop() { /* Some platforms (i.e. Emscripten) don't support * indefinite while loops, so instead we have to * surrender control to the platform's main loop. * -caleb */ if (FNAPlatform.NeedsPlatformMainLoop()) { /* This breaks control flow and jumps * directly into the platform main loop. * Nothing below this call will be executed. */ FNAPlatform.RunPlatformMainLoop(this); } while (RunApplication) { FNAPlatform.PollEvents( this, ref currentAdapter, textInputControlDown, textInputControlRepeat, ref textInputSuppress ); Tick(); } OnExiting(this, EventArgs.Empty); }
public void RunOneFrame() { if (!hasInitialized) { DoInitialize(); gameTimer = Stopwatch.StartNew(); hasInitialized = true; } FNAPlatform.PollEvents( this, ref currentAdapter, textInputControlDown, textInputControlRepeat, ref textInputSuppress ); Tick(); }
public void Tick() { /* NOTE: This code is very sensitive and can break very badly, * even with what looks like a safe change. Be sure to test * any change fully in both the fixed and variable timestep * modes across multiple devices and platforms. */ AdvanceElapsedTime(); if (IsFixedTimeStep) { /* If we are in fixed timestep, we want to wait until the next frame, * but we don't want to oversleep. Requesting repeated 1ms sleeps and * seeing how long we actually slept for lets us estimate the worst case * sleep precision so we don't oversleep the next frame. */ while (accumulatedElapsedTime + worstCaseSleepPrecision < TargetElapsedTime) { System.Threading.Thread.Sleep(1); TimeSpan timeAdvancedSinceSleeping = AdvanceElapsedTime(); UpdateEstimatedSleepPrecision(timeAdvancedSinceSleeping); } /* Now that we have slept into the sleep precision threshold, we need to wait * for just a little bit longer until the target elapsed time has been reached. * SpinWait(1) works by pausing the thread for very short intervals, so it is * an efficient and time-accurate way to wait out the rest of the time. */ while (accumulatedElapsedTime < TargetElapsedTime) { System.Threading.Thread.SpinWait(1); AdvanceElapsedTime(); } } // Now that we are going to perform an update, let's poll events. FNAPlatform.PollEvents( this, ref currentAdapter, textInputControlDown, textInputControlRepeat, ref textInputSuppress ); // Do not allow any update to take longer than our maximum. if (accumulatedElapsedTime > MaxElapsedTime) { accumulatedElapsedTime = MaxElapsedTime; } if (IsFixedTimeStep) { gameTime.ElapsedGameTime = TargetElapsedTime; int stepCount = 0; // Perform as many full fixed length time steps as we can. while (accumulatedElapsedTime >= TargetElapsedTime) { gameTime.TotalGameTime += TargetElapsedTime; accumulatedElapsedTime -= TargetElapsedTime; stepCount += 1; AssertNotDisposed(); Update(gameTime); } // Every update after the first accumulates lag updateFrameLag += Math.Max(0, stepCount - 1); /* If we think we are running slowly, wait * until the lag clears before resetting it */ if (gameTime.IsRunningSlowly) { if (updateFrameLag == 0) { gameTime.IsRunningSlowly = false; } } else if (updateFrameLag >= 5) { /* If we lag more than 5 frames, * start thinking we are running slowly. */ gameTime.IsRunningSlowly = true; } /* Every time we just do one update and one draw, * then we are not running slowly, so decrease the lag. */ if (stepCount == 1 && updateFrameLag > 0) { updateFrameLag -= 1; } /* Draw needs to know the total elapsed time * that occured for the fixed length updates. */ gameTime.ElapsedGameTime = TimeSpan.FromTicks(TargetElapsedTime.Ticks * stepCount); } else { // Perform a single variable length update. if (forceElapsedTimeToZero) { /* When ResetElapsedTime is called, * Elapsed is forced to zero and * Total is ignored entirely. * -flibit */ gameTime.ElapsedGameTime = TimeSpan.Zero; forceElapsedTimeToZero = false; } else { gameTime.ElapsedGameTime = accumulatedElapsedTime; gameTime.TotalGameTime += gameTime.ElapsedGameTime; } accumulatedElapsedTime = TimeSpan.Zero; AssertNotDisposed(); Update(gameTime); } // Draw unless the update suppressed it. if (suppressDraw) { suppressDraw = false; } else { /* Draw/EndDraw should not be called if BeginDraw returns false. * http://stackoverflow.com/questions/4054936/manual-control-over-when-to-redraw-the-screen/4057180#4057180 * http://stackoverflow.com/questions/4235439/xna-3-1-to-4-0-requires-constant-redraw-or-will-display-a-purple-screen */ if (BeginDraw()) { Draw(gameTime); EndDraw(); } } }