123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391 |
- using System;
- using System.Collections.Generic;
- using UnityEditor.Analytics;
- using UnityEngine;
- using UnityEngine.Analytics;
- namespace UnityEditor.Performance.ProfileAnalyzer
- {
- class ProfileAnalyzerAnalytics
- {
- const int k_MaxEventsPerHour = 100;
- const int k_MaxEventItems = 1000;
- const string k_VendorKey = "unity.profileanalyzer";
- const string k_EventTopicName = "usability";
- static bool s_EnableAnalytics = false;
- public static void EnableAnalytics()
- {
- #if UNITY_2018_1_OR_NEWER
- AnalyticsResult result = EditorAnalytics.RegisterEventWithLimit(k_EventTopicName, k_MaxEventsPerHour, k_MaxEventItems, k_VendorKey);
- if (result == AnalyticsResult.Ok)
- s_EnableAnalytics = true;
- #endif
- }
- public enum UIButton
- {
- Pull,
- OpenProfiler,
- CloseProfiler,
- JumpToFrame,
- ExportSingleFrames,
- ExportComparisonFrames,
- };
- public enum UIUsageMode
- {
- Single,
- Comparison,
- };
- public enum UIVisibility
- {
- FrameTimeContextMenu,
- Filters,
- TopTen,
- Frames,
- Threads,
- Markers,
- };
- public enum UIResizeView
- {
- Single,
- Comparison,
- };
- [Serializable]
- struct ProfileAnalyzerUIButtonEventParameters
- {
- public string name;
- public ProfileAnalyzerUIButtonEventParameters(string name)
- {
- this.name = name;
- }
- }
- // camelCase since these events get serialized to Json and naming convention in analytics is camelCase
- [Serializable]
- struct ProfileAnalyzerUIButtonEvent
- {
- public ProfileAnalyzerUIButtonEvent(string name, float durationInTicks)
- {
- subtype = "profileAnalyzerUIButton";
- // ts is auto added so no need to include it here
- //ts = (int)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
- this.duration = durationInTicks;
- parameters = new ProfileAnalyzerUIButtonEventParameters(name);
- }
- public string subtype;
- //public int ts;
- public float duration; // Duration is in "ticks" 100 nanosecond intervals. I.e. 0.1 microseconds
- public ProfileAnalyzerUIButtonEventParameters parameters;
- }
- [Serializable]
- struct ProfileAnalyzerUIUsageEventParameters
- {
- public string name;
- public ProfileAnalyzerUIUsageEventParameters(string name)
- {
- this.name = name;
- }
- }
- [Serializable]
- struct ProfileAnalyzerUIUsageEvent
- {
- public ProfileAnalyzerUIUsageEvent(string name, float durationInTicks)
- {
- subtype = "profileAnalyzerModeUsage";
- this.duration = durationInTicks;
- parameters = new ProfileAnalyzerUIUsageEventParameters(name);
- }
- public string subtype;
- public float duration; // Duration is in "ticks" 100 nanosecond intervals. I.e. 0.1 microseconds
- public ProfileAnalyzerUIUsageEventParameters parameters;
- }
- [Serializable]
- struct ProfileAnalyzerUIVisibilityEventParameters
- {
- public string name;
- public bool show;
- public ProfileAnalyzerUIVisibilityEventParameters(string name, bool show)
- {
- this.name = name;
- this.show = show;
- }
- }
- [Serializable]
- struct ProfileAnalyzerUIVisibilityEvent
- {
- public ProfileAnalyzerUIVisibilityEvent(string name, float durationInTicks, bool show)
- {
- subtype = "profileAnalyzerUIVisibility";
- this.duration = durationInTicks;
- parameters = new ProfileAnalyzerUIVisibilityEventParameters(name, show);
- }
- public string subtype;
- public float duration; // Duration is in "ticks" 100 nanosecond intervals. I.e. 0.1 microseconds
- public ProfileAnalyzerUIVisibilityEventParameters parameters;
- }
- [Serializable]
- struct ProfileAnalyzerUIResizeEventParameters
- {
- public string name;
- public float width;
- public float height;
- public float screenWidth;
- public float screenHeight;
- public bool docked;
- public ProfileAnalyzerUIResizeEventParameters(string name, float width, float height, float screenWidth, float screenHeight, bool isDocked)
- {
- this.name = name;
- this.width = width;
- this.height = height;
- this.screenWidth = screenWidth;
- this.screenHeight = screenHeight;
- docked = isDocked;
- }
- }
- [Serializable]
- struct ProfileAnalyzerUIResizeEvent
- {
- public ProfileAnalyzerUIResizeEvent(string name, float durationInTicks, float width, float height, float screenWidth, float screenHeight, bool isDocked)
- {
- subtype = "profileAnalyzerUIResize";
- this.duration = durationInTicks;
- parameters = new ProfileAnalyzerUIResizeEventParameters(name, width, height, screenWidth, screenHeight, isDocked);
- }
- public string subtype;
- public float duration; // Duration is in "ticks" 100 nanosecond intervals. I.e. 0.1 microseconds
- public ProfileAnalyzerUIResizeEventParameters parameters;
- }
- static float SecondsToTicks(float durationInSeconds)
- {
- return durationInSeconds * 10000;
- }
- public static bool SendUIButtonEvent(UIButton uiButton, float durationInSeconds)
- {
- if (!s_EnableAnalytics)
- return false;
- #if UNITY_2018_1_OR_NEWER
- // Duration is in "ticks" 100 nanosecond intervals. I.e. 0.1 microseconds
- float durationInTicks = SecondsToTicks(durationInSeconds);
- ProfileAnalyzerUIButtonEvent uiButtonEvent;
- switch (uiButton)
- {
- case UIButton.Pull:
- uiButtonEvent = new ProfileAnalyzerUIButtonEvent("profilerAnalyzerGrab", durationInTicks);
- break;
- case UIButton.OpenProfiler:
- uiButtonEvent = new ProfileAnalyzerUIButtonEvent("profilerAnalyzerOpenProfiler", durationInTicks);
- break;
- case UIButton.CloseProfiler:
- uiButtonEvent = new ProfileAnalyzerUIButtonEvent("profilerAnalyzerCloseProfiler", durationInTicks);
- break;
- case UIButton.JumpToFrame:
- uiButtonEvent = new ProfileAnalyzerUIButtonEvent("profilerAnalyzerJumpToFrame", durationInTicks);
- break;
- case UIButton.ExportSingleFrames:
- uiButtonEvent = new ProfileAnalyzerUIButtonEvent("profilerAnalyzerExportSingleFrames", durationInTicks);
- break;
- case UIButton.ExportComparisonFrames:
- uiButtonEvent = new ProfileAnalyzerUIButtonEvent("profilerAnalyzerExportComparisonFrames", durationInTicks);
- break;
- default:
- Debug.LogFormat("SendUIButtonEvent: Unsupported button type : {0}", uiButton);
- return false;
- }
- AnalyticsResult result = EditorAnalytics.SendEventWithLimit(k_EventTopicName, uiButtonEvent);
- if (result != AnalyticsResult.Ok)
- return false;
- return true;
- #else
- return false;
- #endif
- }
- public static bool SendUIUsageModeEvent(UIUsageMode uiUsageMode, float durationInSeconds)
- {
- if (!s_EnableAnalytics)
- return false;
- #if UNITY_2018_1_OR_NEWER
- // Duration is in "ticks" 100 nanosecond intervals. I.e. 0.1 microseconds
- float durationInTicks = SecondsToTicks(durationInSeconds);
- ProfileAnalyzerUIUsageEvent uiUsageEvent;
- switch (uiUsageMode)
- {
- case UIUsageMode.Single:
- uiUsageEvent = new ProfileAnalyzerUIUsageEvent("profileAnalyzerSingle", durationInTicks);
- break;
- case UIUsageMode.Comparison:
- uiUsageEvent = new ProfileAnalyzerUIUsageEvent("profileAnalyzerCompare", durationInTicks);
- break;
- default:
- Debug.LogFormat("SendUsageEvent: Unsupported usage mode : {0}", uiUsageMode);
- return false;
- }
- AnalyticsResult result = EditorAnalytics.SendEventWithLimit(k_EventTopicName, uiUsageEvent);
- if (result != AnalyticsResult.Ok)
- return false;
- return true;
- #else
- return false;
- #endif
- }
- public static bool SendUIVisibilityEvent(UIVisibility uiVisibility, float durationInSeconds, bool show)
- {
- if (!s_EnableAnalytics)
- return false;
- #if UNITY_2018_1_OR_NEWER
- // Duration is in "ticks" 100 nanosecond intervals. I.e. 0.1 microseconds
- float durationInTicks = SecondsToTicks(durationInSeconds);
- ProfileAnalyzerUIVisibilityEvent uiUsageEvent;
- switch (uiVisibility)
- {
- case UIVisibility.FrameTimeContextMenu:
- uiUsageEvent = new ProfileAnalyzerUIVisibilityEvent("profilerAnalyzerFrameTimeContextMenu", durationInTicks, show);
- break;
- case UIVisibility.Filters:
- uiUsageEvent = new ProfileAnalyzerUIVisibilityEvent("profilerAnalyzerFilters", durationInTicks, show);
- break;
- case UIVisibility.TopTen:
- uiUsageEvent = new ProfileAnalyzerUIVisibilityEvent("profilerAnalyzerTopTen", durationInTicks, show);
- break;
- case UIVisibility.Frames:
- uiUsageEvent = new ProfileAnalyzerUIVisibilityEvent("profilerAnalyzerFrames", durationInTicks, show);
- break;
- case UIVisibility.Threads:
- uiUsageEvent = new ProfileAnalyzerUIVisibilityEvent("profilerAnalyzerThreads", durationInTicks, show);
- break;
- case UIVisibility.Markers:
- uiUsageEvent = new ProfileAnalyzerUIVisibilityEvent("profilerAnalyzerMarkers", durationInTicks, show);
- break;
- default:
- Debug.LogFormat("SendUIVisibilityEvent: Unsupported visibililty item : {0}", uiVisibility);
- return false;
- }
- AnalyticsResult result = EditorAnalytics.SendEventWithLimit(k_EventTopicName, uiUsageEvent);
- if (result != AnalyticsResult.Ok)
- return false;
- return true;
- #else
- return false;
- #endif
- }
- public static bool SendUIResizeEvent(UIResizeView uiResizeView, float durationInSeconds, float width, float height, bool isDocked)
- {
- if (!s_EnableAnalytics)
- return false;
- #if UNITY_2018_1_OR_NEWER
- // Duration is in "ticks" 100 nanosecond intervals. I.e. 0.1 microseconds
- float durationInTicks = SecondsToTicks(durationInSeconds);
- ProfileAnalyzerUIResizeEvent uiResizeEvent;
- switch (uiResizeView)
- {
- case UIResizeView.Single:
- // Screen.width, Screen.height is game view size
- uiResizeEvent = new ProfileAnalyzerUIResizeEvent("profileAnalyzerSingle", durationInTicks, width, height, Screen.currentResolution.width, Screen.currentResolution.height, isDocked);
- break;
- case UIResizeView.Comparison:
- uiResizeEvent = new ProfileAnalyzerUIResizeEvent("profileAnalyzerCompare", durationInTicks, width, height, Screen.currentResolution.width, Screen.currentResolution.height, isDocked);
- break;
- default:
- Debug.LogFormat("SendUIResizeEvent: Unsupported view : {0}", uiResizeView);
- return false;
- }
- AnalyticsResult result = EditorAnalytics.SendEventWithLimit(k_EventTopicName, uiResizeEvent);
- if (result != AnalyticsResult.Ok)
- return false;
- return true;
- #else
- return false;
- #endif
- }
- internal class Analytic
- {
- double m_StartTime;
- float m_DurationInSeconds;
- public Analytic()
- {
- m_StartTime = EditorApplication.timeSinceStartup;
- m_DurationInSeconds = 0;
- }
- public void End()
- {
- m_DurationInSeconds = (float)(EditorApplication.timeSinceStartup - m_StartTime);
- }
- public float GetDurationInSeconds()
- {
- return m_DurationInSeconds;
- }
- }
- static public Analytic BeginAnalytic()
- {
- return new Analytic();
- }
- static public void SendUIButtonEvent(UIButton uiButton, Analytic instance)
- {
- instance.End();
- SendUIButtonEvent(uiButton, instance.GetDurationInSeconds());
- }
- static public void SendUIUsageModeEvent(UIUsageMode uiUsageMode, Analytic instance)
- {
- instance.End();
- SendUIUsageModeEvent(uiUsageMode, instance.GetDurationInSeconds());
- }
- }
- }
|