documentor, ide: (#773) bidirectional communication
authorJerome St-Louis <jerome@ecere.com>
Thu, 29 Aug 2013 09:06:55 +0000 (05:06 -0400)
committerJerome St-Louis <jerome@ecere.com>
Thu, 29 Aug 2013 09:16:02 +0000 (05:16 -0400)
- Ensuring only a single instance of Documentor is running per IDE
- The documentor is closed on exiting the IDE
- Paving the way for lookup/search (#143/#441)

documentor/src/Documentor.ec
ecere/src/sys/DualPipe.c
ecere/src/sys/DualPipe.ec
ide/src/ide.ec

index 06bebe6..e023976 100644 (file)
@@ -11,6 +11,8 @@ static NameSpace globalData;
 static OldList excludedSymbols { offset = (uint)&((Symbol)0).left };
 static bool readOnly;
 
+define app = (GuiApplication)__thisModule.application;
+
 #define UTF8_NUM_BYTES(x)  (__extension__({ byte b = x; (b & 0x80 && b & 0x40) ? ((b & 0x20) ? ((b & 0x10) ? 4 : 3) : 2) : 1; }))
 
 default:
@@ -3666,7 +3668,7 @@ class Documentor : GuiApplication
       SetExcludedSymbols(&excludedSymbols);
       SetDefines(&::defines);
       SetImports(&imports);
-      
+
       SetGlobalData(globalData);
 
       settingsContainer.dataOwner = &settings;
@@ -3717,11 +3719,29 @@ class Documentor : GuiApplication
             row.collapsed = false;
       #endif
       }
+
+      commandThread.Create();
+      return true;
+   }
+
+   bool Cycle(bool idle)
+   {
+      if(quit)
+         mainForm.Destroy(0);
       return true;
    }
 
    void Terminate()
    {
+      PrintLn("Exited");
+      console.Flush();
+      quit = true;
+      console.CloseInput();
+      console.CloseOutput();
+      app.Unlock();
+      commandThread.Wait();
+      app.Lock();
+
       FreeContext(globalContext);
       FreeExcludedSymbols(excludedSymbols);
       ::defines.Free(FreeModuleDefine);
@@ -3734,4 +3754,28 @@ class Documentor : GuiApplication
    }
 }
 
+ConsoleFile console { };
 MainForm mainForm { };
+bool quit;
+
+Thread commandThread
+{
+   unsigned int Main()
+   {
+      while(!quit)
+      {
+         char command[1024];
+         console.GetLine(command, sizeof(command));
+         if(!quit && command[0])
+         {
+            app.Lock();
+            if(!strcmpi(command, "Activate"))
+               mainForm.Activate();
+            else if(!strcmpi(command, "Quit"))
+               quit = true;
+            app.Unlock();
+         }
+      }
+      return 0;
+   }
+};
index 4cd1e8b..4e475ac 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
-#define POM_output   1
-#define POM_error    2
-#define POM_input    4
+#define POM_output      1
+#define POM_error       2
+#define POM_input       4
+#define POM_showWindow  8
 
 #define FSM_start    0
 #define FSM_current  1
@@ -446,7 +447,8 @@ _DualPipe * _DualPipeOpen(PipeOpenMode mode, char * commandLine, char * env, voi
 
       // Set up the start up info struct.
       si.cb = sizeof(STARTUPINFO);
-      si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
+      si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+      si.wShowWindow = (mode & POM_showWindow) ? SW_SHOW : SW_HIDE;
       si.hStdOutput = hOutput[PIPE_WRITE] ? hOutput[PIPE_WRITE] : hStdOut;
       si.hStdInput  = hInput [PIPE_READ] ? hInput [PIPE_READ]  : hStdIn;
       if((mode & POM_error) && (mode & POM_output))
index c385e4c..bd9aff8 100644 (file)
@@ -27,7 +27,7 @@ _DualPipe * _DualPipeOpen(PipeOpenMode mode, char * commandLine, char * env, voi
 
 private:
 
-public class PipeOpenMode { public bool output:1, error:1, input:1; };
+public class PipeOpenMode { public bool output:1, error:1, input:1, showWindow:1; };
 
 public class DualPipe : File
 {
index 65911eb..5db4a67 100644 (file)
@@ -407,6 +407,7 @@ class IDEWorkSpace : Window
    MenuItem * driverItems, * skinItems;
    StatusField pos { width = 150 };
    StatusField ovr, caps, num;
+   DualPipe documentor;
 
    BitmapResource back                 { ":ecereBack.jpg", window = this };
    BitmapResource bmpBp                { ":codeMarks/breakpoint.png", window = this };
@@ -1454,18 +1455,26 @@ class IDEWorkSpace : Window
          helpMenu, $"API Reference", r, f1;
          bool NotifySelect(MenuItem selection, Modifiers mods)
          {
-            char * p = new char[MAX_LOCATION];
-            p[0] = '\0';
-            strncpy(p, settingsContainer.moduleLocation, MAX_LOCATION); p[MAX_LOCATION-1] = '\0';
-            PathCat(p, "documentor");
-#if defined(__WIN32__)
-            ChangeExtension(p, "exe", p);
-#endif
-            if(FileExists(p).isFile)
-               Execute(p);
+            if(!documentor)
+            {
+               char * p = new char[MAX_LOCATION];
+               p[0] = '\0';
+               strncpy(p, settingsContainer.moduleLocation, MAX_LOCATION); p[MAX_LOCATION-1] = '\0';
+               PathCat(p, "documentor");
+   #if defined(__WIN32__)
+               ChangeExtension(p, "exe", p);
+   #endif
+               if(!FileExists(p).isFile)
+                  strcpy(p, "documentor");
+
+               documentor = DualPipeOpen({ input = true, output = true, showWindow = true }, p);
+               delete p;
+            }
             else
-               Execute("documentor");
-            delete p;
+            {
+               Process_ShowWindows(documentor.GetProcessID());
+               // documentor.Puts("Activate\n");
+            }
             return true;
          }
       }
@@ -3380,6 +3389,12 @@ class IDEWorkSpace : Window
       delete driverItems;
       delete skinItems;
       delete ideSettings;
+      if(documentor)
+      {
+         documentor.Puts("Quit\n");
+         documentor.Wait();
+         delete documentor;
+      }
    }
 }
 
@@ -3600,6 +3615,23 @@ class IDEApp : GuiApplication
       return true;
    }
 
+   bool Cycle(bool idle)
+   {
+      if(ide.documentor)
+      {
+         if(ide.documentor.Peek())
+         {
+            char line[1024];
+            ide.documentor.GetLine(line, sizeof(line));
+            if(!strcmpi(line, "Exited"))
+               delete ide.documentor;
+         }
+         if(ide.documentor && ide.documentor.eof)
+            delete ide.documentor;
+      }
+      return true;
+   }
+
    bool LoadIncludeFile()
    {
       bool result = false;