summaryrefslogtreecommitdiff
path: root/src/glibext/gwidthtracker.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-06-02 09:07:27 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-06-02 09:07:27 (GMT)
commit30111e5cf6ff5a7766296ac2579a98c16e7cc7c1 (patch)
treed75f268ad20b5ae02f954c03d9a6e19b47b8f839 /src/glibext/gwidthtracker.c
parentf0fa987133468d7d3cae7894d813b852782bf895 (diff)
Computed the initial lines width using all threads.
Diffstat (limited to 'src/glibext/gwidthtracker.c')
-rw-r--r--src/glibext/gwidthtracker.c361
1 files changed, 358 insertions, 3 deletions
diff --git a/src/glibext/gwidthtracker.c b/src/glibext/gwidthtracker.c
index 82ae65b..181759c 100644
--- a/src/glibext/gwidthtracker.c
+++ b/src/glibext/gwidthtracker.c
@@ -30,8 +30,77 @@
#include <string.h>
+#include <i18n.h>
+
+
+#include "delayed-int.h"
#include "gbuffercache.h"
+#include "../core/global.h"
+
+
+
+/* --------------------------- PRISE DE MESURES INITIALES --------------------------- */
+
+
+/* Procédure de mise à jour des mesures de largeurs (instance) */
+typedef struct _GWidthUpdate
+{
+ GDelayedWork parent; /* A laisser en premier */
+
+ activity_id_t id; /* Groupe de progression */
+
+ GWidthTracker *tracker; /* Gestionnaire à manipuler */
+
+ size_t start; /* Premier indice à traiter */
+ size_t end; /* Premier indice à écarter */
+
+ line_width_summary summary; /* Largeurs requises suivies */
+
+} GWidthUpdate;
+
+/* Procédure de mise à jour des mesures de largeurs (classe) */
+typedef struct _GWidthUpdateClass
+{
+ GDelayedWorkClass parent; /* A laisser en premier */
+
+} GWidthUpdateClass;
+
+
+#define G_TYPE_WIDTH_UPDATE g_width_update_get_type()
+#define G_WIDTH_UPDATE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_WIDTH_UPDATE, GWidthUpdate))
+#define G_IS_WIDTH_UPDATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_WIDTH_UPDATE))
+#define G_WIDTH_UPDATE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_WIDTH_UPDATE, GWidthUpdateClass))
+#define G_IS_WIDTH_UPDATE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_WIDTH_UPDATE))
+#define G_WIDTH_UPDATE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_WIDTH_UPDATE, GWidthUpdateClass))
+
+
+/* Initialise la classe des tâches de mesures de largeurs. */
+static void g_width_update_class_init(GWidthUpdateClass *);
+
+/* Initialise une tâche de mesures de largeurs. */
+static void g_width_update_init(GWidthUpdate *);
+
+/* Supprime toutes les références externes. */
+static void g_width_update_dispose(GWidthUpdate *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_width_update_finalize(GWidthUpdate *);
+
+/* Indique le type défini pour les tâches de mesures de largeurs. */
+GType g_width_update_get_type(void);
+
+/* Crée une tâche de mesures de largeurs. */
+static GWidthUpdate *g_width_update_new(activity_id_t, GWidthTracker *, size_t, size_t);
+/* Assure les mesures initiales d'un ensemble de lignes. */
+static void g_width_update_process(GWidthUpdate *, GtkStatusStack *);
+
+/* Récupère les données obtenues lors d'une mesure globale. */
+static void g_width_update_collect(GWidthUpdate *, line_width_summary *);
+
+
+
+/* ---------------------------- RASSEMBLEMENT DE MESURES ---------------------------- */
/* Portions de largeurs communes */
@@ -98,6 +167,209 @@ static void g_width_tracker_ensure_valid_required_widths(GWidthTracker *);
+/* ---------------------------------------------------------------------------------- */
+/* PRISE DE MESURES INITIALES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour les tâches de mesures de largeurs. */
+G_DEFINE_TYPE(GWidthUpdate, g_width_update, G_TYPE_DELAYED_WORK);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des tâches de mesures de largeurs. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_width_update_class_init(GWidthUpdateClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GDelayedWorkClass *work; /* Version en classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_width_update_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_width_update_finalize;
+
+ work = G_DELAYED_WORK_CLASS(klass);
+
+ work->run = (run_task_fc)g_width_update_process;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : update = instance à initialiser. *
+* *
+* Description : Initialise une tâche de mesures de largeurs. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_width_update_init(GWidthUpdate *update)
+{
+ memset(&update->summary, 0, sizeof(line_width_summary));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : update = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_width_update_dispose(GWidthUpdate *update)
+{
+ g_object_unref(G_OBJECT(update->tracker));
+
+ G_OBJECT_CLASS(g_width_update_parent_class)->dispose(G_OBJECT(update));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : update = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_width_update_finalize(GWidthUpdate *update)
+{
+ G_OBJECT_CLASS(g_width_update_parent_class)->finalize(G_OBJECT(update));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : id = identifiant pour signaler la progression courante. *
+* tracker = gestionnaire de largeurs à consulter. *
+* start = indice de la première ligne à traiter. *
+* end = indice de la première ligne à éviter. *
+* *
+* Description : Crée une tâche de mesures de largeurs. *
+* *
+* Retour : Tâche créée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GWidthUpdate *g_width_update_new(activity_id_t id, GWidthTracker *tracker, size_t start, size_t end)
+{
+ GWidthUpdate *result; /* Tâche à retourner */
+
+ result = g_object_new(G_TYPE_WIDTH_UPDATE, NULL);
+
+ result->id = id;
+
+ g_object_ref(G_OBJECT(tracker));
+ result->tracker = tracker;
+
+ result->start = start;
+ result->end = end;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : update = opération de mesures à mener. *
+* status = barre de statut à tenir informée. *
+* *
+* Description : Assure les mesures initiales d'un ensemble de lignes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_width_update_process(GWidthUpdate *update, GtkStatusStack *status)
+{
+ line_width_summary *local; /* Valeurs collectées */
+ size_t i; /* Boucle de parcours #1 */
+ const line_width_summary *summary; /* Valeurs à intégrer */
+ BufferLineColumn k; /* Boucle de parcours #2 */
+
+ local = &update->summary;
+
+ for (i = update->start; i < update->end; i++)
+ {
+ summary = g_width_tracker_get_up_to_date_widths(update->tracker, i);
+
+ for (k = 0; k < BLC_COUNT; k++)
+ local->max_widths[k] = MAX(local->max_widths[k], summary->max_widths[k]);
+
+ local->merged_width = MAX(local->merged_width, summary->merged_width);
+
+ gtk_status_stack_update_activity_value(status, update->id, 1);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : update = opération de mesures menée à bien. *
+* global = lieu de centralisation des données globales. *
+* *
+* Description : Récupère les données obtenues lors d'une mesure globale. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_width_update_collect(GWidthUpdate *update, line_width_summary *global)
+{
+ line_width_summary *local; /* Valeurs collectées */
+ BufferLineColumn i; /* Boucle de parcours */
+
+ local = &update->summary;
+
+ for (i = 0; i < BLC_COUNT; i++)
+ global->max_widths[i] = MAX(global->max_widths[i], local->max_widths[i]);
+
+ global->merged_width = MAX(global->merged_width, local->merged_width);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* RASSEMBLEMENT DE MESURES */
+/* ---------------------------------------------------------------------------------- */
+
+
/* Détermine le type du gestionnaire de largeurs associées aux lignes. */
G_DEFINE_TYPE(GWidthTracker, g_width_tracker, G_TYPE_OBJECT);
@@ -686,6 +958,89 @@ void g_width_tracker_update_deleted(GWidthTracker *tracker, size_t start, size_t
/******************************************************************************
* *
+* Paramètres : tracker = suivi de largeurs dont le cache est à construire. *
+* gid = groupe de travail impliqué. *
+* status = barre de statut à tenir informée. *
+* *
+* Description : Calcule les largeurs requises par un ensemble de lignes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_width_tracker_build_initial_cache(GWidthTracker *tracker, wgroup_id_t gid, GtkStatusStack *status)
+{
+ guint runs_count; /* Qté d'exécutions parallèles */
+ GWidthUpdate **updates; /* Mesures à suivre */
+ size_t run_size; /* Volume réparti par exécution*/
+ GWorkQueue *queue; /* Gestionnaire de différés */
+ activity_id_t id; /* Identifiant de progression */
+ guint i; /* Boucle de parcours */
+ size_t start; /* Début de zone de traitement */
+ bool closing; /* Détection de fin en amont */
+ size_t end; /* Fin de zone de traitement */
+
+ assert(!tracker->cached);
+
+ /* Lancement des traitements */
+
+ runs_count = g_get_num_processors();
+
+ updates = (GWidthUpdate **)calloc(runs_count, sizeof(GWidthUpdate *));
+
+ run_size = tracker->count / runs_count;
+
+ queue = get_work_queue();
+
+ id = gtk_status_stack_add_activity(status, _("Computing width of all lines for rendering"), tracker->count);
+
+ for (i = 0; i < runs_count; i++)
+ {
+ start = i * run_size;
+
+ closing = ((i + 1) == runs_count);
+
+ if (closing)
+ end = tracker->count;
+ else
+ end = start + run_size;
+
+ updates[i] = g_width_update_new(id, tracker, start, end);
+
+ g_object_ref(G_OBJECT(updates[i]));
+ g_work_queue_schedule_work(queue, G_DELAYED_WORK(updates[i]), gid);
+
+ }
+
+ g_work_queue_wait_for_completion(queue, gid);
+
+ /* Récupération des aires */
+
+ memset(&tracker->summary, 0, sizeof(line_width_summary));
+
+ for (i = 0; i < runs_count; i++)
+ {
+ g_width_update_collect(updates[i], &tracker->summary);
+
+ g_object_unref(G_OBJECT(updates[i]));
+
+ }
+
+ /* Fin */
+
+ free(updates);
+
+ gtk_status_stack_remove_activity(status, id);
+
+ tracker->cached = true;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : tracker = suivi de largeurs à mettre à jour si besoin est. *
* *
* Description : Calcule les largeurs requises par un ensemble de lignes. *
@@ -705,14 +1060,14 @@ static void g_width_tracker_ensure_valid_required_widths(GWidthTracker *tracker)
if (!tracker->cached)
{
+ global = &tracker->summary;
+
/* Réinitialisation */
- memset(&tracker->summary, 0, sizeof(line_width_summary));
+ memset(global, 0, sizeof(line_width_summary));
/* Collecte */
- global = &tracker->summary;
-
for (i = 0; i < tracker->count; i++)
{
summary = g_width_tracker_get_up_to_date_widths(tracker, i);