public void Observe() { Connection = null; //Process.Exited += new EventHandler(delegate (Object o, EventArgs a) { // SetProcessState(MegaMolProcessState.MMPS_NONE); // StopObserving(); // ParentForm.SetTabPageTag(TabPage, null); // ParentForm.listBoxLog.Log(Util.Level.Info, string.Format("Tab '{0}' disconnected", TabPage.Text)); //}); connectionString = "tcp://" + Host + ":" + Port; TryConnecting(connectionString); string err = "", ans = ""; string res; if (!stopQueued) { // the following code does not work under Mono -- // detached process gets a different ID if (!IsRunningOnMono()) { if (Connection.Valid) { Request("return mmGetProcessID()"); err = GetAnswer(ref ans); if (String.IsNullOrWhiteSpace(err)) { uint id = 0; try { id = uint.Parse((string)ans); } catch { id = 0; } foreach (var proc in System.Diagnostics.Process.GetProcesses()) { if (proc.Id == id) { Process = proc; break; } } if (Process != null) { try { Process.EnableRaisingEvents = true; Process.Exited += new EventHandler(delegate(Object o, EventArgs a) { SetProcessState(MegaMolProcessState.MMPS_NONE); StopObserving(); ParentForm.SetTabPageTag(TabPage, null); ParentForm.listBoxLog.Log(Util.Level.Info, $"Tab '{TabPage.Text}' disconnected"); ParentForm.SetTabPageIcon(TabPage, 1); ParentForm.listBoxLog.Log(Util.Level.Info, $"Tab '{TabPage.Text}' exited"); Process = null; }); } catch { ParentForm.listBoxLog.Log(Util.Level.Warning, $"could not install exit handler for Tab '{TabPage.Text}'"); // we can only do this if we started the process ourselves } SetProcessState(MegaMolProcessState.MMPS_CONNECTION_GOOD); } else { SetProcessState(MegaMolProcessState.MMPS_CONNECTION_BROKEN); // wrong instance Connection = null; } //if (id == Process.Id) { // SetProcessState(MegaMolProcessState.MMPS_CONNECTION_GOOD); //} else { // SetProcessState(MegaMolProcessState.MMPS_CONNECTION_BROKEN); // wrong instance // Connection = null; //} } else { SetProcessState(MegaMolProcessState.MMPS_CONNECTION_BROKEN); // broken Connection = null; } } else { // could not connect //mmii.Connection = null; SetProcessState(MegaMolProcessState.MMPS_CONNECTION_BROKEN); //broken } } else { if (!Connection.Valid) { // could not connect //mmii.Connection = null; SetProcessState(MegaMolProcessState.MMPS_CONNECTION_BROKEN); //broken } } } System.Threading.Thread.Sleep(100); if (Connection != null && Connection.Valid) { List <string> foundInstances = new List <string>(); do { Request("return mmListInstantiations()"); ans = null; do { res = GetAnswer(ref ans); } while (ans == null); if (String.IsNullOrWhiteSpace(res)) { var insts = ((string)ans).Split(new char[] { '\n' }, StringSplitOptions.None); foreach (var i in insts) { if (!String.IsNullOrEmpty(i)) { foundInstances.Add(i); } } if (foundInstances.Count == 0) { ParentForm.SetTabInstantiation(TabPage, ""); } else if (foundInstances.Count == 1 && !ReadGraphFromInstance) { ParentForm.SetTabInstantiation(TabPage, foundInstances[0]); } else { ParentForm.ChooseInstantiation(TabPage, foundInstances.ToArray()); } } System.Threading.Thread.Sleep(1000); } while (foundInstances.Count == 0); if (ReadGraphFromInstance) { if (string.IsNullOrEmpty(ParentForm.TabInstantiation(TabPage))) { Request("return mmListModules()"); res = GetAnswer(ref ans); } else { Request($"return mmListModules(\"{ParentForm.TabInstantiation(TabPage)}\")"); res = GetAnswer(ref ans); } if (string.IsNullOrWhiteSpace(res)) { var modules = ((string)ans).Split(new char[] { '\n' }, StringSplitOptions.None); foreach (var mod in modules) { var stuff = mod.Split(new char[] { ';' }, StringSplitOptions.None); if (stuff.Length == 2) { ParentForm.AddModule(TabPage, stuff[0], stuff[1]); } } } if (string.IsNullOrEmpty(ParentForm.TabInstantiation(TabPage))) { Request("return mmListCalls()"); res = GetAnswer(ref ans); } else { Request($"return mmListCalls(\"{ParentForm.TabInstantiation(TabPage)}\")"); res = GetAnswer(ref ans); } if (String.IsNullOrWhiteSpace(res)) { var calls = ((string)ans).Split(new char[] { '\n' }, StringSplitOptions.None); foreach (var c in calls) { var stuff = c.Split(new char[] { ';' }, StringSplitOptions.None); if (stuff.Length == 3) { var fromTo = stuff[1].Split(new char[] { ',' }, StringSplitOptions.None); var srcDest = stuff[2].Split(new char[] { ',' }, StringSplitOptions.None); if (fromTo.Length == 2 && srcDest.Length == 2) { ParentForm.AddConnection(TabPage, stuff[0], fromTo[0], srcDest[0], fromTo[1], srcDest[1]); } } } } ParentForm.ForceDirectedLayout(ParentForm.SelectedTab); ParentForm.RefreshCurrent(); ParentForm.listBoxLog.Log(Util.Level.Info, "Done reading attached project info"); } } else { ParentForm.FreePort(Port); return; } while (!stopQueued) { System.Threading.Thread.Sleep(1000); // check current tab (is the correct instance controlled) if (stopQueued) { break; } TabPage tp = ParentForm.SelectedTab; if (tp == TabPage) { lock (moduleCreations) { foreach (GraphicalModule gmc in moduleCreations) { string command = $@"mmCreateModule(""{gmc.Module.Name}"", ""{ParentForm.TabInstantiation(TabPage)}::{gmc.Name}"")"; Request("return " + command); res = GetAnswer(ref ans); if (String.IsNullOrWhiteSpace(res) && !stopQueued) { // huh. } else { ParentForm.listBoxLog.Log(Util.Level.Error, $@"Error on {command}: {res}"); } } moduleCreations.Clear(); } lock (moduleDeletions) { foreach (GraphicalModule gmc in moduleDeletions) { string command = $@"mmDeleteModule(""{ParentForm.TabInstantiation(TabPage)}::{gmc.Name}"")"; Request("return " + command); res = GetAnswer(ref ans); if (String.IsNullOrWhiteSpace(res) && !stopQueued) { // huh. } else { ParentForm.listBoxLog.Log(Util.Level.Error, $@"Error on {command}: {res}"); } } moduleDeletions.Clear(); } // TODO: connections. beware that connections will probably be cleaned if the modules go away, so failure is okayish? :/ lock (connectionDeletions) { foreach (GraphicalConnection gcc in connectionDeletions) { string command = $@"mmDeleteCall(""{ParentForm.TabInstantiation(TabPage)}::{gcc.src.Name}::{ gcc.srcSlot.Name }"", ""{ParentForm.TabInstantiation(TabPage)}::{gcc.dest.Name}::{gcc.destSlot.Name}"")"; Request($"return {command}"); res = GetAnswer(ref ans); if (String.IsNullOrWhiteSpace(res) && !stopQueued) { // huh. } else { ParentForm.listBoxLog.Log(Util.Level.Error, $@"Error on {command}: {res}"); } } connectionDeletions.Clear(); } lock (connectionCreations) { foreach (GraphicalConnection gcc in connectionCreations) { string command = $@"mmCreateCall(""{gcc.Call.Name}"",""{ParentForm.TabInstantiation(TabPage)}::{gcc.src.Name}::{ gcc.srcSlot.Name }"", ""{ParentForm.TabInstantiation(TabPage)}::{gcc.dest.Name}::{gcc.destSlot.Name}"")"; Request("return " + command); res = GetAnswer(ref ans); if (String.IsNullOrWhiteSpace(res) && !stopQueued) { // huh. } else { ParentForm.listBoxLog.Log(Util.Level.Error, $@"Error on {command}: {res}"); } } connectionCreations.Clear(); } // what the hell? GraphicalModule gm = Form1.selectedModule; if (gm != null) { #if true if (stopQueued) { break; } res = UpdateModuleParams(gm); } #else string prefix = "inst::" + gm.Name + "::"; var keys = gm.ParameterValues.Keys.ToList(); foreach (Data.ParamSlot p in keys) { if (stopQueued) { break; } res = this.Request(new MegaMol.SimpleParamRemote.MMSPR1.GETVALUE() { ParameterName = prefix + p.Name }, ref ans); if (String.IsNullOrWhiteSpace(res) && !stopQueued) { if (!p.Type.ValuesEqual(gm.ParameterValues[p], (string)ans)) { gm.ParameterValues[p] = (string)ans; this.ParentForm.ParamChangeDetected(); } } } #endif } } if (Connection != null) { Connection.Close(); } ParentForm.FreePort(Port); }