public static void TestAnimal(int iterations) { var tm = new TimeMonitor(); // Run iterations for (var i = 0; i < iterations; i++) { var cm = new OrganismEmulator(); tm.Start(); cm.EmulateOrganism(); lastQuanta = tm.EndGetMicroseconds(); allQuanta.Add(lastQuanta); } // Sort by speed allQuanta.Sort(); // Pick the middle 80% of all iterations for (var i = (int) (iterations*0.15); i < (int) (iterations*0.85); i++) { samples++; lastQuanta = (long) allQuanta[i]; if (worstQuanta == 0 && bestQuanta == 0) { worstQuanta = lastQuanta; bestQuanta = lastQuanta; } else { if (lastQuanta > worstQuanta) { worstQuanta = lastQuanta; } if (lastQuanta < bestQuanta) { bestQuanta = lastQuanta; } } totalQuanta += lastQuanta; } }
/// <summary> /// Renders a new frame of animation. This is the entry point for drawing /// code and is required every time a new frame is to be drawn. /// </summary> public void RenderFrame() { #if TRACE Profiler.Start("TerrariumDirectDrawGameView.RenderFrame()"); #else TimeMonitor tm = new TimeMonitor(); tm.Start(); #endif // Don't draw while we are resizing the viewer // This might happen on a secondary thread so // we need some minimal protection. if (resizing) { return; } // If we are still drawing then skip this frame. // However, only skip one frame to prevent hangs. if (drawing) { drawing = false; return; } try { paused = false; drawing = true; skipframe = !skipframe; if (fullscreen) { // No full screen mode } else { if (ScreenSurface == null || ScreenSurface.Surface.isLost() != 0 || BackBufferSurface == null || BackBufferSurface.Surface.isLost() != 0) { if (ResizeViewer() == false) { return; } } if (updateTickerChanged && (updateTicker%10) == 0) { updateTickerChanged = false; updateMiniMap = true; if (wld != null && miniMap == null) { //this.miniMap = new Bitmap(wld.MiniMap); miniMap = new Bitmap(wld.MiniMap, (actualsize.Right - actualsize.Left)/4, (actualsize.Bottom - actualsize.Top)/4); } if (miniMap != null) { var graphics = Graphics.FromImage(miniMap); graphics.Clear(Color.Transparent); graphics.Dispose(); } } CheckScroll(); #if TRACE Profiler.Start("TerrariumDirectDrawGameView.RenderFrame()::Primary Surface Blit"); #endif if (drawScreen) { if (videomemory || !skipframe) { PaintBackground(); PaintSprites(BackBufferSurface, false); PaintMessage(); PaintCursor(); // Grab the Window RECT var windowRect = new RECT(); ManagedDirectX.DirectX.GetWindowRect( Handle.ToInt32(), ref windowRect); // Set up a sample destination rectangle var destRect = new RECT(); destRect.Left = windowRect.Left; destRect.Top = windowRect.Top; destRect.Right = windowRect.Right; destRect.Bottom = windowRect.Bottom; // Grab the Source Rectangle for the Bezel var srcRect = BackBufferSurface.Rect; var destWidth = destRect.Right - destRect.Left; var destHeight = destRect.Bottom - destRect.Top; var srcWidth = srcRect.Right; var srcHeight = srcRect.Bottom; bltUsingBezel = false; if (srcWidth < destWidth) { destRect.Left += (destWidth - srcWidth)/2; destRect.Right = destRect.Left + srcWidth; bltUsingBezel = true; } if (srcHeight < destHeight) { destRect.Top += (destHeight - srcHeight)/2; destRect.Bottom = destRect.Top + srcHeight; bltUsingBezel = true; } if (bltUsingBezel) { if (destRect.Top != bezelRect.Top || destRect.Left != bezelRect.Left || destRect.Bottom != bezelRect.Bottom || destRect.Right != bezelRect.Right) { ScreenSurface.Surface.BltColorFill(ref windowRect, 0); } bezelRect = destRect; } ScreenSurface.Surface.Blt( ref destRect, BackBufferSurface.Surface, ref srcRect, CONST_DDBLTFLAGS.DDBLT_WAIT); } } #if TRACE Profiler.End("TerrariumDirectDrawGameView.RenderFrame()::Primary Surface Blit"); #endif if (updateMiniMap) { updateMiniMap = false; OnMiniMapUpdated(new MiniMapUpdatedEventArgs(miniMap)); } } } finally { drawing = false; } #if TRACE Profiler.End("TerrariumDirectDrawGameView.RenderFrame()"); #else renderTime += tm.EndGetMicroseconds(); samples++; #endif }
// NEVER pop up UI in this function, or in any function that it calls. If you do, and the // function pumps messages, we could shut the game down without DoTick expecting it. private void DoTick() { if (GameEngine.Current == null) { return; } double outsideTime = 0; if (outsideTimer.IsStarted) { outsideTime = (double)outsideTimer.EndGetMicroseconds() / (double)1000; } totalOutsideTime += outsideTime; if (frameNumber == 0) { outsideTimes[9] = outsideTime; ReportTimes(); } else { outsideTimes[frameNumber - 1] = outsideTime; } // Shutdown if our appdomain is getting too big if (GameEngine.Current.Pac.PacOrganismCount > 600 || GameEngine.Current.Pac.PacSize > 104857600) { LoadEcosystem(null); } // Paint the screen if (this.Visible == true && !this.resizeBar.Dragging && !_options.NoDirectX && !turnOffDirectX) { TimeMonitor startRefreshTime = new TimeMonitor(); startRefreshTime.Start(); TimeMonitor paintFrame = new TimeMonitor(); paintFrame.Start(); if (oldVector != null) { PaintFrame(oldVector, newVector, frameNumber, false); } totalPaintFrameTime += paintFrame.EndGetMicroseconds(); try { tddGameView.DrawScreen = GameConfig.DrawScreen; tddGameView.DrawBoundingBox = GameConfig.BoundingBoxes; // NOTE: Removed since we change how we render background grids // we only need to set it once and the view will handle it // from then on //tddGameView.DrawBackgroundGrid = GameConfig.BackgroundGrid; tddGameView.DrawDestinationLines = GameConfig.DestinationLines; tddGameView.RenderFrame(); // Successful frame, reset our counter // This prevents us from turning off DirectX rendering when we // get a hiccup like an out of memory exception. turnOffDirectXCounter = 0; this.developerPanel.MapLocation = new Point(tddGameView.ViewSize.Left, tddGameView.ViewSize.Top); } catch (Exception exc) { Trace.WriteLine(exc.ToString()); this.turnOffDirectXCounter++; if (turnOffDirectXCounter > 10) { Trace.WriteLine("Turning off DirectX"); turnOffDirectX = true; } } Int64 refreshTime = startRefreshTime.EndGetMicroseconds(); paintTimes[frameNumber] = (double)refreshTime / (double)1000; totalPaintTime += refreshTime; } // Process the turn TimeMonitor startProcessTime = new TimeMonitor(); startProcessTime.Start(); Boolean turnFinished = false; try { turnFinished = GameEngine.Current.ProcessTurn(); } catch (InvalidPeerException ipe) { timer1.Enabled = false; MessageBox.Show(this, ipe.Message, "Can't run EcoSystem", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); CloseTerrarium(false); return; } catch (MaliciousOrganismException) { timer1.Enabled = false; relaunch = true; maliciousOrganism = true; this.Close(); return; } catch (ShutdownFailureException) { // This version of the game has been marked as bad timer1.Enabled = false; GameConfig.BlockedVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); runningBlockedVersion = true; relaunch = true; this.Close(); return; } catch (OrganismBlacklistException) { // Reload the ecosystem but blacklist on startup blacklistCheckOnRestart = true; LoadEcosystem(null); return; } catch (StateTimedOutException) { // our state has been timed out -- need to create a new ecosystem timer1.Enabled = false; MessageBox.Show(this, "Your animals have all died since you haven't run Terrarium for a long time. Starting fresh.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); CloseTerrarium(false); LoadEcosystem(SpecialUserAppDataPath + ecosystemStateFileName); return; } catch (StateCorruptedException corruptedException) { // our state is corrupted, probably because the app was killed and we're reporting duplicate data -- need to create a new ecosystem timer1.Enabled = false; MessageBox.Show(this, "Your part of the ecosystem is messed up. Starting fresh. [Last Reported Tick = " + corruptedException.LastReportedTick + "]", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); CloseTerrarium(false); LoadEcosystem(SpecialUserAppDataPath + ecosystemStateFileName); return; } Int64 processTime = startProcessTime.EndGetMicroseconds(); processTimes[frameNumber] = (double)processTime / (double)1000; totalProcessTime += processTime; frameNumber++; if (turnFinished) { if (frameNumber != 10) { throw new ApplicationException("Frame numbers messed up."); } frameNumber = 0; if (propertySheet != null) { propertySheet.RefreshGrid(); } } outsideTimer.Start(); }
/// <summary> /// Creates a new node given an id. Sets up the initial /// TimeMonitor used to record high performance timings. /// </summary> /// <param name="id">ID for this node.</param> public ProfilerNode(string id) { _timeMonitor = new TimeMonitor(); _isCounting = false; }
/// <summary> /// Creates a new node given an id. Sets up the initial /// TimeMonitor used to record high performance timings. /// </summary> /// <param name="id">ID for this node.</param> public ProfilerNode(string id) { tm = new TimeMonitor(); this.id = id; counting = false; }