|
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
|
|
|
|
using UnityEditor;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
using Codice.Client.BaseCommands;
|
|
|
|
|
using Codice.Client.BaseCommands.EventTracking;
|
|
|
|
|
using Codice.Client.Common;
|
|
|
|
|
using Codice.Client.Common.Connection;
|
|
|
|
|
using Codice.Client.Common.Encryption;
|
|
|
|
|
using Codice.Client.Common.EventTracking;
|
|
|
|
|
using Codice.Client.Common.FsNodeReaders;
|
|
|
|
|
using Codice.Client.Common.FsNodeReaders.Watcher;
|
|
|
|
|
using Codice.Client.Common.Threading;
|
|
|
|
|
using Codice.CM.Common;
|
|
|
|
|
using Codice.CM.ConfigureHelper;
|
|
|
|
|
using Codice.LogWrapper;
|
|
|
|
|
using Codice.Utils;
|
|
|
|
|
using CodiceApp.EventTracking;
|
|
|
|
|
using MacUI;
|
|
|
|
|
using PlasticGui;
|
|
|
|
|
using PlasticGui.EventTracking;
|
|
|
|
|
using PlasticGui.WebApi;
|
|
|
|
|
using PlasticPipe.Certificates;
|
|
|
|
|
using Unity.PlasticSCM.Editor.AssetUtils;
|
|
|
|
|
using Unity.PlasticSCM.Editor.Configuration;
|
|
|
|
|
using Unity.PlasticSCM.Editor.UI;
|
|
|
|
|
|
|
|
|
|
namespace Unity.PlasticSCM.Editor
|
|
|
|
|
{
|
|
|
|
|
internal static class PlasticApp
|
|
|
|
|
{
|
|
|
|
|
internal static void InitializeIfNeeded()
|
|
|
|
|
{
|
|
|
|
|
if (mIsInitialized)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
mIsInitialized = true;
|
|
|
|
|
|
|
|
|
|
ConfigureLogging();
|
|
|
|
|
|
|
|
|
|
if (!PlasticPlugin.IsUnitTesting)
|
|
|
|
|
GuiMessage.Initialize(new UnityPlasticGuiMessage());
|
|
|
|
|
|
|
|
|
|
RegisterExceptionHandlers();
|
|
|
|
|
|
|
|
|
|
InitLocalization();
|
|
|
|
|
|
|
|
|
|
if (!PlasticPlugin.IsUnitTesting)
|
|
|
|
|
ThreadWaiter.Initialize(new UnityThreadWaiterBuilder());
|
|
|
|
|
|
|
|
|
|
ServicePointConfigurator.ConfigureServicePoint();
|
|
|
|
|
CertificateUi.RegisterHandler(new ChannelCertificateUiImpl());
|
|
|
|
|
|
|
|
|
|
SetupFsWatcher();
|
|
|
|
|
|
|
|
|
|
EditionManager.Get().DisableCapability(
|
|
|
|
|
EnumEditionCapabilities.Extensions);
|
|
|
|
|
|
|
|
|
|
ClientHandlers.Register();
|
|
|
|
|
|
|
|
|
|
PlasticGuiConfig.SetConfigFile(
|
|
|
|
|
PlasticGuiConfig.UNITY_GUI_CONFIG_FILE);
|
|
|
|
|
|
|
|
|
|
if (!PlasticPlugin.IsUnitTesting)
|
|
|
|
|
{
|
|
|
|
|
sEventSenderScheduler = EventTracking.Configure(
|
|
|
|
|
(PlasticWebRestApi)PlasticGui.Plastic.WebRestAPI,
|
|
|
|
|
ApplicationIdentifier.UnityPackage,
|
|
|
|
|
IdentifyEventPlatform.Get());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sEventSenderScheduler != null)
|
|
|
|
|
{
|
|
|
|
|
sPingEventLoop = new PingEventLoop();
|
|
|
|
|
sPingEventLoop.Start();
|
|
|
|
|
sPingEventLoop.SetUnityVersion(Application.unityVersion);
|
|
|
|
|
|
|
|
|
|
CollabPlugin.GetVersion(pluginVersion => sPingEventLoop.SetPluginVersion(pluginVersion));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PlasticMethodExceptionHandling.InitializeAskCredentialsUi(
|
|
|
|
|
new CredentialsUiImpl());
|
|
|
|
|
ClientEncryptionServiceProvider.SetEncryptionPasswordProvider(
|
|
|
|
|
new MissingEncryptionPasswordPromptHandler());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static void SetWorkspace(WorkspaceInfo wkInfo)
|
|
|
|
|
{
|
|
|
|
|
RegisterApplicationFocusHandlers();
|
|
|
|
|
RegisterAssemblyReloadHandlers();
|
|
|
|
|
|
|
|
|
|
if (sEventSenderScheduler == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
sPingEventLoop.SetWorkspace(wkInfo);
|
|
|
|
|
PlasticGui.Plastic.WebRestAPI.SetToken(
|
|
|
|
|
CmConnection.Get().BuildWebApiTokenForCloudEditionDefaultUser());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static void Dispose()
|
|
|
|
|
{
|
|
|
|
|
mIsInitialized = false;
|
|
|
|
|
|
|
|
|
|
UnRegisterExceptionHandlers();
|
|
|
|
|
|
|
|
|
|
UnRegisterApplicationFocusHandlers();
|
|
|
|
|
UnRegisterAssemblyReloadHandlers();
|
|
|
|
|
|
|
|
|
|
if (sEventSenderScheduler != null)
|
|
|
|
|
{
|
|
|
|
|
sPingEventLoop.Stop();
|
|
|
|
|
// Launching and forgetting to avoid a timeout when sending events files and no
|
|
|
|
|
// network connection is available.
|
|
|
|
|
// This will be refactored once a better mechanism to send event is in place
|
|
|
|
|
sEventSenderScheduler.EndAndSendEventsAsync();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WorkspaceInfo wkInfo = FindWorkspace.InfoForApplicationPath(
|
|
|
|
|
ApplicationDataPath.Get(), PlasticGui.Plastic.API);
|
|
|
|
|
|
|
|
|
|
if (wkInfo == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
WorkspaceFsNodeReaderCachesCleaner.CleanWorkspaceFsNodeReader(wkInfo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void InitLocalization()
|
|
|
|
|
{
|
|
|
|
|
string language = null;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
language = ClientConfig.Get().GetLanguage();
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
language = string.Empty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Localization.Init(language);
|
|
|
|
|
PlasticLocalization.SetLanguage(language);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void ConfigureLogging()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
string log4netpath = ToolConfig.GetUnityPlasticLogConfigFile();
|
|
|
|
|
|
|
|
|
|
if (!File.Exists(log4netpath))
|
|
|
|
|
WriteLogConfiguration.For(log4netpath);
|
|
|
|
|
|
|
|
|
|
XmlConfigurator.Configure(new FileInfo(log4netpath));
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
//it failed configuring the logging info; nothing to do.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void RegisterExceptionHandlers()
|
|
|
|
|
{
|
|
|
|
|
AppDomain.CurrentDomain.UnhandledException += HandleUnhandledException;
|
|
|
|
|
|
|
|
|
|
Application.logMessageReceivedThreaded += HandleLog;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void RegisterApplicationFocusHandlers()
|
|
|
|
|
{
|
|
|
|
|
EditorWindowFocus.OnApplicationActivated += EnableFsWatcher;
|
|
|
|
|
|
|
|
|
|
EditorWindowFocus.OnApplicationDeactivated += DisableFsWatcher;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void UnRegisterExceptionHandlers()
|
|
|
|
|
{
|
|
|
|
|
AppDomain.CurrentDomain.UnhandledException -= HandleUnhandledException;
|
|
|
|
|
|
|
|
|
|
Application.logMessageReceivedThreaded -= HandleLog;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void UnRegisterApplicationFocusHandlers()
|
|
|
|
|
{
|
|
|
|
|
EditorWindowFocus.OnApplicationActivated -= EnableFsWatcher;
|
|
|
|
|
|
|
|
|
|
EditorWindowFocus.OnApplicationDeactivated -= DisableFsWatcher;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void RegisterAssemblyReloadHandlers()
|
|
|
|
|
{
|
|
|
|
|
AssemblyReloadEvents.beforeAssemblyReload += DisableFsWatcher;
|
|
|
|
|
AssemblyReloadEvents.afterAssemblyReload += EnableFsWatcher;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void UnRegisterAssemblyReloadHandlers()
|
|
|
|
|
{
|
|
|
|
|
AssemblyReloadEvents.beforeAssemblyReload -= DisableFsWatcher;
|
|
|
|
|
AssemblyReloadEvents.afterAssemblyReload -= EnableFsWatcher;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void HandleUnhandledException(object sender, UnhandledExceptionEventArgs args)
|
|
|
|
|
{
|
|
|
|
|
Exception ex = (Exception)args.ExceptionObject;
|
|
|
|
|
|
|
|
|
|
if (IsExitGUIException(ex) ||
|
|
|
|
|
!IsPlasticStackTrace(ex.StackTrace))
|
|
|
|
|
throw ex;
|
|
|
|
|
|
|
|
|
|
GUIActionRunner.RunGUIAction(delegate {
|
|
|
|
|
ExceptionsHandler.HandleException("HandleUnhandledException", ex);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void HandleLog(string logString, string stackTrace, LogType type)
|
|
|
|
|
{
|
|
|
|
|
if (type != LogType.Exception)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!IsPlasticStackTrace(stackTrace))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
GUIActionRunner.RunGUIAction(delegate {
|
|
|
|
|
mLog.ErrorFormat("[HandleLog] Unexpected error: {0}", logString);
|
|
|
|
|
mLog.DebugFormat("Stack trace: {0}", stackTrace);
|
|
|
|
|
|
|
|
|
|
string message = logString;
|
|
|
|
|
if (ExceptionsHandler.DumpStackTrace())
|
|
|
|
|
message += Environment.NewLine + stackTrace;
|
|
|
|
|
|
|
|
|
|
GuiMessage.ShowError(message);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void EnableFsWatcher()
|
|
|
|
|
{
|
|
|
|
|
MonoFileSystemWatcher.IsEnabled = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void DisableFsWatcher()
|
|
|
|
|
{
|
|
|
|
|
MonoFileSystemWatcher.IsEnabled = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void SetupFsWatcher()
|
|
|
|
|
{
|
|
|
|
|
if (!PlatformIdentifier.IsMac())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
WorkspaceWatcherFsNodeReadersCache.Get().SetMacFsWatcherBuilder(
|
|
|
|
|
new MacFsWatcherBuilder());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool IsPlasticStackTrace(string stackTrace)
|
|
|
|
|
{
|
|
|
|
|
if (stackTrace == null)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
string[] namespaces = new[] {
|
|
|
|
|
"Codice.",
|
|
|
|
|
"GluonGui.",
|
|
|
|
|
"PlasticGui."
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return namespaces.Any(stackTrace.Contains);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool IsExitGUIException(Exception ex)
|
|
|
|
|
{
|
|
|
|
|
return ex is ExitGUIException;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool mIsInitialized;
|
|
|
|
|
|
|
|
|
|
static EventSenderScheduler sEventSenderScheduler;
|
|
|
|
|
static PingEventLoop sPingEventLoop;
|
|
|
|
|
|
|
|
|
|
static readonly ILog mLog = LogManager.GetLogger("PlasticApp");
|
|
|
|
|
}
|
|
|
|
|
}
|