From 47f626cc99c93a28b2d6867ed6cc717b39ec062c Mon Sep 17 00:00:00 2001 From: Drachenkaetzchen Date: Fri, 10 Jan 2020 14:08:25 +0100 Subject: Moved most PerformanceCounter logic out of SCore into the new PerformanceCounterManager, some namespace refactoring --- src/SMAPI/Framework/Events/ManagedEvent.cs | 8 +- .../EventPerformanceCounterCategory.cs | 16 ++++ .../PerformanceCounter/IPerformanceCounterEvent.cs | 16 ++++ .../PerformanceCounter/PerformanceCounter.cs | 103 +++++++++++++++++++++ .../PerformanceCounter/PerformanceCounterEntry.cs | 10 ++ .../PerformanceCounterManager.cs | 82 ++++++++++++++++ src/SMAPI/Framework/SCore.cs | 83 ++--------------- .../Utilities/EventPerformanceCounterCategory.cs | 16 ---- .../Utilities/IPerformanceCounterEvent.cs | 16 ---- .../Framework/Utilities/PerformanceCounter.cs | 102 -------------------- .../Framework/Utilities/PerformanceCounterEntry.cs | 10 -- src/SMAPI/Program.cs | 1 + 12 files changed, 242 insertions(+), 221 deletions(-) create mode 100644 src/SMAPI/Framework/PerformanceCounter/EventPerformanceCounterCategory.cs create mode 100644 src/SMAPI/Framework/PerformanceCounter/IPerformanceCounterEvent.cs create mode 100644 src/SMAPI/Framework/PerformanceCounter/PerformanceCounter.cs create mode 100644 src/SMAPI/Framework/PerformanceCounter/PerformanceCounterEntry.cs create mode 100644 src/SMAPI/Framework/PerformanceCounter/PerformanceCounterManager.cs delete mode 100644 src/SMAPI/Framework/Utilities/EventPerformanceCounterCategory.cs delete mode 100644 src/SMAPI/Framework/Utilities/IPerformanceCounterEvent.cs delete mode 100644 src/SMAPI/Framework/Utilities/PerformanceCounter.cs delete mode 100644 src/SMAPI/Framework/Utilities/PerformanceCounterEntry.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/PerformanceCounter/EventPerformanceCounterCategory.cs b/src/SMAPI/Framework/PerformanceCounter/EventPerformanceCounterCategory.cs new file mode 100644 index 00000000..14f74317 --- /dev/null +++ b/src/SMAPI/Framework/PerformanceCounter/EventPerformanceCounterCategory.cs @@ -0,0 +1,16 @@ +namespace StardewModdingAPI.Framework.Utilities +{ + public class EventPerformanceCounterCategory + { + public IPerformanceCounterEvent Event { get; } + public double MonitorThreshold { get; } + public bool IsImportant { get; } + public bool Monitor { get; } + + public EventPerformanceCounterCategory(IPerformanceCounterEvent @event, bool isImportant) + { + this.Event = @event; + this.IsImportant = isImportant; + } + } +} diff --git a/src/SMAPI/Framework/PerformanceCounter/IPerformanceCounterEvent.cs b/src/SMAPI/Framework/PerformanceCounter/IPerformanceCounterEvent.cs new file mode 100644 index 00000000..6b83586d --- /dev/null +++ b/src/SMAPI/Framework/PerformanceCounter/IPerformanceCounterEvent.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; + +namespace StardewModdingAPI.Framework.Utilities +{ + public interface IPerformanceCounterEvent + { + string GetEventName(); + long GetAverageCallsPerSecond(); + IDictionary PerformanceCounters { get; } + + double GetGameAverageExecutionTime(); + double GetModsAverageExecutionTime(); + double GetAverageExecutionTime(); + } +} diff --git a/src/SMAPI/Framework/PerformanceCounter/PerformanceCounter.cs b/src/SMAPI/Framework/PerformanceCounter/PerformanceCounter.cs new file mode 100644 index 00000000..04e0f5f5 --- /dev/null +++ b/src/SMAPI/Framework/PerformanceCounter/PerformanceCounter.cs @@ -0,0 +1,103 @@ +using System; +using System.Diagnostics; +using System.Linq; +using Cyotek.Collections.Generic; +using StardewModdingAPI.Framework.Utilities; + +namespace StardewModdingAPI.Framework.PerformanceCounter +{ + public class PerformanceCounter + { + private const int MAX_ENTRIES = 16384; + + public string Name { get; } + public static Stopwatch Stopwatch = new Stopwatch(); + public static long TotalNumEventsLogged; + + + private readonly CircularBuffer _counter; + + private PerformanceCounterEntry? PeakPerformanceCounterEntry; + + public PerformanceCounter(string name) + { + this.Name = name; + this._counter = new CircularBuffer(PerformanceCounter.MAX_ENTRIES); + } + + public int GetAverageCallsPerSecond() + { + var x = this._counter.GroupBy( + p => + (int) p.EventTime.Subtract( + new DateTime(1970, 1, 1) + ).TotalSeconds); + + return x.Last().Count(); + } + + public void Add(PerformanceCounterEntry entry) + { + PerformanceCounter.Stopwatch.Start(); + this._counter.Put(entry); + + if (this.PeakPerformanceCounterEntry == null) + { + this.PeakPerformanceCounterEntry = entry; + } + else + { + if (entry.Elapsed.TotalMilliseconds > this.PeakPerformanceCounterEntry.Value.Elapsed.TotalMilliseconds) + { + this.PeakPerformanceCounterEntry = entry; + } + } + + PerformanceCounter.Stopwatch.Stop(); + PerformanceCounter.TotalNumEventsLogged++; + } + + public PerformanceCounterEntry? GetPeak() + { + return this.PeakPerformanceCounterEntry; + } + + public void ResetPeak() + { + this.PeakPerformanceCounterEntry = null; + } + + public PerformanceCounterEntry? GetLastEntry() + { + if (this._counter.IsEmpty) + { + return null; + } + return this._counter.PeekLast(); + } + + public double GetAverage() + { + if (this._counter.IsEmpty) + { + return 0; + } + + return this._counter.Average(p => p.Elapsed.TotalMilliseconds); + } + + public double GetAverage(TimeSpan range) + { + if (this._counter.IsEmpty) + { + return 0; + } + + var lastTime = this._counter.Max(x => x.EventTime); + var start = lastTime.Subtract(range); + + var entries = this._counter.Where(x => (x.EventTime >= start) && (x.EventTime <= lastTime)); + return entries.Average(x => x.Elapsed.TotalMilliseconds); + } + } +} diff --git a/src/SMAPI/Framework/PerformanceCounter/PerformanceCounterEntry.cs b/src/SMAPI/Framework/PerformanceCounter/PerformanceCounterEntry.cs new file mode 100644 index 00000000..8e156a32 --- /dev/null +++ b/src/SMAPI/Framework/PerformanceCounter/PerformanceCounterEntry.cs @@ -0,0 +1,10 @@ +using System; + +namespace StardewModdingAPI.Framework.Utilities +{ + public struct PerformanceCounterEntry + { + public DateTime EventTime; + public TimeSpan Elapsed; + } +} 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/Framework/Utilities/EventPerformanceCounterCategory.cs b/src/SMAPI/Framework/Utilities/EventPerformanceCounterCategory.cs deleted file mode 100644 index 14f74317..00000000 --- a/src/SMAPI/Framework/Utilities/EventPerformanceCounterCategory.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace StardewModdingAPI.Framework.Utilities -{ - public class EventPerformanceCounterCategory - { - public IPerformanceCounterEvent Event { get; } - public double MonitorThreshold { get; } - public bool IsImportant { get; } - public bool Monitor { get; } - - public EventPerformanceCounterCategory(IPerformanceCounterEvent @event, bool isImportant) - { - this.Event = @event; - this.IsImportant = isImportant; - } - } -} diff --git a/src/SMAPI/Framework/Utilities/IPerformanceCounterEvent.cs b/src/SMAPI/Framework/Utilities/IPerformanceCounterEvent.cs deleted file mode 100644 index 55302f90..00000000 --- a/src/SMAPI/Framework/Utilities/IPerformanceCounterEvent.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace StardewModdingAPI.Framework.Utilities -{ - public interface IPerformanceCounterEvent - { - string GetEventName(); - long GetAverageCallsPerSecond(); - IDictionary PerformanceCounters { get; } - - double GetGameAverageExecutionTime(); - double GetModsAverageExecutionTime(); - double GetAverageExecutionTime(); - } -} diff --git a/src/SMAPI/Framework/Utilities/PerformanceCounter.cs b/src/SMAPI/Framework/Utilities/PerformanceCounter.cs deleted file mode 100644 index c9ffcf5b..00000000 --- a/src/SMAPI/Framework/Utilities/PerformanceCounter.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using System.Diagnostics; -using System.Linq; -using Cyotek.Collections.Generic; - -namespace StardewModdingAPI.Framework.Utilities -{ - public class PerformanceCounter - { - private const int MaxCount = 16384; - - public string Name { get; } - public static Stopwatch Stopwatch = new Stopwatch(); - public static long EventsLogged; - - - private readonly CircularBuffer _counter; - - private PerformanceCounterEntry? PeakPerformanceCounterEntry; - - public PerformanceCounter(string name) - { - this.Name = name; - this._counter = new CircularBuffer(PerformanceCounter.MaxCount); - } - - public int GetAverageCallsPerSecond() - { - var x = this._counter.GroupBy( - p => - (int) p.EventTime.Subtract( - new DateTime(1970, 1, 1) - ).TotalSeconds); - - return x.Last().Count(); - } - - public void Add(PerformanceCounterEntry entry) - { - PerformanceCounter.Stopwatch.Start(); - this._counter.Put(entry); - - if (this.PeakPerformanceCounterEntry == null) - { - this.PeakPerformanceCounterEntry = entry; - } - else - { - if (entry.Elapsed.TotalMilliseconds > this.PeakPerformanceCounterEntry.Value.Elapsed.TotalMilliseconds) - { - this.PeakPerformanceCounterEntry = entry; - } - } - - PerformanceCounter.Stopwatch.Stop(); - EventsLogged++; - } - - public PerformanceCounterEntry? GetPeak() - { - return this.PeakPerformanceCounterEntry; - } - - public void ResetPeak() - { - this.PeakPerformanceCounterEntry = null; - } - - public PerformanceCounterEntry? GetLastEntry() - { - if (this._counter.IsEmpty) - { - return null; - } - return this._counter.PeekLast(); - } - - public double GetAverage() - { - if (this._counter.IsEmpty) - { - return 0; - } - - return this._counter.Average(p => p.Elapsed.TotalMilliseconds); - } - - public double GetAverage(TimeSpan range) - { - if (this._counter.IsEmpty) - { - return 0; - } - - var lastTime = this._counter.Max(x => x.EventTime); - var start = lastTime.Subtract(range); - - var entries = this._counter.Where(x => (x.EventTime >= start) && (x.EventTime <= lastTime)); - return entries.Average(x => x.Elapsed.TotalMilliseconds); - } - } -} diff --git a/src/SMAPI/Framework/Utilities/PerformanceCounterEntry.cs b/src/SMAPI/Framework/Utilities/PerformanceCounterEntry.cs deleted file mode 100644 index 8e156a32..00000000 --- a/src/SMAPI/Framework/Utilities/PerformanceCounterEntry.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; - -namespace StardewModdingAPI.Framework.Utilities -{ - public struct PerformanceCounterEntry - { - public DateTime EventTime; - public TimeSpan Elapsed; - } -} 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 { -- cgit