From f0fa987133468d7d3cae7894d813b852782bf895 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 1 Jun 2018 23:33:51 +0200 Subject: Setup more control when updating panels. --- src/gui/panels/errors.c | 27 ++++++++++++++++++++------- src/gui/panels/panel-int.h | 6 ++++++ src/gui/panels/panel.c | 35 +++++++++++++++++++++++++++++++++++ src/gui/panels/symbols.c | 27 ++++++++++++++++++++------- src/gui/panels/updating-int.h | 4 ++++ src/gui/panels/updating.c | 35 +++++++++++++++++++++++++++++++++-- src/gui/panels/updating.h | 3 +++ 7 files changed, 121 insertions(+), 16 deletions(-) diff --git a/src/gui/panels/errors.c b/src/gui/panels/errors.c index b4be9ad..87c0a02 100644 --- a/src/gui/panels/errors.c +++ b/src/gui/panels/errors.c @@ -37,6 +37,7 @@ #include "updating-int.h" #include "../core/global.h" #include "../../core/global.h" +#include "../../core/queue.h" #include "../../format/format.h" #include "../../glibext/signal.h" #include "../../gtkext/support.h" @@ -161,8 +162,6 @@ static void on_error_selection_changed(GtkTreeSelection *, gpointer); /* Données utiles à la mise à jour */ struct _error_update_data { - GtkTreeModel *model; /* Source de données associée */ - size_t count; /* Nombre de soucis présents */ size_t kept; /* Nombre d'éléments affichés */ @@ -242,6 +241,8 @@ static void g_error_panel_class_init(GErrorPanelClass *klass) panel->unique = true; + panel->gid = setup_tiny_global_work_group(1); + } @@ -356,6 +357,7 @@ static void g_error_panel_init(GErrorPanel *panel) static void g_error_panel_interface_init(GUpdatablePanelInterface *iface) { iface->setup = (setup_updatable_cb)g_error_panel_setup; + iface->get_group = (get_updatable_group_cb)g_panel_item_get_group; iface->introduce = (introduce_updatable_cb)g_error_panel_introduce; iface->process = (process_updatable_cb)g_error_panel_process; iface->conclude = (conclude_updatable_cb)g_error_panel_conclude; @@ -1067,6 +1069,7 @@ static void g_error_panel_introduce(const GErrorPanel *panel, unsigned int uid, { GtkBuilder *builder; /* Constructeur utilisé */ GtkTreeView *treeview; /* Arborescence graphique */ + GtkTreeModel *model; /* Source de données associée */ /* Basculement de l'affichage hors ligne */ @@ -1076,10 +1079,13 @@ static void g_error_panel_introduce(const GErrorPanel *panel, unsigned int uid, treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); - data->model = gtk_tree_view_get_model(treeview); - g_object_ref(G_OBJECT(data->model)); + model = gtk_tree_view_get_model(treeview); - gtk_tree_view_set_model(treeview, NULL); + if (model != NULL) + { + g_object_ref(G_OBJECT(model)); + gtk_tree_view_set_model(treeview, NULL); + } } @@ -1135,6 +1141,10 @@ static void g_error_panel_conclude(GErrorPanel *panel, unsigned int uid, error_u { GtkBuilder *builder; /* Constructeur utilisé */ GtkTreeView *treeview; /* Arborescence graphique */ + GtkTreeModel *model; /* Source de données associée */ + + if (g_atomic_int_get(&G_PANEL_ITEM(panel)->switched) > 1) + goto skip_this_step; /* Mise à jour des statistiques */ @@ -1149,9 +1159,12 @@ static void g_error_panel_conclude(GErrorPanel *panel, unsigned int uid, error_u treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); - gtk_tree_view_set_model(treeview, data->model); + model = GTK_TREE_MODEL(gtk_builder_get_object(builder, "filter")); + + g_object_ref(G_OBJECT(model)); + gtk_tree_view_set_model(treeview, model); - g_object_unref(G_OBJECT(data->model)); + skip_this_step: g_panel_item_switch_to_updated_content(G_PANEL_ITEM(panel)); diff --git a/src/gui/panels/panel-int.h b/src/gui/panels/panel-int.h index 98c8b79..8f5f42f 100644 --- a/src/gui/panels/panel-int.h +++ b/src/gui/panels/panel-int.h @@ -80,6 +80,7 @@ struct _GPanelItem cairo_surface_t *surface; /* Copie d'écran préalable */ gdouble hadj_value; /* Sauvegarde de défilement #1 */ gdouble vadj_value; /* Sauvegarde de défilement #2 */ + gint switched; /* Mémorise l'état de bascule */ }; @@ -94,6 +95,8 @@ struct _GPanelItemClass ack_dock_process_fc ack_dock; /* Prise en compte d'accroche */ ack_undock_process_fc ack_undock; /* Prise en compte de décroche */ + wgroup_id_t gid; /* Groupe de travail dédié */ + /* Signaux */ void (* dock_request) (GPanelItem); @@ -114,6 +117,9 @@ GtkBuilder *g_panel_item_build(GPanelItem *, const char *); /* ---------------------- MECANISMES DE MISE A JOUR DE PANNEAU ---------------------- */ +/* Obtient le groupe de travail dédié à une mise à jour. */ +wgroup_id_t g_panel_item_get_group(const GPanelItem *); + /* Bascule l'affichage d'un panneau avant sa mise à jour. */ void g_panel_item_switch_to_updating_mask(GPanelItem *); diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c index dcb3d3f..424e779 100644 --- a/src/gui/panels/panel.c +++ b/src/gui/panels/panel.c @@ -144,6 +144,8 @@ static void g_panel_item_init(GPanelItem *item) item->personality = PIP_INVALID; + g_atomic_int_set(&item->switched, 0); + } @@ -675,6 +677,29 @@ void g_panel_item_undock(GPanelItem *item) /****************************************************************************** * * +* Paramètres : item = panneau ciblé par une mise à jour. * +* * +* Description : Obtient le groupe de travail dédié à une mise à jour. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +wgroup_id_t g_panel_item_get_group(const GPanelItem *item) +{ + wgroup_id_t result; /* Identifiant à retourner */ + + result = G_PANEL_ITEM_GET_CLASS(item)->gid; + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : widget = composant graphique sur lequel dessiner. * * cr = contexte graphique pour le dessin. * * panel = panneau ciblé par une mise à jour. * @@ -733,6 +758,9 @@ void g_panel_item_switch_to_updating_mask(GPanelItem *item) GtkStack *stack; /* Pile de composants GTK */ GtkWidget *mask; /* Masque des travaux */ + if (g_atomic_int_add(&item->switched, 1) > 0) + return; + /* Copie de l'affichage courant */ assert(item->surface == NULL); @@ -805,6 +833,9 @@ void g_panel_item_switch_to_updated_content(GPanelItem *item) GtkStack *stack; /* Pile de composants GTK */ GtkWidget *mask; /* Masque des travaux */ + if (g_atomic_int_get(&item->switched) > 1) + goto skip; + /* Restauration d'une éventuelle position */ content = GTK_WIDGET(gtk_builder_get_object(item->builder, "content")); @@ -839,4 +870,8 @@ void g_panel_item_switch_to_updated_content(GPanelItem *item) item->surface = NULL; } + skip: + + g_atomic_int_dec_and_test(&item->switched); + } diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c index fa671a4..fe295e0 100644 --- a/src/gui/panels/symbols.c +++ b/src/gui/panels/symbols.c @@ -40,6 +40,7 @@ #include "updating-int.h" #include "../core/global.h" #include "../../common/extstr.h" +#include "../../core/queue.h" #include "../../format/format.h" #include "../../format/symiter.h" #include "../../gtkext/easygtk.h" @@ -192,8 +193,6 @@ static bool is_symbol_matching(const GSymbolsPanel *, const GBinSymbol *, regmat /* Données utiles à la mise à jour */ struct _symbols_update_data { - GtkTreeModel *model; /* Source de données associée */ - size_t count; /* Qté d'inscriptions réalisées*/ char **expanded; /* Chemins des noeuds ouverts */ @@ -294,6 +293,8 @@ static void g_symbols_panel_class_init(GSymbolsPanelClass *klass) panel->unique = true; panel->bindings = "F3"; + panel->gid = setup_tiny_global_work_group(1); + } @@ -401,6 +402,7 @@ static void g_symbols_panel_init(GSymbolsPanel *panel) static void g_symbols_panel_interface_init(GUpdatablePanelInterface *iface) { iface->setup = (setup_updatable_cb)g_symbols_panel_setup; + iface->get_group = (get_updatable_group_cb)g_panel_item_get_group; iface->introduce = (introduce_updatable_cb)g_symbols_panel_introduce; iface->process = (process_updatable_cb)g_symbols_panel_process; iface->conclude = (conclude_updatable_cb)g_symbols_panel_conclude; @@ -1603,6 +1605,7 @@ static void g_symbols_panel_introduce(const GSymbolsPanel *panel, unsigned int u { GtkBuilder *builder; /* Constructeur utilisé */ GtkTreeView *treeview; /* Arborescence graphique */ + GtkTreeModel *model; /* Source de données associée */ /* Basculement de l'affichage hors ligne */ @@ -1612,10 +1615,13 @@ static void g_symbols_panel_introduce(const GSymbolsPanel *panel, unsigned int u treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); - data->model = gtk_tree_view_get_model(treeview); - g_object_ref(G_OBJECT(data->model)); + model = gtk_tree_view_get_model(treeview); - gtk_tree_view_set_model(treeview, NULL); + if (model != NULL) + { + g_object_ref(G_OBJECT(model)); + gtk_tree_view_set_model(treeview, NULL); + } } @@ -1671,10 +1677,14 @@ static void g_symbols_panel_conclude(GSymbolsPanel *panel, unsigned int uid, sym { GtkBuilder *builder; /* Constructeur utilisé */ GtkTreeView *treeview; /* Arborescence graphique */ + GtkTreeModel *model; /* Source de données associée */ size_t i; /* Boucle de parcours */ GtkTreePath *path; /* Chemin d'accès à un noeud */ GtkToggleToolButton *button; /* Mode de représentation */ + if (g_atomic_int_get(&G_PANEL_ITEM(panel)->switched) > 1) + goto skip_this_step; + /* Mise à jour des compteurs */ panel->count = data->count; @@ -1685,9 +1695,10 @@ static void g_symbols_panel_conclude(GSymbolsPanel *panel, unsigned int uid, sym treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview")); - gtk_tree_view_set_model(treeview, data->model); + model = GTK_TREE_MODEL(gtk_builder_get_object(builder, "filter")); - g_object_unref(G_OBJECT(data->model)); + g_object_ref(G_OBJECT(model)); + gtk_tree_view_set_model(treeview, model); for (i = 0; i < data->ecount; i++) { @@ -1706,6 +1717,8 @@ static void g_symbols_panel_conclude(GSymbolsPanel *panel, unsigned int uid, sym if (!gtk_toggle_tool_button_get_active(button)) reorganize_symbols_tree_view(NULL, panel); + skip_this_step: + g_panel_item_switch_to_updated_content(G_PANEL_ITEM(panel)); } diff --git a/src/gui/panels/updating-int.h b/src/gui/panels/updating-int.h index 40414ce..18c038e 100644 --- a/src/gui/panels/updating-int.h +++ b/src/gui/panels/updating-int.h @@ -32,6 +32,9 @@ /* Prépare une opération de mise à jour de panneau. */ typedef const char * (* setup_updatable_cb) (const GUpdatablePanel *, unsigned int, size_t *, void **); +/* Obtient le groupe de travail dédié à une mise à jour. */ +typedef wgroup_id_t (* get_updatable_group_cb) (const GUpdatablePanel *); + /* Bascule l'affichage d'un panneau avant mise à jour. */ typedef void (* introduce_updatable_cb) (const GUpdatablePanel *, unsigned int, void *); @@ -53,6 +56,7 @@ struct _GUpdatablePanelIface /* Méthodes virtuelles */ setup_updatable_cb setup; /* Préparation des traitements */ + get_updatable_group_cb get_group; /* Obtention du groupe dédié */ introduce_updatable_cb introduce; /* Changement d'affichage #0 */ process_updatable_cb process; /* Mise à jour d'affichage */ conclude_updatable_cb conclude; /* Changement d'affichage #1 */ diff --git a/src/gui/panels/updating.c b/src/gui/panels/updating.c index 824898a..a54a1af 100644 --- a/src/gui/panels/updating.c +++ b/src/gui/panels/updating.c @@ -29,7 +29,6 @@ #include "updating-int.h" #include "../../core/global.h" -#include "../../core/queue.h" #include "../../glibext/delayed-int.h" #include "../../glibext/signal.h" @@ -146,6 +145,32 @@ const char *g_updatable_panel_setup(const GUpdatablePanel *panel, unsigned int u /****************************************************************************** * * * Paramètres : panel = panneau ciblé par une mise à jour. * +* * +* Description : Obtient le groupe de travail dédié à une mise à jour. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +wgroup_id_t g_updatable_panel_get_group(const GUpdatablePanel *panel) +{ + wgroup_id_t result; /* Identifiant à retourner */ + GUpdatablePanelIface *iface; /* Interface utilisée */ + + iface = G_UPDATABLE_PANEL_GET_IFACE(panel); + + result = iface->get_group(panel); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : panel = panneau ciblé par une mise à jour. * * uid = identifiant de la phase de traitement. * * data = données préparées par l'appelant. * * * @@ -446,6 +471,8 @@ static void conclude_panel_update(GPanelUpdate *update, GUpdatablePanel *panel) void run_panel_update(GUpdatablePanel *panel, unsigned int uid) { + GWorkQueue *queue; /* Gestionnaire de tâches */ + wgroup_id_t gid; /* Groupe de travail à utiliser*/ GPanelUpdate *update; /* Procédure de mise à jour */ update = g_panel_update_new(panel, uid); @@ -455,6 +482,10 @@ void run_panel_update(GUpdatablePanel *panel, unsigned int uid) g_updatable_panel_introduce(panel, uid, update->data); - g_work_queue_schedule_work(get_work_queue(), G_DELAYED_WORK(update), DEFAULT_WORK_GROUP); + queue = get_work_queue(); + + gid = g_updatable_panel_get_group(panel); + + g_work_queue_schedule_work(queue, G_DELAYED_WORK(update), gid); } diff --git a/src/gui/panels/updating.h b/src/gui/panels/updating.h index 2eeb09c..3f3ed8f 100644 --- a/src/gui/panels/updating.h +++ b/src/gui/panels/updating.h @@ -58,6 +58,9 @@ GType g_updatable_panel_get_type(void) G_GNUC_CONST; /* Prépare une opération de mise à jour de panneau. */ const char *g_updatable_panel_setup(const GUpdatablePanel *, unsigned int, size_t *, void **); +/* Obtient le groupe de travail dédié à une mise à jour. */ +wgroup_id_t g_updatable_panel_get_group(const GUpdatablePanel *); + /* Bascule l'affichage d'un panneau avant mise à jour. */ void g_updatable_panel_introduce(const GUpdatablePanel *, unsigned int, void *); -- cgit v0.11.2-87-g4458