public UnityInstallationSynchronizer(Lifetime lifetime, UnitySolutionTracker solutionTracker, UnityHost host, UnityInstallationFinder finder, UnityVersion unityVersion) { solutionTracker.IsUnityProjectFolder.AdviseNotNull(lifetime, isUnityProjectFolder => { if (!isUnityProjectFolder) { return; } var version = unityVersion.GetActualVersionForSolution(); var info = finder.GetApplicationInfo(version); if (info == null) { return; } var contentPath = finder.GetApplicationContentsPath(version); host.PerformModelAction(rd => { // ApplicationPath may be already set via UnityEditorProtocol, which is more accurate if (!rd.ApplicationPath.HasValue()) { rd.ApplicationPath.SetValue(info.Path.FullPath); } if (!rd.ApplicationContentsPath.HasValue()) { rd.ApplicationContentsPath.SetValue(contentPath.FullPath); } if (!rd.ApplicationVersion.HasValue()) { rd.ApplicationVersion.SetValue(UnityVersion.VersionToString(info.Version)); } }); }); }
public UnityRefreshTracker(Lifetime lifetime, ISolution solution, UnityRefresher refresher, ILogger logger, IFileSystemTracker fileSystemTracker, UnityHost host, UnitySolutionTracker unitySolutionTracker) { myLogger = logger; if (solution.GetData(ProjectModelExtensions.ProtocolSolutionKey) == null) { return; } unitySolutionTracker.IsUnityProject.ViewNotNull(lifetime, (lf, args) => { if (!args) { return; } host.PerformModelAction(rd => rd.Refresh.Advise(lifetime, force => { refresher.Refresh(force); })); }); // Rgc.Guarded - beware RIDER-15577 myGroupingEvent = solution.Locks.GroupingEvents.CreateEvent(lifetime, "UnityRefresherOnSaveEvent", TimeSpan.FromMilliseconds(500), Rgc.Guarded, () => refresher.Refresh(false)); var protocolSolution = solution.GetProtocolSolution(); protocolSolution.Editors.AfterDocumentInEditorSaved.Advise(lifetime, _ => { myLogger.Verbose("protocolSolution.Editors.AfterDocumentInEditorSaved"); myGroupingEvent.FireIncoming(); }); fileSystemTracker.RegisterPrioritySink(lifetime, FileSystemChange, HandlingPriority.Other); }
public UnityEditorProtocol(Lifetime lifetime, ILogger logger, UnityHost host, IScheduler dispatcher, IShellLocks locks, ISolution solution, ISettingsStore settingsStore, JetBrains.Application.ActivityTrackingNew.UsageStatistics usageStatistics, UnitySolutionTracker unitySolutionTracker, IThreading threading, UnityVersion unityVersion, NotificationsModel notificationsModel, IHostProductInfo hostProductInfo) { myPluginInstallations = new JetHashSet <FileSystemPath>(); myComponentLifetime = lifetime; myLogger = logger; myDispatcher = dispatcher; myLocks = locks; mySolution = solution; myUsageStatistics = usageStatistics; myThreading = threading; myUnityVersion = unityVersion; myNotificationsModel = notificationsModel; myHostProductInfo = hostProductInfo; myHost = host; myBoundSettingsStore = settingsStore.BindToContextLive(lifetime, ContextRange.Smart(solution.ToDataContext())); mySessionLifetimes = new SequentialLifetimes(lifetime); if (solution.GetData(ProjectModelExtensions.ProtocolSolutionKey) == null) { return; } unitySolutionTracker.IsUnityProject.View(lifetime, (lf, args) => { if (!args) { return; } var solFolder = mySolution.SolutionDirectory; AdviseModelData(lifetime); // todo: consider non-Unity Solution with Unity-generated projects var protocolInstancePath = solFolder.Combine("Library/ProtocolInstance.json"); protocolInstancePath.Directory.CreateDirectory(); var watcher = new FileSystemWatcher(); watcher.Path = protocolInstancePath.Directory.FullPath; watcher.NotifyFilter = NotifyFilters.LastWrite; //Watch for changes in LastWrite times watcher.Filter = protocolInstancePath.Name; // Add event handlers. watcher.Changed += OnChanged; watcher.Created += OnChanged; lf.Bracket(() => { }, () => { watcher.Dispose(); }); watcher.EnableRaisingEvents = true; // Begin watching. // connect on start of Rider CreateProtocols(protocolInstancePath); }); }
public ConnectionTracker(Lifetime lifetime, ILogger logger, UnityHost host, UnityEditorProtocol editorProtocol, IThreading locks, UnitySolutionTracker unitySolutionTracker, IIsApplicationActiveState isApplicationActiveState) { State = new Property <UnityEditorState>(lifetime, "UnityEditorPlugin::ConnectionState", UnityEditorState.Disconnected); if (locks.Dispatcher.IsAsyncBehaviorProhibited) { return; } unitySolutionTracker.IsUnityProject.AdviseOnce(lifetime, args => { if (!args) { return; } var updateConnectionAction = new Action(() => { var model = editorProtocol.UnityModel.Value; if (model == null) { State.SetValue(UnityEditorState.Disconnected); } else { if (!model.IsBound) { State.SetValue(UnityEditorState.Disconnected); } var rdTask = model.GetUnityEditorState.Start(Unit.Instance); rdTask?.Result.Advise(lifetime, result => { State.SetValue(result.Result); logger.Trace($"Inside Result. Sending connection state. State: {State.Value}"); host.PerformModelAction(m => m.EditorState.Value = Wrap(State.Value)); }); var waitTask = Task.Delay(TimeSpan.FromSeconds(2)); waitTask.ContinueWith(_ => { if (rdTask != null && !rdTask.AsTask().IsCompleted) { logger.Trace("There were no response from Unity in two seconds. Set connection state to Disconnected."); State.SetValue(UnityEditorState.Disconnected); } }, locks.Tasks.GuardedMainThreadScheduler); } logger.Trace($"Sending connection state. State: {State.Value}"); host.PerformModelAction(m => m.EditorState.Value = Wrap(State.Value)); }); lifetime.StartMainUnguardedAsync(async() => { while (lifetime.IsAlive) { if (isApplicationActiveState.IsApplicationActive.Value || host.GetValue(rdUnityModel => rdUnityModel.RiderFrontendTests).HasTrueValue()) { updateConnectionAction(); } await Task.Delay(1000, lifetime); } }); }); }
public ConnectionTracker(Lifetime lifetime, ILogger logger, UnityHost host, UnityEditorProtocol editorProtocol, IShellLocks locks, UnitySolutionTracker unitySolutionTracker) { // TODO: this shouldn't be up in tests until we figure out how to test unity-editor requiring features if (locks.Dispatcher.IsAsyncBehaviorProhibited) { return; } unitySolutionTracker.IsUnityProjectFolder.AdviseOnce(lifetime, args => { //check connection between backend and unity editor locks.QueueRecurring(lifetime, "PeriodicallyCheck", TimeSpan.FromSeconds(1), () => { if (editorProtocol.UnityModel.Value == null) { myLastCheckResult = UnityEditorState.Disconnected; } else { var rdTask = editorProtocol.UnityModel.Value.GetUnityEditorState.Start(RdVoid.Instance); rdTask?.Result.Advise(lifetime, result => { myLastCheckResult = result.Result; logger.Trace($"myIsConnected = {myLastCheckResult}"); }); } logger.Trace($"Sending connection state. State: {myLastCheckResult}"); host.PerformModelAction(m => m.EditorState.Value = Wrap(myLastCheckResult)); }); }); }
public MonoInstallTrigger(Lifetime lifetime, ILogger logger, ISolutionLoadTasksScheduler scheduler, ISolution solution, UnitySolutionTracker unitySolutionTracker, UnityHost host, NotificationsModel notificationsModel) { if (PlatformUtil.RuntimePlatform == PlatformUtil.Platform.Windows) { return; } scheduler.EnqueueTask(new SolutionLoadTask("Check mono runtime", SolutionLoadTaskKinds.AfterDone, () => { if (!unitySolutionTracker.IsUnityGeneratedProject.Value) { return; } if (!HasModernUnityProjects(solution)) { return; } solution.Locks.Tasks.Queue(lifetime, () => { var wellKnownMonoRuntimes = MonoRuntimeDetector.DetectWellKnownMonoRuntimes(); var installedValidMono = wellKnownMonoRuntimes .Any(runtime => { var parsedVersion = string.Empty; try { parsedVersion = ProcessOutputUtil.ExtractMonoVersion(runtime.ExePath); } catch (Exception e) { logger.Warn(e); } // if we fail to parse version - consider it is old if (Version.TryParse(parsedVersion, out var version)) { return(version >= new Version(5, 16)); // mono 5.16+ supports C# 7.3 } logger.Warn("Failed to parse ProcessOutputUtil.ExtractMonoVersion output."); return(false); }); if (installedValidMono) { return; } if (PlatformUtil.RuntimePlatform == PlatformUtil.Platform.MacOsX) { solution.Locks.ExecuteOrQueue(lifetime, "Show install mono dialog", () => { host.PerformModelAction(model => model.ShowInstallMonoDialog()); }); } else if (PlatformUtil.RuntimePlatform == PlatformUtil.Platform.Linux) { var notification = new NotificationModel("Mono 5.16+ is required", "<html>Project requires new Mono with MSBuild for new C# language features support.<br>" + RiderContextNotificationHelper.MakeOpenSettingsLink( WellKnownSettingPages.Environment, "Install the latest Mono") + ".<br>" + "If a Mono runtime is available in a non-standard location, please " + RiderContextNotificationHelper.MakeOpenSettingsLink( WellKnownSettingPages.ToolsetAndBuild, "specify the custom runtime location in settings") + ".</html>" , true, RdNotificationEntryType.WARN); solution.Locks.ExecuteOrQueue(lifetime, "MonoInstallTrigger.Notify", () => notificationsModel.Notification(notification)); } }); })); }
public ConnectionTracker(Lifetime lifetime, ILogger logger, UnityHost host, UnityEditorProtocol editorProtocol, IShellLocks locks, UnitySolutionTracker unitySolutionTracker) { unitySolutionTracker.IsUnityProjectFolder.AdviseOnce(lifetime, args => { //check connection between backend and unity editor locks.QueueRecurring(lifetime, "PeriodicallyCheck", TimeSpan.FromSeconds(1), () => { if (editorProtocol.UnityModel.Value == null) { myLastCheckResult = UnityEditorState.Disconnected; } else { var rdTask = editorProtocol.UnityModel.Value.GetUnityEditorState.Start(Unit.Instance); rdTask?.Result.Advise(lifetime, result => { myLastCheckResult = result.Result; logger.Trace($"myIsConnected = {myLastCheckResult}"); }); } logger.Trace($"Sending connection state. State: {myLastCheckResult}"); host.PerformModelAction(m => m.EditorState.Value = Wrap(myLastCheckResult)); }); }); }