Example #1
0
        private static void AdviseRefresh(EditorPluginModel model)
        {
            model.Refresh.Set((l, force) =>
            {
                var task = new RdTask <Unit>();
                ourLogger.Verbose("Refresh: SyncSolution Enqueue");
                MainThreadDispatcher.Instance.Queue(() =>
                {
                    if (!EditorApplication.isPlaying && EditorPrefsWrapper.AutoRefresh || force != RefreshType.Normal)
                    {
                        if (force == RefreshType.ForceRequestScriptReload)
                        {
                            ourLogger.Verbose("Refresh: RequestScriptReload");
                            UnityEditorInternal.InternalEditorUtility.RequestScriptReload();
                        }

                        ourLogger.Verbose("Refresh: SyncSolution Started");
                        UnityUtils.SyncSolution();
                        ourLogger.Verbose("Refresh: SyncSolution Completed");
                    }
                    else
                    {
                        ourLogger.Verbose("AutoRefresh is disabled via Unity settings.");
                    }
                    task.Set(Unit.Instance);
                });
                return(task);
            });
        }
        private static void CreateProtocolAndAdvise(Lifetime lifetime, List <ProtocolInstance> list, string solutionName)
        {
            try
            {
                var dispatcher = MainThreadDispatcher.Instance;
                var riderProtocolController = new RiderProtocolController(dispatcher, lifetime);
                list.Add(new ProtocolInstance(riderProtocolController.Wire.Port, solutionName));

#if !NET35
                var serializers = new Serializers(lifetime, null, null);
#else
                var serializers = new Serializers();
#endif
                var identities = new Identities(IdKind.Server);

                MainThreadDispatcher.AssertThread();
                var protocol = new Protocol("UnityEditorPlugin" + solutionName, serializers, identities, MainThreadDispatcher.Instance, riderProtocolController.Wire, lifetime);
                riderProtocolController.Wire.Connected.WhenTrue(lifetime, connectionLifetime =>
                {
                    ourLogger.Log(LoggingLevel.VERBOSE, "Create UnityModel and advise for new sessions...");
                    var model = new EditorPluginModel(connectionLifetime, protocol);
                    AdviseUnityActions(model, connectionLifetime);
                    AdviseEditorState(model);
                    OnModelInitialization(new UnityModelAndLifetime(model, connectionLifetime));
                    AdviseRefresh(model);
                    InitEditorLogPath(model);

                    model.UnityProcessId.SetValue(Process.GetCurrentProcess().Id);
                    model.UnityApplicationData.SetValue(new UnityApplicationData(
                                                            EditorApplication.applicationPath,
                                                            EditorApplication.applicationContentsPath, UnityUtils.UnityApplicationVersion));
                    model.ScriptingRuntime.SetValue(UnityUtils.ScriptingRuntime);

                    if (UnityUtils.UnityVersion >= new Version(2018, 2))
                    {
                        model.ScriptCompilationDuringPlay.Set(EditorPrefsWrapper.ScriptChangesDuringPlayOptions);
                    }
                    else
                    {
                        model.ScriptCompilationDuringPlay.Set((int)PluginSettings.AssemblyReloadSettings);
                    }

                    AdviseShowPreferences(model, connectionLifetime, ourLogger);
                    AdviseGenerateUISchema(model);
                    AdviseExitUnity(model);
                    GetBuildLocation(model);
                    AdviseRunMethod(model);
                    GetInitTime(model);

                    ourLogger.Verbose("UnityModel initialized.");
                    var pair = new ModelWithLifetime(model, connectionLifetime);
                    connectionLifetime.OnTermination(() => { UnityModels.Remove(pair); });
                    UnityModels.Add(pair);
                });
            }
            catch (Exception ex)
            {
                ourLogger.Error("Init Rider Plugin " + ex);
            }
        }
Example #3
0
        private static void AdviseUnityActions(EditorPluginModel model, Lifetime connectionLifetime)
        {
            var isPlayingAction = new Action(() =>
            {
                MainThreadDispatcher.Instance.Queue(() =>
                {
                    var isPlayOrWillChange = EditorApplication.isPlayingOrWillChangePlaymode;
                    var isPlaying          = isPlayOrWillChange && EditorApplication.isPlaying;
                    if (!model.Play.HasValue() || model.Play.HasValue() && model.Play.Value != isPlaying)
                    {
                        model.Play.SetValue(isPlaying);
                    }

                    var isPaused = EditorApplication.isPaused;
                    if (!model.Pause.HasValue() || model.Pause.HasValue() && model.Pause.Value != isPaused)
                    {
                        model.Pause.SetValue(isPaused);
                    }
                });
            });

            isPlayingAction(); // get Unity state
            model.Play.AdviseNotNull(connectionLifetime, play =>
            {
                MainThreadDispatcher.Instance.Queue(() =>
                {
                    var res = EditorApplication.isPlayingOrWillChangePlaymode && EditorApplication.isPlaying;
                    if (res != play)
                    {
                        EditorApplication.isPlaying = play;
                    }
                });
            });

            model.Pause.AdviseNotNull(connectionLifetime, pause =>
            {
                MainThreadDispatcher.Instance.Queue(() =>
                {
                    EditorApplication.isPaused = pause;
                });
            });

            model.Step.AdviseNotNull(connectionLifetime, x =>
            {
                MainThreadDispatcher.Instance.Queue(EditorApplication.Step);
            });

            var isPlayingHandler = new EditorApplication.CallbackFunction(() => isPlayingAction());

// left for compatibility with Unity <= 5.5
#pragma warning disable 618
            connectionLifetime.AddBracket(() => { EditorApplication.playmodeStateChanged += isPlayingHandler; },
                                          () => { EditorApplication.playmodeStateChanged -= isPlayingHandler; });
#pragma warning restore 618
            // new api - not present in Unity 5.5
            // private static Action<PauseState> IsPauseStateChanged(UnityModel model)
            //    {
            //      return state => model?.Pause.SetValue(state == PauseState.Paused);
            //    }
        }
Example #4
0
 private void SendLogEvent(EditorPluginModel model, RdLogEvent logEvent)
 {
     if (!myConnectionLifetime.IsTerminated)
     {
         model.Log.Fire(logEvent);
     }
 }
 private static void GetInitTime(EditorPluginModel model)
 {
     model.LastInitTime.SetValue(ourInitTime);
     if (EditorApplication.isPaused || EditorApplication.isPlaying)
     {
         model.LastPlayTime.SetValue(ourInitTime);
     }
 }
 private void SubscribeToLogs(Lifetime lifetime, EditorPluginModel model)
 {
     model.Log.Advise(lifetime, entry =>
     {
         myLogger.Verbose(entry.Time + " " + entry.Mode + " " + entry.Type + " " + entry.Message + " " + Environment.NewLine + " " + entry.StackTrace);
         myHost.SetModelData("UNITY_LogEntry", JsonConvert.SerializeObject(entry));
     });
 }
        private static void AdviseRunMethod(EditorPluginModel model)
        {
            model.RunMethodInUnity.Set((lifetime, data) =>
            {
                var task = new RdTask <RunMethodResult>();
                MainThreadDispatcher.Instance.Queue(() =>
                {
                    if (!lifetime.IsAlive)
                    {
                        task.SetCancelled();
                        return;
                    }

                    try
                    {
                        ourLogger.Verbose($"Attempt to execute {data.MethodName}");
                        var assemblies = AppDomain.CurrentDomain.GetAssemblies();
                        var assembly   = assemblies
                                         .FirstOrDefault(a => a.GetName().Name.Equals(data.AssemblyName));
                        if (assembly == null)
                        {
                            throw new Exception($"Could not find {data.AssemblyName} assembly in current AppDomain");
                        }

                        var type = assembly.GetType(data.TypeName);
                        if (type == null)
                        {
                            throw new Exception($"Could not find {data.TypeName} in assembly {data.AssemblyName}.");
                        }

                        var method = type.GetMethod(data.MethodName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);

                        if (method == null)
                        {
                            throw new Exception($"Could not find {data.MethodName} in type {data.TypeName}");
                        }

                        try
                        {
                            method.Invoke(null, null);
                        }
                        catch (Exception e)
                        {
                            Debug.LogException(e);
                        }

                        task.Set(new RunMethodResult(true, string.Empty, string.Empty));
                    }
                    catch (Exception e)
                    {
                        ourLogger.Log(LoggingLevel.WARN, $"Execute {data.MethodName} failed.", e);
                        task.Set(new RunMethodResult(false, e.Message, e.StackTrace));
                    }
                });
                return(task);
            });
        }
 private void SubscribeToLogs(Lifetime lifetime, EditorPluginModel editor)
 {
     editor.Log.Advise(lifetime, entry =>
     {
         myLogger.Verbose(entry.Time + " " + entry.Mode + " " + entry.Type + " " + entry.Message + " " + Environment.NewLine + " " + entry.StackTrace);
         var logEntry = new EditorLogEntry((int)entry.Type, (int)entry.Mode, entry.Time, entry.Message, entry.StackTrace);
         myHost.PerformModelAction(m => m.OnUnityLogEvent(logEntry));
     });
 }
 private void SendLogEvent(EditorPluginModel model, RdLogEvent logEvent)
 {
     MainThreadDispatcher.Instance.Queue(() =>
     {
         if (!myConnectionLifetime.IsTerminated)
         {
             model.Log.Fire(logEvent);
         }
     });
 }
Example #10
0
        private void RunInternal(IUnitTestRun firstRun, Lifetime connectionLifetime, EditorPluginModel unityModel, TaskCompletionSource <bool> tcs)
        {
            mySolution.Locks.AssertMainThread();

            var elementToIdMap   = new Dictionary <string, IUnitTestElement>();
            var unitTestElements = CollectElementsToRunInUnityEditor(firstRun);
            var allNames         = InitElementsMap(unitTestElements, elementToIdMap);
            var emptyList        = new List <string>();

            var launch = new UnitTestLaunch(allNames, emptyList, emptyList);

            launch.TestResult.Advise(connectionLifetime, result =>
            {
                var unitTestElement = GetElementById(result.TestId, elementToIdMap);
                if (unitTestElement == null)
                {
                    return;
                }

                switch (result.Status)
                {
                case Status.Pending:
                    myUnitTestResultManager.MarkPending(unitTestElement,
                                                        firstRun.Launch.Session);
                    break;

                case Status.Running:
                    myUnitTestResultManager.TestStarting(unitTestElement,
                                                         firstRun.Launch.Session);
                    break;

                case Status.Passed:
                case Status.Failed:
                    var taskResult = result.Status == Status.Failed ? TaskResult.Error : TaskResult.Success;
                    var message    = result.Status == Status.Failed ? "Failed" : "Passed";

                    myUnitTestResultManager.TestOutput(unitTestElement, firstRun.Launch.Session, result.Output, TaskOutputType.STDOUT);
                    myUnitTestResultManager.TestDuration(unitTestElement, firstRun.Launch.Session, TimeSpan.FromMilliseconds(result.Duration));
                    myUnitTestResultManager.TestFinishing(unitTestElement,
                                                          firstRun.Launch.Session, message, taskResult);
                    break;

                default:
                    throw new ArgumentOutOfRangeException(
                        $"Unknown test result from the protocol: {result.Status}");
                }
            });

            launch.RunResult.Advise(connectionLifetime, result =>
            {
                tcs.SetResult(true);
            });

            unityModel.UnitTestLaunch.Value = launch;
        }
        private static void InitEditorLogPath(EditorPluginModel editorPluginModel)
        {
            // https://docs.unity3d.com/Manual/LogFiles.html
            //PlayerSettings.productName;
            //PlayerSettings.companyName;
            //~/Library/Logs/Unity/Editor.log
            //C:\Users\username\AppData\Local\Unity\Editor\Editor.log
            //~/.config/unity3d/Editor.log

            string editorLogpath = string.Empty;
            string playerLogPath = string.Empty;

            switch (PluginSettings.SystemInfoRiderPlugin.operatingSystemFamily)
            {
            case OperatingSystemFamilyRider.Windows:
            {
                var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
                editorLogpath = Path.Combine(localAppData, @"Unity\Editor\Editor.log");
                var userProfile = Environment.GetEnvironmentVariable("USERPROFILE");
                if (!string.IsNullOrEmpty(userProfile))
                {
                    playerLogPath = Path.Combine(
                        Path.Combine(Path.Combine(Path.Combine(userProfile, @"AppData\LocalLow"), PlayerSettings.companyName),
                                     PlayerSettings.productName), "output_log.txt");
                }
                break;
            }

            case OperatingSystemFamilyRider.MacOSX:
            {
                var home = Environment.GetEnvironmentVariable("HOME");
                if (!string.IsNullOrEmpty(home))
                {
                    editorLogpath = Path.Combine(home, "Library/Logs/Unity/Editor.log");
                    playerLogPath = Path.Combine(home, "Library/Logs/Unity/Player.log");
                }
                break;
            }

            case OperatingSystemFamilyRider.Linux:
            {
                var home = Environment.GetEnvironmentVariable("HOME");
                if (!string.IsNullOrEmpty(home))
                {
                    editorLogpath = Path.Combine(home, ".config/unity3d/Editor.log");
                    playerLogPath = Path.Combine(home, $".config/unity3d/{PlayerSettings.companyName}/{PlayerSettings.productName}/Player.log");
                }
                break;
            }
            }

            editorPluginModel.EditorLogPath.SetValue(editorLogpath);
            editorPluginModel.PlayerLogPath.SetValue(playerLogPath);
        }
        private static void CreateProtocolAndAdvise(Lifetime lifetime, List <ProtocolInstance> list, string solutionFileName)
        {
            try
            {
                var dispatcher = MainThreadDispatcher.Instance;
                var riderProtocolController = new RiderProtocolController(dispatcher, lifetime);
                list.Add(new ProtocolInstance(riderProtocolController.Wire.Port, solutionFileName));

                var serializers = new Serializers();
                var identities  = new Identities(IdKind.Server);

                MainThreadDispatcher.AssertThread();

                riderProtocolController.Wire.Connected.WhenTrue(lifetime, connectionLifetime =>
                {
                    var protocol = new Protocol("UnityEditorPlugin", serializers, identities, MainThreadDispatcher.Instance, riderProtocolController.Wire);
                    ourLogger.Log(LoggingLevel.VERBOSE, "Create UnityModel and advise for new sessions...");
                    var model = new EditorPluginModel(connectionLifetime, protocol);
                    AdviseUnityActions(model, connectionLifetime);
                    AdviseEditorState(model);
                    OnModelInitialization(new UnityModelAndLifetime(model, connectionLifetime));
                    AdviseRefresh(model);
                    InitEditorLogPath(model);
                    AdviseScriptCompilationDuringPlay(model, connectionLifetime);

                    model.UnityProcessId.Set(Process.GetCurrentProcess().Id);
                    model.FullPluginPath.AdviseNotNull(connectionLifetime, AdditionalPluginsInstaller.UpdateSelf);
                    model.ApplicationPath.SetValue(EditorApplication.applicationPath);
                    model.ApplicationContentsPath.SetValue(EditorApplication.applicationContentsPath);
                    model.ApplicationVersion.SetValue(Application.unityVersion);
                    model.ScriptingRuntime.SetValue(UnityUtils.ScriptingRuntime);

                    if (UnityUtils.UnityVersion >= new Version(2018, 2) && EditorPrefsWrapper.ScriptChangesDuringPlayOptions == 0)
                    {
                        model.NotifyIsRecompileAndContinuePlaying.Fire("General");
                    }
                    else if (UnityUtils.UnityVersion < new Version(2018, 2) && PluginSettings.AssemblyReloadSettings == AssemblyReloadSettings.RecompileAndContinuePlaying)
                    {
                        model.NotifyIsRecompileAndContinuePlaying.Fire("Rider");
                    }

                    ourLogger.Verbose("UnityModel initialized.");
                    var pair = new ModelWithLifetime(model, connectionLifetime);
                    connectionLifetime.AddAction(() => { UnityModels.Remove(pair); });
                    UnityModels.Add(pair);
                    new UnityEventLogSender(ourLogEventCollector);
                });
            }
            catch (Exception ex)
            {
                ourLogger.Error("Init Rider Plugin " + ex);
            }
        }
Example #13
0
        private static void GetBuildLocation(EditorPluginModel model)
        {
            var path = EditorUserBuildSettings.GetBuildLocation(EditorUserBuildSettings.selectedStandaloneTarget);

            if (PluginSettings.SystemInfoRiderPlugin.operatingSystemFamily == OperatingSystemFamilyRider.MacOSX)
            {
                path = Path.Combine(Path.Combine(Path.Combine(path, "Contents"), "MacOS"), PlayerSettings.productName);
            }
            if (!string.IsNullOrEmpty(path) && File.Exists(path))
            {
                model.BuildLocation.Value = path;
            }
        }
        private static void AdviseShowPreferences(EditorPluginModel model, Lifetime connectionLifetime, ILog log)
        {
            model.ShowPreferences.Advise(connectionLifetime, result =>
            {
                if (result != null)
                {
                    MainThreadDispatcher.Instance.Queue(() =>
                    {
                        try
                        {
                            var tab = UnityUtils.UnityVersion >= new Version(2018, 2) ? "_General" : "Rider";

                            var type = typeof(SceneView).Assembly.GetType("UnityEditor.SettingsService");
                            if (type != null)
                            {
                                // 2018+
                                var method = type.GetMethod("OpenUserPreferences", BindingFlags.Static | BindingFlags.Public);

                                if (method == null)
                                {
                                    log.Error("'OpenUserPreferences' was not found");
                                }
                                else
                                {
                                    method.Invoke(null, new object[] { $"Preferences/{tab}" });
                                }
                            }
                            else
                            {
                                // 5.5, 2017 ...
                                type       = typeof(SceneView).Assembly.GetType("UnityEditor.PreferencesWindow");
                                var method = type?.GetMethod("ShowPreferencesWindow", BindingFlags.Static | BindingFlags.NonPublic);

                                if (method == null)
                                {
                                    log.Error("'ShowPreferencesWindow' was not found");
                                }
                                else
                                {
                                    method.Invoke(null, null);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            log.Error("Show preferences " + ex);
                        }
                    });
                }
            });
        }
        private static void AdviseRefresh(EditorPluginModel model)
        {
            model.Refresh.Set((l, force) =>
            {
                var refreshTask = new RdTask <Unit>();
                void SendResult()
                {
                    if (!EditorApplication.isCompiling)
                    {
                        // ReSharper disable once DelegateSubtraction
                        EditorApplication.update -= SendResult;
                        ourLogger.Verbose("Refresh: SyncSolution Completed");
                        refreshTask.Set(Unit.Instance);
                    }
                }

                ourLogger.Verbose("Refresh: SyncSolution Enqueue");
                MainThreadDispatcher.Instance.Queue(() =>
                {
                    if (!EditorApplication.isPlaying && EditorPrefsWrapper.AutoRefresh || force != RefreshType.Normal)
                    {
                        try
                        {
                            if (force == RefreshType.ForceRequestScriptReload)
                            {
                                ourLogger.Verbose("Refresh: RequestScriptReload");
                                UnityEditorInternal.InternalEditorUtility.RequestScriptReload();
                            }

                            ourLogger.Verbose("Refresh: SyncSolution Started");
                            UnityUtils.SyncSolution();
                        }
                        catch (Exception e)
                        {
                            ourLogger.Error("Refresh failed with exception", e);
                        }
                        finally
                        {
                            EditorApplication.update += SendResult;
                        }
                    }
                    else
                    {
                        refreshTask.Set(Unit.Instance);
                        ourLogger.Verbose("AutoRefresh is disabled via Unity settings.");
                    }
                });
                return(refreshTask);
            });
        }
        private void SubscribeToOpenFile([NotNull] EditorPluginModel editor)
        {
            editor.OpenFileLineCol.Set(args =>
            {
                var result = false;
                mySolution.Locks.ExecuteWithReadLock(() =>
                {
                    mySolution.GetComponent <IEditorManager>()
                    .OpenFile(FileSystemPath.Parse(args.Path), OpenFileOptions.DefaultActivate, myThreading,
                              textControl =>
                    {
                        var line   = args.Line;
                        var column = args.Col;

                        if (line > 0 || column > 0)         // avoid changing placement when it is not requested
                        {
                            if (line > 0)
                            {
                                line = line - 1;
                            }
                            if (line < 0)
                            {
                                line = 0;
                            }
                            if (column > 0)
                            {
                                column = column - 1;
                            }
                            if (column < 0)
                            {
                                column = 0;
                            }
                            textControl.Caret.MoveTo((Int32 <DocLine>)line,
                                                     (Int32 <DocColumn>)column,
                                                     CaretVisualPlacement.Generic);
                        }

                        myHost.PerformModelAction(m =>
                        {
                            m.ActivateRider();
                            result = true;
                        });
                    },
                              () => { result = false; });
                });

                return(result);
            });
        }
Example #17
0
        private void BindPluginPathToSettings(Lifetime lf, EditorPluginModel editor)
        {
            var entry = myBoundSettingsStore.Schema.GetScalarEntry((UnitySettings s) => s.InstallUnity3DRiderPlugin);

            myBoundSettingsStore.GetValueProperty <bool>(lf, entry, null).Change.Advise(lf,
                                                                                        val =>
            {
                if (val.HasNew && val.New)
                {
                    editor.FullPluginPath.SetValue(myPluginPathsProvider.GetEditorPluginPathDir()
                                                   .Combine(PluginPathsProvider.FullPluginDllFile).FullPath);
                }
                editor.FullPluginPath.SetValue(string.Empty);
            });
        }
Example #18
0
 private static void AdviseScriptCompilationDuringPlay(EditorPluginModel model, Lifetime lifetime)
 {
     model.SetScriptCompilationDuringPlay.Advise(lifetime,
                                                 scriptCompilationDuringPlay =>
     {
         if (UnityUtils.UnityVersion >= new Version(2018, 2))
         {
             EditorPrefsWrapper.ScriptChangesDuringPlayOptions = scriptCompilationDuringPlay;
         }
         else
         {
             PluginSettings.AssemblyReloadSettings = (AssemblyReloadSettings)scriptCompilationDuringPlay;
         }
     });
 }
Example #19
0
        private static void AdviseEditorState(EditorPluginModel modelValue)
        {
            modelValue.GetUnityEditorState.Set(rdVoid =>
            {
                if (EditorApplication.isPlaying)
                {
                    return(UnityEditorState.Play);
                }

                if (EditorApplication.isCompiling || EditorApplication.isUpdating)
                {
                    return(UnityEditorState.Refresh);
                }

                return(UnityEditorState.Idle);
            });
        }
        public static void Init(UnityModelAndLifetime modelAndLifetime)
        {
            ourModel = modelAndLifetime.Model;

            void OnCompilationFinished(string assemblyPath, CompilerMessage[] messages)
            {
                if (!ourCompiledAssemblyPaths.Contains(assemblyPath))
                {
                    UpdateAssemblies();
                }
            }

            modelAndLifetime.Lifetime.Bracket(
                () => CompilationPipeline.assemblyCompilationFinished += OnCompilationFinished,
                () => CompilationPipeline.assemblyCompilationFinished -= OnCompilationFinished);

            UpdateAssemblies();
        }
Example #21
0
 private void TrackActivity(EditorPluginModel editor, Lifetime lf)
 {
     if (!editor.ApplicationVersion.HasValue())
     {
         editor.ApplicationVersion.AdviseNotNull(lf, version => { myUsageStatistics.TrackActivity("UnityVersion", version); });
     }
     else
     {
         myUsageStatistics.TrackActivity("UnityVersion", editor.ApplicationVersion.Value);
     }
     if (!editor.ScriptingRuntime.HasValue())
     {
         editor.ScriptingRuntime.AdviseNotNull(lf, runtime => { myUsageStatistics.TrackActivity("ScriptingRuntime", runtime.ToString()); });
     }
     else
     {
         myUsageStatistics.TrackActivity("ScriptingRuntime", editor.ScriptingRuntime.Value.ToString());
     }
 }
Example #22
0
 private static void AdviseRefresh(EditorPluginModel model)
 {
     model.Refresh.Set((l, force) =>
     {
         var task = new RdTask <RdVoid>();
         MainThreadDispatcher.Instance.Queue(() =>
         {
             if (!EditorApplication.isPlaying && EditorPrefsWrapper.AutoRefresh || force)
             {
                 UnityUtils.SyncSolution();
             }
             else
             {
                 ourLogger.Verbose("AutoRefresh is disabled via Unity settings.");
             }
             task.Set(RdVoid.Instance);
         });
         return(task);
     });
 }
Example #23
0
        private static void CreateProtocolAndAdvise(Lifetime lifetime, List <ProtocolInstance> list, string solutionFileName)
        {
            try
            {
                var riderProtocolController = new RiderProtocolController(MainThreadDispatcher.Instance, lifetime);
                list.Add(new ProtocolInstance(riderProtocolController.Wire.Port, solutionFileName));

                var serializers = new Serializers();
                var identities  = new Identities(IdKind.Server);

                MainThreadDispatcher.AssertThread();

                riderProtocolController.Wire.Connected.WhenTrue(lifetime, connectionLifetime =>
                {
                    var protocol = new Protocol("UnityEditorPlugin", serializers, identities, MainThreadDispatcher.Instance, riderProtocolController.Wire);
                    ourLogger.Log(LoggingLevel.VERBOSE, "Create UnityModel and advise for new sessions...");
                    var model = new EditorPluginModel(connectionLifetime, protocol);
                    AdviseUnityActions(model, connectionLifetime);
                    AdviseEditorState(model);
                    OnModelInitialization(new UnityModelAndLifetime(model, connectionLifetime));
                    AdviseRefresh(model);
                    InitEditorLogPath(model);

                    model.FullPluginPath.AdviseNotNull(connectionLifetime, AdditionalPluginsInstaller.UpdateSelf);
                    model.ApplicationPath.SetValue(EditorApplication.applicationPath);
                    model.ApplicationContentsPath.SetValue(EditorApplication.applicationContentsPath);
                    model.ApplicationVersion.SetValue(Application.unityVersion);
                    model.ScriptingRuntime.SetValue(UnityUtils.ScriptingRuntime);

                    ourLogger.Verbose("UnityModel initialized.");
                    var pair = new ModelWithLifetime(model, connectionLifetime);
                    connectionLifetime.AddAction(() => { UnityModels.Remove(pair); });
                    UnityModels.Add(pair);
                    new UnityEventLogSender(ourLogEventCollector);
                });
            }
            catch (Exception ex)
            {
                ourLogger.Error("Init Rider Plugin " + ex);
            }
        }
        internal static bool CheckConnectedToBackendSync(EditorPluginModel model)
        {
            if (model == null)
            {
                return(false);
            }
            var connected = false;

            try
            {
                // HostConnected also means that in Rider and in Unity the same solution is opened
                connected = model.IsBackendConnected.Sync(Unit.Instance,
                                                          new RpcTimeouts(TimeSpan.FromMilliseconds(200), TimeSpan.FromMilliseconds(200)));
            }
            catch (Exception)
            {
                ourLogger.Verbose("Rider Protocol not connected.");
            }

            return(connected);
        }
        private void ProcessQueue(EditorPluginModel model, UnityEventCollector collector)
        {
            if (!collector.myDelayedLogEvents.Any())
            {
                return;
            }

            var head = collector.myDelayedLogEvents.First;

            while (head != null)
            {
                if (myConnectionLifetime.IsTerminated)
                {
                    return;
                }

                SendLogEvent(model, head.Value);
                head = head.Next;
            }

            collector.myDelayedLogEvents.Clear();
        }
Example #26
0
        private void SubscribeToOpenFile([NotNull] EditorPluginModel editor)
        {
            editor.OpenFileLineCol.Set(args =>
            {
                using (ReadLockCookie.Create())
                {
                    var textControl = mySolution.GetComponent <IEditorManager>()
                                      .OpenFile(FileSystemPath.Parse(args.Path), OpenFileOptions.DefaultActivate);
                    if (textControl == null)
                    {
                        return(false);
                    }
                    if (args.Line > 0 || args.Col > 0)
                    {
                        textControl.Caret.MoveTo((Int32 <DocLine>)(args.Line - 1), (Int32 <DocColumn>)args.Col,
                                                 CaretVisualPlacement.Generic);
                    }
                }

                myHost.PerformModelAction(m => m.ActivateRider.Fire());
                return(true);
            });
        }
Example #27
0
 private static void AdviseExitUnity(EditorPluginModel model)
 {
     model.ExitUnity.Set((_, rdVoid) =>
     {
         var task = new RdTask <bool>();
         MainThreadDispatcher.Instance.Queue(() =>
         {
             try
             {
                 ourLogger.Verbose("ExitUnity: Started");
                 EditorApplication.Exit(0);
                 ourLogger.Verbose("ExitUnity: Completed");
                 task.Set(true);
             }
             catch (Exception e)
             {
                 ourLogger.Log(LoggingLevel.WARN, "EditorApplication.Exit failed.", e);
                 task.Set(false);
             }
         });
         return(task);
     });
 }
 public UnityModelAndLifetime(EditorPluginModel model, Lifetime lifetime)
 {
     Model    = model;
     Lifetime = lifetime;
 }
        private static void AdviseUnityActions(EditorPluginModel model, Lifetime connectionLifetime)
        {
            var syncPlayState = new Action(() =>
            {
                MainThreadDispatcher.Instance.Queue(() =>
                {
                    var isPlaying = EditorApplication.isPlayingOrWillChangePlaymode && EditorApplication.isPlaying;

                    if (!model.Play.HasValue() || model.Play.HasValue() && model.Play.Value != isPlaying)
                    {
                        ourLogger.Verbose("Reporting play mode change to model: {0}", isPlaying);
                        model.Play.SetValue(isPlaying);
                        if (isPlaying)
                        {
                            model.ClearOnPlay(DateTime.UtcNow.Ticks);
                        }
                    }

                    var isPaused = EditorApplication.isPaused;
                    if (!model.Pause.HasValue() || model.Pause.HasValue() && model.Pause.Value != isPaused)
                    {
                        ourLogger.Verbose("Reporting pause mode change to model: {0}", isPaused);
                        model.Pause.SetValue(isPaused);
                    }
                });
            });

            syncPlayState();

            model.Play.Advise(connectionLifetime, play =>
            {
                MainThreadDispatcher.Instance.Queue(() =>
                {
                    var current = EditorApplication.isPlayingOrWillChangePlaymode && EditorApplication.isPlaying;
                    if (current != play)
                    {
                        ourLogger.Verbose("Request to change play mode from model: {0}", play);
                        EditorApplication.isPlaying = play;
                    }
                });
            });

            model.Pause.Advise(connectionLifetime, pause =>
            {
                MainThreadDispatcher.Instance.Queue(() =>
                {
                    ourLogger.Verbose("Request to change pause mode from model: {0}", pause);
                    EditorApplication.isPaused = pause;
                });
            });

            model.Step.Advise(connectionLifetime, x =>
            {
                MainThreadDispatcher.Instance.Queue(EditorApplication.Step);
            });

            var onPlaymodeStateChanged = new EditorApplication.CallbackFunction(() => syncPlayState());

// left for compatibility with Unity <= 5.5
#pragma warning disable 618
            connectionLifetime.AddBracket(() => { EditorApplication.playmodeStateChanged += onPlaymodeStateChanged; },
                                          () => { EditorApplication.playmodeStateChanged -= onPlaymodeStateChanged; });
#pragma warning restore 618
            // new api - not present in Unity 5.5
            // private static Action<PauseState> IsPauseStateChanged(UnityModel model)
            //    {
            //      return state => model?.Pause.SetValue(state == PauseState.Paused);
            //    }
        }
 private static void AdviseGenerateUISchema(EditorPluginModel model)
 {
     model.GenerateUIElementsSchema.Set(_ => UIElementsSupport.GenerateSchema());
 }