// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using System.Collections.Specialized; using System.Linq; using osu.Framework.Bindables; using osu.Framework.Logging; namespace osu.Framework.Statistics { /// /// A store that can be used to track application-wide statistics and monitor runtime components. /// public static class GlobalStatistics { /// /// An event which is raised when the available statistics change. /// internal static event NotifyCollectionChangedEventHandler StatisticsChanged; private static readonly BindableList statistics = new BindableList(); static GlobalStatistics() { statistics.BindCollectionChanged((o, e) => StatisticsChanged?.Invoke(o, e)); } /// /// Retrieve a of specified type. /// If no matching statistic already exists, a new instance is created and registered automatically. /// /// The group specification. /// The name specification. /// The type. public static GlobalStatistic Get(string group, string name) { lock (statistics) { var existing = statistics.OfType>().FirstOrDefault(s => s.Name == name && s.Group == group); if (existing != null) return existing; var newStat = new GlobalStatistic(group, name); register(newStat); return newStat; } } /// /// Clear all statistics. /// /// An optional group identifier, limiting the clear operation to the matching group. public static void Clear(string group = null) { lock (statistics) { for (int i = 0; i < statistics.Count; i++) { if (group?.Equals(statistics[i].Group, StringComparison.Ordinal) != false) statistics.RemoveAt(i--); } } } /// /// Remove a specific statistic. /// /// The statistic to remove. public static void Remove(IGlobalStatistic statistic) { lock (statistics) statistics.Remove(statistic); } /// /// Register a new statistic type. /// /// The statistic to register. private static void register(IGlobalStatistic stat) { lock (statistics) statistics.Add(stat); } public static void OutputToLog() { var statisticsSnapshot = GetStatistics(); Logger.Log("----- Global Statistics -----", LoggingTarget.Performance); foreach (var group in statisticsSnapshot.GroupBy(s => s.Group)) { Logger.Log($"# {group.Key}", LoggingTarget.Performance); foreach (var i in group) Logger.Log($"{i.Name.PadRight(30)}: {i.DisplayValue}", LoggingTarget.Performance); } Logger.Log("--- Global Statistics End ---", LoggingTarget.Performance); } internal static IGlobalStatistic[] GetStatistics() { lock (statistics) return statistics.ToArray(); } } }