[beast: 6/14] BEAST: use Python to run the Beast main event loop



commit f5caa40651e5b20eb0ce1b3f5a1e89118e59149b
Author: Tim Janik <timj gnu org>
Date:   Sun Dec 6 14:28:20 2015 +0100

    BEAST: use Python to run the Beast main event loop
    
    Signed-off-by: Tim Janik <timj gnu org>

 beast-gtk/bstapp.cc   |    2 +-
 beast-gtk/bstdefs.hh  |    5 ++-
 beast-gtk/bstmain.cc  |   56 ++++++++++++++++++++++++++++++++++++++----------
 beast-gtk/bstutils.cc |   33 ++++++++++++++++++++++++++++
 beast-gtk/bstutils.hh |   10 ++++++++
 5 files changed, 91 insertions(+), 15 deletions(-)
---
diff --git a/beast-gtk/bstapp.cc b/beast-gtk/bstapp.cc
index 89978f2..d20be36 100644
--- a/beast-gtk/bstapp.cc
+++ b/beast-gtk/bstapp.cc
@@ -345,7 +345,7 @@ bst_app_destroy (GtkObject *object)
   if (!bst_app_class->apps && bst_app_class->seen_apps)
     {
       bst_app_class->seen_apps = FALSE;
-      BST_MAIN_LOOP_QUIT ();
+      Bst::event_loop_quit ();
     }
 }
 
diff --git a/beast-gtk/bstdefs.hh b/beast-gtk/bstdefs.hh
index d70f403..13573ec 100644
--- a/beast-gtk/bstdefs.hh
+++ b/beast-gtk/bstdefs.hh
@@ -6,6 +6,9 @@
 #include "bstzoomedwindow.hh"
 #include "bse/bse.hh"
 
+// == G++ attributes ==
+#define __unused        __attribute__ ((unused))
+
 G_BEGIN_DECLS
 
 /* --- generic constants --- */
@@ -63,7 +66,6 @@ typedef enum /*< skip >*/
 /* --- miscellaneous --- */
 #define        BST_DVL_HINTS           (bst_developer_hints != FALSE)
 #define        BST_DBG_EXT             (bst_debug_extensions != FALSE)
-#define        BST_MAIN_LOOP_QUIT()    do { bst_main_loop_running = FALSE; } while (0)
 #define        GNOME_CANVAS_NOTIFY(object)     G_STMT_START { \
     if (GTK_IS_OBJECT (object)) \
       g_signal_emit_by_name (object, "notify::generic-change", NULL); \
@@ -79,7 +81,6 @@ void    beast_show_about_box (void);
 void    bst_main_loop_wakeup    ();
 extern gboolean bst_developer_hints;
 extern gboolean bst_debug_extensions;
-extern gboolean bst_main_loop_running;
 
 G_END_DECLS
 
diff --git a/beast-gtk/bstmain.cc b/beast-gtk/bstmain.cc
index 745400a..b9c5323 100644
--- a/beast-gtk/bstmain.cc
+++ b/beast-gtk/bstmain.cc
@@ -30,7 +30,6 @@ static void                     bst_init_aida_idl       ();
 /* --- variables --- */
 gboolean            bst_developer_hints = FALSE;
 gboolean            bst_debug_extensions = FALSE;
-gboolean            bst_main_loop_running = TRUE;
 static GtkWidget   *beast_splash = NULL;
 static gboolean     registration_done = FALSE;
 static gboolean     arg_force_xkb = FALSE;
@@ -76,7 +75,7 @@ static BstApp*  main_open_files (int filesc, char **filesv);
 static BstApp*  main_open_default_window();
 static void     main_show_release_notes();
 static void     main_splash_down ();
-static void     main_run_event_loops ();
+static void     main_run_event_loop ();
 static bool     force_saving_rc_files = false;
 static void     main_save_rc_files ();
 static void     main_cleanup ();
@@ -136,7 +135,9 @@ main (int argc, char *argv[])
     app = main_open_default_window();
   main_show_release_notes();
   main_splash_down();
-  main_run_event_loops();
+
+  main_run_event_loop();
+
   main_save_rc_files();
   main_cleanup();
 
@@ -470,19 +471,50 @@ main_splash_down ()
   bst_splash_release_grab (beast_splash);
 }
 
-static void
-main_run_event_loops ()
+#define Py_None_INCREF()        ({ Py_INCREF (Py_None); Py_None;  })
+
+static PyObject*
+main_quit (PyObject *self, PyObject *args)
 {
-  /* away into the main loop */
-  while (bst_main_loop_running)
+  int exit_code = 0;
+  if (PyTuple_Check (args) && PyTuple_GET_SIZE (args) > 0)
     {
-      sfi_glue_gc_run ();
-      GDK_THREADS_LEAVE ();
-      g_main_iteration (TRUE);
-      GDK_THREADS_ENTER ();
+      if (!PyArg_ParseTuple (args, "i:main_quit", &exit_code))
+        return NULL;
     }
+  Bst::event_loop_quit (exit_code);
+  return Py_None_INCREF();
+}
+
+static PyObject*
+main_loop (PyObject *self, PyObject *args)
+{
+  if (!PyArg_ParseTuple (args, ":main_loop"))
+    return NULL;
+  const int quit_code = Bst::event_loop_run();
+  return Py_BuildValue ("i", quit_code);
+}
+
+static PyMethodDef embedded_bst_methods[] = {
+  { "main_quit", main_quit, METH_VARARGS, "Quit the currently running main event loop." },
+  { "main_loop", main_loop, METH_VARARGS, "Run the main event loop until main_quit()." },
+  { NULL, NULL, 0, NULL }
+};
+
+static void
+main_run_event_loop ()
+{
+  // register embedded methods
+  static __unused bool initialized = []() { Py_InitModule ("bst", embedded_bst_methods); return true; } ();
+
+  // run main loop from Python
+  const char commands[] =
+    "import bst;\n"
+    "bst.main_loop()\n";
+  PyRun_SimpleString (commands);
+
+  // run pending cleanup handlers
   bst_message_dialogs_popdown ();
-  /* perform necessary cleanup cycles */
   GDK_THREADS_LEAVE ();
   while (g_main_iteration (FALSE))
     {
diff --git a/beast-gtk/bstutils.cc b/beast-gtk/bstutils.cc
index 7b753a3..e249c2b 100644
--- a/beast-gtk/bstutils.cc
+++ b/beast-gtk/bstutils.cc
@@ -20,6 +20,39 @@
 #include <unistd.h>
 #include <string.h>
 
+
+namespace Bst {
+
+static const uint16 EVENT_LOOP_RUNNING   = 0xffff;
+static uint16       event_loop_quit_code = EVENT_LOOP_RUNNING;
+
+int
+event_loop_run ()
+{
+  // run main event loop until main_quit()
+  while (event_loop_quit_code == EVENT_LOOP_RUNNING)
+    {
+      sfi_glue_gc_run ();
+      GDK_THREADS_LEAVE ();
+      g_main_iteration (TRUE);
+      GDK_THREADS_ENTER ();
+    }
+  // return exit status and reset state to allow restarts
+  const int quit_code = event_loop_quit_code;
+  event_loop_quit_code = EVENT_LOOP_RUNNING;
+  return quit_code;
+}
+
+void
+event_loop_quit (uint8 exit_code)
+{
+  if (event_loop_quit_code == EVENT_LOOP_RUNNING)
+    event_loop_quit_code = exit_code;
+}
+
+} // Bst                                                                                                 |
+
+
 /* --- variables --- */
 static GtkIconFactory *stock_icon_factory = NULL;
 Bse::ServerH bse_server;
diff --git a/beast-gtk/bstutils.hh b/beast-gtk/bstutils.hh
index f645708..d6f0163 100644
--- a/beast-gtk/bstutils.hh
+++ b/beast-gtk/bstutils.hh
@@ -8,9 +8,19 @@
 /* generated type IDs, idl types */
 #include "bstserverapi.hh"
 
+namespace Bst {
+
+// == event loop ==
+int  event_loop_run  ();
+void event_loop_quit (uint8 exit_code = 0);
+
+} // Bst
+
+
 // == Bse Server (BSE remote origin) ==
 extern Bse::ServerH bse_server;
 
+
 G_BEGIN_DECLS
 
 /* --- GUI utilities --- */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]