[devhelp/wip/book-list: 2/3] BookList: different API, maintain an internal GList



commit f565a6858065cb45071ef5eaf8bb1959d9942725
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sun Apr 22 16:46:43 2018 +0200

    BookList: different API, maintain an internal GList
    
    I think it'll be more convenient for the subclasses.

 devhelp/dh-book-list.c              |  128 +++++++++++++++++++++++++++--------
 devhelp/dh-book-list.h              |   14 ++--
 docs/reference/devhelp-sections.txt |    4 +-
 3 files changed, 109 insertions(+), 37 deletions(-)
---
diff --git a/devhelp/dh-book-list.c b/devhelp/dh-book-list.c
index 8270cc6..f0785f2 100644
--- a/devhelp/dh-book-list.c
+++ b/devhelp/dh-book-list.c
@@ -23,63 +23,127 @@
 /**
  * SECTION:dh-book-list
  * @Title: DhBookList
- * @Short_description: Abstract class for a list of #DhBook's
+ * @Short_description: Base class for a list of #DhBook's
  *
- * #DhBookList is an abstract class for a list of #DhBook's.
+ * #DhBookList is a base class for a list of #DhBook's.
+ *
+ * The default implementation maintains an internal #GList when books are added
+ * and removed with the #DhBookList::add-book and #DhBookList::remove-book
+ * signals, and returns that #GList in dh_book_list_get_books().
  */
 
 struct _DhBookListPrivate {
+        /* The list of DhBook's. */
+        GList *books;
 };
 
 enum {
-        SIGNAL_BOOK_ADDED,
-        SIGNAL_BOOK_REMOVED,
+        SIGNAL_ADD_BOOK,
+        SIGNAL_REMOVE_BOOK,
         N_SIGNALS
 };
 
 static guint signals[N_SIGNALS] = { 0 };
 
-G_DEFINE_TYPE (DhBookList, dh_book_list, G_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_PRIVATE (DhBookList, dh_book_list, G_TYPE_OBJECT)
+
+static void
+dh_book_list_dispose (GObject *object)
+{
+        DhBookList *book_list = DH_BOOK_LIST (object);
+
+        g_list_free_full (book_list->priv->books, g_object_unref);
+        book_list->priv->books = NULL;
+
+        G_OBJECT_CLASS (dh_book_list_parent_class)->dispose (object);
+}
+
+static void
+dh_book_list_add_book_default (DhBookList *book_list,
+                               DhBook     *book)
+{
+        g_return_if_fail (g_list_find (book_list->priv->books, book) == NULL);
+
+        book_list->priv->books = g_list_prepend (book_list->priv->books,
+                                                 g_object_ref (book));
+}
+
+static void
+dh_book_list_remove_book_default (DhBookList *book_list,
+                                  DhBook     *book)
+{
+        GList *node;
+
+        node = g_list_find (book_list->priv->books, book);
+        g_return_if_fail (node != NULL);
+
+        book_list->priv->books = g_list_delete_link (book_list->priv->books, node);
+
+        if (g_list_find (book_list->priv->books, book) != NULL)
+                g_warning ("The same DhBook was inserted several times.");
+
+        g_object_unref (book);
+}
 
 static GList *
 dh_book_list_get_books_default (DhBookList *book_list)
 {
-        return NULL;
+        return book_list->priv->books;
 }
 
 static void
 dh_book_list_class_init (DhBookListClass *klass)
 {
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+        object_class->dispose = dh_book_list_dispose;
+
+        klass->add_book = dh_book_list_add_book_default;
+        klass->remove_book = dh_book_list_remove_book_default;
         klass->get_books = dh_book_list_get_books_default;
 
         /**
-         * DhBookList::book-added:
+         * DhBookList::add-book:
          * @book_list: the #DhBookList emitting the signal.
-         * @book: the added #DhBook.
+         * @book: the #DhBook being added.
+         *
+         * The ::add-book signal is emitted when a #DhBook is added to a
+         * #DhBookList.
+         *
+         * The default object method handler adds @book to the internal #GList
+         * of @book_list after verifying that @book is not already present in
+         * the list.
          *
          * Since: 3.30
          */
-        signals[SIGNAL_BOOK_ADDED] =
-                g_signal_new ("book-added",
+        signals[SIGNAL_ADD_BOOK] =
+                g_signal_new ("add-book",
                               G_TYPE_FROM_CLASS (klass),
                               G_SIGNAL_RUN_LAST,
-                              G_STRUCT_OFFSET (DhBookListClass, book_added),
+                              G_STRUCT_OFFSET (DhBookListClass, add_book),
                               NULL, NULL, NULL,
                               G_TYPE_NONE,
                               1, DH_TYPE_BOOK);
 
         /**
-         * DhBookList::book-removed:
+         * DhBookList::remove-book:
          * @book_list: the #DhBookList emitting the signal.
-         * @book: the removed #DhBook.
+         * @book: the #DhBook being removed.
+         *
+         * The ::remove-book signal is emitted when a #DhBook is removed from a
+         * #DhBookList.
+         *
+         * The default object method handler removes @book from the internal
+         * #GList of @book_list, and verifies that @book was present in the list
+         * and that @book was not inserted several times.
          *
          * Since: 3.30
          */
-        signals[SIGNAL_BOOK_REMOVED] =
-                g_signal_new ("book-removed",
+        signals[SIGNAL_REMOVE_BOOK] =
+                g_signal_new ("remove-book",
                               G_TYPE_FROM_CLASS (klass),
                               G_SIGNAL_RUN_LAST,
-                              G_STRUCT_OFFSET (DhBookListClass, book_removed),
+                              G_STRUCT_OFFSET (DhBookListClass, remove_book),
                               NULL, NULL, NULL,
                               G_TYPE_NONE,
                               1, DH_TYPE_BOOK);
@@ -88,6 +152,7 @@ dh_book_list_class_init (DhBookListClass *klass)
 static void
 dh_book_list_init (DhBookList *book_list)
 {
+        book_list->priv = dh_book_list_get_instance_private (book_list);
 }
 
 /**
@@ -107,49 +172,56 @@ dh_book_list_get_books (DhBookList *book_list)
 }
 
 /**
- * dh_book_list_book_added:
+ * dh_book_list_add_book:
  * @book_list: a #DhBookList.
  * @book: a #DhBook.
  *
- * Emits the #DhBookList::book-added signal.
+ * Emits the #DhBookList::add-book signal.
  *
- * This function is intended to be used by #DhBookList subclasses.
+ * It is a programmer error to call this function if @book is already inserted
+ * in @book_list.
  *
  * Since: 3.30
  */
 void
-dh_book_list_book_added (DhBookList *book_list,
-                         DhBook     *book)
+dh_book_list_add_book (DhBookList *book_list,
+                       DhBook     *book)
 {
         g_return_if_fail (DH_IS_BOOK_LIST (book_list));
         g_return_if_fail (DH_IS_BOOK (book));
 
         g_signal_emit (book_list,
-                       signals[SIGNAL_BOOK_ADDED],
+                       signals[SIGNAL_ADD_BOOK],
                        0,
                        book);
 }
 
 /**
- * dh_book_list_book_removed:
+ * dh_book_list_remove_book:
  * @book_list: a #DhBookList.
  * @book: a #DhBook.
  *
- * Emits the #DhBookList::book-removed signal.
+ * Emits the #DhBookList::remove-book signal.
  *
- * This function is intended to be used by #DhBookList subclasses.
+ * It is a programmer error to call this function if @book is not present in
+ * @book_list.
  *
  * Since: 3.30
  */
 void
-dh_book_list_book_removed (DhBookList *book_list,
-                           DhBook     *book)
+dh_book_list_remove_book (DhBookList *book_list,
+                          DhBook     *book)
 {
         g_return_if_fail (DH_IS_BOOK_LIST (book_list));
         g_return_if_fail (DH_IS_BOOK (book));
 
+        /* Keep the DhBook alive during the whole signal emission. */
+        g_object_ref (book);
+
         g_signal_emit (book_list,
-                       signals[SIGNAL_BOOK_REMOVED],
+                       signals[SIGNAL_REMOVE_BOOK],
                        0,
                        book);
+
+        g_object_unref (book);
 }
diff --git a/devhelp/dh-book-list.h b/devhelp/dh-book-list.h
index f4ac70b..8e27a97 100644
--- a/devhelp/dh-book-list.h
+++ b/devhelp/dh-book-list.h
@@ -46,20 +46,20 @@ struct _DhBookList {
 /**
  * DhBookListClass:
  * @parent_class: The parent class.
- * @book_added: Virtual function pointer for the #DhBookList::book-added signal.
- * @book_removed: Virtual function pointer for the #DhBookList::book-removed
+ * @add_book: Virtual function pointer for the #DhBookList::add-book signal.
+ * @remove_book: Virtual function pointer for the #DhBookList::remove-book
  *   signal.
  * @get_books: Virtual function pointer for dh_book_list_get_books(). Returns
- *   %NULL by default.
+ *   the #DhBookList internal #GList by default.
  */
 struct _DhBookListClass {
         GObjectClass parent_class;
 
         /* Signals */
-        void    (* book_added)          (DhBookList *book_list,
+        void    (* add_book)            (DhBookList *book_list,
                                          DhBook     *book);
 
-        void    (* book_removed)        (DhBookList *book_list,
+        void    (* remove_book)         (DhBookList *book_list,
                                          DhBook     *book);
 
         /* Vfuncs */
@@ -75,10 +75,10 @@ GType   dh_book_list_get_type           (void);
 
 GList * dh_book_list_get_books          (DhBookList *book_list);
 
-void    dh_book_list_book_added         (DhBookList *book_list,
+void    dh_book_list_add_book           (DhBookList *book_list,
                                          DhBook     *book);
 
-void    dh_book_list_book_removed       (DhBookList *book_list,
+void    dh_book_list_remove_book        (DhBookList *book_list,
                                          DhBook     *book);
 
 G_END_DECLS
diff --git a/docs/reference/devhelp-sections.txt b/docs/reference/devhelp-sections.txt
index edcc4a1..fa3bd7b 100644
--- a/docs/reference/devhelp-sections.txt
+++ b/docs/reference/devhelp-sections.txt
@@ -55,8 +55,8 @@ dh_book_get_type
 DhBookList
 DhBookListClass
 dh_book_list_get_books
-dh_book_list_book_added
-dh_book_list_book_removed
+dh_book_list_add_book
+dh_book_list_remove_book
 <SUBSECTION Standard>
 DH_BOOK_LIST
 DH_BOOK_LIST_CLASS


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