From 47f626cc99c93a28b2d6867ed6cc717b39ec062c Mon Sep 17 00:00:00 2001 From: Drachenkaetzchen Date: Fri, 10 Jan 2020 14:08:25 +0100 Subject: [PATCH] Moved most PerformanceCounter logic out of SCore into the new PerformanceCounterManager, some namespace refactoring --- src/SMAPI/Framework/Events/ManagedEvent.cs | 8 +- .../EventPerformanceCounterCategory.cs | 0 .../IPerformanceCounterEvent.cs | 2 +- .../PerformanceCounter.cs | 11 +-- .../PerformanceCounterEntry.cs | 0 .../PerformanceCounterManager.cs | 82 ++++++++++++++++++ src/SMAPI/Framework/SCore.cs | 83 +++---------------- src/SMAPI/Program.cs | 1 + 8 files changed, 104 insertions(+), 83 deletions(-) rename src/SMAPI/Framework/{Utilities => PerformanceCounter}/EventPerformanceCounterCategory.cs (100%) rename src/SMAPI/Framework/{Utilities => PerformanceCounter}/IPerformanceCounterEvent.cs (79%) rename src/SMAPI/Framework/{Utilities => PerformanceCounter}/PerformanceCounter.cs (89%) rename src/SMAPI/Framework/{Utilities => PerformanceCounter}/PerformanceCounterEntry.cs (100%) create mode 100644 src/SMAPI/Framework/PerformanceCounter/PerformanceCounterManager.cs diff --git a/src/SMAPI/Framework/Events/ManagedEvent.cs b/src/SMAPI/Framework/Events/ManagedEvent.cs index 9a5cb174..bb915738 100644 --- a/src/SMAPI/Framework/Events/ManagedEvent.cs +++ b/src/SMAPI/Framework/Events/ManagedEvent.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using StardewModdingAPI.Framework.Utilities; -using PerformanceCounter = StardewModdingAPI.Framework.Utilities.PerformanceCounter; +using PerformanceCounter = StardewModdingAPI.Framework.PerformanceCounter.PerformanceCounter; namespace StardewModdingAPI.Framework.Events { @@ -32,7 +32,7 @@ namespace StardewModdingAPI.Framework.Events /// The cached invocation list. private EventHandler[] CachedInvocationList; - public IDictionary PerformanceCounters { get; } = new Dictionary(); + public IDictionary PerformanceCounters { get; } = new Dictionary(); private readonly Stopwatch Stopwatch = new Stopwatch(); @@ -47,7 +47,7 @@ namespace StardewModdingAPI.Framework.Events public double GetGameAverageExecutionTime() { - if (this.PerformanceCounters.TryGetValue(Constants.GamePerformanceCounterName, out PerformanceCounter gameExecTime)) + if (this.PerformanceCounters.TryGetValue(Constants.GamePerformanceCounterName, out PerformanceCounter.PerformanceCounter gameExecTime)) { return gameExecTime.GetAverage(); } @@ -151,7 +151,7 @@ namespace StardewModdingAPI.Framework.Events if (!this.PerformanceCounters.ContainsKey(modName)) { - this.PerformanceCounters.Add(modName, new PerformanceCounter($"{modName}.{this.EventName}")); + this.PerformanceCounters.Add(modName, new PerformanceCounter.PerformanceCounter($"{modName}.{this.EventName}")); } this.PerformanceCounters[modName].Add(performanceCounterEntry); diff --git a/src/SMAPI/Framework/Utilities/EventPerformanceCounterCategory.cs b/src/SMAPI/Framework/PerformanceCounter/EventPerformanceCounterCategory.cs similarity index 100% rename from src/SMAPI/Framework/Utilities/EventPerformanceCounterCategory.cs rename to src/SMAPI/Framework/PerformanceCounter/EventPerformanceCounterCategory.cs diff --git a/src/SMAPI/Framework/Utilities/IPerformanceCounterEvent.cs b/src/SMAPI/Framework/PerformanceCounter/IPerformanceCounterEvent.cs similarity index 79% rename from src/SMAPI/Framework/Utilities/IPerformanceCounterEvent.cs rename to src/SMAPI/Framework/PerformanceCounter/IPerformanceCounterEvent.cs index 55302f90..6b83586d 100644 --- a/src/SMAPI/Framework/Utilities/IPerformanceCounterEvent.cs +++ b/src/SMAPI/Framework/PerformanceCounter/IPerformanceCounterEvent.cs @@ -7,7 +7,7 @@ namespace StardewModdingAPI.Framework.Utilities { string GetEventName(); long GetAverageCallsPerSecond(); - IDictionary PerformanceCounters { get; } + IDictionary PerformanceCounters { get; } double GetGameAverageExecutionTime(); double GetModsAverageExecutionTime(); diff --git a/src/SMAPI/Framework/Utilities/PerformanceCounter.cs b/src/SMAPI/Framework/PerformanceCounter/PerformanceCounter.cs similarity index 89% rename from src/SMAPI/Framework/Utilities/PerformanceCounter.cs rename to src/SMAPI/Framework/PerformanceCounter/PerformanceCounter.cs index c9ffcf5b..04e0f5f5 100644 --- a/src/SMAPI/Framework/Utilities/PerformanceCounter.cs +++ b/src/SMAPI/Framework/PerformanceCounter/PerformanceCounter.cs @@ -2,16 +2,17 @@ using System; using System.Diagnostics; using System.Linq; using Cyotek.Collections.Generic; +using StardewModdingAPI.Framework.Utilities; -namespace StardewModdingAPI.Framework.Utilities +namespace StardewModdingAPI.Framework.PerformanceCounter { public class PerformanceCounter { - private const int MaxCount = 16384; + private const int MAX_ENTRIES = 16384; public string Name { get; } public static Stopwatch Stopwatch = new Stopwatch(); - public static long EventsLogged; + public static long TotalNumEventsLogged; private readonly CircularBuffer _counter; @@ -21,7 +22,7 @@ namespace StardewModdingAPI.Framework.Utilities public PerformanceCounter(string name) { this.Name = name; - this._counter = new CircularBuffer(PerformanceCounter.MaxCount); + this._counter = new CircularBuffer(PerformanceCounter.MAX_ENTRIES); } public int GetAverageCallsPerSecond() @@ -53,7 +54,7 @@ namespace StardewModdingAPI.Framework.Utilities } PerformanceCounter.Stopwatch.Stop(); - EventsLogged++; + PerformanceCounter.TotalNumEventsLogged++; } public PerformanceCounterEntry? GetPeak() diff --git a/src/SMAPI/Framework/Utilities/PerformanceCounterEntry.cs b/src/SMAPI/Framework/PerformanceCounter/PerformanceCounterEntry.cs similarity index 100% rename from src/SMAPI/Framework/Utilities/PerformanceCounterEntry.cs rename to src/SMAPI/Framework/PerformanceCounter/PerformanceCounterEntry.cs diff --git a/src/SMAPI/Framework/PerformanceCounter/PerformanceCounterManager.cs b/src/SMAPI/Framework/PerformanceCounter/PerformanceCounterManager.cs new file mode 100644 index 00000000..e2200e74 --- /dev/null +++ b/src/SMAPI/Framework/PerformanceCounter/PerformanceCounterManager.cs @@ -0,0 +1,82 @@ +using System.Collections.Generic; +using StardewModdingAPI.Framework.Events; +using StardewModdingAPI.Framework.Utilities; + +namespace StardewModdingAPI.Framework.PerformanceCounter +{ + internal class PerformanceCounterManager + { + public HashSet PerformanceCounterEvents = new HashSet(); + + private readonly EventManager EventManager; + + public PerformanceCounterManager(EventManager eventManager) + { + this.EventManager = eventManager; + this.InitializePerformanceCounterEvents(); + } + + private void InitializePerformanceCounterEvents() + { + this.PerformanceCounterEvents = new HashSet() + { + new EventPerformanceCounterCategory(this.EventManager.MenuChanged, false), + + // Rendering Events + new EventPerformanceCounterCategory(this.EventManager.Rendering, true), + new EventPerformanceCounterCategory(this.EventManager.Rendered, true), + new EventPerformanceCounterCategory(this.EventManager.RenderingWorld, true), + new EventPerformanceCounterCategory(this.EventManager.RenderedWorld, true), + new EventPerformanceCounterCategory(this.EventManager.RenderingActiveMenu, true), + new EventPerformanceCounterCategory(this.EventManager.RenderedActiveMenu, true), + new EventPerformanceCounterCategory(this.EventManager.RenderingHud, true), + new EventPerformanceCounterCategory(this.EventManager.RenderedHud, true), + + new EventPerformanceCounterCategory(this.EventManager.WindowResized, false), + new EventPerformanceCounterCategory(this.EventManager.GameLaunched, false), + new EventPerformanceCounterCategory(this.EventManager.UpdateTicking, true), + new EventPerformanceCounterCategory(this.EventManager.UpdateTicked, true), + new EventPerformanceCounterCategory(this.EventManager.OneSecondUpdateTicking, true), + new EventPerformanceCounterCategory(this.EventManager.OneSecondUpdateTicked, true), + + new EventPerformanceCounterCategory(this.EventManager.SaveCreating, false), + new EventPerformanceCounterCategory(this.EventManager.SaveCreated, false), + new EventPerformanceCounterCategory(this.EventManager.Saving, false), + new EventPerformanceCounterCategory(this.EventManager.Saved, false), + + new EventPerformanceCounterCategory(this.EventManager.DayStarted, false), + new EventPerformanceCounterCategory(this.EventManager.DayEnding, false), + + new EventPerformanceCounterCategory(this.EventManager.TimeChanged, true), + + new EventPerformanceCounterCategory(this.EventManager.ReturnedToTitle, false), + + new EventPerformanceCounterCategory(this.EventManager.ButtonPressed, true), + new EventPerformanceCounterCategory(this.EventManager.ButtonReleased, true), + new EventPerformanceCounterCategory(this.EventManager.CursorMoved, true), + new EventPerformanceCounterCategory(this.EventManager.MouseWheelScrolled, true), + + new EventPerformanceCounterCategory(this.EventManager.PeerContextReceived, true), + new EventPerformanceCounterCategory(this.EventManager.ModMessageReceived, true), + new EventPerformanceCounterCategory(this.EventManager.PeerDisconnected, true), + new EventPerformanceCounterCategory(this.EventManager.InventoryChanged, true), + new EventPerformanceCounterCategory(this.EventManager.LevelChanged, true), + new EventPerformanceCounterCategory(this.EventManager.Warped, true), + + new EventPerformanceCounterCategory(this.EventManager.LocationListChanged, true), + new EventPerformanceCounterCategory(this.EventManager.BuildingListChanged, true), + new EventPerformanceCounterCategory(this.EventManager.LocationListChanged, true), + new EventPerformanceCounterCategory(this.EventManager.DebrisListChanged, true), + new EventPerformanceCounterCategory(this.EventManager.LargeTerrainFeatureListChanged, true), + new EventPerformanceCounterCategory(this.EventManager.NpcListChanged, true), + new EventPerformanceCounterCategory(this.EventManager.ObjectListChanged, true), + new EventPerformanceCounterCategory(this.EventManager.ChestInventoryChanged, true), + new EventPerformanceCounterCategory(this.EventManager.TerrainFeatureListChanged, true), + new EventPerformanceCounterCategory(this.EventManager.LoadStageChanged, false), + new EventPerformanceCounterCategory(this.EventManager.UnvalidatedUpdateTicking, true), + new EventPerformanceCounterCategory(this.EventManager.UnvalidatedUpdateTicked, true), + + }; + } + } +} diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index 6946a817..74a256fe 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -34,7 +34,7 @@ using StardewModdingAPI.Toolkit.Serialization; using StardewModdingAPI.Toolkit.Utilities; using StardewValley; using Object = StardewValley.Object; -using PerformanceCounter = StardewModdingAPI.Framework.Utilities.PerformanceCounter; +using PerformanceCounterManager = StardewModdingAPI.Framework.PerformanceCounter.PerformanceCounterManager; using ThreadState = System.Threading.ThreadState; namespace StardewModdingAPI.Framework @@ -79,11 +79,11 @@ namespace StardewModdingAPI.Framework /// This is initialized after the game starts. private readonly ModRegistry ModRegistry = new ModRegistry(); - private HashSet PerformanceCounterEvents = new HashSet(); - /// Manages SMAPI events for mods. private readonly EventManager EventManager; + private readonly PerformanceCounterManager PerformanceCounterManager; + /// Whether the game is currently running. private bool IsGameRunning; @@ -166,7 +166,7 @@ namespace StardewModdingAPI.Framework }; this.MonitorForGame = this.GetSecondaryMonitor("game"); this.EventManager = new EventManager(this.Monitor, this.ModRegistry); - this.InitializePerformanceCounterEvents(); + this.PerformanceCounterManager = new PerformanceCounterManager(this.EventManager); SCore.DeprecationManager = new DeprecationManager(this.Monitor, this.ModRegistry); @@ -206,69 +206,6 @@ namespace StardewModdingAPI.Framework #endif } - private void InitializePerformanceCounterEvents() - { - this.PerformanceCounterEvents = new HashSet() - { - new EventPerformanceCounterCategory(this.EventManager.MenuChanged, false), - - // Rendering Events - new EventPerformanceCounterCategory(this.EventManager.Rendering, true), - new EventPerformanceCounterCategory(this.EventManager.Rendered, true), - new EventPerformanceCounterCategory(this.EventManager.RenderingWorld, true), - new EventPerformanceCounterCategory(this.EventManager.RenderedWorld, true), - new EventPerformanceCounterCategory(this.EventManager.RenderingActiveMenu, true), - new EventPerformanceCounterCategory(this.EventManager.RenderedActiveMenu, true), - new EventPerformanceCounterCategory(this.EventManager.RenderingHud, true), - new EventPerformanceCounterCategory(this.EventManager.RenderedHud, true), - - new EventPerformanceCounterCategory(this.EventManager.WindowResized, false), - new EventPerformanceCounterCategory(this.EventManager.GameLaunched, false), - new EventPerformanceCounterCategory(this.EventManager.UpdateTicking, true), - new EventPerformanceCounterCategory(this.EventManager.UpdateTicked, true), - new EventPerformanceCounterCategory(this.EventManager.OneSecondUpdateTicking, true), - new EventPerformanceCounterCategory(this.EventManager.OneSecondUpdateTicked, true), - - new EventPerformanceCounterCategory(this.EventManager.SaveCreating, false), - new EventPerformanceCounterCategory(this.EventManager.SaveCreated, false), - new EventPerformanceCounterCategory(this.EventManager.Saving, false), - new EventPerformanceCounterCategory(this.EventManager.Saved, false), - - new EventPerformanceCounterCategory(this.EventManager.DayStarted, false), - new EventPerformanceCounterCategory(this.EventManager.DayEnding, false), - - new EventPerformanceCounterCategory(this.EventManager.TimeChanged, true), - - new EventPerformanceCounterCategory(this.EventManager.ReturnedToTitle, false), - - new EventPerformanceCounterCategory(this.EventManager.ButtonPressed, true), - new EventPerformanceCounterCategory(this.EventManager.ButtonReleased, true), - new EventPerformanceCounterCategory(this.EventManager.CursorMoved, true), - new EventPerformanceCounterCategory(this.EventManager.MouseWheelScrolled, true), - - new EventPerformanceCounterCategory(this.EventManager.PeerContextReceived, true), - new EventPerformanceCounterCategory(this.EventManager.ModMessageReceived, true), - new EventPerformanceCounterCategory(this.EventManager.PeerDisconnected, true), - new EventPerformanceCounterCategory(this.EventManager.InventoryChanged, true), - new EventPerformanceCounterCategory(this.EventManager.LevelChanged, true), - new EventPerformanceCounterCategory(this.EventManager.Warped, true), - - new EventPerformanceCounterCategory(this.EventManager.LocationListChanged, true), - new EventPerformanceCounterCategory(this.EventManager.BuildingListChanged, true), - new EventPerformanceCounterCategory(this.EventManager.LocationListChanged, true), - new EventPerformanceCounterCategory(this.EventManager.DebrisListChanged, true), - new EventPerformanceCounterCategory(this.EventManager.LargeTerrainFeatureListChanged, true), - new EventPerformanceCounterCategory(this.EventManager.NpcListChanged, true), - new EventPerformanceCounterCategory(this.EventManager.ObjectListChanged, true), - new EventPerformanceCounterCategory(this.EventManager.ChestInventoryChanged, true), - new EventPerformanceCounterCategory(this.EventManager.TerrainFeatureListChanged, true), - new EventPerformanceCounterCategory(this.EventManager.LoadStageChanged, false), - new EventPerformanceCounterCategory(this.EventManager.UnvalidatedUpdateTicking, true), - new EventPerformanceCounterCategory(this.EventManager.UnvalidatedUpdateTicked, true), - - }; - } - /// Launch SMAPI. [HandleProcessCorruptedStateExceptions, SecurityCritical] // let try..catch handle corrupted state exceptions public void RunInteractively() @@ -1471,7 +1408,7 @@ namespace StardewModdingAPI.Framework } else { - var data = this.PerformanceCounterEvents.Where(p => p.Event.GetEventName().ToLowerInvariant().Contains(filterByName.ToLowerInvariant())); + var data = this.PerformanceCounterManager.PerformanceCounterEvents.Where(p => p.Event.GetEventName().ToLowerInvariant().Contains(filterByName.ToLowerInvariant())); foreach (var i in data) { @@ -1479,8 +1416,8 @@ namespace StardewModdingAPI.Framework } } - double avgTime = PerformanceCounter.Stopwatch.ElapsedMilliseconds / (double)PerformanceCounter.EventsLogged; - this.Monitor.Log($"Logged {PerformanceCounter.EventsLogged} events in {PerformanceCounter.Stopwatch.ElapsedMilliseconds}ms (avg {avgTime:F4}ms / event)"); + double avgTime = PerformanceCounter.PerformanceCounter.Stopwatch.ElapsedMilliseconds / (double)PerformanceCounter.PerformanceCounter.TotalNumEventsLogged; + this.Monitor.Log($"Logged {PerformanceCounter.PerformanceCounter.TotalNumEventsLogged} events in {PerformanceCounter.PerformanceCounter.Stopwatch.ElapsedMilliseconds}ms (avg {avgTime:F4}ms / event)"); } @@ -1492,17 +1429,17 @@ namespace StardewModdingAPI.Framework if (eventNameFilter != null) { - data = this.PerformanceCounterEvents.Where(p => p.Event.GetEventName().ToLowerInvariant().Contains(eventNameFilter.ToLowerInvariant())); + data = this.PerformanceCounterManager.PerformanceCounterEvents.Where(p => p.Event.GetEventName().ToLowerInvariant().Contains(eventNameFilter.ToLowerInvariant())); } else { if (showOnlyImportant) { - data = this.PerformanceCounterEvents.Where(p => p.IsImportant); + data = this.PerformanceCounterManager.PerformanceCounterEvents.Where(p => p.IsImportant); } else { - data = this.PerformanceCounterEvents; + data = this.PerformanceCounterManager.PerformanceCounterEvents; } } diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs index 6bacf564..b5e6307a 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -11,6 +11,7 @@ using StardewModdingAPI.Framework; using StardewModdingAPI.Toolkit.Utilities; [assembly: InternalsVisibleTo("SMAPI.Tests")] +[assembly: InternalsVisibleTo("SMAPI.Mods.ConsoleCommands")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // Moq for unit testing namespace StardewModdingAPI {