[gtksourceview/wip/chergert/vim] improve ownership tracking



commit 8c68b8479cda2551aaf4d0ead92452b79cf883f0
Author: Christian Hergert <chergert redhat com>
Date:   Fri Nov 5 16:29:26 2021 -0700

    improve ownership tracking
    
    this helps us keep the hierarchy of states while also keeping the current
    stack position.

 gtksourceview/vim/gtk-source-vim-command.c | 35 +++++++++--------------------
 gtksourceview/vim/gtk-source-vim-insert.c  | 26 ++++++++++-----------
 gtksourceview/vim/gtk-source-vim-motion.c  | 10 ++++++++-
 gtksourceview/vim/gtk-source-vim-normal.c  |  9 ++++----
 gtksourceview/vim/gtk-source-vim-state.c   |  6 ++---
 gtksourceview/vim/gtk-source-vim-state.h   | 36 ++++++++++++++++++++++++++++++
 gtksourceview/vim/gtk-source-vim-visual.c  | 10 ++++-----
 7 files changed, 81 insertions(+), 51 deletions(-)
---
diff --git a/gtksourceview/vim/gtk-source-vim-command.c b/gtksourceview/vim/gtk-source-vim-command.c
index 33cb5c76..b9388913 100644
--- a/gtksourceview/vim/gtk-source-vim-command.c
+++ b/gtksourceview/vim/gtk-source-vim-command.c
@@ -676,7 +676,7 @@ gtk_source_vim_command_resume (GtkSourceVimState *state,
        /* Complete if waiting for a motion */
        if (GTK_SOURCE_IS_VIM_MOTION (from) && self->motion == NULL)
        {
-               g_set_object (&self->motion, GTK_SOURCE_VIM_MOTION (from));
+               gtk_source_vim_state_reparent (from, state, &self->motion);
                gtk_source_vim_state_pop (state);
                return;
        }
@@ -718,9 +718,10 @@ gtk_source_vim_command_dispose (GObject *object)
 {
        GtkSourceVimCommand *self = (GtkSourceVimCommand *)object;
 
-       g_clear_object (&self->motion);
-       g_clear_object (&self->selection_motion);
-       g_clear_object (&self->text_object);
+       gtk_source_vim_state_release (&self->motion);
+       gtk_source_vim_state_release (&self->selection_motion);
+       gtk_source_vim_state_release (&self->text_object);
+
        g_clear_pointer (&self->command, g_free);
 
        G_OBJECT_CLASS (gtk_source_vim_command_parent_class)->dispose (object);
@@ -862,16 +863,8 @@ gtk_source_vim_command_set_motion (GtkSourceVimCommand *self,
        g_return_if_fail (GTK_SOURCE_IS_VIM_COMMAND (self));
        g_return_if_fail (!motion || GTK_SOURCE_IS_VIM_MOTION (motion));
 
-       if (g_set_object (&self->motion, motion))
-       {
-               if (motion)
-               {
-                       gtk_source_vim_state_set_parent (GTK_SOURCE_VIM_STATE (motion),
-                                                        GTK_SOURCE_VIM_STATE (self));
-               }
-
-               g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MOTION]);
-       }
+       gtk_source_vim_state_reparent (motion, self, &self->motion);
+       g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MOTION]);
 }
 
 void
@@ -881,16 +874,8 @@ gtk_source_vim_command_set_selection_motion (GtkSourceVimCommand *self,
        g_return_if_fail (GTK_SOURCE_IS_VIM_COMMAND (self));
        g_return_if_fail (!selection_motion || GTK_SOURCE_IS_VIM_MOTION (selection_motion));
 
-       if (g_set_object (&self->selection_motion, selection_motion))
-       {
-               if (selection_motion)
-               {
-                       gtk_source_vim_state_set_parent (GTK_SOURCE_VIM_STATE (selection_motion),
-                                                        GTK_SOURCE_VIM_STATE (self));
-               }
-
-               g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTION_MOTION]);
-       }
+       gtk_source_vim_state_reparent (selection_motion, self, &self->selection_motion);
+       g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTION_MOTION]);
 }
 
 const char *
@@ -917,7 +902,7 @@ gtk_source_vim_command_set_text_object (GtkSourceVimCommand    *self,
 {
        g_return_if_fail (GTK_SOURCE_IS_VIM_COMMAND (self));
 
-       g_set_object (&self->text_object, text_object);
+       gtk_source_vim_state_reparent (text_object, self, &self->text_object);
 }
 
 GtkSourceVimState *
diff --git a/gtksourceview/vim/gtk-source-vim-insert.c b/gtksourceview/vim/gtk-source-vim-insert.c
index d95ecb3f..246910bd 100644
--- a/gtksourceview/vim/gtk-source-vim-insert.c
+++ b/gtksourceview/vim/gtk-source-vim-insert.c
@@ -294,20 +294,19 @@ static void
 gtk_source_vim_insert_enter (GtkSourceVimState *state)
 {
        GtkSourceVimInsert *self = (GtkSourceVimInsert *)state;
+       GtkSourceVimState *history;
 
        g_assert (GTK_SOURCE_IS_VIM_INSERT (self));
 
        gtk_source_vim_state_begin_user_action (state);
        gtk_source_vim_state_set_overwrite (state, FALSE);
 
-       g_clear_object (&self->history);
-       self->history = g_object_new (GTK_SOURCE_TYPE_VIM_TEXT_HISTORY,
-                                     "parent", self,
-                                     NULL);
-
+       history = gtk_source_vim_text_history_new ();
+       gtk_source_vim_state_reparent (history, self, &self->history);
        gtk_source_vim_insert_prepare (self);
-
        gtk_source_vim_text_history_begin (self->history);
+
+       g_object_unref (history);
 }
 
 static void
@@ -422,10 +421,11 @@ gtk_source_vim_insert_dispose (GObject *object)
        GtkSourceVimInsert *self = (GtkSourceVimInsert *)object;
 
        g_clear_pointer (&self->prefix, g_free);
-       g_clear_object (&self->history);
-       g_clear_object (&self->motion);
-       g_clear_object (&self->selection_motion);
-       g_clear_object (&self->text_object);
+
+       gtk_source_vim_state_release (&self->history);
+       gtk_source_vim_state_release (&self->motion);
+       gtk_source_vim_state_release (&self->selection_motion);
+       gtk_source_vim_state_release (&self->text_object);
 
        G_OBJECT_CLASS (gtk_source_vim_insert_parent_class)->dispose (object);
 }
@@ -530,7 +530,7 @@ gtk_source_vim_insert_set_motion (GtkSourceVimInsert *self,
        g_return_if_fail (GTK_SOURCE_IS_VIM_INSERT (self));
        g_return_if_fail (GTK_SOURCE_IS_VIM_MOTION (motion));
 
-       g_set_object (&self->motion, motion);
+       gtk_source_vim_state_reparent (motion, self, &self->motion);
 }
 
 void
@@ -540,7 +540,7 @@ gtk_source_vim_insert_set_selection_motion (GtkSourceVimInsert *self,
        g_return_if_fail (GTK_SOURCE_IS_VIM_INSERT (self));
        g_return_if_fail (GTK_SOURCE_IS_VIM_MOTION (selection_motion));
 
-       g_set_object (&self->selection_motion, selection_motion);
+       gtk_source_vim_state_reparent (selection_motion, self, &self->selection_motion);
 }
 
 void
@@ -558,5 +558,5 @@ gtk_source_vim_insert_set_text_object (GtkSourceVimInsert     *self,
 {
        g_return_if_fail (GTK_SOURCE_IS_VIM_INSERT (self));
 
-       g_set_object (&self->text_object, text_object);
+       gtk_source_vim_state_reparent (text_object, self, &self->text_object);
 }
diff --git a/gtksourceview/vim/gtk-source-vim-motion.c b/gtksourceview/vim/gtk-source-vim-motion.c
index 73933f13..e33fcc6e 100644
--- a/gtksourceview/vim/gtk-source-vim-motion.c
+++ b/gtksourceview/vim/gtk-source-vim-motion.c
@@ -1931,6 +1931,14 @@ gtk_source_vim_motion_add (GtkSourceVimMotion *self,
                                         GTK_SOURCE_VIM_STATE (self));
 }
 
+static void
+clear_state (gpointer data)
+{
+       GtkSourceVimState *state = data;
+       gtk_source_vim_state_unparent (state);
+       g_object_unref (state);
+}
+
 GtkSourceVimState *
 gtk_source_vim_motion_chain (GtkSourceVimMotion *self,
                              GtkSourceVimMotion *other)
@@ -1945,7 +1953,7 @@ gtk_source_vim_motion_chain (GtkSourceVimMotion *self,
                chained = GTK_SOURCE_VIM_MOTION (gtk_source_vim_motion_new ());
                chained->motion = motion_chained;
                chained->inclusivity = INCLUSIVE;
-               chained->chained = g_ptr_array_new_with_free_func (g_object_unref);
+               chained->chained = g_ptr_array_new_with_free_func (clear_state);
        }
        else
        {
diff --git a/gtksourceview/vim/gtk-source-vim-normal.c b/gtksourceview/vim/gtk-source-vim-normal.c
index df9b3edb..0554ee1c 100644
--- a/gtksourceview/vim/gtk-source-vim-normal.c
+++ b/gtksourceview/vim/gtk-source-vim-normal.c
@@ -1285,7 +1285,7 @@ gtk_source_vim_normal_resume (GtkSourceVimState *state,
        if (GTK_SOURCE_IS_VIM_VISUAL (from))
        {
                /* Store last visual around for reselection in gv */
-               g_set_object (&self->last_visual, from);
+               gtk_source_vim_state_reparent (from, self, &self->last_visual);
        }
 
        if (!GTK_SOURCE_IS_VIM_MOTION (from) ||
@@ -1307,7 +1307,7 @@ gtk_source_vim_normal_resume (GtkSourceVimState *state,
 
        if (gtk_source_vim_state_get_can_repeat (from))
        {
-               g_set_object (&self->repeat, from);
+               gtk_source_vim_state_reparent (from, self, &self->repeat);
        }
 }
 
@@ -1341,8 +1341,9 @@ gtk_source_vim_normal_dispose (GObject *object)
 {
        GtkSourceVimNormal *self = (GtkSourceVimNormal *)object;
 
-       g_clear_object (&self->last_visual);
-       g_clear_object (&self->repeat);
+       gtk_source_vim_state_release (&self->last_visual);
+       gtk_source_vim_state_release (&self->repeat);
+
        g_string_free (self->command_text, TRUE);
        self->command_text = NULL;
 
diff --git a/gtksourceview/vim/gtk-source-vim-state.c b/gtksourceview/vim/gtk-source-vim-state.c
index 14f86c9c..4d4d4103 100644
--- a/gtksourceview/vim/gtk-source-vim-state.c
+++ b/gtksourceview/vim/gtk-source-vim-state.c
@@ -265,7 +265,7 @@ gtk_source_vim_state_dispose (GObject *object)
        priv->current_register = NULL;
 
        g_clear_weak_pointer (&priv->view);
-       g_clear_object (&priv->registers);
+       gtk_source_vim_state_release (&priv->registers);
 
        /* First remove the children from our list */
        while (priv->children.length > 0)
@@ -324,7 +324,7 @@ gtk_source_vim_state_set_property (GObject      *object,
        switch (prop_id)
        {
                case PROP_PARENT:
-                       g_set_object (&priv->parent, g_value_get_object (value));
+                       gtk_source_vim_state_set_parent (self, g_value_get_object (value));
                        break;
 
                case PROP_VIEW:
@@ -593,7 +593,7 @@ gtk_source_vim_state_pop (GtkSourceVimState *self)
                GTK_SOURCE_VIM_STATE_GET_CLASS (parent)->resume (parent, self);
        }
 
-       g_clear_object (&parent);
+       g_object_unref (parent);
 }
 
 void
diff --git a/gtksourceview/vim/gtk-source-vim-state.h b/gtksourceview/vim/gtk-source-vim-state.h
index 73fa452b..f2ddd06a 100644
--- a/gtksourceview/vim/gtk-source-vim-state.h
+++ b/gtksourceview/vim/gtk-source-vim-state.h
@@ -129,6 +129,42 @@ void               gtk_source_vim_state_select_linewise            (GtkSourceVim
                                                                     GtkTextIter       *insert,
                                                                     GtkTextIter       *selection);
 
+static inline void
+gtk_source_vim_state_release (GtkSourceVimState **dest)
+{
+       if (*dest != NULL)
+       {
+               gtk_source_vim_state_unparent (*dest);
+               g_clear_object (dest);
+       }
+}
+
+static inline void
+gtk_source_vim_state_reparent (GtkSourceVimState  *state,
+                               GtkSourceVimState  *parent,
+                               GtkSourceVimState **dest)
+{
+       if (*dest == state)
+               return;
+
+       g_object_ref (parent);
+       g_object_ref (state);
+
+       gtk_source_vim_state_release (dest);
+       gtk_source_vim_state_set_parent (state, parent);
+
+       *dest = state;
+       g_object_unref (parent);
+}
+
+#define gtk_source_vim_state_reparent(a,b,c)                   \
+       (gtk_source_vim_state_reparent)((GtkSourceVimState*)a, \
+                                       (GtkSourceVimState*)b, \
+                                       (GtkSourceVimState**)c)
+
+#define gtk_source_vim_state_release(a) \
+       (gtk_source_vim_state_release)((GtkSourceVimState**)a)
+
 static inline gboolean
 gtk_source_vim_state_is_escape (guint           keyval,
                                 GdkModifierType mods)
diff --git a/gtksourceview/vim/gtk-source-vim-visual.c b/gtksourceview/vim/gtk-source-vim-visual.c
index 289cdc99..4908085b 100644
--- a/gtksourceview/vim/gtk-source-vim-visual.c
+++ b/gtksourceview/vim/gtk-source-vim-visual.c
@@ -366,7 +366,7 @@ gtk_source_vim_visual_begin_command (GtkSourceVimVisual *self,
        count = self->count, self->count = 0;
 
        gtk_source_vim_visual_clear (self);
-       g_clear_object (&self->command);
+       gtk_source_vim_state_release (&self->command);
 
        if (restore_cursor)
                cursor_info_stash (self, &info);
@@ -433,7 +433,7 @@ gtk_source_vim_visual_begin_insert (GtkSourceVimVisual *self)
        gtk_source_vim_state_set_can_repeat (GTK_SOURCE_VIM_STATE (self), TRUE);
        gtk_source_vim_state_push (GTK_SOURCE_VIM_STATE (self), insert);
 
-       g_set_object (&self->command, insert);
+       gtk_source_vim_state_reparent (insert, self, &self->command);
 
        g_object_unref (motion);
 
@@ -703,7 +703,7 @@ gtk_source_vim_visual_resume (GtkSourceVimState *state,
                 */
                chained = gtk_source_vim_motion_chain (self->motion, GTK_SOURCE_VIM_MOTION (from));
                gtk_source_vim_state_set_parent (chained, GTK_SOURCE_VIM_STATE (self));
-               g_set_object (&self->motion, GTK_SOURCE_VIM_MOTION (chained));
+               gtk_source_vim_state_reparent (chained, self, &self->motion);
                g_object_unref (chained);
        }
 
@@ -809,8 +809,8 @@ gtk_source_vim_visual_dispose (GObject *object)
                gtk_text_buffer_delete_mark (GTK_TEXT_BUFFER (buffer), mark);
        }
 
-       g_clear_object (&self->motion);
-       g_clear_object (&self->command);
+       gtk_source_vim_state_release (&self->motion);
+       gtk_source_vim_state_release (&self->command);
 
        G_OBJECT_CLASS (gtk_source_vim_visual_parent_class)->dispose (object);
 }


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