From 0b5e9a3c7bcd3eb15be0e888ebfe46d14497b101 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 28 Sep 2021 23:40:39 +0200 Subject: Rely on a generic task to analyze loaded content. --- src/analysis/loaded.c | 351 ++++++++++++++++---------------------------- src/glibext/seq.c | 2 +- src/glibext/seq.h | 4 + src/gtkext/gtkstatusstack.c | 2 +- src/gtkext/gtkstatusstack.h | 3 + 5 files changed, 138 insertions(+), 224 deletions(-) diff --git a/src/analysis/loaded.c b/src/analysis/loaded.c index c1f6e17..10ab05e 100644 --- a/src/analysis/loaded.c +++ b/src/analysis/loaded.c @@ -25,6 +25,7 @@ #include +#include #include "loaded-int.h" @@ -33,6 +34,7 @@ #include "../glibext/chrysamarshal.h" #include "../glibext/gloadedpanel.h" #include "../glibext/named-int.h" +#include "../glibext/seq.h" #include "../plugins/pglist.h" @@ -45,66 +47,32 @@ typedef struct _GLoadedAnalysis GLoadedAnalysis; /* ---------------------- GESTION SOUS FORME DE CONTENU CHARGE ---------------------- */ -/* Procède à l'initialisation de l'interface de contenu chargé. */ -static void g_loaded_content_default_init(GLoadedContentInterface *); - -/* Acquitte la fin d'une tâche d'analyse différée et complète. */ -static void on_loaded_content_analysis_completed(GLoadedAnalysis *, GLoadedContent *); - - - -/* -------------------------- PHASE D'ANALYSE EN PARALLELE -------------------------- */ - - -#define G_TYPE_LOADED_ANALYSIS g_loaded_analysis_get_type() -#define G_LOADED_ANALYSIS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_LOADED_ANALYSIS, GDelayedDisassembly)) -#define G_IS_LOADED_ANALYSIS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_LOADED_ANALYSIS)) -#define G_LOADED_ANALYSIS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_LOADED_ANALYSIS, GDelayedDisassemblyClass)) -#define G_IS_LOADED_ANALYSIS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_LOADED_ANALYSIS)) -#define G_LOADED_ANALYSIS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_LOADED_ANALYSIS, GDelayedDisassemblyClass)) - - -/* Analyse de contenu chargé (instance) */ -struct _GLoadedAnalysis +/* Données de travail */ +typedef struct _analysis_data_t { - GDelayedWork parent; /* A laisser en premier */ - GLoadedContent *content; /* Cible de l'analyse à mener */ bool connect; /* Lancement de connexions ? */ bool cache; /* Degré d'opération à mener */ bool success; /* Bilan de l'opération */ -}; - -/* Analyse de contenu chargé (classe) */ -typedef struct _GLoadedAnalysisClass -{ - GDelayedWorkClass parent; /* A laisser en premier */ - -} GLoadedAnalysisClass; - - -/* Indique le type défini pour les tâches d'analyse différée. */ -static GType g_loaded_analysis_get_type(void); +} analysis_data_t; -/* Initialise la classe des tâches d'analyse différées. */ -static void g_loaded_analysis_class_init(GLoadedAnalysisClass *); -/* Initialise une tâche d'analyse de contenu différée. */ -static void g_loaded_analysis_init(GLoadedAnalysis *); +/* Procède à l'initialisation de l'interface de contenu chargé. */ +static void g_loaded_content_default_init(GLoadedContentInterface *); -/* Supprime toutes les références externes. */ -static void g_loaded_analysis_dispose(GLoadedAnalysis *); +/* Crée une structure pour accompagner une tâche d'analyse. */ +static analysis_data_t *create_analysis_data(GLoadedContent *, bool, bool); -/* Procède à la libération totale de la mémoire. */ -static void g_loaded_analysis_finalize(GLoadedAnalysis *); +/* Assure l'analyse d'un contenu chargé en différé. */ +static bool process_analysis_with_data(analysis_data_t *, size_t, GtkStatusStack *, activity_id_t); -/* Crée une tâche d'analyse de contenu différée. */ -static GLoadedAnalysis *g_loaded_analysis_new(GLoadedContent *, bool, bool); +/* Efface une structure d'accompagnement de tâche d'analyse. */ +static void delete_analysis_data(analysis_data_t *); -/* Assure l'analyse d'un contenu chargé en différé. */ -static void g_loaded_analysis_process(GLoadedAnalysis *, GtkStatusStack *); +/* Acquitte la fin d'une tâche d'analyse différée et complète. */ +static void on_loaded_content_analysis_completed(GSeqWork *, analysis_data_t *); @@ -282,6 +250,99 @@ char *g_loaded_content_get_format_name(const GLoadedContent *content) /****************************************************************************** * * +* Paramètres : content = contenu chargé à traiter. * +* connect = organise le lancement des connexions aux serveurs. * +* cache = précise si la préparation d'un rendu est demandée. * +* * +* Description : Crée une structure pour accompagner une tâche d'analyse. * +* * +* Retour : Structure d'accompagnement initialisée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static analysis_data_t *create_analysis_data(GLoadedContent *content, bool connect, bool cache) +{ + analysis_data_t *result; /* Structure à retourner */ + + result = malloc(sizeof(analysis_data_t)); + + result->content = content; + g_object_ref(G_OBJECT(content)); + + result->connect = connect; + result->cache = cache; + + result->success = true; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = ensemble d'informations utiles à l'opération. * +* i = indice des éléments à traiter. * +* status = barre de statut à tenir informée. * +* id = identifiant du message affiché à l'utilisateur. * +* * +* Description : Assure l'analyse d'un contenu chargé en différé. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool process_analysis_with_data(analysis_data_t *data, size_t i, GtkStatusStack *status, activity_id_t id) +{ + GLoadedContentIface *iface; /* Interface utilisée */ + GWorkQueue *queue; /* Gestionnaire de différés */ + wgroup_id_t gid; /* Identifiant pour les tâches */ + + iface = G_LOADED_CONTENT_GET_IFACE(data->content); + + queue = get_work_queue(); + + gid = g_work_queue_define_work_group(queue); + + data->success = iface->analyze(data->content, data->connect, data->cache, gid, status); + + if (data->success) + handle_loaded_content(PGA_CONTENT_ANALYZED, data->content, gid, status); + + g_work_queue_delete_work_group(queue, gid); + + return data->success; + +} + + +/****************************************************************************** +* * +* Paramètres : data = données à supprimer de la mémoire. * +* * +* Description : Efface une structure d'accompagnement de tâche d'analyse. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void delete_analysis_data(analysis_data_t *data) +{ + g_clear_object(&data->content); + + free(data); + +} + + +/****************************************************************************** +* * * Paramètres : content = élément chargé à manipuler. * * connect = organise le lancement des connexions aux serveurs. * * cache = précise si la préparation d'un rendu est demandée. * @@ -296,13 +357,19 @@ char *g_loaded_content_get_format_name(const GLoadedContent *content) void g_loaded_content_analyze(GLoadedContent *content, bool connect, bool cache) { - GLoadedAnalysis *analysis; /* Analyse à mener */ + analysis_data_t *data; /* Données d'accompagnement */ + GSeqWork *analysis; /* Analyse à mener */ GWorkQueue *queue; /* Gestionnaire de différés */ - analysis = g_loaded_analysis_new(content, connect, cache); + data = create_analysis_data(content, connect, cache); + + analysis = g_gen_work_new_boolean(data, NO_ACTIVITY_ID, + (seq_work_bool_cb)process_analysis_with_data, &data->success); + + g_object_set_data_full(G_OBJECT(analysis), "analysis_data", data, (GDestroyNotify)delete_analysis_data); g_signal_connect(analysis, "work-completed", - G_CALLBACK(on_loaded_content_analysis_completed), content); + G_CALLBACK(on_loaded_content_analysis_completed), data); queue = get_work_queue(); @@ -314,7 +381,7 @@ void g_loaded_content_analyze(GLoadedContent *content, bool connect, bool cache) /****************************************************************************** * * * Paramètres : analysis = tâche d'analyse menée à bien. * -* content = contenu chargé dont l'analyse est terminée. * +* data = données associées à l'opération. * * * * Description : Acquitte la fin d'une tâche d'analyse différée et complète. * * * @@ -324,9 +391,9 @@ void g_loaded_content_analyze(GLoadedContent *content, bool connect, bool cache) * * ******************************************************************************/ -static void on_loaded_content_analysis_completed(GLoadedAnalysis *analysis, GLoadedContent *content) +static void on_loaded_content_analysis_completed(GSeqWork *analysis, analysis_data_t *data) { - g_signal_emit_by_name(content, "analyzed", analysis->success); + g_signal_emit_by_name(data->content, "analyzed", data->success); } @@ -348,12 +415,15 @@ static void on_loaded_content_analysis_completed(GLoadedAnalysis *analysis, GLoa bool g_loaded_content_analyze_and_wait(GLoadedContent *content, bool connect, bool cache) { bool result; /* Bilan à retourner */ - GLoadedAnalysis *analysis; /* Analyse à mener */ + analysis_data_t *data; /* Données d'accompagnement */ + GSeqWork *analysis; /* Analyse à mener */ GWorkQueue *queue; /* Gestionnaire de différés */ wgroup_id_t gid; /* Identifiant pour les tâches */ - analysis = g_loaded_analysis_new(content, connect, cache); - g_object_ref(G_OBJECT(analysis)); + data = create_analysis_data(content, connect, cache); + + analysis = g_gen_work_new_boolean(data, NO_ACTIVITY_ID, + (seq_work_bool_cb)process_analysis_with_data, &data->success); queue = get_work_queue(); @@ -365,8 +435,9 @@ bool g_loaded_content_analyze_and_wait(GLoadedContent *content, bool connect, bo g_work_queue_delete_work_group(queue, gid); - result = analysis->success; - g_object_unref(G_OBJECT(analysis)); + result = data->success; + + delete_analysis_data(data); return result; @@ -604,170 +675,6 @@ GDisplayOptions *g_loaded_content_get_display_options(const GLoadedContent *cont /* ---------------------------------------------------------------------------------- */ -/* PHASE D'ANALYSE EN PARALLELE */ -/* ---------------------------------------------------------------------------------- */ - - -/* Indique le type défini pour les tâches d'analyse différée. */ -G_DEFINE_TYPE(GLoadedAnalysis, g_loaded_analysis, G_TYPE_DELAYED_WORK); - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des tâches d'analyse différées. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_loaded_analysis_class_init(GLoadedAnalysisClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - GDelayedWorkClass *work; /* Version en classe parente */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_loaded_analysis_dispose; - object->finalize = (GObjectFinalizeFunc)g_loaded_analysis_finalize; - - work = G_DELAYED_WORK_CLASS(klass); - - work->run = (run_task_fc)g_loaded_analysis_process; - -} - - -/****************************************************************************** -* * -* Paramètres : analysis = instance à initialiser. * -* * -* Description : Initialise une tâche d'analyse de contenu différée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_loaded_analysis_init(GLoadedAnalysis *analysis) -{ - analysis->success = false; - -} - - -/****************************************************************************** -* * -* Paramètres : disass = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_loaded_analysis_dispose(GLoadedAnalysis *analysis) -{ - g_clear_object(&analysis->content); - - G_OBJECT_CLASS(g_loaded_analysis_parent_class)->dispose(G_OBJECT(analysis)); - -} - - -/****************************************************************************** -* * -* Paramètres : analysis = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_loaded_analysis_finalize(GLoadedAnalysis *analysis) -{ - G_OBJECT_CLASS(g_loaded_analysis_parent_class)->finalize(G_OBJECT(analysis)); - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu chargé à traiter. * -* connect = organise le lancement des connexions aux serveurs. * -* cache = précise si la préparation d'un rendu est demandée. * -* * -* Description : Crée une tâche d'analyse de contenu différée. * -* * -* Retour : Tâche créée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GLoadedAnalysis *g_loaded_analysis_new(GLoadedContent *content, bool connect, bool cache) -{ - GLoadedAnalysis *result; /* Tâche à retourner */ - - result = g_object_new(G_TYPE_LOADED_ANALYSIS, NULL); - - result->content = content; - g_object_ref(G_OBJECT(content)); - - result->connect = connect; - result->cache = cache; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : analysis = analyse à mener. * -* status = barre de statut à tenir informée. * -* * -* Description : Assure l'analyse d'un contenu chargé en différé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_loaded_analysis_process(GLoadedAnalysis *analysis, GtkStatusStack *status) -{ - GLoadedContentIface *iface; /* Interface utilisée */ - GWorkQueue *queue; /* Gestionnaire de différés */ - wgroup_id_t gid; /* Identifiant pour les tâches */ - - iface = G_LOADED_CONTENT_GET_IFACE(analysis->content); - - queue = get_work_queue(); - - gid = g_work_queue_define_work_group(queue); - - analysis->success = iface->analyze(analysis->content, analysis->connect, analysis->cache, gid, status); - - if (analysis->success) - handle_loaded_content(PGA_CONTENT_ANALYZED, analysis->content, gid, status); - - g_work_queue_delete_work_group(queue, gid); - -} - - - -/* ---------------------------------------------------------------------------------- */ /* VUES ET BASCULEMENT ENTRE LES VUES */ /* ---------------------------------------------------------------------------------- */ diff --git a/src/glibext/seq.c b/src/glibext/seq.c index 3474d72..ba5cc35 100644 --- a/src/glibext/seq.c +++ b/src/glibext/seq.c @@ -343,7 +343,7 @@ static void g_seq_work_process(GSeqWork *work, GtkStatusStack *status) } - if (work->type == SWT_BOOLEAN) + if (work->status != NULL && (work->type == SWT_BOOLEAN || work->type == SWT_OBJECT)) *(work->status) = (i == work->end && state); } diff --git a/src/glibext/seq.h b/src/glibext/seq.h index f275375..c00b4e2 100644 --- a/src/glibext/seq.h +++ b/src/glibext/seq.h @@ -71,6 +71,10 @@ GSeqWork *g_seq_work_new_boolean(void *, size_t, size_t, activity_id_t, seq_work /* Crée une tâche de traitement séquentiel avec objects. */ GSeqWork *g_seq_work_new_object(void *, size_t, size_t, activity_id_t, seq_work_obj_cb, bool *); +#define g_gen_work_new(d, i, c) g_seq_work_new(d, 0, 1, i, c) +#define g_gen_work_new_boolean(d, i, c, b) g_seq_work_new_boolean(d, 0, 1, i, c, b) +#define g_gen_work_new_object(d, i, c, b) g_seq_work_new_object(d, 0, 1, i, c, b) + #endif /* _GLIBEXT_SEQ_H */ diff --git a/src/gtkext/gtkstatusstack.c b/src/gtkext/gtkstatusstack.c index 1df5d35..0b35e1b 100644 --- a/src/gtkext/gtkstatusstack.c +++ b/src/gtkext/gtkstatusstack.c @@ -839,7 +839,7 @@ activity_id_t gtk_status_stack_add_activity(GtkStatusStack *stack, const char *m progress_info *info; /* Informations à consulter */ size_t new; /* Indice de l'activité créée */ - if (stack == NULL) return 0; + if (stack == NULL) return NO_ACTIVITY_ID; info = stack->prog_info; diff --git a/src/gtkext/gtkstatusstack.h b/src/gtkext/gtkstatusstack.h index b68e387..91182a1 100644 --- a/src/gtkext/gtkstatusstack.h +++ b/src/gtkext/gtkstatusstack.h @@ -75,6 +75,9 @@ void gtk_status_stack_reset_current_location(GtkStatusStack *); /* Identifiant unique de rapport de progression */ typedef unsigned long activity_id_t; +/* Identifiant particulier pour une absence d'identifiant */ +#define NO_ACTIVITY_ID 0 + /* Démarre le suivi d'une nouvelle activité. */ activity_id_t gtk_status_stack_add_activity(GtkStatusStack *, const char *, unsigned long); -- cgit v0.11.2-87-g4458