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); } }
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); // } }
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); } }); }
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); } }
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); }); }
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); }); }
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; } }); }
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(); }
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()); } }
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); }); }
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(); }
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); }); }
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()); }