From aa7cbdda718efd7ec41f0ce580847a0d0c31cfd3 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 6 Dec 2020 20:01:21 +0100
Subject: Extended the plugin API to notify several stages of loading.

---
 plugins/pychrysalide/constants.c |  3 ++-
 plugins/pychrysalide/core.c      | 22 +++++++++++++---------
 plugins/pychrysalide/core.h      |  2 +-
 plugins/pychrysalide/plugin.c    | 25 +++++++++++++------------
 src/plugins/pglist.c             |  4 +++-
 src/plugins/pglist.h             |  7 +++++--
 src/plugins/plugin-def.h         |  7 +++++--
 src/plugins/plugin-int.h         |  4 ++--
 src/plugins/plugin.c             | 18 ++++++++++--------
 src/plugins/plugin.h             |  2 +-
 10 files changed, 55 insertions(+), 39 deletions(-)

diff --git a/plugins/pychrysalide/constants.c b/plugins/pychrysalide/constants.c
index ded25c3..53d4375 100644
--- a/plugins/pychrysalide/constants.c
+++ b/plugins/pychrysalide/constants.c
@@ -56,7 +56,8 @@ bool define_plugin_module_constants(PyTypeObject *type)
     if (result) result = add_const_to_group(values, "BASIC_NONE", PGA_BASIC_NONE);
     if (result) result = add_const_to_group(values, "PLUGIN_INIT", PGA_PLUGIN_INIT);
     if (result) result = add_const_to_group(values, "PLUGIN_EXIT", PGA_PLUGIN_EXIT);
-    if (result) result = add_const_to_group(values, "NATIVE_LOADED", PGA_NATIVE_LOADED);
+    if (result) result = add_const_to_group(values, "NATIVE_PLUGINS_LOADED", PGA_NATIVE_PLUGINS_LOADED);
+    if (result) result = add_const_to_group(values, "PLUGINS_LOADED", PGA_PLUGINS_LOADED);
     if (result) result = add_const_to_group(values, "TYPE_BUILDING", PGA_TYPE_BUILDING);
     if (result) result = add_const_to_group(values, "GUI_THEME", PGA_GUI_THEME);
     if (result) result = add_const_to_group(values, "PANEL_CREATION", PGA_PANEL_CREATION);
diff --git a/plugins/pychrysalide/core.c b/plugins/pychrysalide/core.c
index 1ba738d..94fb899 100644
--- a/plugins/pychrysalide/core.c
+++ b/plugins/pychrysalide/core.c
@@ -70,7 +70,7 @@
 DEFINE_CHRYSALIDE_CONTAINER_PLUGIN("PyChrysalide", "Chrysalide bindings to Python",
                                    PACKAGE_VERSION, CHRYSALIDE_WEBSITE("api/python/pychrysalide"),
                                    NO_REQ, AL(PGA_PLUGIN_INIT, PGA_PLUGIN_EXIT,
-                                              PGA_NATIVE_LOADED, PGA_TYPE_BUILDING));
+                                              PGA_NATIVE_PLUGINS_LOADED, PGA_TYPE_BUILDING));
 
 
 /* Note la nature du chargement */
@@ -875,20 +875,24 @@ G_MODULE_EXPORT void chrysalide_plugin_exit(GPluginModule *plugin)
 *                                                                             *
 ******************************************************************************/
 
-G_MODULE_EXPORT void chrysalide_plugin_on_native_loaded(GPluginModule *plugin, PluginAction action)
+G_MODULE_EXPORT void chrysalide_plugin_on_plugins_loaded(GPluginModule *plugin, PluginAction action)
 {
     PyThreadState *tstate;                  /* Contexte d'environnement    */
 
-    if (!_standalone)
+    if (action == PGA_NATIVE_PLUGINS_LOADED)
     {
-        tstate = get_pychrysalide_main_tstate();
-        PyEval_RestoreThread(tstate);
-    }
+        if (!_standalone)
+        {
+            tstate = get_pychrysalide_main_tstate();
+            PyEval_RestoreThread(tstate);
+        }
 
-    load_python_plugins(plugin);
+        load_python_plugins(plugin);
 
-    if (!_standalone)
-        PyEval_SaveThread();
+        if (!_standalone)
+            PyEval_SaveThread();
+
+    }
 
 }
 
diff --git a/plugins/pychrysalide/core.h b/plugins/pychrysalide/core.h
index 0f8b484..6a7b9d1 100644
--- a/plugins/pychrysalide/core.h
+++ b/plugins/pychrysalide/core.h
@@ -50,7 +50,7 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *);
 G_MODULE_EXPORT void chrysalide_plugin_exit(GPluginModule *);
 
 /* Accompagne la fin du chargement des modules natifs. */
-G_MODULE_EXPORT void chrysalide_plugin_on_native_loaded(GPluginModule *, PluginAction);
+G_MODULE_EXPORT void chrysalide_plugin_on_plugins_loaded(GPluginModule *, PluginAction);
 
 /* Crée une instance à partir d'un type dynamique externe. */
 G_MODULE_EXPORT gpointer chrysalide_plugin_build_type_instance(GPluginModule *, PluginAction, GType);
diff --git a/plugins/pychrysalide/plugin.c b/plugins/pychrysalide/plugin.c
index b3bcce5..0fd6c26 100644
--- a/plugins/pychrysalide/plugin.c
+++ b/plugins/pychrysalide/plugin.c
@@ -58,7 +58,7 @@ static void py_plugin_module_init_gclass(GPluginModuleClass *, gpointer);
 static int py_plugin_module_init(PyObject *self, PyObject *args, PyObject *kwds);
 
 /* Accompagne la fin du chargement des modules natifs. */
-static void py_plugin_module_notify_native_loaded_wrapper(GPluginModule *, PluginAction);
+static void py_plugin_module_notify_plugins_loaded_wrapper(GPluginModule *, PluginAction);
 
 /* Complète une liste de resources pour thème. */
 static void py_plugin_module_include_theme_wrapper(const GPluginModule *, PluginAction, gboolean, char ***, size_t *);
@@ -231,7 +231,7 @@ static void py_plugin_module_init_gclass(GPluginModuleClass *class, gpointer unu
     class->init = NULL;
     class->exit = NULL;
 
-    class->native_loaded = py_plugin_module_notify_native_loaded_wrapper;
+    class->plugins_loaded = py_plugin_module_notify_plugins_loaded_wrapper;
 
     class->include_theme = py_plugin_module_include_theme_wrapper;
     class->notify_panel = py_plugin_module_notify_panel_creation_wrapper;
@@ -293,7 +293,7 @@ static int py_plugin_module_init(PyObject *self, PyObject *args, PyObject *kwds)
     "\n"                                                                    \
     "Depending on the implemented actions, some of the following methods"   \
     " have to be defined for new classes:\n"                                \
-    "* pychrysalide.PluginModule._notify_native_loaded();\n"                \
+    "* pychrysalide.PluginModule._notify_plugins_loaded();\n"               \
     "* pychrysalide.PluginModule._include_theme();\n"                       \
     "* pychrysalide.PluginModule._on_panel_creation;\n"                     \
     "* pychrysalide.PluginModule._on_panel_docking();\n"                    \
@@ -394,37 +394,38 @@ static int py_plugin_module_init(PyObject *self, PyObject *args, PyObject *kwds)
 *                                                                             *
 ******************************************************************************/
 
-static void py_plugin_module_notify_native_loaded_wrapper(GPluginModule *plugin, PluginAction action)
+static void py_plugin_module_notify_plugins_loaded_wrapper(GPluginModule *plugin, PluginAction action)
 {
     PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
     PyObject *pyobj;                        /* Objet Python concerné       */
     PyObject *args;                         /* Arguments pour l'appel      */
     PyObject *pyret;                        /* Bilan d'exécution           */
 
-#define PLUGIN_MODULE_NOTIFY_NATIVE_LOADED_WRAPPER PYTHON_WRAPPER_DEF   \
+#define PLUGIN_MODULE_NOTIFY_PLUGINS_LOADED_WRAPPER PYTHON_WRAPPER_DEF  \
 (                                                                       \
-    _notify_native_loaded, "$self, action, /",                          \
+    _notify_plugins_loaded, "$self, action, /",                         \
     METH_VARARGS,                                                       \
-    "Abstract method called once all the native plugins are loaded.\n"  \
+    "Abstract method called once all the (native?) plugins are"         \
+    " loaded.\n"                                                        \
     "\n"                                                                \
     "The expected action is a pychrysalide.PluginModule.PluginAction"   \
     " value.\n"                                                         \
     "\n"                                                                \
-    "This method has to be defined in order to handle action such as"   \
-    " *NATIVE_LOADED*."                                                 \
+    "This method has to be defined in order to handle actions such as"  \
+    " *NATIVE_PLUGINS_LOADED* or *PLUGINS_LOADED*."                     \
 )
 
     gstate = PyGILState_Ensure();
 
     pyobj = pygobject_new(G_OBJECT(plugin));
 
-    if (has_python_method(pyobj, "_notify_native_loaded"))
+    if (has_python_method(pyobj, "_notify_plugins_loaded"))
     {
         args = PyTuple_New(1);
 
         PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(action));
 
-        pyret = run_python_method(pyobj, "_notify_native_loaded", args);
+        pyret = run_python_method(pyobj, "_notify_plugins_loaded", args);
 
         Py_XDECREF(pyret);
         Py_DECREF(args);
@@ -1629,7 +1630,7 @@ static PyObject *py_plugin_module_get_filename(PyObject *self, void *closure)
 PyTypeObject *get_python_plugin_module_type(void)
 {
     static PyMethodDef py_plugin_module_methods[] = {
-        PLUGIN_MODULE_NOTIFY_NATIVE_LOADED_WRAPPER,
+        PLUGIN_MODULE_NOTIFY_PLUGINS_LOADED_WRAPPER,
         PLUGIN_MODULE_INCLUDE_THEME_WRAPPER,
         PLUGIN_MODULE_ON_PANEL_CREATION_WRAPPER,
         PLUGIN_MODULE_ON_PANEL_DOCKING_WRAPPER,
diff --git a/src/plugins/pglist.c b/src/plugins/pglist.c
index cb366fe..ffcda63 100644
--- a/src/plugins/pglist.c
+++ b/src/plugins/pglist.c
@@ -470,7 +470,9 @@ void load_remaning_plugins(void)
 
     g_rw_lock_reader_unlock(&_pg_lock);
 
-    notify_native_loaded;
+    notify_native_plugins_loaded();
+
+    notify_plugins_loaded();
 
 }
 
diff --git a/src/plugins/pglist.h b/src/plugins/pglist.h
index ccf854f..d6c539d 100644
--- a/src/plugins/pglist.h
+++ b/src/plugins/pglist.h
@@ -107,8 +107,11 @@ GPluginModule **get_all_plugins_for_action(PluginAction, size_t *);
 
 /* DPS_PG_MANAGEMENT */
 
-#define notify_native_loaded \
-    process_all_plugins_for(PGA_NATIVE_LOADED, g_plugin_module_notify_native_loaded, NULL)
+#define notify_native_plugins_loaded() \
+    process_all_plugins_for(PGA_NATIVE_PLUGINS_LOADED, g_plugin_module_notify_plugins_loaded, NULL)
+
+#define notify_plugins_loaded() \
+    process_all_plugins_for(PGA_PLUGINS_LOADED, g_plugin_module_notify_plugins_loaded, NULL)
 
 #define build_type_instance(t) \
     process_plugins_while_null(PGA_TYPE_BUILDING, g_plugin_module_build_type_instance, t)
diff --git a/src/plugins/plugin-def.h b/src/plugins/plugin-def.h
index e99d7b1..0c25a7a 100644
--- a/src/plugins/plugin-def.h
+++ b/src/plugins/plugin-def.h
@@ -121,10 +121,13 @@ typedef enum _PluginAction
      */
 
     /* Fin du chargement des greffons natifs */
-    PGA_NATIVE_LOADED = DPC_BASIC | DPS_CORE_MANAGEMENT | DEFINE_PLUGIN_ACTION(0),
+    PGA_NATIVE_PLUGINS_LOADED = DPC_BASIC | DPS_CORE_MANAGEMENT | DEFINE_PLUGIN_ACTION(0),
+
+    /* Fin du chargement de tous greffons */
+    PGA_PLUGINS_LOADED = DPC_BASIC | DPS_CORE_MANAGEMENT | DEFINE_PLUGIN_ACTION(1),
 
     /* Mise en place de type à partir de code externe */
-    PGA_TYPE_BUILDING = DPC_BASIC | DPS_CORE_MANAGEMENT | DEFINE_PLUGIN_ACTION(1),
+    PGA_TYPE_BUILDING = DPC_BASIC | DPS_CORE_MANAGEMENT | DEFINE_PLUGIN_ACTION(2),
 
     /**
      * DPC_GUI | DPS_SETUP
diff --git a/src/plugins/plugin-int.h b/src/plugins/plugin-int.h
index 9dd9173..98a07bb 100644
--- a/src/plugins/plugin-int.h
+++ b/src/plugins/plugin-int.h
@@ -43,7 +43,7 @@ typedef void (* pg_set_self_fc) (GPluginModule *);
 typedef bool (* pg_management_fc) (GPluginModule *);
 
 /* Accompagne la fin du chargement des modules natifs. */
-typedef void (* pg_native_loaded_fc) (GPluginModule *, PluginAction);
+typedef void (* pg_plugins_loaded_fc) (GPluginModule *, PluginAction);
 
 /* Crée une instance à partir d'un type dynamique externe. */
 typedef gpointer (* pg_build_instance_fc) (GPluginModule *, PluginAction, GType);
@@ -107,7 +107,7 @@ struct _GPluginModuleClass
     pg_management_fc init;                  /* Procédure d'initialisation  */
     pg_management_fc exit;                  /* Procédure d'extinction      */
 
-    pg_native_loaded_fc native_loaded;      /* Fin des chargements natifs  */
+    pg_plugins_loaded_fc plugins_loaded;    /* Fin des chargements         */
     pg_build_instance_fc build_instance;    /* Création d'objets           */
 
     pg_get_modname_fc get_modname;          /* Fourniture du nom brut      */
diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c
index 8b3654e..23ef34c 100644
--- a/src/plugins/plugin.c
+++ b/src/plugins/plugin.c
@@ -324,8 +324,9 @@ GPluginModule *g_plugin_module_new(const gchar *filename)
 
                         switch (action)
                         {
-                            case PGA_NATIVE_LOADED:
-                                valid = check_plugin_symbol(module, "chrysalide_plugin_on_native_loaded");
+                            case PGA_NATIVE_PLUGINS_LOADED:
+                            case PGA_PLUGINS_LOADED:
+                                valid = check_plugin_symbol(module, "chrysalide_plugin_on_plugins_loaded");
                                 break;
 
                             case PGA_TYPE_BUILDING:
@@ -615,9 +616,10 @@ static void g_plugin_module_init_gclass(GPluginModuleClass *class, GModule *modu
 
                         switch (action)
                         {
-                            case PGA_NATIVE_LOADED:
-                                load_plugin_symbol(module, "chrysalide_plugin_on_native_loaded",
-                                                   &class->native_loaded);
+                            case PGA_NATIVE_PLUGINS_LOADED:
+                            case PGA_PLUGINS_LOADED:
+                                load_plugin_symbol(module, "chrysalide_plugin_on_plugins_loaded",
+                                                   &class->plugins_loaded);
                                 break;
 
                             case PGA_TYPE_BUILDING:
@@ -1238,7 +1240,7 @@ void g_plugin_module_log_variadic_message(const GPluginModule *plugin, LogMessag
 *                action = type d'action attendue.                             *
 *                unused = variable non utilisé pour l'usage de __VA_ARGS__.   *
 *                                                                             *
-*  Description : Accompagne la fin du chargement des modules natifs.          *
+*  Description : Accompagne la fin du chargement des modules.                 *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -1246,13 +1248,13 @@ void g_plugin_module_log_variadic_message(const GPluginModule *plugin, LogMessag
 *                                                                             *
 ******************************************************************************/
 
-void g_plugin_module_notify_native_loaded(GPluginModule *plugin, PluginAction action, void *unused)
+void g_plugin_module_notify_plugins_loaded(GPluginModule *plugin, PluginAction action, void *unused)
 {
     GPluginModuleClass *class;              /* Classe de l'instance active */
 
     class = G_PLUGIN_MODULE_GET_CLASS(plugin);
 
-    class->native_loaded(plugin, action);
+    class->plugins_loaded(plugin, action);
 
 }
 
diff --git a/src/plugins/plugin.h b/src/plugins/plugin.h
index 3e8d9c1..fc54aee 100644
--- a/src/plugins/plugin.h
+++ b/src/plugins/plugin.h
@@ -107,7 +107,7 @@ void g_plugin_module_log_simple_message(const GPluginModule *, LogMessageType, c
 void g_plugin_module_log_variadic_message(const GPluginModule *, LogMessageType, const char *, ...);
 
 /* Accompagne la fin du chargement des modules natifs. */
-void g_plugin_module_notify_native_loaded(GPluginModule *, PluginAction, void *);
+void g_plugin_module_notify_plugins_loaded(GPluginModule *, PluginAction, void *);
 
 /* Crée une instance à partir d'un type dynamique externe. */
 gpointer g_plugin_module_build_type_instance(GPluginModule *, PluginAction, GType);
-- 
cgit v0.11.2-87-g4458