PlasticApp.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. using UnityEngine;
  5. using Codice.Client.BaseCommands;
  6. using Codice.Client.BaseCommands.EventTracking;
  7. using Codice.Client.Common;
  8. using Codice.Client.Common.Connection;
  9. using Codice.Client.Common.Encryption;
  10. using Codice.Client.Common.EventTracking;
  11. using Codice.Client.Common.FsNodeReaders;
  12. using Codice.Client.Common.FsNodeReaders.Watcher;
  13. using Codice.Client.Common.Threading;
  14. using Codice.CM.Common;
  15. using Codice.CM.ConfigureHelper;
  16. using Codice.LogWrapper;
  17. using Codice.Utils;
  18. using CodiceApp.EventTracking;
  19. using PlasticGui;
  20. using PlasticGui.EventTracking;
  21. using PlasticGui.WebApi;
  22. using PlasticPipe.Certificates;
  23. using Unity.PlasticSCM.Editor.AssetUtils;
  24. using Unity.PlasticSCM.Editor.Configuration;
  25. using Unity.PlasticSCM.Editor.UI;
  26. using MacUI;
  27. using UnityEditor;
  28. namespace Unity.PlasticSCM.Editor
  29. {
  30. internal static class PlasticApp
  31. {
  32. internal static IPlasticAPI PlasticAPI { get; private set; }
  33. internal static PlasticWebRestApi PlasticWebRestApi { get; private set; }
  34. internal static bool IsInitialized
  35. {
  36. get { return mIsInitialized; }
  37. }
  38. internal static void InitializeIfNeeded()
  39. {
  40. if (mIsInitialized)
  41. return;
  42. mIsInitialized = true;
  43. PlasticAPI = new PlasticAPI();
  44. PlasticWebRestApi = new PlasticWebRestApi();
  45. ConfigureLogging();
  46. GuiMessage.Initialize(new UnityPlasticGuiMessage());
  47. RegisterExceptionHandlers();
  48. InitLocalization();
  49. ThreadWaiter.Initialize(new UnityThreadWaiterBuilder());
  50. ServicePointConfigurator.ConfigureServicePoint();
  51. CertificateUi.RegisterHandler(new ChannelCertificateUiImpl());
  52. SetupFsWatcher();
  53. EditionManager.Get().DisableCapability(
  54. EnumEditionCapabilities.Extensions);
  55. ClientHandlers.Register();
  56. PlasticGuiConfig.SetConfigFile(
  57. PlasticGuiConfig.UNITY_GUI_CONFIG_FILE);
  58. sEventSenderScheduler = EventTracking.Configure(
  59. PlasticApp.PlasticWebRestApi,
  60. AssetsPath.IsRunningAsUPMPackage() ?
  61. ApplicationIdentifier.UnityPackage :
  62. ApplicationIdentifier.UnityAssetStorePlugin,
  63. IdentifyEventPlatform.Get());
  64. if (sEventSenderScheduler != null)
  65. {
  66. sPingEventLoop = new PingEventLoop();
  67. sPingEventLoop.Start();
  68. sPingEventLoop.SetUnityVersion(Application.unityVersion);
  69. CollabPlugin.GetVersion(pluginVersion => sPingEventLoop.SetPluginVersion(pluginVersion));
  70. }
  71. PlasticMethodExceptionHandling.InitializeAskCredentialsUi(
  72. new CredentialsUiImpl());
  73. ClientEncryptionServiceProvider.SetEncryptionPasswordProvider(
  74. new MissingEncryptionPasswordPromptHandler());
  75. DiffMergeToolConfigFactory.Get().SetDiffMergeToolConfig(
  76. GetDiffMergeToolConfig.ForPlatform());
  77. }
  78. internal static void SetWorkspace(WorkspaceInfo wkInfo)
  79. {
  80. RegisterApplicationFocusHandlers();
  81. RegisterAssemblyReloadHandlers();
  82. if (sEventSenderScheduler == null)
  83. return;
  84. sPingEventLoop.SetWorkspace(wkInfo);
  85. ((IPlasticWebRestApi)PlasticWebRestApi).SetToken(
  86. CmConnection.Get().BuildWebApiTokenForCloudEditionDefaultUser());
  87. }
  88. // These two (ClientHandlers and ThreadWatier) need to be reinitialized if they have not been
  89. // or else an error will be thrown and the Plastic context menu will not show up
  90. internal static void RegisterClientHandlersIfNeeded()
  91. {
  92. if (mIsInitialized)
  93. return;
  94. ClientHandlers.Register();
  95. ThreadWaiter.Initialize(new UnityThreadWaiterBuilder());
  96. mIsInitialized = true;
  97. }
  98. internal static void Dispose()
  99. {
  100. mIsInitialized = false;
  101. UnRegisterExceptionHandlers();
  102. UnRegisterApplicationFocusHandlers();
  103. UnRegisterAssemblyReloadHandlers();
  104. if (sEventSenderScheduler != null)
  105. {
  106. sPingEventLoop.Stop();
  107. sEventSenderScheduler.End();
  108. }
  109. WorkspaceInfo wkInfo = FindWorkspace.InfoForApplicationPath(
  110. Application.dataPath,
  111. PlasticAPI);
  112. if (wkInfo == null)
  113. return;
  114. WorkspaceFsNodeReaderCachesCleaner.CleanWorkspaceFsNodeReader(wkInfo);
  115. }
  116. static void InitLocalization()
  117. {
  118. string language = null;
  119. try
  120. {
  121. language = ClientConfig.Get().GetLanguage();
  122. }
  123. catch
  124. {
  125. language = string.Empty;
  126. }
  127. Localization.Init(language);
  128. PlasticLocalization.SetLanguage(language);
  129. }
  130. static void ConfigureLogging()
  131. {
  132. try
  133. {
  134. string log4netpath = ToolConfig.GetUnityPlasticLogConfigFile();
  135. if (!File.Exists(log4netpath))
  136. WriteLogConfiguration.For(log4netpath);
  137. XmlConfigurator.Configure(new FileInfo(log4netpath));
  138. }
  139. catch
  140. {
  141. //it failed configuring the logging info; nothing to do.
  142. }
  143. }
  144. static void RegisterExceptionHandlers()
  145. {
  146. AppDomain.CurrentDomain.UnhandledException += HandleUnhandledException;
  147. Application.logMessageReceivedThreaded += HandleLog;
  148. }
  149. static void RegisterApplicationFocusHandlers()
  150. {
  151. EditorWindowFocus.OnApplicationActivated += EnableFsWatcher;
  152. EditorWindowFocus.OnApplicationDeactivated += DisableFsWatcher;
  153. }
  154. static void UnRegisterExceptionHandlers()
  155. {
  156. AppDomain.CurrentDomain.UnhandledException -= HandleUnhandledException;
  157. Application.logMessageReceivedThreaded -= HandleLog;
  158. }
  159. static void UnRegisterApplicationFocusHandlers()
  160. {
  161. EditorWindowFocus.OnApplicationActivated -= EnableFsWatcher;
  162. EditorWindowFocus.OnApplicationDeactivated -= DisableFsWatcher;
  163. }
  164. static void RegisterAssemblyReloadHandlers()
  165. {
  166. AssemblyReloadEvents.beforeAssemblyReload += DisableFsWatcher;
  167. AssemblyReloadEvents.afterAssemblyReload += EnableFsWatcher;
  168. }
  169. static void UnRegisterAssemblyReloadHandlers()
  170. {
  171. AssemblyReloadEvents.beforeAssemblyReload -= DisableFsWatcher;
  172. AssemblyReloadEvents.afterAssemblyReload -= EnableFsWatcher;
  173. }
  174. static void HandleUnhandledException(object sender, UnhandledExceptionEventArgs args)
  175. {
  176. Exception ex = (Exception)args.ExceptionObject;
  177. if (IsExitGUIException(ex) ||
  178. !IsPlasticStackTrace(ex.StackTrace))
  179. throw ex;
  180. GUIActionRunner.RunGUIAction(delegate {
  181. ExceptionsHandler.HandleException("HandleUnhandledException", ex);
  182. });
  183. }
  184. static void HandleLog(string logString, string stackTrace, LogType type)
  185. {
  186. if (type != LogType.Exception)
  187. return;
  188. if (!IsPlasticStackTrace(stackTrace))
  189. return;
  190. GUIActionRunner.RunGUIAction(delegate {
  191. mLog.ErrorFormat("[HandleLog] Unexpected error: {0}", logString);
  192. mLog.DebugFormat("Stack trace: {0}", stackTrace);
  193. string message = logString;
  194. if (ExceptionsHandler.DumpStackTrace())
  195. message += Environment.NewLine + stackTrace;
  196. GuiMessage.ShowError(message);
  197. });
  198. }
  199. static void EnableFsWatcher()
  200. {
  201. MonoFileSystemWatcher.IsEnabled = true;
  202. }
  203. static void DisableFsWatcher()
  204. {
  205. MonoFileSystemWatcher.IsEnabled = false;
  206. }
  207. static void SetupFsWatcher()
  208. {
  209. if (!PlatformIdentifier.IsMac())
  210. return;
  211. WorkspaceWatcherFsNodeReadersCache.Get().SetMacFsWatcherBuilder(
  212. new MacFsWatcherBuilder());
  213. }
  214. static bool IsPlasticStackTrace(string stackTrace)
  215. {
  216. if (stackTrace == null)
  217. return false;
  218. string[] namespaces = new[] {
  219. "Codice.",
  220. "GluonGui.",
  221. "PlasticGui."
  222. };
  223. return namespaces.Any(stackTrace.Contains);
  224. }
  225. static bool IsExitGUIException(Exception ex)
  226. {
  227. return ex is ExitGUIException;
  228. }
  229. static bool mIsInitialized;
  230. static EventSenderScheduler sEventSenderScheduler;
  231. static PingEventLoop sPingEventLoop;
  232. static readonly ILog mLog = LogManager.GetLogger("PlasticApp");
  233. }
  234. }