A game framework written with osu! in mind.
at master 109 lines 3.8 kB view raw
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. 2// See the LICENCE file in the repository root for full licence text. 3 4using System; 5using System.Collections.Specialized; 6using System.Linq; 7using osu.Framework.Bindables; 8using osu.Framework.Logging; 9 10namespace osu.Framework.Statistics 11{ 12 /// <summary> 13 /// A store that can be used to track application-wide statistics and monitor runtime components. 14 /// </summary> 15 public static class GlobalStatistics 16 { 17 /// <summary> 18 /// An event which is raised when the available statistics change. 19 /// </summary> 20 internal static event NotifyCollectionChangedEventHandler StatisticsChanged; 21 22 private static readonly BindableList<IGlobalStatistic> statistics = new BindableList<IGlobalStatistic>(); 23 24 static GlobalStatistics() 25 { 26 statistics.BindCollectionChanged((o, e) => StatisticsChanged?.Invoke(o, e)); 27 } 28 29 /// <summary> 30 /// Retrieve a <see cref="IGlobalStatistic"/> of specified type. 31 /// If no matching statistic already exists, a new instance is created and registered automatically. 32 /// </summary> 33 /// <param name="group">The group specification.</param> 34 /// <param name="name">The name specification.</param> 35 /// <typeparam name="T">The type.</typeparam> 36 public static GlobalStatistic<T> Get<T>(string group, string name) 37 { 38 lock (statistics) 39 { 40 var existing = statistics.OfType<GlobalStatistic<T>>().FirstOrDefault(s => s.Name == name && s.Group == group); 41 if (existing != null) 42 return existing; 43 44 var newStat = new GlobalStatistic<T>(group, name); 45 register(newStat); 46 return newStat; 47 } 48 } 49 50 /// <summary> 51 /// Clear all statistics. 52 /// </summary> 53 /// <param name="group">An optional group identifier, limiting the clear operation to the matching group.</param> 54 public static void Clear(string group = null) 55 { 56 lock (statistics) 57 { 58 for (int i = 0; i < statistics.Count; i++) 59 { 60 if (group?.Equals(statistics[i].Group, StringComparison.Ordinal) != false) 61 statistics.RemoveAt(i--); 62 } 63 } 64 } 65 66 /// <summary> 67 /// Remove a specific statistic. 68 /// </summary> 69 /// <param name="statistic">The statistic to remove.</param> 70 public static void Remove(IGlobalStatistic statistic) 71 { 72 lock (statistics) 73 statistics.Remove(statistic); 74 } 75 76 /// <summary> 77 /// Register a new statistic type. 78 /// </summary> 79 /// <param name="stat">The statistic to register.</param> 80 private static void register(IGlobalStatistic stat) 81 { 82 lock (statistics) 83 statistics.Add(stat); 84 } 85 86 public static void OutputToLog() 87 { 88 var statisticsSnapshot = GetStatistics(); 89 90 Logger.Log("----- Global Statistics -----", LoggingTarget.Performance); 91 92 foreach (var group in statisticsSnapshot.GroupBy(s => s.Group)) 93 { 94 Logger.Log($"# {group.Key}", LoggingTarget.Performance); 95 96 foreach (var i in group) 97 Logger.Log($"{i.Name.PadRight(30)}: {i.DisplayValue}", LoggingTarget.Performance); 98 } 99 100 Logger.Log("--- Global Statistics End ---", LoggingTarget.Performance); 101 } 102 103 internal static IGlobalStatistic[] GetStatistics() 104 { 105 lock (statistics) 106 return statistics.ToArray(); 107 } 108 } 109}