[gtk/wip/otte/listview: 31/161] sortlistmodel: Redo the way we store the items



commit da938b63d506352dda2e8927a62b99e9756a625c
Author: Benjamin Otte <otte redhat com>
Date:   Wed Dec 11 01:11:59 2019 +0100

    sortlistmodel: Redo the way we store the items
    
    We need to keep this data around for changes in future commits where we
    make the sorting stable.
    
    An important part of the new data handling is that the unsorted list
    needs to always be dealt with before the sorted list - upon creation we
    rely on the unsorted iter and upon destruction, the sorted sequence
    frees the entry leaving the unsorted sequence pointer invalid.
    
    This change does not do any behavioral changes.

 gtk/gtksortlistmodel.c | 64 ++++++++++++++++++++++++++++++++++----------------
 1 file changed, 44 insertions(+), 20 deletions(-)
---
diff --git a/gtk/gtksortlistmodel.c b/gtk/gtksortlistmodel.c
index 471e174fe4..4b9571a425 100644
--- a/gtk/gtksortlistmodel.c
+++ b/gtk/gtksortlistmodel.c
@@ -48,6 +48,8 @@ enum {
   NUM_PROPERTIES
 };
 
+typedef struct _GtkSortListEntry GtkSortListEntry;
+
 struct _GtkSortListModel
 {
   GObject parent_instance;
@@ -56,8 +58,8 @@ struct _GtkSortListModel
   GListModel *model;
   GtkSorter *sorter;
 
-  GSequence *sorted; /* NULL if sort_func == NULL */
-  GSequence *unsorted; /* NULL if sort_func == NULL */
+  GSequence *sorted; /* NULL if known unsorted */
+  GSequence *unsorted; /* NULL if known unsorted */
 };
 
 struct _GtkSortListModelClass
@@ -65,8 +67,25 @@ struct _GtkSortListModelClass
   GObjectClass parent_class;
 };
 
+struct _GtkSortListEntry
+{
+  GSequenceIter *sorted_iter;
+  GSequenceIter *unsorted_iter;
+  gpointer item; /* holds ref */
+};
+
 static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
 
+static void
+gtk_sort_list_entry_free (gpointer data)
+{
+  GtkSortListEntry *entry = data;
+
+  g_object_unref (entry->item);
+
+  g_slice_free (GtkSortListEntry, entry);
+}
+
 static GType
 gtk_sort_list_model_get_item_type (GListModel *list)
 {
@@ -83,9 +102,6 @@ gtk_sort_list_model_get_n_items (GListModel *list)
   if (self->model == NULL)
     return 0;
 
-  if (self->sorted)
-    return g_sequence_get_length (self->sorted);
-
   return g_list_model_get_n_items (self->model);
 }
 
@@ -95,6 +111,7 @@ gtk_sort_list_model_get_item (GListModel *list,
 {
   GtkSortListModel *self = GTK_SORT_LIST_MODEL (list);
   GSequenceIter *iter;
+  GtkSortListEntry *entry;
 
   if (self->model == NULL)
     return NULL;
@@ -104,9 +121,11 @@ gtk_sort_list_model_get_item (GListModel *list,
 
   iter = g_sequence_get_iter_at_pos (self->sorted, position);
   if (g_sequence_iter_is_end (iter))
-      return NULL;
+    return NULL;
 
-  return g_object_ref (g_sequence_get (iter));
+  entry = g_sequence_get (iter);
+
+  return g_object_ref (entry->item);
 }
 
 static void
@@ -135,18 +154,18 @@ gtk_sort_list_model_remove_items (GtkSortListModel *self,
 
   for (i = 0; i < n_items ; i++)
     {
-      GSequenceIter *sorted_iter;
+      GtkSortListEntry *entry;
       GSequenceIter *next;
 
       next = g_sequence_iter_next (unsorted_iter);
 
-      sorted_iter = g_sequence_get (unsorted_iter);
-      pos = g_sequence_iter_get_position (sorted_iter);
+      entry = g_sequence_get (unsorted_iter);
+      pos = g_sequence_iter_get_position (entry->sorted_iter);
       start = MIN (start, pos);
       end = MIN (end, length_before - i - 1 - pos);
 
-      g_sequence_remove (sorted_iter);
-      g_sequence_remove (unsorted_iter);
+      g_sequence_remove (entry->unsorted_iter);
+      g_sequence_remove (entry->sorted_iter);
 
       unsorted_iter = next;
     }
@@ -160,7 +179,10 @@ _sort_func (gconstpointer item1,
             gconstpointer item2,
             gpointer      data)
 {
-  switch (gtk_sorter_compare (GTK_SORTER (data), (gpointer)item1, (gpointer)item2))
+  GtkSortListEntry *entry1 = (GtkSortListEntry *) item1;
+  GtkSortListEntry *entry2 = (GtkSortListEntry *) item2;
+
+  switch (gtk_sorter_compare (GTK_SORTER (data), entry1->item, entry2->item))
   {
     case GTK_ORDERING_EQUAL:
     case GTK_ORDERING_INVALID:
@@ -182,20 +204,22 @@ gtk_sort_list_model_add_items (GtkSortListModel *self,
                                guint            *unmodified_start,
                                guint            *unmodified_end)
 {
-  GSequenceIter *unsorted_iter, *sorted_iter;
+  GSequenceIter *unsorted_end;
   guint i, pos, start, end, length_before;
 
-  unsorted_iter = g_sequence_get_iter_at_pos (self->unsorted, position);
+  unsorted_end = g_sequence_get_iter_at_pos (self->unsorted, position);
   start = end = length_before = g_sequence_get_length (self->sorted);
 
   for (i = 0; i < n_items; i++)
     {
-      gpointer item = g_list_model_get_item (self->model, position + i);
-      sorted_iter = g_sequence_insert_sorted (self->sorted, item, _sort_func, self->sorter);
-      g_sequence_insert_before (unsorted_iter, sorted_iter);
+      GtkSortListEntry *entry = g_slice_new0 (GtkSortListEntry);
+
+      entry->item = g_list_model_get_item (self->model, position + i);
+      entry->unsorted_iter = g_sequence_insert_before (unsorted_end, entry);
+      entry->sorted_iter = g_sequence_insert_sorted (self->sorted, entry, _sort_func, self->sorter);
       if (unmodified_start != NULL || unmodified_end != NULL)
         {
-          pos = g_sequence_iter_get_position (sorted_iter);
+          pos = g_sequence_iter_get_position (entry->sorted_iter);
           start = MIN (start, pos);
           end = MIN (end, length_before + i - pos);
         }
@@ -439,7 +463,7 @@ gtk_sort_list_model_create_sequences (GtkSortListModel *self)
   if (self->sorter == NULL || self->model == NULL)
     return;
 
-  self->sorted = g_sequence_new (g_object_unref);
+  self->sorted = g_sequence_new (gtk_sort_list_entry_free);
   self->unsorted = g_sequence_new (NULL);
 
   gtk_sort_list_model_add_items (self, 0, g_list_model_get_n_items (self->model), NULL, NULL);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]