private void AfterSolutionLoadDone() { using (myShellLocks.UsingReadLock()) { // Track the lifetime of all projects, so we can pass it to the handler later myProjects.Projects.View(myLifetime, (projectLifetime, project) => myProjectLifetimes.Add(project, projectLifetime)); var unityProjectLifetimes = myProjectLifetimes.Where(pl => pl.Key.IsUnityProject()).ToList(); if (unityProjectLifetimes.Any()) { HasUnityReference.SetValue(true); } foreach (var handler in myHandlers) { foreach (var(project, lifetime) in unityProjectLifetimes) { handler.OnUnityProjectAdded(lifetime, project); } } myChangeManager.RegisterChangeProvider(myLifetime, this); myChangeManager.AddDependency(myLifetime, this, myModuleReferenceResolveSync); } }
private void SetValues() { IsUnityProjectFolder.SetValue(HasUnityFileStructure(mySolution.SolutionDirectory)); IsUnityProject.SetValue(IsUnityProjectFolder.Value && mySolution.IsValid() && mySolution.SolutionFilePath.ExtensionNoDot.ToLower() == "sln"); IsUnityGeneratedProject.SetValue(IsUnityProject.Value && SolutionNameMatchesUnityProjectName()); }
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); 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.AdviseNotNull(lf, b => myHost.PerformModelAction(rd => rd.Play.SetValue(b))); editor.Pause.AdviseNotNull(lf, b => myHost.PerformModelAction(rd => rd.Pause.SetValue(b))); 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()))); // 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.NotifyIsRecompileAndContinuePlaying.AdviseOnce(lifetime, s => myHost.PerformModelAction(a => a.NotifyIsRecompileAndContinuePlaying.Fire(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); } }
private static void Init() { var projectDirectory = Directory.GetParent(Application.dataPath).FullName; var projectName = Path.GetFileName(projectDirectory); SlnFile = Path.GetFullPath($"{projectName}.sln"); InitializeEditorInstanceJson(); // process csproj files once per Unity process if (!RiderScriptableSingleton.Instance.CsprojProcessedOnce) { ourLogger.Verbose("Call OnGeneratedCSProjectFiles once per Unity process."); CsprojAssetPostprocessor.OnGeneratedCSProjectFiles(); RiderScriptableSingleton.Instance.CsprojProcessedOnce = true; } Log.DefaultFactory = new RiderLoggerFactory(); var lifetimeDefinition = Lifetimes.Define(EternalLifetime.Instance); var lifetime = lifetimeDefinition.Lifetime; AppDomain.CurrentDomain.DomainUnload += (EventHandler)((_, __) => { ourLogger.Verbose("lifetimeDefinition.Terminate"); lifetimeDefinition.Terminate(); }); if (PluginSettings.SelectedLoggingLevel >= LoggingLevel.VERBOSE) { Debug.Log($"Rider plugin initialized. LoggingLevel: {PluginSettings.SelectedLoggingLevel}. Change it in Unity Preferences -> Rider. Logs path: {LogPath}."); } try { var riderProtocolController = new RiderProtocolController(MainThreadDispatcher.Instance, lifetime); 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); AdviseModel(model); OnModelInitialization(new UnityModelAndLifetime(model, connectionLifetime)); AdviseRefresh(model); model.FullPluginPath.Advise(connectionLifetime, AdditionalPluginsInstaller.UpdateSelf); model.ApplicationVersion.SetValue(UnityUtils.UnityVersion.ToString()); model.ScriptingRuntime.SetValue(UnityUtils.ScriptingRuntime); ourLogger.Verbose("UnityModel initialized."); UnityModel.SetValue(model); new UnityEventLogSender(ourLogEventCollector, connectionLifetime); }); } catch (Exception ex) { ourLogger.Error("Init Rider Plugin " + ex); } ourOpenAssetHandler = new OnOpenAssetHandler(UnityModel, ourRiderPathLocator, ourPluginSettings, SlnFile); ourInitialized = true; }