public ConnectionTracker(Lifetime lifetime, ILogger logger, UnityHost host, UnityEditorProtocol unityEditorProtocolController, IShellLocks locks) { // TODO: this shouldn't be up in tests until we figure out how to test unity-editor requiring features if (locks.Dispatcher.IsAsyncBehaviorProhibited) { return; } //check connection between backend and unity editor locks.QueueRecurring(lifetime, "PeriodicallyCheck", TimeSpan.FromSeconds(1), () => { if (unityEditorProtocolController.UnityModel.Value == null) { myLastCheckResult = UnityEditorState.Disconnected; } else { var rdTask = unityEditorProtocolController.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.SetModelData("UNITY_EditorState", Wrap(myLastCheckResult)); }); }
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 CreateProtocol(FileSystemPath protocolInstancePath) { if (!protocolInstancePath.ExistsFile) { return; } int port; try { var protocolInstance = JsonConvert.DeserializeObject <ProtocolInstance>(protocolInstancePath.ReadAllText2().Text); port = protocolInstance.port_id; } catch (Exception e) { myLogger.Warn($"Unable to parse {protocolInstancePath}" + Environment.NewLine + e); return; } myLogger.Info($"UNITY_Port {port}."); try { var lifetime = mySessionLifetimes.Next(); myLogger.Info("Create protocol..."); myLogger.Info("Creating SocketWire with port = {0}", port); var wire = new SocketWire.Client(lifetime, myDispatcher, port, "UnityClient"); wire.Connected.WhenTrue(lifetime, lf => { myLogger.Info("WireConnected."); myHost.SetModelData("UNITY_Play", "undef"); var protocol = new Protocol("UnityEditorPlugin", new Serializers(), new Identities(IdKind.Client), myDispatcher, wire); var model = new EditorPluginModel(lf, protocol); model.IsBackendConnected.Set(rdVoid => true); model.RiderProcessId.SetValue(Process.GetCurrentProcess().Id); myHost.SetModelData("UNITY_SessionInitialized", "true"); SubscribeToLogs(lf, model); SubscribeToOpenFile(model); model.Play.AdviseNotNull(lf, b => myHost.SetModelData("UNITY_Play", b.ToString().ToLower())); model.Pause.AdviseNotNull(lf, b => myHost.SetModelData("UNITY_Pause", b.ToString().ToLower())); BindPluginPathToSettings(lf, model); TrackActivity(model, lf); if (!myComponentLifetime.IsTerminated) { myLocks.ExecuteOrQueueEx(myComponentLifetime, "setModel", () => { myUnityModel.SetValue(model, myReadonlyToken); }); } lf.AddAction(() => { if (!myComponentLifetime.IsTerminated) { myLocks.ExecuteOrQueueEx(myComponentLifetime, "clearModel", () => { myLogger.Info("Wire disconnected."); myHost.SetModelData("UNITY_SessionInitialized", "false"); myUnityModel.SetValue(null, myReadonlyToken); }); } }); }); } catch (Exception ex) { myLogger.Error(ex); } }
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($"UNITY_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 model = new EditorPluginModel(lf, protocol); model.IsBackendConnected.Set(rdVoid => true); var frontendProcess = Process.GetCurrentProcess().GetParent(); if (frontendProcess != null) { model.RiderProcessId.SetValue(frontendProcess.Id); } myHost.SetModelData("UNITY_SessionInitialized", "true"); SubscribeToLogs(lf, model); SubscribeToOpenFile(model); model.Play.AdviseNotNull(lf, b => myHost.PerformModelAction(a => a.Play.SetValue(b))); model.Pause.AdviseNotNull(lf, b => myHost.SetModelData("UNITY_Pause", b.ToString().ToLower())); // 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 model.EditorLogPath.Advise(lifetime, s => myHost.PerformModelAction(a => a.EditorLogPath.SetValue(s))); model.PlayerLogPath.Advise(lifetime, s => myHost.PerformModelAction(a => a.PlayerLogPath.SetValue(s))); model.ApplicationPath.Advise(lifetime, s => myHost.PerformModelAction(a => a.ApplicationPath.SetValue(s))); model.ApplicationContentsPath.Advise(lifetime, s => myHost.PerformModelAction(a => a.ApplicationContentsPath.SetValue(s))); BindPluginPathToSettings(lf, model); TrackActivity(model, lf); if (!myComponentLifetime.IsTerminated) { myLocks.ExecuteOrQueueEx(myComponentLifetime, "setModel", () => { myUnityModel.SetValue(model, myReadonlyToken); }); } lf.AddAction(() => { if (!myComponentLifetime.IsTerminated) { myLocks.ExecuteOrQueueEx(myComponentLifetime, "clearModel", () => { myLogger.Info("Wire disconnected."); myHost.SetModelData("UNITY_SessionInitialized", "false"); myUnityModel.SetValue(null, myReadonlyToken); }); } }); }); } catch (Exception ex) { myLogger.Error(ex); } }