[Gnucash-changes] add finalizers for the user-data hooks.

Linas Vepstas linas at cvs.gnucash.org
Sun May 30 19:32:52 EDT 2004


Log Message:
-----------
add finalizers for the user-data hooks.  The finalizer is called when the 
book is being destroyed, allowing user to clean up thier data.

Modified Files:
--------------
    gnucash/src/engine:
        qofbook-p.h
        qofbook.c
        qofbook.h

Revision Data
-------------
Index: qofbook.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofbook.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -Lsrc/engine/qofbook.h -Lsrc/engine/qofbook.h -u -r1.12 -r1.13
--- src/engine/qofbook.h
+++ src/engine/qofbook.h
@@ -67,6 +67,8 @@
 /** GList of QofBook */
 typedef GList                 QofBookList;
 
+typedef void (*QofBookFinalCB) (QofBook *, gpointer key, gpointer user_data);
+
 /** Register the book object with the QOF object system. */
 gboolean qof_book_register (void);
                                                                                 
@@ -90,19 +92,33 @@
 typedef void (*QofCollectionForeachCB) (QofCollection *, gpointer user_data);
 void qof_book_foreach_collection (QofBook *, QofCollectionForeachCB, gpointer);
 
-/** \return The kvp data for the book */
+/** \return The kvp data for the book.
+ *  Note that the boom KVP data is persistant, and is stored/retrevied
+ *  from the file/database.  Thus, the book KVP is the correct place to
+ *  store data that needs to be persistant accross sessions (or shared
+ *  between multiple users).  To store application runtime data, use
+ *  qof_book_set_data() isntead.
+ */
 KvpFrame   * qof_book_get_slots (QofBook *book);
 
 /** The qof_book_set_data() allows arbitrary pointers to structs 
  *    to be stored in QofBook. This is the "prefered" method for 
- *    extending QofBook to hold new data types.
+ *    extending QofBook to hold new data types.  This is also
+ *    the ideal location to store other arbitrary runtime data 
+ *    that the application may need.
  *
- * XXX FIXME: we need to add a destroy callback, so that when the
- * book gets destroyed, the user gets notified and thus has a chance
- * to clean up.
+ *    The book data differs from the book KVP in that the contents
+ *    of the book KVP are persistant (are saved and restored to file 
+ *    or database), whereas the data pointers exist only at runtime.
  */
 void qof_book_set_data (QofBook *book, const char *key, gpointer data);
 
+/** Same as qof_book_set_data(), except that the callback will be called
+ *  when the book is destroyed.  The argument to the callback will be 
+ *  the book followed by the data pointer.
+ */
+void qof_book_set_data_fin (QofBook *book, const char *key, gpointer data, QofBookFinalCB);
+
 /** Retreives arbitrary pointers to structs stored by qof_book_set_data. */
 gpointer qof_book_get_data (QofBook *book, const char *key);
 
Index: qofbook.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofbook.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -Lsrc/engine/qofbook.c -Lsrc/engine/qofbook.c -u -r1.22 -r1.23
--- src/engine/qofbook.c
+++ src/engine/qofbook.c
@@ -69,6 +69,7 @@
   book->kvp_data = kvp_frame_new ();
   
   book->data_tables = g_hash_table_new (g_str_hash, g_str_equal);
+  book->data_table_finalizers = g_hash_table_new (g_str_hash, g_str_equal);
   
   book->book_open = 'y';
   book->version = 0;
@@ -98,21 +99,35 @@
   return TRUE;
 }
 
+static void
+book_final (gpointer key, gpointer value, gpointer booq)
+{
+  QofBookFinalCB cb = value;
+  QofBook *book = booq;
+
+  gpointer user_data = g_hash_table_lookup (book->data_tables, key);
+  (*cb) (book, key, user_data);
+}
+
 void
 qof_book_destroy (QofBook *book) 
 {
   if (!book) return;
+  ENTER ("book=%p", book);
 
   book->shutting_down = TRUE;
-
-  ENTER ("book=%p", book);
   gnc_engine_force_event (&book->entity, GNC_EVENT_DESTROY);
 
+  /* Call the list of finalizers, let them do thier thing. 
+   * Do this before tearing into the rest of the book.
+   */
+  g_hash_table_foreach (book->data_table_finalizers, book_final, book);
+
   qof_object_book_end (book);
 
   kvp_frame_delete (book->kvp_data);
 
-  /* FIXME: Make sure the data_table is empty */
+  g_hash_table_destroy (book->data_table_finalizers);
   g_hash_table_destroy (book->data_tables);
 
   qof_entity_release (&book->entity);
@@ -201,13 +216,6 @@
 
 /* Store arbitrary pointers in the QofBook for data storage extensibility */
 /* XXX if data is NULL, we should remove the key from the hash table!
- *
- * XXX We need some design comments:  an equivalent storage mechanism
- * would have been to give each item a GUID, store the GUID in a kvp frame,
- * and then do a GUID lookup to get the pointer to the actual object.
- * Of course, doing a kvp lookup followed by a GUID lookup would be 
- * a good bit slower, but may be that's OK? In most cases, book data
- * is accessed only infrequently?  --linas
  */
 void 
 qof_book_set_data (QofBook *book, const char *key, gpointer data)
@@ -216,6 +224,16 @@
   g_hash_table_insert (book->data_tables, (gpointer)key, data);
 }
 
+void 
+qof_book_set_data_fin (QofBook *book, const char *key, gpointer data, QofBookFinalCB cb)
+{
+  if (!book || !key) return;
+  g_hash_table_insert (book->data_tables, (gpointer)key, data);
+
+  if (!cb) return;
+  g_hash_table_insert (book->data_table_finalizers, (gpointer)key, cb);
+}
+
 gpointer 
 qof_book_get_data (QofBook *book, const char *key)
 {
Index: qofbook-p.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofbook-p.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -Lsrc/engine/qofbook-p.h -Lsrc/engine/qofbook-p.h -u -r1.7 -r1.8
--- src/engine/qofbook-p.h
+++ src/engine/qofbook-p.h
@@ -62,6 +62,9 @@
    */
   GHashTable *data_tables;
 
+  /** Hash table of destroy callbacks for the data table. */
+  GHashTable *data_table_finalizers;
+
   /** state flag: 'y' means 'open for editing', 
    * 'n' means 'book is closed'  
    */


More information about the gnucash-changes mailing list