summaryrefslogtreecommitdiff
path: root/src/gtkext/graph/rank.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gtkext/graph/rank.c')
-rw-r--r--src/gtkext/graph/rank.c149
1 files changed, 105 insertions, 44 deletions
diff --git a/src/gtkext/graph/rank.c b/src/gtkext/graph/rank.c
index 0fadb27..bffefe9 100644
--- a/src/gtkext/graph/rank.c
+++ b/src/gtkext/graph/rank.c
@@ -104,6 +104,28 @@ void exit_graph_rank(graph_rank_t *grank)
* *
* Paramètres : grank = ensemble de même rang à consulter. *
* *
+* Description : Parcours l'ensemble des blocs du rang avec un visiteur. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void visit_graph_rank(const graph_rank_t *grank, graph_rank_cb cb)
+{
+ size_t i; /* Boucle de parcours */
+
+ for (i = 0; i < grank->count; i++)
+ cb(grank->clusters[i]);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : grank = ensemble de même rang à consulter. *
+* *
* Description : Assigne à un ensemble de blocs un emplacement initial. *
* *
* Retour : - *
@@ -494,24 +516,29 @@ void dispatch_x_graph_rank(const graph_rank_t *grank)
/******************************************************************************
* *
-* Paramètres : grank = ensemble de blocs de même rang à actualiser. *
+* Paramètres : grank = ensemble de blocs de même rang à actualiser. *
+* root = élément à ne jamais croiser dans la paternité. *
+* dir = préférence à actualiser si possible. [OUT] *
* *
* Description : Réorganise au besoin les liens entrants un ensemble de blocs.*
* *
-* Retour : - *
+* Retour : false si une incapacité de détermination a été rencontrée. *
* *
* Remarques : - *
* *
******************************************************************************/
-void sort_graph_rank_incoming_links(graph_rank_t *grank)
+bool get_graph_rank_exit_direction(graph_rank_t *grank, const GGraphCluster *root, LeavingLinkDir *dir)
{
+ bool result; /* Bilan à renvoyer */
size_t i; /* Boucle de parcours */
- for (i = 0; i < grank->count; i++)
- g_graph_cluster_sort_incoming_links(grank->clusters[i]);
+ result = true;
- sort_incoming_links_for_vspace_manager(&grank->vspaces);
+ for (i = 0; i < grank->count && result; i++)
+ result = g_graph_cluster_get_exit_direction(grank->clusters[i], root, dir);
+
+ return result;
}
@@ -519,8 +546,37 @@ void sort_graph_rank_incoming_links(graph_rank_t *grank)
/******************************************************************************
* *
* Paramètres : grank = ensemble de blocs de même rang à actualiser. *
+* pos = ordonnées minimale et maximale en bout. [OUT] *
+* *
+* Description : Calcule les ordonnées extrèmes atteintes via liens sortants. *
* *
-* Description : Réordonne les blocs sortant d'un ensemble. *
+* Retour : true si un lien sortant a été trouvé, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool compute_graph_rank_min_max_bottom(const graph_rank_t *grank, gint pos[2])
+{
+ bool result; /* Bilan à renvoyer */
+ size_t i; /* Boucle de parcours */
+
+ result = false;
+
+ for (i = 0; i < grank->count; i++)
+ result |= g_graph_cluster_compute_min_max_bottom(grank->clusters[i], pos);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : grank = ensemble de blocs de même rang à actualiser. *
+* origin = cluster d'origine à considérer. *
+* *
+* Description : Réorganise au besoin les blocs selon les liens d'origine. *
* *
* Retour : - *
* *
@@ -528,64 +584,69 @@ void sort_graph_rank_incoming_links(graph_rank_t *grank)
* *
******************************************************************************/
-void reorder_graph_rank_exit_blocks(graph_rank_t *grank)
+void reorder_graph_rank_clusters(graph_rank_t *grank, const GGraphCluster *origin)
{
- GGraphCluster **exit_2_left; /* Liste avec sortie à gauche */
- GGraphCluster **exit_2_right; /* Liste avec sortie à droite */
- GGraphCluster **no_exit; /* Liste sans sortie */
- size_t count_2_left; /* Quantité de présents */
- size_t count_2_right; /* Quantité de présents */
- size_t count_no; /* Quantité de présents */
size_t i; /* Boucle de parcours */
- bool l2r; /* Détermination de catégorie */
+ GGraphCluster **filtered; /* Blocs à réorganiser */
+ size_t fcount; /* Nombre de ces blocs */
+ size_t next; /* Prochain indice à réinsérer */
if (grank->count > 1)
{
- exit_2_left = malloc(grank->count * sizeof(GGraphCluster *));
- exit_2_right = malloc(grank->count * sizeof(GGraphCluster *));
- no_exit = malloc(grank->count * sizeof(GGraphCluster *));
+ /**
+ * On prend garde de ne déplacer que les blocs avec un lien concernant
+ * un bloc d'origine, dont les liens au départ ont été réorganisés.
+ */
- count_2_left = 0;
- count_2_right = 0;
- count_no = 0;
+ filtered = malloc(grank->count * sizeof(GGraphCluster *));
+ fcount = 0;
for (i = 0; i < grank->count; i++)
- {
- if (g_graph_cluster_has_exit_link(grank->clusters[i], &l2r))
+ if (g_graph_cluster_has_origin(grank->clusters[i], origin) != NULL)
{
- if (l2r)
- exit_2_right[count_2_right++] = grank->clusters[i];
- else
- exit_2_left[count_2_left++] = grank->clusters[i];
+ filtered[fcount++] = grank->clusters[i];
+ grank->clusters[i] = NULL;
}
- else
- no_exit[count_no++] = grank->clusters[i];
- }
+ qsort_r(filtered, fcount, sizeof(GGraphCluster *),
+ (__compar_d_fn_t)g_graph_cluster_compare_by_origin, (void *)origin);
- assert((count_2_left + count_2_right + count_no) == grank->count);
+ next = 0;
- qsort_r(exit_2_left, count_2_left, sizeof(GGraphCluster *),
- (__compar_d_fn_t)g_graph_cluster_compare_by_exit, (bool []){ false });
+ for (i = 0; i < grank->count; i++)
+ if (grank->clusters[i] == NULL)
+ {
+ assert(next < fcount);
+ grank->clusters[i] = filtered[next++];
+ }
- qsort_r(exit_2_right, count_2_right, sizeof(GGraphCluster *),
- (__compar_d_fn_t)g_graph_cluster_compare_by_exit, (bool []){ true });
+ free(filtered);
- grank->count = 0;
+ }
- for (i = 0; i < count_2_left; i++)
- grank->clusters[grank->count++] = exit_2_left[i];
+}
- for (i = 0; i < count_no; i++)
- grank->clusters[grank->count++] = no_exit[i];
- for (i = 0; i < count_2_right; i++)
- grank->clusters[grank->count++] = exit_2_right[i];
+/******************************************************************************
+* *
+* Paramètres : grank = ensemble de blocs de même rang à actualiser. *
+* *
+* Description : Réorganise au besoin les liens entrants un ensemble de blocs.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- }
+void sort_graph_rank_incoming_links(graph_rank_t *grank)
+{
+ size_t i; /* Boucle de parcours */
for (i = 0; i < grank->count; i++)
- g_graph_cluster_reorder_exit_blocks(grank->clusters[i]);
+ g_graph_cluster_sort_incoming_links(grank->clusters[i]);
+
+ sort_incoming_links_for_vspace_manager(&grank->vspaces);
}