From f782c58bc24df2b500ba163ece2568a434756409 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 29 Jan 2023 20:38:41 +0100
Subject: Create new helpers for constructors of abstract Python objects.

---
 plugins/pychrysalide/helpers.c | 62 ++++++++++++++++++++++++++++++++++++++++++
 plugins/pychrysalide/helpers.h | 34 +++++++++++++++++------
 2 files changed, 87 insertions(+), 9 deletions(-)

diff --git a/plugins/pychrysalide/helpers.c b/plugins/pychrysalide/helpers.c
index c289798..7199eca 100644
--- a/plugins/pychrysalide/helpers.c
+++ b/plugins/pychrysalide/helpers.c
@@ -567,6 +567,68 @@ PyObject *python_constructor_with_dynamic_gtype(PyTypeObject *type, PyObject *ar
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : type  = type du nouvel objet à mettre en place.              *
+*                args  = éventuelle liste d'arguments.                        *
+*                kwds  = éventuel dictionnaire de valeurs mises à disposition.*
+*                base  = type de base en Python.                              *
+*                gbase = type de base natif.                                  *
+*                cinit = procédure d'initialisation de la classe associée.    *
+*                                                                             *
+*  Description : Accompagne la création d'une instance dérivée en Python.     *
+*                                                                             *
+*  Retour      : Nouvel objet Python mis en place ou NULL en cas d'échec.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyObject *python_abstract_constructor_with_dynamic_gtype(PyTypeObject *type, PyObject *args, PyObject *kwds, PyTypeObject *base, GType gbase, GClassInitFunc cinit)
+{
+    PyObject *result;                       /* Objet à retourner           */
+    bool first_time;                        /* Evite les multiples passages*/
+    GType gtype;                            /* Nouveau type de processeur  */
+    bool status;                            /* Bilan d'un enregistrement   */
+
+    /* Validations diverses */
+
+    if (type == base)
+    {
+        result = NULL;
+        PyErr_Format(PyExc_RuntimeError, _("%s is an abstract class"), type->tp_name);
+        goto exit;
+    }
+
+    /* Mise en place d'un type dédié */
+
+    first_time = (g_type_from_name(type->tp_name) == 0);
+
+    gtype = build_dynamic_type(gbase, type->tp_name, cinit, NULL, NULL);
+
+    if (first_time)
+    {
+        status = register_class_for_dynamic_pygobject(gtype, type, base);
+
+        if (!status)
+        {
+            result = NULL;
+            goto exit;
+        }
+
+    }
+
+    /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
+
+    result = PyType_GenericNew(type, args, kwds);
+
+ exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : type = type du nouvel objet à mettre en place.               *
 *                args = éventuelle liste d'arguments.                         *
 *                kwds = éventuel dictionnaire de valeurs mises à disposition. *
diff --git a/plugins/pychrysalide/helpers.h b/plugins/pychrysalide/helpers.h
index 6b2bddf..348c110 100644
--- a/plugins/pychrysalide/helpers.h
+++ b/plugins/pychrysalide/helpers.h
@@ -163,16 +163,32 @@ bool register_python_module_object(PyObject *, PyTypeObject *);
 /* Accompagne la création d'une instance dérivée en Python. */
 PyObject *python_constructor_with_dynamic_gtype(PyTypeObject *, PyObject *, PyObject *, PyTypeObject *, GType);
 
+/* Accompagne la création d'une instance dérivée en Python. */
+PyObject *python_abstract_constructor_with_dynamic_gtype(PyTypeObject *, PyObject *, PyObject *, PyTypeObject *, GType, GClassInitFunc);
+
+
+#define CREATE_DYN_CONSTRUCTOR(pyname, gbase)                                                       \
+static PyObject *py_ ## pyname ## _new(PyTypeObject *, PyObject *, PyObject *);                     \
+static PyObject *py_ ## pyname ## _new(PyTypeObject *type, PyObject *args, PyObject *kwds)          \
+{                                                                                                   \
+    PyObject *result;                       /* Objet à retourner           */                       \
+    PyTypeObject *base;                     /* Type de base à dériver      */                       \
+    base = get_python_ ## pyname ## _type();                                                        \
+    result = python_constructor_with_dynamic_gtype(type, args, kwds, base, gbase);                  \
+    return result;                                                                                  \
+}
+
 
-#define CREATE_DYN_CONSTRUCTOR(pyname, gbase)                                               \
-static PyObject *py_ ## pyname ## _new(PyTypeObject *, PyObject *, PyObject *);             \
-static PyObject *py_ ## pyname ## _new(PyTypeObject *type, PyObject *args, PyObject *kwds)  \
-{                                                                                           \
-    PyObject *result;                       /* Objet à retourner           */               \
-    PyTypeObject *base;                     /* Type de base à dériver      */               \
-    base = get_python_ ## pyname ## _type();                                                \
-    result = python_constructor_with_dynamic_gtype(type, args, kwds, base, gbase);          \
-    return result;                                                                          \
+#define CREATE_DYN_ABSTRACT_CONSTRUCTOR(pyname, gbase, cinit)                                       \
+static PyObject *py_ ## pyname ## _new(PyTypeObject *, PyObject *, PyObject *);                     \
+static PyObject *py_ ## pyname ## _new(PyTypeObject *type, PyObject *args, PyObject *kwds)          \
+{                                                                                                   \
+    PyObject *result;                       /* Objet à retourner           */                       \
+    PyTypeObject *base;                     /* Type de base à dériver      */                       \
+    base = get_python_ ## pyname ## _type();                                                        \
+    result = python_abstract_constructor_with_dynamic_gtype(type, args, kwds,                       \
+                                                            base, gbase, (GClassInitFunc)cinit);    \
+    return result;                                                                                  \
 }
 
 
-- 
cgit v0.11.2-87-g4458