public void NavigateToIssue(string id) { var url = store.GetValueProperty <ReTrackSettingsReSharper, string>(lifetime, x => x.YouTrackUrl); string path = string.Format("{0}/issue/{1}", url.Value, id); IVsWindowFrame _; if (wbs != null) { wbs.Navigate(path, 0, out _); } }
public LtgConfigWatcher(Lifetime lifetime, ISettingsStore settingsStore) { _boundSettings = settingsStore.BindToContextLive(lifetime, ContextRange.ApplicationWide); _filepath = _boundSettings.GetValueProperty <string>(lifetime, _boundSettings.Schema.GetScalarEntry((ZenSharpSettings s) => s.TreeFilename), null); _filepath.Change.Advise_HasNew(lifetime, v => Initialize(v.New)); }
private void BindToInstallationSettingChange() { var entry = myBoundSettingsStore.Schema.GetScalarEntry((UnrealLinkSettings s) => s.InstallRiderLinkPlugin); myBoundSettingsStore.GetValueProperty <bool>(Lifetime, entry, null).Change.Advise_When(Lifetime, newValue => newValue, args => { InstallPluginIfInfoAvailable(); }); }
private void OnOutOfSync(Lifetime lifetime) { if (myPluginInstallations.Contains(mySolution.SolutionFilePath)) { return; } // avoid displaying Notification multiple times on each AppDomain.Reload in Unity myPluginInstallations.Add(mySolution.SolutionFilePath); var appVersion = myUnityVersion.ActualVersionForSolution.Value; if (appVersion < new Version(2019, 2)) { var entry = myBoundSettingsStore.Schema.GetScalarEntry((UnitySettings s) => s.InstallUnity3DRiderPlugin); var isEnabled = myBoundSettingsStore.GetValueProperty <bool>(lifetime, entry, null).Value; if (!isEnabled) { myFrontendBackendHost.Do(model => model.OnEditorModelOutOfSync()); } } else { var notification = new NotificationModel("Advanced Unity integration is unavailable", $"Make sure Rider {myHostProductInfo.VersionMarketingString} is set as the External Editor in Unity preferences.", true, RdNotificationEntryType.WARN, new List <NotificationHyperlink>()); mySolution.Locks.ExecuteOrQueue(lifetime, "OutOfSyncModels.Notify", () => myNotificationsModel.Notification(notification)); } }
private void BindToInstallationSettingChange() { var entry = myBoundSettingsStore.Schema.GetScalarEntry((UnrealLinkSettings s) => s.InstallRiderLinkPlugin); myBoundSettingsStore.GetValueProperty <bool>(myLifetime, entry, null).Change.Advise_When(myLifetime, newValue => newValue, args => { myShellLocks.ExecuteOrQueueReadLockEx(myLifetime, "UnrealPluginInstaller.CheckAllProjectsIfAutoInstallEnabled", InstallPluginIfInfoAvailable); }); }
public void OnSolutionLoaded(UnityProjectsCollection solution) { var entry = myBoundStore.Schema.GetScalarEntry((UnitySettings s) => s.EnableShaderLabHippieCompletion); myBoundStore.GetValueProperty <bool>(myLifetime, entry, null).Change.Advise(myLifetime, pcea => { if (pcea.HasNew) { myHost.SetModelData("UNITY_SETTINGS_EnableShaderLabHippieCompletion", pcea.New.ToString()); } }); }
private void BindToInstallationSettingChange() { var entry = myBoundSettingsStore.Schema.GetScalarEntry((UnitySettings s) => s.InstallUnity3DRiderPlugin); myBoundSettingsStore.GetValueProperty <bool>(myLifetime, entry, null).Change.Advise_NoAcknowledgement(myLifetime, args => { if (!args.GetNewOrNull()) { return; } myShellLocks.ExecuteOrQueueReadLockEx(myLifetime, "UnityPluginInstaller.CheckAllProjectsIfAutoInstallEnabled", InstallPluginIfRequired); }); }
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); }); }
public void OnSolutionLoaded(UnityProjectsCollection solution) { var entry = myBoundStore.Schema.GetScalarEntry((UnitySettings s) => s.EnableShaderLabHippieCompletion); myBoundStore.GetValueProperty <bool>(myLifetime, entry, null).Change.Advise(myLifetime, pcea => { if (pcea.HasNew) { if (mySolutionModel.HasCurrentSolution()) // in tests we don't have one { mySolutionModel.GetCurrentSolution() .CustomData .Data["UNITY_SETTINGS_EnableShaderLabHippieCompletion"] = pcea.New.ToString(); } } }); }
private static void BindSettingToProperty <TKeyClass, TEntryMemberType>( Lifetime lifetime, ISolution solution, FrontendBackendHost frontendBackendHost, IContextBoundSettingsStoreLive boundStore, Expression <Func <TKeyClass, TEntryMemberType> > entry, Action <FrontendBackendModel, PropertyChangedEventArgs <TEntryMemberType> > action) { var name = entry.GetInstanceMemberName(); var setting = boundStore.Schema.GetScalarEntry(entry); boundStore.GetValueProperty <TEntryMemberType>(lifetime, setting, null).Change.Advise_HasNew(lifetime, args => { solution.Locks.ExecuteOrQueueEx(lifetime, name, () => { frontendBackendHost.Do(m => action(m, args)); }); }); }
private void CreateProtocols(FileSystemPath protocolInstancePath) { if (!protocolInstancePath.ExistsFile) { return; } List <ProtocolInstance> protocolInstanceList; try { protocolInstanceList = ProtocolInstance.FromJson(protocolInstancePath.ReadAllText2().Text); } catch (Exception e) { myLogger.Warn($"Unable to parse {protocolInstancePath}" + Environment.NewLine + e); return; } var protocolInstance = protocolInstanceList?.SingleOrDefault(a => a.SolutionName == mySolution.SolutionFilePath.NameWithoutExtension); if (protocolInstance == null) { return; } myLogger.Info($"EditorPlugin protocol port {protocolInstance.Port} for Solution: {protocolInstance.SolutionName}."); try { var lifetime = mySessionLifetimes.Next(); myLogger.Info("Create protocol..."); myLogger.Info("Creating SocketWire with port = {0}", protocolInstance.Port); var wire = new SocketWire.Client(lifetime, myDispatcher, protocolInstance.Port, "UnityClient"); var protocol = new Protocol("UnityEditorPlugin", new Serializers(), new Identities(IdKind.Client), myDispatcher, wire, lifetime); protocol.ThrowErrorOnOutOfSyncModels = false; protocol.OutOfSyncModels.AdviseOnce(lifetime, e => { if (myPluginInstallations.Contains(mySolution.SolutionFilePath)) { return; } myPluginInstallations.Add(mySolution.SolutionFilePath); // avoid displaying Notification multiple times on each AppDomain.Reload in Unity var appVersion = myUnityVersion.GetActualVersionForSolution(); if (appVersion < new Version(2019, 2)) { var entry = myBoundSettingsStore.Schema.GetScalarEntry((UnitySettings s) => s.InstallUnity3DRiderPlugin); var isEnabled = myBoundSettingsStore.GetValueProperty <bool>(lifetime, entry, null).Value; if (!isEnabled) { myHost.PerformModelAction(model => model.OnEditorModelOutOfSync()); } } else { var notification = new NotificationModel("Advanced Unity integration is unavailable", $"Please update External Editor to {myHostProductInfo.VersionMarketingString} in Unity Preferences.", true, RdNotificationEntryType.WARN); mySolution.Locks.ExecuteOrQueue(lifetime, "OutOfSyncModels.Notify", () => myNotificationsModel.Notification(notification)); } }); wire.Connected.WhenTrue(lifetime, lf => { myLogger.Info("WireConnected."); var editor = new EditorPluginModel(lf, protocol); editor.IsBackendConnected.Set(rdVoid => true); if (PlatformUtil.RuntimePlatform == PlatformUtil.Platform.Windows) { var frontendProcess = Process.GetCurrentProcess().GetParent(); // RiderProcessId is not used on non-Windows, but this line gives bad warning in the log if (frontendProcess != null) { editor.RiderProcessId.SetValue(frontendProcess.Id); } } myHost.PerformModelAction(m => m.SessionInitialized.Value = true); SubscribeToLogs(lf, editor); SubscribeToOpenFile(editor); editor.Play.Advise(lf, b => myHost.PerformModelAction(rd => rd.Play.SetValue(b))); editor.Pause.Advise(lf, b => myHost.PerformModelAction(rd => rd.Pause.SetValue(b))); editor.ClearOnPlay.Advise(lf, time => myHost.PerformModelAction(rd => rd.ClearOnPlay(time))); editor.UnityProcessId.View(lf, (_, pid) => myHost.PerformModelAction(t => t.UnityProcessId.Set(pid))); // I have split this into groups, because want to use async api for finding reference and pass them via groups to Unity myHost.PerformModelAction(t => t.ShowFileInUnity.Advise(lf, v => editor.ShowFileInUnity.Fire(v))); myHost.PerformModelAction(t => t.ShowPreferences.Advise(lf, v => { editor.ShowPreferences.Fire(); })); editor.EditorLogPath.Advise(lifetime, s => myHost.PerformModelAction(a => a.EditorLogPath.SetValue(s))); editor.PlayerLogPath.Advise(lifetime, s => myHost.PerformModelAction(a => a.PlayerLogPath.SetValue(s))); // Note that these are late-init properties. Once set, they are always set and do not allow nulls. // This means that if/when the Unity <-> Backend protocol closes, they still retain the last value // they had - so the front end will retain the log and application paths of the just-closed editor. // Opening a new editor instance will reconnect and push a new value through to the front end editor.UnityApplicationData.Advise(lifetime, s => myHost.PerformModelAction(a => { var version = UnityVersion.Parse(s.ApplicationVersion); a.UnityApplicationData.SetValue(new UnityApplicationData(s.ApplicationPath, s.ApplicationContentsPath, s.ApplicationVersion, UnityVersion.RequiresRiderPackage(version))); })); editor.ScriptCompilationDuringPlay.Advise(lifetime, s => myHost.PerformModelAction(a => a.ScriptCompilationDuringPlay.Set(ConvertToScriptCompilationEnum(s)))); myHost.PerformModelAction(rd => { rd.GenerateUIElementsSchema.Set((l, u) => editor.GenerateUIElementsSchema.Start(l, u).ToRdTask(l)); }); TrackActivity(editor, lf); if (!myComponentLifetime.IsTerminated) { myLocks.ExecuteOrQueueEx(myComponentLifetime, "setModel", () => { UnityModel.SetValue(editor); }); } lf.AddAction(() => { if (!myComponentLifetime.IsTerminated) { myLocks.ExecuteOrQueueEx(myComponentLifetime, "clearModel", () => { myLogger.Info("Wire disconnected."); myHost.PerformModelAction(m => m.SessionInitialized.Value = false); UnityModel.SetValue(null); }); } }); }); } catch (Exception ex) { myLogger.Error(ex); } }
private void BindToInstallationSettingChange() { var entry = myBoundSettingsStore.Schema.GetScalarEntry((UnitySettings s) => s.InstallUnity3DRiderPlugin); myBoundSettingsStore.GetValueProperty <bool>(myLifetime, entry, null).Change.Advise(myLifetime, CheckAllProjectsIfAutoInstallEnabled); }
private void CreateProtocols(FileSystemPath protocolInstancePath) { if (!protocolInstancePath.ExistsFile) { return; } List <ProtocolInstance> protocolInstanceList; try { protocolInstanceList = ProtocolInstance.FromJson(protocolInstancePath.ReadAllText2().Text); } catch (Exception e) { myLogger.Warn($"Unable to parse {protocolInstancePath}" + Environment.NewLine + e); return; } var protocolInstance = protocolInstanceList?.SingleOrDefault(a => a.SolutionName == mySolution.SolutionFilePath.NameWithoutExtension); if (protocolInstance == null) { return; } myLogger.Info($"EditorPlugin protocol port {protocolInstance.Port} for Solution: {protocolInstance.SolutionName}."); try { var lifetime = mySessionLifetimes.Next(); myLogger.Info("Create protocol..."); myLogger.Info("Creating SocketWire with port = {0}", protocolInstance.Port); var wire = new SocketWire.Client(lifetime, myDispatcher, protocolInstance.Port, "UnityClient"); wire.Connected.WhenTrue(lifetime, lf => { myLogger.Info("WireConnected."); var protocol = new Protocol("UnityEditorPlugin", new Serializers(), new Identities(IdKind.Client), myDispatcher, wire, lf); protocol.ThrowErrorOnOutOfSyncModels = false; protocol.OutOfSyncModels.Advise(lf, e => { var entry = myBoundSettingsStore.Schema.GetScalarEntry((UnitySettings s) => s.InstallUnity3DRiderPlugin); var isEnabled = myBoundSettingsStore.GetValueProperty <bool>(lf, entry, null).Value; if (!isEnabled) { myHost.PerformModelAction(model => model.OnEditorModelOutOfSync()); } }); var editor = new EditorPluginModel(lf, protocol); editor.IsBackendConnected.Set(rdVoid => true); if (PlatformUtil.RuntimePlatform == PlatformUtil.Platform.Windows) { var frontendProcess = Process.GetCurrentProcess().GetParent(); // RiderProcessId is not used on non-Windows, but this line gives bad warning in the log if (frontendProcess != null) { editor.RiderProcessId.SetValue(frontendProcess.Id); } } myHost.PerformModelAction(m => m.SessionInitialized.Value = true); SubscribeToLogs(lf, editor); SubscribeToOpenFile(editor); editor.Play.Advise(lf, b => myHost.PerformModelAction(rd => rd.Play.SetValue(b))); editor.Pause.Advise(lf, b => myHost.PerformModelAction(rd => rd.Pause.SetValue(b))); editor.ClearOnPlay.Advise(lf, time => myHost.PerformModelAction(rd => rd.ClearOnPlay(time))); editor.UnityProcessId.View(lf, (_, pid) => myHost.PerformModelAction(t => t.UnityProcessId.Set(pid))); // I have split this into groups, because want to use async api for finding reference and pass them via groups to Unity myHost.PerformModelAction(t => t.ShowGameObjectOnScene.Advise(lf, v => editor.ShowGameObjectOnScene.Fire(v.ConvertToUnityModel()))); myHost.PerformModelAction(t => t.ShowFileInUnity.Advise(lf, v => editor.ShowFileInUnity.Fire(v))); myHost.PerformModelAction(t => t.ShowPreferences.Advise(lf, v => { if (t.UnityProcessId.HasValue()) { UnityFocusUtil.FocusUnity(t.UnityProcessId.Value); } editor.ShowPreferences.Fire(); })); // pass all references to Unity TODO temp workaround, replace with async api myHost.PerformModelAction(t => t.FindUsageResults.Advise(lf, v => editor.FindUsageResults.Fire(v.ConvertToUnityModel()))); editor.EditorLogPath.Advise(lifetime, s => myHost.PerformModelAction(a => a.EditorLogPath.SetValue(s))); editor.PlayerLogPath.Advise(lifetime, s => myHost.PerformModelAction(a => a.PlayerLogPath.SetValue(s))); // Note that these are late-init properties. Once set, they are always set and do not allow nulls. // This means that if/when the Unity <-> Backend protocol closes, they still retain the last value // they had - so the front end will retain the log and application paths of the just-closed editor. // Opening a new editor instance will reconnect and push a new value through to the front end editor.ApplicationPath.Advise(lifetime, s => myHost.PerformModelAction(a => a.ApplicationPath.SetValue(s))); editor.ApplicationContentsPath.Advise(lifetime, s => myHost.PerformModelAction(a => a.ApplicationContentsPath.SetValue(s))); editor.ScriptCompilationDuringPlay.Advise(lifetime, s => myHost.PerformModelAction(a => a.ScriptCompilationDuringPlay.Set(ConvertToScriptCompilationEnum(s)))); BindPluginPathToSettings(lf, editor); TrackActivity(editor, lf); if (!myComponentLifetime.IsTerminated) { myLocks.ExecuteOrQueueEx(myComponentLifetime, "setModel", () => { UnityModel.SetValue(editor); }); } lf.AddAction(() => { if (!myComponentLifetime.IsTerminated) { myLocks.ExecuteOrQueueEx(myComponentLifetime, "clearModel", () => { myLogger.Info("Wire disconnected."); myHost.PerformModelAction(m => m.SessionInitialized.Value = false); UnityModel.SetValue(null); }); } }); }); } catch (Exception ex) { myLogger.Error(ex); } }