From 2c33301f914d19516f8a107033a5dd7a97d70d07 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 8 Dec 2024 19:33:48 +0100
Subject: Restore a reviewed singleton interface.

---
 plugins/pychrysalide/glibext/Makefile.am |   2 +-
 plugins/pychrysalide/glibext/module.c    |   7 +-
 plugins/pychrysalide/glibext/singleton.c | 176 +-------------------------
 src/glibext/Makefile.am                  |   2 +
 src/glibext/singleton-int.h              |  36 ++++--
 src/glibext/singleton.c                  | 204 +++----------------------------
 src/glibext/singleton.h                  |  47 +------
 7 files changed, 59 insertions(+), 415 deletions(-)

diff --git a/plugins/pychrysalide/glibext/Makefile.am b/plugins/pychrysalide/glibext/Makefile.am
index 8b021bb..69d272a 100644
--- a/plugins/pychrysalide/glibext/Makefile.am
+++ b/plugins/pychrysalide/glibext/Makefile.am
@@ -10,7 +10,6 @@ noinst_LTLIBRARIES = libpychrysaglibext.la
 # 	linecursor.h linecursor.c				\
 # 	linegen.h linegen.c						\
 # 	module.h module.c						\
-# 	singleton.h singleton.c
 
 # if BUILD_GTK_SUPPORT
 
@@ -25,6 +24,7 @@ libpychrysaglibext_la_SOURCES =				\
 	constants.h constants.c					\
 	module.h module.c						\
 	portion.h portion.c						\
+	singleton.h singleton.c					\
 	work.h work.c							\
 	workqueue.h workqueue.c
 
diff --git a/plugins/pychrysalide/glibext/module.c b/plugins/pychrysalide/glibext/module.c
index e62d587..d913d92 100644
--- a/plugins/pychrysalide/glibext/module.c
+++ b/plugins/pychrysalide/glibext/module.c
@@ -39,9 +39,9 @@
 #include "linegen.h"
 #include "loadedpanel.h"
 #include "named.h"
-#include "singleton.h"
 */
 #include "portion.h"
+#include "singleton.h"
 #include "work.h"
 #include "workqueue.h"
 #include "../helpers.h"
@@ -110,12 +110,14 @@ bool populate_glibext_module(void)
 
     result = true;
 
+    if (result) result = ensure_python_singleton_candidate_is_registered();
+
     if (result) result = ensure_python_binary_portion_is_registered();
     if (result) result = ensure_python_generic_work_is_registered();
+    if (result) result = ensure_python_singleton_factory_is_registered();
     if (result) result = ensure_python_work_queue_is_registered();
 
     /*
-    if (result) result = ensure_python_singleton_candidate_is_registered();
 
     if (result) result = ensure_python_binary_cursor_is_registered();
     if (result) result = ensure_python_buffer_cache_is_registered();
@@ -133,7 +135,6 @@ bool populate_glibext_module(void)
     if (result) result = ensure_python_loaded_panel_is_registered();
     if (result) result = ensure_python_named_widget_is_registered();
 #endif
-    if (result) result = ensure_python_singleton_factory_is_registered();
     */
 
     assert(result);
diff --git a/plugins/pychrysalide/glibext/singleton.c b/plugins/pychrysalide/glibext/singleton.c
index 8491473..4aad7f5 100644
--- a/plugins/pychrysalide/glibext/singleton.c
+++ b/plugins/pychrysalide/glibext/singleton.c
@@ -42,7 +42,7 @@
 
 
 /* Procède à l'initialisation de l'interface de candidature. */
-static void py_singleton_candidate_interface_init(GSingletonCandidateIface *, gpointer *);
+static void py_singleton_candidate_interface_init(GSingletonCandidateInterface *, gpointer *);
 
 /* Fournit une liste de candidats embarqués par un candidat. */
 static GSingletonCandidate **py_singleton_candidate_list_inner_instances_wrapper(const GSingletonCandidate *, size_t *);
@@ -56,21 +56,12 @@ static guint py_singleton_candidate___hash__wrapper(const GSingletonCandidate *)
 /* Détermine si deux candidats à l'unicité sont identiques. */
 static gboolean py_singleton_candidate___eq__wrapper(const GSingletonCandidate *, const GSingletonCandidate *);
 
-/* Marque un candidat comme figé. */
-static void py_singleton_candidate_set_ro_wrapper(GSingletonCandidate *);
-
-/* Indique si le candidat est figé. */
-static bool py_singleton_candidate_is_ro_wrapper(const GSingletonCandidate *);
-
 /* Fournit l'empreinte d'un candidat à une centralisation. */
 static PyObject *py_singleton_candidate_hash(PyObject *, PyObject *);
 
 /* Fournit une liste de candidats embarqués par un candidat. */
 static PyObject *py_singleton_candidate_get_inner_instances(PyObject *, void *);
 
-/* Indique si le candidat est figé. */
-static PyObject *py_singleton_candidate_get_read_only(PyObject *, void *);
-
 /* Effectue une comparaison avec un objet 'SingletonCandidate'. */
 static PyObject *py_singleton_candidate_richcompare(PyObject *, PyObject *, int);
 
@@ -108,7 +99,7 @@ static PyObject *py_singleton_factory_get_instance(PyObject *, PyObject *);
 *                                                                             *
 ******************************************************************************/
 
-static void py_singleton_candidate_interface_init(GSingletonCandidateIface *iface, gpointer *unused)
+static void py_singleton_candidate_interface_init(GSingletonCandidateInterface *iface, gpointer *unused)
 {
 #define SINGLETON_CANDIDATE_DOC                                             \
     "The SingletonCandidate class is a required interface for objects"      \
@@ -127,9 +118,7 @@ static void py_singleton_candidate_interface_init(GSingletonCandidateIface *ifac
     "* pychrysalide.glibext.SingletonCandidate._list_inner_instances();\n"  \
     "* pychrysalide.glibext.SingletonCandidate._update_inner_instances();\n"\
     "* pychrysalide.glibext.SingletonCandidate.__hash__();\n"               \
-    "* pychrysalide.glibext.SingletonCandidate.__eq__();\n"                 \
-    "* pychrysalide.glibext.SingletonCandidate._set_read_only();\n"         \
-    "* pychrysalide.glibext.SingletonCandidate._is_read_only().\n"
+    "* pychrysalide.glibext.SingletonCandidate.__eq__().\n"
 
     iface->update_inner = py_singleton_candidate_update_inner_instances_wrapper;
     iface->list_inner = py_singleton_candidate_list_inner_instances_wrapper;
@@ -137,9 +126,6 @@ static void py_singleton_candidate_interface_init(GSingletonCandidateIface *ifac
     iface->hash = py_singleton_candidate___hash__wrapper;
     iface->is_equal = py_singleton_candidate___eq__wrapper;
 
-    iface->set_ro = py_singleton_candidate_set_ro_wrapper;
-    iface->is_ro = py_singleton_candidate_is_ro_wrapper;
-
 }
 
 
@@ -440,111 +426,6 @@ static gboolean py_singleton_candidate___eq__wrapper(const GSingletonCandidate *
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : candidate = objet dont l'instance se veut unique.            *
-*                                                                             *
-*  Description : Marque un candidat comme figé.                               *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void py_singleton_candidate_set_ro_wrapper(GSingletonCandidate *candidate)
-{
-    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
-    PyObject *pyobj;                        /* Objet Python concerné       */
-    PyObject *pyret;                        /* Bilan de consultation       */
-
-#define SINGLETON_CANDIDATE_SET_RO_WRAPPER PYTHON_WRAPPER_DEF   \
-(                                                               \
-    _set_read_only, "$self, /",                        \
-    METH_NOARGS,                                                \
-    "Abstract method used to mark the content of a singleton"   \
-    " candidate as read-only.\n"                                \
-    "\n"                                                        \
-    "The read-only state is mandatory once the candidate is"    \
-    " registered inside a pychrysalide.glibext.SingletonFactory"\
-    " instance as official singleton."                          \
-)
-
-    gstate = PyGILState_Ensure();
-
-    pyobj = pygobject_new(G_OBJECT(candidate));
-
-    if (has_python_method(pyobj, "_set_read_only"))
-    {
-        pyret = run_python_method(pyobj, "_set_read_only", NULL);
-
-        Py_XDECREF(pyret);
-
-    }
-
-    Py_DECREF(pyobj);
-
-    PyGILState_Release(gstate);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : candidate = objet dont l'instance se veut unique.            *
-*                                                                             *
-*  Description : Indique si le candidat est figé.                             *
-*                                                                             *
-*  Retour      : true si le contenu du candidat ne peut plus être modifié.    *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool py_singleton_candidate_is_ro_wrapper(const GSingletonCandidate *candidate)
-{
-    bool result;                            /* Etat à retourner            */
-    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
-    PyObject *pyobj;                        /* Objet Python concerné       */
-    PyObject *pyret;                        /* Bilan de consultation       */
-
-#define SINGLETON_CANDIDATE_IS_RO_WRAPPER PYTHON_WRAPPER_DEF    \
-(                                                               \
-    _is_read_only, "$self, /",                                  \
-    METH_NOARGS,                                                \
-    "Abstract method used to retrieve the status of the data"   \
-    " contained by a singleton candidate.\n"                    \
-    "\n"                                                        \
-    "The retured value is *True* if the candidate is"           \
-    " registered inside a pychrysalide.glibext.SingletonFactory"\
-    " instance as official singleton, *False* otherwise."       \
-)
-
-    result = false;
-
-    gstate = PyGILState_Ensure();
-
-    pyobj = pygobject_new(G_OBJECT(candidate));
-
-    if (has_python_method(pyobj, "_is_read_only"))
-    {
-        pyret = run_python_method(pyobj, "_is_read_only", NULL);
-
-        result = (pyret == Py_True);
-
-        Py_XDECREF(pyret);
-
-    }
-
-    Py_DECREF(pyobj);
-
-    PyGILState_Release(gstate);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : self = objet dont l'instance se veut unique.                 *
 *                args = adresse non utilisée ici.                             *
 *                                                                             *
@@ -644,49 +525,6 @@ static PyObject *py_singleton_candidate_get_inner_instances(PyObject *self, void
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : self    = objet Python concerné par l'appel.                 *
-*                closure = non utilisé ici.                                   *
-*                                                                             *
-*  Description : Indique si le candidat est figé.                             *
-*                                                                             *
-*  Retour      : true si le contenu du candidat ne peut plus être modifié.    *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_singleton_candidate_get_read_only(PyObject *self, void *closure)
-{
-    PyObject *result;                       /* Valeur à retourner          */
-    GSingletonCandidate *candidate;         /* Mécanismes natifs           */
-    bool status;                            /* Etat de l'élément consulté  */
-
-#define SINGLETON_CANDIDATE_READ_ONLY_ATTRIB PYTHON_GET_DEF_FULL    \
-(                                                                   \
-    read_only, py_singleton_candidate,                              \
-    "State of the singleton candidate content.\n"                   \
-    "\n"                                                            \
-    "The result is a boolean: *True* if the object is registered"   \
-    " as singleton, *False* otherwise.\n"                           \
-    "\n"                                                            \
-    "Once a singleton, the object must not change its content as"   \
-    " it is a shared instance."                                     \
-)
-
-    candidate = G_SINGLETON_CANDIDATE(pygobject_get(self));
-
-    status = g_singleton_candidate_is_read_only(candidate);
-
-    result = status ? Py_True : Py_False;
-    Py_INCREF(result);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : a  = premier object Python à consulter.                      *
 *                b  = second object Python à consulter.                       *
 *                op = type de comparaison menée.                              *
@@ -755,15 +593,12 @@ PyTypeObject *get_python_singleton_candidate_type(void)
         SINGLETON_CANDIDATE_UPDATE_INNER_INSTANCES_WRAPPER,
         SINGLETON_CANDIDATE_HASH_WRAPPER,
         SINGLETON_CANDIDATE_EQ_WRAPPER,
-        SINGLETON_CANDIDATE_SET_RO_WRAPPER,
-        SINGLETON_CANDIDATE_IS_RO_WRAPPER,
         SINGLETON_CANDIDATE_HASH_METHOD,
         { NULL }
     };
 
     static PyGetSetDef py_singleton_candidate_getseters[] = {
         SINGLETON_CANDIDATE_INNER_INSTANCES_ATTRIB,
-        SINGLETON_CANDIDATE_READ_ONLY_ATTRIB,
         { NULL }
     };
 
@@ -973,11 +808,6 @@ static int py_singleton_factory_init(PyObject *self, PyObject *args, PyObject *k
     "\n"                                                                    \
     "The first processed instance defines the type handled by the factory."
 
-    /* Récupération des paramètres */
-
-    ret = PyArg_ParseTuple(args, "");
-    if (!ret) return -1;
-
     /* Initialisation d'un objet GLib */
 
     ret = forward_pygobjet_init(self);
diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am
index adbec4c..c6fbf2a 100644
--- a/src/glibext/Makefile.am
+++ b/src/glibext/Makefile.am
@@ -43,6 +43,8 @@ libglibext_la_SOURCES =						\
 	helpers.h								\
 	portion-int.h							\
 	portion.h portion.c						\
+	singleton-int.h							\
+	singleton.h singleton.c					\
 	work-int.h								\
 	work.h work.c							\
 	workgroup-int.h							\
diff --git a/src/glibext/singleton-int.h b/src/glibext/singleton-int.h
index 3db17f9..9212e2e 100644
--- a/src/glibext/singleton-int.h
+++ b/src/glibext/singleton-int.h
@@ -2,7 +2,7 @@
 /* Chrysalide - Outil d'analyse de fichiers binaires
  * singleton-int.h - définitions internes propres aux réductions du nombre d'instances d'un même type
  *
- * Copyright (C) 2021 Cyrille Bagard
+ * Copyright (C) 2021-2024 Cyrille Bagard
  *
  *  This file is part of Chrysalide.
  *
@@ -29,6 +29,9 @@
 
 
 
+/* ------------------ INTERFACE POUR CANDIDAT A UNE CENTRALISATION ------------------ */
+
+
 /* Fournit une liste de candidats embarqués par un candidat. */
 typedef GSingletonCandidate ** (* list_inner_instances_fc) (const GSingletonCandidate *, size_t *);
 
@@ -41,15 +44,9 @@ typedef guint (* hash_candidate_fc) (const GSingletonCandidate *);
 /* Détermine si deux candidats à l'unicité sont identiques. */
 typedef gboolean (* is_candidate_equal_fc) (const GSingletonCandidate *, const GSingletonCandidate *);
 
-/* Marque un candidat comme figé. */
-typedef void (* set_candidate_ro_fc) (GSingletonCandidate *);
-
-/* Indique si le candidat est figé. */
-typedef bool (* is_candidate_ro_fc) (const GSingletonCandidate *);
-
 
 /* Instance d'objet visant à être unique (interface) */
-struct _GSingletonCandidateIface
+struct _GSingletonCandidateInterface
 {
     GTypeInterface base_iface;              /* A laisser en premier        */
 
@@ -59,14 +56,29 @@ struct _GSingletonCandidateIface
     hash_candidate_fc hash;                 /* Prise d'empreinte           */
     is_candidate_equal_fc is_equal;         /* Comparaison                 */
 
-    set_candidate_ro_fc set_ro;             /* Bascule en mode figé        */
-    is_candidate_ro_fc is_ro;               /* Consultation de l'état      */
+};
+
+
+
+/* ------------------------- COLLECTION D'INSTANCES UNIQUES ------------------------- */
+
+
+/* Définition d'un compacteur d'instances de types (instance) */
+struct _GSingletonFactory
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    GHashTable *table;                      /* Suivi des conservations     */
+    GMutex access;                          /* Verrou pour la concurrence  */
 
 };
 
+/* Définition d'un compacteur d'instances de types (classe) */
+struct _GSingletonFactoryClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
 
-/* Redéfinition */
-typedef GSingletonCandidateIface GSingletonCandidateInterface;
+};
 
 
 
diff --git a/src/glibext/singleton.c b/src/glibext/singleton.c
index 78a3ad4..65b83e7 100644
--- a/src/glibext/singleton.c
+++ b/src/glibext/singleton.c
@@ -2,7 +2,7 @@
 /* Chrysalide - Outil d'analyse de fichiers binaires
  * singleton.c - réduction du nombre d'instances d'un même type
  *
- * Copyright (C) 2021 Cyrille Bagard
+ * Copyright (C) 2021-2024 Cyrille Bagard
  *
  *  This file is part of Chrysalide.
  *
@@ -25,6 +25,8 @@
 
 
 #include <assert.h>
+#include <malloc.h>
+#include <stdbool.h>
 
 
 #include "singleton-int.h"
@@ -33,44 +35,21 @@
 
 /* ------------------ INTERFACE POUR CANDIDAT A UNE CENTRALISATION ------------------ */
 
+
 /* Procède à l'initialisation de l'interface de rassemblement. */
 static void g_singleton_candidate_default_init(GSingletonCandidateInterface *);
 
 /* Met à jour une liste de candidats embarqués par un candidat. */
 static void g_singleton_candidate_update_inner_instances(GSingletonCandidate *, GSingletonCandidate **, size_t);
 
-/* Fournit l'empreinte d'un candidat à une centralisation. */
-static guint _g_singleton_candidate_hash(GSingletonCandidate *, GList **);
-
 /* Détermine si deux candidats à l'unicité sont identiques. */
 static gboolean _g_singleton_candidate_is_equal(GSingletonCandidate *, GSingletonCandidate *, GList **);
 
-/* Marque un candidat comme figé. */
-static void _g_singleton_candidate_set_read_only(GSingletonCandidate *, GList **);
-
 
 
 /* ------------------------- COLLECTION D'INSTANCES UNIQUES ------------------------- */
 
 
-/* Définition d'un compacteur d'instances de types (instance) */
-struct _GSingletonFactory
-{
-    GObject parent;                         /* A laisser en premier        */
-
-    GHashTable *table;                      /* Suivi des conservations     */
-    GMutex access;                          /* Verrou pour la concurrence  */
-
-};
-
-/* Définition d'un compacteur d'instances de types (classe) */
-struct _GSingletonFactoryClass
-{
-    GObjectClass parent;                    /* A laisser en premier        */
-
-};
-
-
 /* Initialise la classe des compacteurs d'instances de types. */
 static void g_singleton_factory_class_init(GSingletonFactoryClass *);
 
@@ -90,7 +69,7 @@ static void g_singleton_factory_finalize(GSingletonFactory *);
 /* ---------------------------------------------------------------------------------- */
 
 
-/* Détermine le type d'une interface pour la lecture de binaire. */
+/* Détermine le type d'une interface pour la constitution d'objets uniques. */
 G_DEFINE_INTERFACE(GSingletonCandidate, g_singleton_candidate, G_TYPE_OBJECT)
 
 
@@ -128,7 +107,7 @@ static void g_singleton_candidate_default_init(GSingletonCandidateInterface *ifa
 GSingletonCandidate **g_singleton_candidate_list_inner_instances(const GSingletonCandidate *candidate, size_t *count)
 {
     GSingletonCandidate **result;           /* Instances à retourner       */
-    GSingletonCandidateIface *iface;        /* Interface utilisée          */
+    GSingletonCandidateInterface *iface;    /* Interface utilisée          */
 
     iface = G_SINGLETON_CANDIDATE_GET_IFACE(candidate);
 
@@ -162,7 +141,7 @@ GSingletonCandidate **g_singleton_candidate_list_inner_instances(const GSingleto
 
 static void g_singleton_candidate_update_inner_instances(GSingletonCandidate *candidate, GSingletonCandidate **instances, size_t count)
 {
-    GSingletonCandidateIface *iface;        /* Interface utilisée          */
+    GSingletonCandidateInterface *iface;    /* Interface utilisée          */
 
     iface = G_SINGLETON_CANDIDATE_GET_IFACE(candidate);
 
@@ -181,7 +160,6 @@ static void g_singleton_candidate_update_inner_instances(GSingletonCandidate *ca
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : candidate = objet dont l'instance se veut unique.            *
-*                processed = liste de candidats déjà traités.                 *
 *                                                                             *
 *  Description : Fournit l'empreinte d'un candidat à une centralisation.      *
 *                                                                             *
@@ -191,70 +169,28 @@ static void g_singleton_candidate_update_inner_instances(GSingletonCandidate *ca
 *                                                                             *
 ******************************************************************************/
 
-static guint _g_singleton_candidate_hash(GSingletonCandidate *candidate, GList **processed)
+guint g_singleton_candidate_hash(GSingletonCandidate *candidate)
 {
     guint result;                           /* Valeur à retourner          */
-    GList *skip;                            /* Détection de boucle         */
-    GSingletonCandidateIface *iface;        /* Interface utilisée          */
+    GSingletonCandidateInterface *iface;    /* Interface utilisée          */
     GSingletonCandidate **children;         /* Instances internes          */
     size_t count;                           /* Quantité de ces instances   */
     size_t i;                               /* Boucle de parcours          */
 
-    skip = g_list_find(*processed, candidate);
-
-    if (skip != NULL)
-        result = 0;
-
-    else
-    {
-        iface = G_SINGLETON_CANDIDATE_GET_IFACE(candidate);
-
-        result = iface->hash(candidate);
-
-        *processed = g_list_append(*processed, candidate);
-
-        children = g_singleton_candidate_list_inner_instances(candidate, &count);
+    iface = G_SINGLETON_CANDIDATE_GET_IFACE(candidate);
 
-        for (i = 0; i < count; i++)
-        {
-            result ^= _g_singleton_candidate_hash(children[i], processed);
-            g_object_unref(G_OBJECT(children[i]));
-        }
+    result = iface->hash(candidate);
 
-        if (children != NULL)
-            free(children);
+    children = g_singleton_candidate_list_inner_instances(candidate, &count);
 
+    for (i = 0; i < count; i++)
+    {
+        result ^= g_singleton_candidate_hash(children[i]);
+        unref_object(children[i]);
     }
 
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : candidate = objet dont l'instance se veut unique.            *
-*                                                                             *
-*  Description : Fournit l'empreinte d'un candidat à une centralisation.      *
-*                                                                             *
-*  Retour      : Empreinte de l'élément représenté.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-guint g_singleton_candidate_hash(GSingletonCandidate *candidate)
-{
-    guint result;                           /* Valeur à retourner          */
-    GList *processed;                       /* Suivi des traitements       */
-
-    processed = NULL;
-
-    result = _g_singleton_candidate_hash(candidate, &processed);
-
-    assert(processed != NULL);
-
-    g_list_free(processed);
+    if (children != NULL)
+        free(children);
 
     return result;
 
@@ -279,7 +215,7 @@ static gboolean _g_singleton_candidate_is_equal(GSingletonCandidate *candidate,
 {
     gboolean result;                        /* Bilan à renvoyer            */
     GList *skip;                            /* Détection de boucle         */
-    GSingletonCandidateIface *iface;        /* Interface utilisée          */
+    GSingletonCandidateInterface *iface;    /* Interface utilisée          */
     GSingletonCandidate **children[2];      /* Instances internes          */
     size_t count[2];                        /* Quantité de ces instances   */
     size_t i;                               /* Boucle de parcours          */
@@ -380,106 +316,6 @@ gboolean g_singleton_candidate_is_equal(GSingletonCandidate *candidate, GSinglet
 }
 
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : candidate = objet dont l'instance se veut unique.            *
-*                processed = liste de candidats déjà traités.                 *
-*                                                                             *
-*  Description : Marque un candidat comme figé.                               *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void _g_singleton_candidate_set_read_only(GSingletonCandidate *candidate, GList **processed)
-{
-    GList *skip;                            /* Détection de boucle         */
-    GSingletonCandidateIface *iface;        /* Interface utilisée          */
-    GSingletonCandidate **children;         /* Instances internes          */
-    size_t count;                           /* Quantité de ces instances   */
-    size_t i;                               /* Boucle de parcours          */
-
-    skip = g_list_find(*processed, candidate);
-
-    if (skip == NULL)
-    {
-        iface = G_SINGLETON_CANDIDATE_GET_IFACE(candidate);
-
-        iface->set_ro(candidate);
-
-        *processed = g_list_append(*processed, candidate);
-
-        children = g_singleton_candidate_list_inner_instances(candidate, &count);
-
-        for (i = 0; i < count; i++)
-        {
-            _g_singleton_candidate_set_read_only(candidate, processed);
-            g_object_unref(G_OBJECT(children[i]));
-        }
-
-        if (children != NULL)
-            free(children);
-
-    }
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : candidate = objet dont l'instance se veut unique.            *
-*                                                                             *
-*  Description : Marque un candidat comme figé.                               *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_singleton_candidate_set_read_only(GSingletonCandidate *candidate)
-{
-    GList *processed;                       /* Suivi des traitements       */
-
-    processed = NULL;
-
-    _g_singleton_candidate_set_read_only(candidate, &processed);
-
-    assert(processed != NULL);
-
-    g_list_free(processed);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : candidate = objet dont l'instance se veut unique.            *
-*                                                                             *
-*  Description : Indique si le candidat est figé.                             *
-*                                                                             *
-*  Retour      : true si le contenu du candidat ne peut plus être modifié.    *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_singleton_candidate_is_read_only(const GSingletonCandidate *candidate)
-{
-    bool result;                            /* Etat à retourner            */
-    GSingletonCandidateIface *iface;        /* Interface utilisée          */
-
-    iface = G_SINGLETON_CANDIDATE_GET_IFACE(candidate);
-
-    result = iface->is_ro(candidate);
-
-    return result;
-
-}
-
-
 
 /* ---------------------------------------------------------------------------------- */
 /*                           COLLECTION D'INSTANCES UNIQUES                           */
@@ -688,8 +524,6 @@ GSingletonCandidate *g_singleton_factory_get_instance(GSingletonFactory *factory
         g_hash_table_add(factory->table, candidate);
 #endif
 
-        g_singleton_candidate_set_read_only(candidate);
-
         result = candidate;
 
     }
diff --git a/src/glibext/singleton.h b/src/glibext/singleton.h
index 629687a..36714fa 100644
--- a/src/glibext/singleton.h
+++ b/src/glibext/singleton.h
@@ -2,7 +2,7 @@
 /* Chrysalide - Outil d'analyse de fichiers binaires
  * singleton.h - prototypes pour la réduction du nombre d'instances d'un même type
  *
- * Copyright (C) 2021 Cyrille Bagard
+ * Copyright (C) 2021-2024 Cyrille Bagard
  *
  *  This file is part of Chrysalide.
  *
@@ -25,37 +25,18 @@
 #define _GLIBEXT_SINGLETON_H
 
 
-#include <glib-object.h>
-#include <stdbool.h>
-
-
-
-/* Définition d'un compacteur d'instances de types (instance) */
-typedef struct _GSingletonFactory GSingletonFactory;
+#include "helpers.h"
 
 
 
 /* ------------------ INTERFACE POUR CANDIDAT A UNE CENTRALISATION ------------------ */
 
 
-#define G_TYPE_SINGLETON_CANDIDATE             (g_singleton_candidate_get_type())
-#define G_SINGLETON_CANDIDATE(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SINGLETON_CANDIDATE, GSingletonCandidate))
-#define G_SINGLETON_CANDIDATE_CLASS(vtable)    (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_SINGLETON_CANDIDATE, GSingletonCandidateIface))
-#define G_IS_SINGLETON_CANDIDATE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SINGLETON_CANDIDATE))
-#define G_IS_SINGLETON_CANDIDATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_SINGLETON_CANDIDATE))
-#define G_SINGLETON_CANDIDATE_GET_IFACE(inst)  (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_SINGLETON_CANDIDATE, GSingletonCandidateIface))
-
-
-/* Instance d'objet visant à être unique (coquille vide) */
-typedef struct _GSingletonCandidate GSingletonCandidate;
+#define G_TYPE_SINGLETON_CANDIDATE (g_singleton_candidate_get_type())
 
-/* Instance d'objet visant à être unique (interface) */
-typedef struct _GSingletonCandidateIface GSingletonCandidateIface;
+DECLARE_INTERFACE(GSingletonCandidate, g_singleton_candidate, G, SINGLETON_CANDIDATE);
 
 
-/* Détermine le type d'une interface pour la lecture de binaire. */
-GType g_singleton_candidate_get_type(void) G_GNUC_CONST;
-
 /* Fournit une liste de candidats embarqués par un candidat. */
 GSingletonCandidate **g_singleton_candidate_list_inner_instances(const GSingletonCandidate *, size_t *);
 
@@ -65,31 +46,15 @@ guint g_singleton_candidate_hash(GSingletonCandidate *);
 /* Détermine si deux candidats à l'unicité sont identiques. */
 gboolean g_singleton_candidate_is_equal(GSingletonCandidate *, GSingletonCandidate *);
 
-/* Marque un candidat comme figé. */
-void g_singleton_candidate_set_read_only(GSingletonCandidate *);
-
-/* Indique si le candidat est figé. */
-bool g_singleton_candidate_is_read_only(const GSingletonCandidate *);
-
 
 
 /* ------------------------- COLLECTION D'INSTANCES UNIQUES ------------------------- */
 
 
-#define G_TYPE_SINGLETON_FACTORY            g_singleton_factory_get_type()
-#define G_SINGLETON_FACTORY(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SINGLETON_FACTORY, GSingletonFactory))
-#define G_IS_SINGLETON_FACTORY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SINGLETON_FACTORY))
-#define G_SINGLETON_FACTORY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SINGLETON_FACTORY, GSingletonFactoryClass))
-#define G_IS_SINGLETON_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SINGLETON_FACTORY))
-#define G_SINGLETON_FACTORY_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SINGLETON_FACTORY, GSingletonFactoryClass))
-
-
-/* Définition d'un compacteur d'instances de types (classe) */
-typedef struct _GSingletonFactoryClass GSingletonFactoryClass;
+#define G_TYPE_SINGLETON_FACTORY (g_singleton_factory_get_type())
 
+DECLARE_GTYPE(GSingletonFactory, g_singleton_factory, G, SINGLETON_FACTORY);
 
-/* Indique le type défini pour une mémoire de types d'objets. */
-GType g_singleton_factory_get_type(void);
 
 /* Crée un compacteur d'instances de types. */
 GSingletonFactory *g_singleton_factory_new(void);
-- 
cgit v0.11.2-87-g4458