[Gnucash-changes] Prepare gnc hook architecture to combine C and Scheme.

Derek Atkins warlord at cvs.gnucash.org
Wed Jun 8 14:41:54 EDT 2005


Log Message:
-----------
Prepare gnc hook architecture to combine C and Scheme.

	* src/core-utils/gnc-hooks.[ch]: rename some functions, set up the
	  architecture to handle SCM and C hook danglers all in the same
	  place.
	* src/app-file/gnc-file.c:
	* src/core-utils/gw-core-utils-spec.scm:
	* src/gnome/dialog-new-user.c:
	* src/gnome/top-level.c:
	  point to new gnc-hook function names

Tags:
----
gnucash-gnome2-dev

Modified Files:
--------------
    gnucash:
        ChangeLog
    gnucash/src/app-file:
        gnc-file.c
    gnucash/src/core-utils:
        gnc-hooks.c
        gnc-hooks.h
        gw-core-utils-spec.scm
    gnucash/src/gnome:
        dialog-new-user.c
        top-level.c

Revision Data
-------------
Index: ChangeLog
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/ChangeLog,v
retrieving revision 1.1487.2.219
retrieving revision 1.1487.2.220
diff -LChangeLog -LChangeLog -u -r1.1487.2.219 -r1.1487.2.220
--- ChangeLog
+++ ChangeLog
@@ -1,3 +1,14 @@
+2005-06-08  Derek Atkins  <derek at ihtfp.com>
+
+	* src/core-utils/gnc-hooks.[ch]: rename some functions, set up the
+	  architecture to handle SCM and C hook danglers all in the same
+	  place.
+	* src/app-file/gnc-file.c:
+	* src/core-utils/gw-core-utils-spec.scm:
+	* src/gnome/dialog-new-user.c:
+	* src/gnome/top-level.c:
+	  point to new gnc-hook function names
+
 2005-06-07  David Hampton  <hampton at employees.org>
 
 	* src/gnome/gnc-plugin-page-register.c:
Index: gnc-hooks.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/core-utils/Attic/gnc-hooks.h,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -Lsrc/core-utils/gnc-hooks.h -Lsrc/core-utils/gnc-hooks.h -u -r1.1.2.1 -r1.1.2.2
--- src/core-utils/gnc-hooks.h
+++ src/core-utils/gnc-hooks.h
@@ -21,12 +21,47 @@
  *
  */
 
-void gnc_run_c_hook(const gchar *name, gpointer data);
-void gnc_add_to_c_hook(const gchar *name, GHookFunc callback);
-void gnc_remove_from_c_hook(const gchar *name, GHookFunc callback);
+#ifndef GNC_HOOKS_H
+#define GNC_HOOKS_H
 
+/**
+ * Create a new hook.  Not a common occurrance, but...
+ * The returned string is just the 'name' argument,
+ * which belongs to the caller.
+ */
+const gchar * gnc_hook_create(const gchar *name, const gchar *desc);
 
-/* Common hook name */
+/**
+ * lookup the description of a hook.  returned description belongs to
+ * the hook and not the caller
+ */
+const gchar * gnc_hook_get_description(const gchar *name);
+
+/**
+ * add and remove C-style dangers from a hook
+ */
+void gnc_hook_add_dangler(const gchar *name, GHookFunc callback);
+void gnc_hook_remove_dangler(const gchar *name, GHookFunc callback);
+
+#if 0
+/**
+ * add and remove Scheme-style danglers from a hook
+ */
+void gnc_hook_add_scm_dangler(const gchar *name, SCM proc);
+void gnc_hook_del_scm_dangler(const gchar *name, SCM proc);
+#endif
+
+/**
+ * Run the hook danglers.
+ */
+void gnc_hook_run(const gchar *name, gpointer data);
+
+/**
+ * Initialize the known hooks
+ */
+void gnc_hooks_init(void);
+
+/* Common hook names */
 #define HOOK_STARTUP		"hook_startup"
 #define HOOK_SHUTDOWN		"hook_shutdown"
 #define HOOK_UI_STARTUP		"ui-startup-hook"
@@ -38,3 +73,5 @@
 /* Common session hook names */
 #define HOOK_BOOK_OPENED	"book-opened-hook"
 #define HOOK_BOOK_CLOSED	"book-closed-hook"
+
+#endif /* GNC_HOOKS_H */
Index: gnc-hooks.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/core-utils/Attic/gnc-hooks.c,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -Lsrc/core-utils/gnc-hooks.c -Lsrc/core-utils/gnc-hooks.c -u -r1.1.2.1 -r1.1.2.2
--- src/core-utils/gnc-hooks.c
+++ src/core-utils/gnc-hooks.c
@@ -26,113 +26,175 @@
 #include <stdio.h>
 #include "gnc-hooks.h"
 
-GHashTable* all_hook_lists = NULL;
+static GHashTable* gnc_hooks_list = NULL;
+static gboolean gnc_hooks_initialized = FALSE;
 
-static GHookList *
-gnc_lookup_hook_list (const gchar *name)
+typedef struct {
+  gchar		*desc;
+  GHookList	*c_danglers;
+  GHookList	*scm_danglers;
+} GncHook;
+
+const gchar *
+gnc_hook_create (const gchar *name, const gchar *desc)
 {
-  GHookList *hook_list;
+  GncHook *hook_list;
 
   //printf("Enter %s: name %s\n", __FUNCTION__, name);
-  if (all_hook_lists == NULL) {
-    //printf("Leave %s: no hook lists\n", __FUNCTION__);
-    return NULL;
+  if (gnc_hooks_list == NULL) {
+    gnc_hooks_list = g_hash_table_new(g_str_hash, g_str_equal);
+
+    /* If we're not initialized then initialize now */
+    if (!gnc_hooks_initialized)
+      gnc_hooks_init();
   }
 
-  hook_list = g_hash_table_lookup(all_hook_lists, name);
-  //printf("Leave %s: hook list %p\n", __FUNCTION__, hook_list);
-  return(hook_list);
+  hook_list = g_hash_table_lookup(gnc_hooks_list, name);
+  if (hook_list) {
+    //printf("Leave %s: list %s(%p) already exists\n\n", __FUNCTION__, name, hook_list);
+    return(name);
+  }
+
+  hook_list = g_new0(GncHook, 1);
+  hook_list->desc = g_strdup(desc);
+  hook_list->c_danglers = g_malloc(sizeof(GHookList));
+  g_hook_list_init(hook_list->c_danglers, sizeof(GHook));
+  hook_list->scm_danglers = g_malloc(sizeof(GHookList));
+  g_hook_list_init(hook_list->scm_danglers, sizeof(GHook));
+  g_hash_table_insert(gnc_hooks_list, (gchar *)name, hook_list);
+  //printf("Leave %s: created list %s(%p)\n", __FUNCTION__, name, hook_list);
+
+  return name;
 }
 
-static GHookList *
-gnc_create_hook_list (const gchar *name)
+static GncHook *
+gnc_hook_lookup (const gchar *name)
 {
-  GHookList *hook_list;
+  GncHook *hook;
 
   //printf("Enter %s: name %s\n", __FUNCTION__, name);
-  if (all_hook_lists == NULL)
-    all_hook_lists = g_hash_table_new(g_str_hash, g_str_equal);
-
-  hook_list = g_hash_table_lookup(all_hook_lists, name);
-  if (hook_list) {
-    //printf("Leave %s: list %s(%p) already exists\n\n", __FUNCTION__, name, hook_list);
-    return(hook_list);
+  if (gnc_hooks_list == NULL) {
+    //printf("Leave %s: no hook lists\n", __FUNCTION__);
+    gnc_hooks_init();
   }
 
-  hook_list = g_malloc(sizeof(GHookList));
-  g_hook_list_init(hook_list, sizeof(GHook));
-  g_hash_table_insert(all_hook_lists, (gchar *)name, hook_list);
-  //printf("Leave %s: created list %s(%p)\n", __FUNCTION__, name, hook_list);
-  return(hook_list);
+  hook = g_hash_table_lookup(gnc_hooks_list, name);
+  //printf("Leave %s: hook list %p\n", __FUNCTION__, hook_list);
+  return(hook);
+}
+
+const gchar *
+gnc_hook_get_description(const gchar *name)
+{
+  GncHook *hook;
+
+  hook = gnc_hook_lookup(name);
+  if (!hook) return "";
+  return hook->desc;
 }
 
 void
-gnc_add_to_c_hook (const gchar *name,
-		   GHookFunc callback)
+gnc_hook_add_dangler (const gchar *name, GHookFunc callback)
 {
-  GHookList *hook_list;
+  GncHook *gnc_hook;
   GHook *hook;
 
   //printf("Enter %s: list %s, function %p\n\n", __FUNCTION__, name, callback);
-  hook_list = gnc_create_hook_list(name);
-  hook = g_hook_alloc(hook_list);
+  gnc_hook = gnc_hook_lookup(name);
+  g_return_if_fail(gnc_hook != NULL);
+  hook = g_hook_alloc(gnc_hook->c_danglers);
   hook->func = callback;
-  g_hook_append(hook_list, hook);
+  g_hook_append(gnc_hook->c_danglers, hook);
   //printf("Leave %s:  \n", __FUNCTION__);
 }
 
 static gboolean
-hook_remove_runner (GHook *hook,
-		    gpointer data)
+hook_remove_runner (GHook *hook, gpointer data)
 {
   return(hook->func == data);
 }
 
-
 void
-gnc_remove_from_c_hook (const gchar *name,
-			GHookFunc callback)
+gnc_hook_remove_dangler (const gchar *name, GHookFunc callback)
 {
-  GHookList *hook_list;
+  GncHook *gnc_hook;
   GHook *hook;
 
   //printf("Enter %s: name %s, function %p\n\n", __FUNCTION__, name, callback);
-  hook_list = gnc_lookup_hook_list(name);
-  if (hook_list == NULL) {
+  gnc_hook = gnc_hook_lookup(name);
+  if (gnc_hook == NULL) {
     //printf("Leave %s: Unknown hook list %s\n", __FUNCTION__, name);
     return;
   }
 
-  hook = g_hook_find(hook_list, TRUE, hook_remove_runner, callback);
+  hook = g_hook_find(gnc_hook->c_danglers, TRUE, hook_remove_runner, callback);
   if (hook == NULL) {
     //printf("Leave %s: Hook %p not found in %s\n", __FUNCTION__, callback, name);
     return;
   }
 
-  g_hook_unref(hook_list, hook);
+  g_hook_unref(gnc_hook->c_danglers, hook);
   //printf("Leave %s: Removed %p from %s\n", __FUNCTION__ , hook, name);
 }
 
 
 static void
-call_hook (GHook *hook, gpointer data)
+call_c_hook (GHook *hook, gpointer data)
 {
   //printf("Enter %s: hook %p (func %p), data %p\n", __FUNCTION__, hook, hook->func, data);
   ((GHookFunc)hook->func)(data);
   //printf("Leave %s:  \n", __FUNCTION__);
 }
 
+static void
+call_scm_hook (GHook *hook, gpointer data)
+{
+  // XXX.  Implement me.
+}
+
 void
-gnc_run_c_hook (const gchar *name, gpointer data)
+gnc_hook_run (const gchar *name, gpointer data)
 {
-  GHookList *hook_list;
+  GncHook *hook;
 
   //printf("Enter %s: list %s, data %p\n", __FUNCTION__, name, data);
-  hook_list = gnc_lookup_hook_list(name);
-  if (!hook_list) {
+  hook = gnc_hook_lookup(name);
+  if (!hook) {
     //printf("Leave %s: No such hook list\n", __FUNCTION__);
     return;
   }
-  g_hook_list_marshal(hook_list, TRUE, call_hook, data);
+  g_hook_list_marshal(hook->c_danglers, TRUE, call_c_hook, data);
+  g_hook_list_marshal(hook->scm_danglers, TRUE, call_scm_hook, data);
   //printf("Leave %s:  \n", __FUNCTION__);
 }
+
+void
+gnc_hooks_init(void)
+{
+  if (gnc_hooks_initialized)
+    return;
+
+  gnc_hooks_initialized = TRUE;
+
+  gnc_hook_create(HOOK_STARTUP,
+		  "Functions to run at startup.  Hook args: ()");
+  gnc_hook_create(HOOK_SHUTDOWN,
+		  "Functions to run at guile shutdown.  Hook args: ()");
+  gnc_hook_create(HOOK_UI_STARTUP,
+		  "Functions to run when the ui comes up.  Hook args: ()");
+  gnc_hook_create(HOOK_UI_POST_STARTUP,
+		  "Functions to run after the ui comes up.  Hook args: ()");
+  gnc_hook_create(HOOK_UI_SHUTDOWN,
+		  "Functions to run at ui shutdown.  Hook args: ()");
+  gnc_hook_create(HOOK_NEW_BOOK,
+		  "Run after a new (empty) book is opened, before the"
+		  " book-opened-hook. Hook args: ()");
+  gnc_hook_create(HOOK_REPORT,
+		  "Run just before the reports are pushed into the menus."
+		  "  Hook args: ()");
+
+  gnc_hook_create(HOOK_BOOK_OPENED,
+		  "Run after book open.  Hook args: <gnc:Session*>.");
+  gnc_hook_create(HOOK_BOOK_CLOSED,
+		  "Run before file close.  Hook args: <gnc:Session*>");
+}
Index: gw-core-utils-spec.scm
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/core-utils/gw-core-utils-spec.scm,v
retrieving revision 1.2.4.1
retrieving revision 1.2.4.2
diff -Lsrc/core-utils/gw-core-utils-spec.scm -Lsrc/core-utils/gw-core-utils-spec.scm -u -r1.2.4.1 -r1.2.4.2
--- src/core-utils/gw-core-utils-spec.scm
+++ src/core-utils/gw-core-utils-spec.scm
@@ -41,7 +41,7 @@
    ws
    'gnc:run-c-hook
    '<gw:void>
-   "gnc_run_c_hook"
+   "gnc_hook_run"
    '(((<gw:mchars> caller-owned) name) (<gw:void*> data))
    "Run a callback hook in the C domain.")
 )
Index: gnc-file.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/app-file/gnc-file.c,v
retrieving revision 1.25.4.15
retrieving revision 1.25.4.16
diff -Lsrc/app-file/gnc-file.c -Lsrc/app-file/gnc-file.c -u -r1.25.4.15 -r1.25.4.16
--- src/app-file/gnc-file.c
+++ src/app-file/gnc-file.c
@@ -355,7 +355,7 @@
               (session ? 
                gw_wcp_assimilate_ptr (session, scm_c_eval_string("<gnc:Session*>")) :
                SCM_BOOL_F));
-  gnc_run_c_hook(HOOK_BOOK_OPENED, session);
+  gnc_hook_run(HOOK_BOOK_OPENED, session);
 }
 
 void
@@ -380,7 +380,7 @@
              (session ?
               gw_wcp_assimilate_ptr (session, scm_c_eval_string("<gnc:Session*>")) :
               SCM_BOOL_F));
-  gnc_run_c_hook(HOOK_BOOK_CLOSED, session);
+  gnc_hook_run(HOOK_BOOK_CLOSED, session);
 
   gnc_close_gui_component_by_session (session);
   xaccLogDisable();
@@ -392,7 +392,7 @@
 
   scm_call_1(scm_c_eval_string("gnc:hook-run-danglers"),
              scm_c_eval_string("gnc:*new-book-hook*"));
-  gnc_run_c_hook(HOOK_NEW_BOOK, NULL);
+  gnc_hook_run(HOOK_NEW_BOOK, NULL);
 
   gnc_book_opened ();
 
@@ -475,7 +475,7 @@
               gw_wcp_assimilate_ptr (current_session,
                                      scm_c_eval_string("<gnc:Session*>")) :
               SCM_BOOL_F));
-  gnc_run_c_hook(HOOK_BOOK_CLOSED, current_session);
+  gnc_hook_run(HOOK_BOOK_CLOSED, current_session);
   xaccLogDisable();
   qof_session_destroy (current_session);
   xaccLogEnable();
@@ -970,7 +970,7 @@
              (session ?
               gw_wcp_assimilate_ptr (session, scm_c_eval_string("<gnc:Session*>")) :
               SCM_BOOL_F));
-  gnc_run_c_hook(HOOK_BOOK_CLOSED, session);
+  gnc_hook_run(HOOK_BOOK_CLOSED, session);
   
   xaccLogDisable();
   qof_session_destroy (session);
Index: dialog-new-user.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/gnome/dialog-new-user.c,v
retrieving revision 1.4.4.10
retrieving revision 1.4.4.11
diff -Lsrc/gnome/dialog-new-user.c -Lsrc/gnome/dialog-new-user.c -u -r1.4.4.10 -r1.4.4.11
--- src/gnome/dialog-new-user.c
+++ src/gnome/dialog-new-user.c
@@ -137,5 +137,5 @@
 gncp_new_user_finish (void)
 {
   scm_c_eval_string("(gnc:hook-run-danglers gnc:*book-opened-hook* #f)");
-  gnc_run_c_hook(HOOK_BOOK_OPENED, NULL);
+  gnc_hook_run(HOOK_BOOK_OPENED, NULL);
 }
Index: top-level.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/gnome/top-level.c,v
retrieving revision 1.140.4.20
retrieving revision 1.140.4.21
diff -Lsrc/gnome/top-level.c -Lsrc/gnome/top-level.c -u -r1.140.4.20 -r1.140.4.21
--- src/gnome/top-level.c
+++ src/gnome/top-level.c
@@ -403,7 +403,7 @@
       SCM run_danglers = scm_c_eval_string("gnc:hook-run-danglers");
       SCM hook = scm_c_eval_string("gnc:*ui-startup-hook*");
       scm_call_1(run_danglers, hook); 
-      gnc_run_c_hook(HOOK_UI_STARTUP, NULL);
+      gnc_hook_run(HOOK_UI_STARTUP, NULL);
     }
 
     // return ( main_window . command_line )


More information about the gnucash-changes mailing list