A game about forced loneliness, made by TACStudios
at master 5.9 kB view raw
1#if UNITY_EDITOR 2 3using System; 4using UnityEditor; 5using UnityEngine.Serialization; 6 7namespace UnityEngine.InputSystem.Editor 8{ 9#if UNITY_2023_2_OR_NEWER 10 [UnityEngine.Analytics.AnalyticInfo(eventName: kEventName, maxEventsPerHour: kMaxEventsPerHour, 11 maxNumberOfElements: kMaxNumberOfElements, vendorKey: UnityEngine.InputSystem.InputAnalytics.kVendorKey)] 12#endif // UNITY_2023_2_OR_NEWER 13 internal class InputExitPlayModeAnalytic : UnityEngine.InputSystem.InputAnalytics.IInputAnalytic 14 { 15 public const string kEventName = "input_exit_playmode"; 16 public const int kMaxEventsPerHour = 100; // default: 1000 17 public const int kMaxNumberOfElements = 100; // default: 1000 18 19 /// <summary> 20 /// Enumeration type for code authoring APIs mapping to <see cref="InputActionSetupExtensions"/>. 21 /// </summary> 22 /// <remarks> 23 /// This enumeration type may be added to, but NEVER changed, since it would break older data. 24 /// </remarks> 25 public enum Api 26 { 27 AddBinding = 0, 28 AddCompositeBinding = 1, 29 ChangeBinding = 2, 30 ChangeCompositeBinding = 3, 31 Rename = 4, 32 AddControlScheme = 5, 33 RemoveControlScheme = 6, 34 ControlSchemeWithBindingGroup = 7, 35 ControlSchemeWithDevice = 8, 36 ControlSchemeWithRequiredDevice = 9, 37 ControlSchemeWithOptionalDevice = 10, 38 ControlSchemeOrWithRequiredDevice = 11, 39 ControlSchemeOrWithOptionalDevice = 12 40 } 41 42 private static readonly int[] m_Counters = new int[Enum.GetNames(typeof(Api)).Length]; 43 44 /// <summary> 45 /// Registers a call to the associated API. 46 /// </summary> 47 /// <param name="api">Enumeration identifying the API.</param> 48 public static void Register(Api api) 49 { 50 if (suppress) 51 return; 52 53 // Note: Currently discards detailed information and only sets a boolean (aggregated) value. 54 ++m_Counters[(int)api]; 55 } 56 57 /// <summary> 58 /// Suppresses the registration of analytics. 59 /// </summary> 60 /// <remarks> 61 /// May be used to temporarily suppress analytics to avoid false positives from internal usage. 62 /// </remarks> 63 public static bool suppress 64 { 65 get; set; 66 } 67 68 // Cache delegate 69 private static readonly Action<PlayModeStateChange> PlayModeChanged = OnPlayModeStateChange; 70 71 // Note: Internal visibility to simplify unit testing 72 internal static void OnPlayModeStateChange(PlayModeStateChange change) 73 { 74 if (change == PlayModeStateChange.ExitingEditMode) 75 { 76 // Reset all counters when exiting edit mode 77 Array.Clear(m_Counters, 0, m_Counters.Length); 78 79 // Make sure not suppressed 80 suppress = false; 81 } 82 if (change == PlayModeStateChange.ExitingPlayMode) 83 { 84 // Send analytics and unhook delegate when exiting play-mode 85 EditorApplication.playModeStateChanged -= PlayModeChanged; 86 new InputExitPlayModeAnalytic().Send(); 87 88 // No reason to not suppress 89 suppress = true; 90 } 91 } 92 93 [InitializeOnEnterPlayMode] 94 private static void Hook() 95 { 96 // Make sure only a single play-mode change delegate is registered 97 EditorApplication.playModeStateChanged -= PlayModeChanged; 98 EditorApplication.playModeStateChanged += PlayModeChanged; 99 } 100 101 private InputExitPlayModeAnalytic() 102 { 103 info = new InputAnalytics.InputAnalyticInfo(kEventName, kMaxEventsPerHour, kMaxNumberOfElements); 104 } 105 106 /// <summary> 107 /// Represents data collected when exiting play-mode.. 108 /// </summary> 109 /// <remarks> 110 /// Ideally this struct should be readonly but then Unity cannot serialize/deserialize it. 111 /// </remarks> 112 [Serializable] 113 public struct Data : UnityEngine.InputSystem.InputAnalytics.IInputAnalyticData 114 { 115 /// <summary> 116 /// Creates a new <c>Data</c> instance. 117 /// </summary> 118 /// <param name="usesCodeAuthoring">Specifies whether code authoring has been used during play-mode.</param> 119 public Data(bool usesCodeAuthoring) 120 { 121 uses_code_authoring = usesCodeAuthoring; 122 } 123 124 /// <summary> 125 /// Specifies whether code-authoring (Input Action setup via extensions) was used at least once during play-mode. 126 /// </summary> 127 public bool uses_code_authoring; 128 } 129 130#if UNITY_2023_2_OR_NEWER 131 public bool TryGatherData(out UnityEngine.Analytics.IAnalytic.IData data, out Exception error) 132#else 133 public bool TryGatherData(out InputAnalytics.IInputAnalyticData data, out Exception error) 134#endif 135 { 136 try 137 { 138 // Determine aggregated perspective, i.e. was "any" code-authoring API used 139 var usedCodeAuthoringDuringPlayMode = false; 140 for (var i = 0; i < m_Counters.Length; ++i) 141 { 142 if (m_Counters[i] > 0) 143 { 144 usedCodeAuthoringDuringPlayMode = true; 145 break; 146 } 147 } 148 149 data = new Data(usedCodeAuthoringDuringPlayMode); 150 error = null; 151 return true; 152 } 153 catch (Exception e) 154 { 155 data = null; 156 error = e; 157 return false; 158 } 159 } 160 161 public InputAnalytics.InputAnalyticInfo info { get; } 162 } 163} 164 165#endif // UNITY_EDITOR