mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
gnc-hooks - factor out scm calls into a separate source file
This required the addition of an extra parameter to gnc_hook_add_dangler to allow the scm hooks to unprotect the scm data on hook destruction.
This commit is contained in:
parent
49bf27fad5
commit
b1ba16c33b
@ -2542,9 +2542,9 @@ gnc_main_window_class_init (GncMainWindowClass *klass)
|
||||
NULL);
|
||||
|
||||
gnc_hook_add_dangler(HOOK_BOOK_SAVED,
|
||||
(GFunc)gnc_main_window_update_all_titles, NULL);
|
||||
(GFunc)gnc_main_window_update_all_titles, NULL, NULL);
|
||||
gnc_hook_add_dangler(HOOK_BOOK_OPENED,
|
||||
(GFunc)gnc_main_window_attach_to_book, NULL);
|
||||
(GFunc)gnc_main_window_attach_to_book, NULL, NULL);
|
||||
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ gnc_plugin_manager_get (void)
|
||||
singleton = g_object_new (GNC_TYPE_PLUGIN_MANAGER,
|
||||
NULL);
|
||||
gnc_hook_add_dangler (HOOK_SHUTDOWN,
|
||||
gnc_plugin_manager_shutdown, NULL);
|
||||
gnc_plugin_manager_shutdown, NULL, NULL);
|
||||
}
|
||||
|
||||
return singleton;
|
||||
|
@ -138,7 +138,7 @@ gnc_tree_view_account_class_init (GncTreeViewAccountClass *klass)
|
||||
o_class->finalize = gnc_tree_view_account_finalize;
|
||||
|
||||
gnc_hook_add_dangler(HOOK_CURRENCY_CHANGED,
|
||||
(GFunc)gtva_currency_changed_cb, NULL);
|
||||
(GFunc)gtva_currency_changed_cb, NULL, NULL);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
|
@ -110,7 +110,7 @@ gnc_tree_view_owner_class_init (GncTreeViewOwnerClass *klass)
|
||||
o_class->finalize = gnc_tree_view_owner_finalize;
|
||||
|
||||
gnc_hook_add_dangler(HOOK_CURRENCY_CHANGED,
|
||||
(GFunc)gtvo_currency_changed_cb, NULL);
|
||||
(GFunc)gtvo_currency_changed_cb, NULL, NULL);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
|
@ -1366,5 +1366,5 @@ void
|
||||
gnc_ui_hierarchy_assistant_initialize (void)
|
||||
{
|
||||
gnc_hook_add_dangler(HOOK_NEW_BOOK,
|
||||
(GFunc)gnc_ui_hierarchy_assistant_hook, NULL);
|
||||
(GFunc)gnc_ui_hierarchy_assistant_hook, NULL, NULL);
|
||||
}
|
||||
|
@ -1822,7 +1822,7 @@ gnc_ui_sx_initialize (void)
|
||||
_sx_engine_event_handler_id = qof_event_register_handler(_sx_engine_event_handler, NULL);
|
||||
|
||||
gnc_hook_add_dangler(HOOK_BOOK_OPENED,
|
||||
(GFunc)gnc_sx_sxsincelast_book_opened, NULL);
|
||||
(GFunc)gnc_sx_sxsincelast_book_opened, NULL, NULL);
|
||||
|
||||
/* Add page to preferences page for Scheduled Transactions */
|
||||
/* The parameters are; glade file, items to add from glade file - last being the dialog, preference tab name */
|
||||
|
@ -1771,7 +1771,7 @@ gnc_ui_sx_initialize2 (void) //FIXME need to remove the 2 when live
|
||||
_sx_engine_event_handler_id = qof_event_register_handler (_sx_engine_event_handler, NULL);
|
||||
|
||||
gnc_hook_add_dangler (HOOK_BOOK_OPENED,
|
||||
(GFunc)gnc_sx_sxsincelast_book_opened, NULL);
|
||||
(GFunc)gnc_sx_sxsincelast_book_opened, NULL, NULL);
|
||||
|
||||
/* Add page to preferences page for Scheduled Transactions */
|
||||
/* The parameters are; glade file, items to add from glade file - last being the dialog, preference tab name */
|
||||
|
@ -411,15 +411,15 @@ gnc_main_gui_init (void)
|
||||
gnc_hook_run(HOOK_UI_STARTUP, NULL);
|
||||
|
||||
gnc_hook_add_dangler(HOOK_BOOK_OPENED,
|
||||
gnc_restore_all_state, NULL);
|
||||
gnc_restore_all_state, NULL, NULL);
|
||||
gnc_hook_add_dangler(HOOK_BOOK_CLOSED,
|
||||
gnc_save_all_state, NULL);
|
||||
gnc_save_all_state, NULL, NULL);
|
||||
gnc_hook_add_dangler(HOOK_BOOK_CLOSED,
|
||||
(GFunc)gnc_reports_flush_global, NULL);
|
||||
(GFunc)gnc_reports_flush_global, NULL, NULL);
|
||||
gnc_hook_add_dangler(HOOK_BOOK_OPENED,
|
||||
(GFunc)gnc_invoice_remind_bills_due_cb, NULL);
|
||||
(GFunc)gnc_invoice_remind_bills_due_cb, NULL, NULL);
|
||||
gnc_hook_add_dangler(HOOK_BOOK_OPENED,
|
||||
(GFunc)gnc_invoice_remind_invoices_due_cb, NULL);
|
||||
(GFunc)gnc_invoice_remind_invoices_due_cb, NULL, NULL);
|
||||
|
||||
gnc_ui_sx_initialize();
|
||||
|
||||
|
@ -636,7 +636,7 @@ inner_main (void *closure, int argc, char **argv)
|
||||
before booting guile. */
|
||||
gnc_main_gui_init();
|
||||
|
||||
gnc_hook_add_dangler(HOOK_UI_SHUTDOWN, (GFunc)gnc_file_quit, NULL);
|
||||
gnc_hook_add_dangler(HOOK_UI_SHUTDOWN, (GFunc)gnc_file_quit, NULL, NULL);
|
||||
|
||||
/* Install Price Quote Sources */
|
||||
gnc_update_splash_screen(_("Checking Finance::Quote..."), GNC_SPLASH_PERCENTAGE_UNKNOWN);
|
||||
|
@ -122,7 +122,7 @@
|
||||
(define gnc:current-saved-stylesheets
|
||||
(gnc-build-userdata-path "stylesheets-2.0"))
|
||||
|
||||
(define (gnc:save-style-sheet-options)
|
||||
(define (gnc:save-style-sheet-options)
|
||||
(let ((port (false-if-exception
|
||||
(open gnc:current-saved-stylesheets
|
||||
(logior O_WRONLY O_CREAT O_TRUNC)))))
|
||||
|
@ -95,8 +95,8 @@ libgncmod_app_utils_gnc_module_init(int refcount)
|
||||
if (refcount == 0)
|
||||
{
|
||||
gnc_component_manager_init ();
|
||||
gnc_hook_add_dangler(HOOK_STARTUP, (GFunc)gnc_exp_parser_init, NULL);
|
||||
gnc_hook_add_dangler(HOOK_SHUTDOWN, (GFunc)app_utils_shutdown, NULL);
|
||||
gnc_hook_add_dangler(HOOK_STARTUP, (GFunc)gnc_exp_parser_init, NULL, NULL);
|
||||
gnc_hook_add_dangler(HOOK_SHUTDOWN, (GFunc)app_utils_shutdown, NULL, NULL);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -160,6 +160,7 @@ set (engine_SOURCES
|
||||
gnc-event.c
|
||||
gnc-features.c
|
||||
gnc-hooks.c
|
||||
gnc-hooks-scm.c
|
||||
gnc-int128.cpp
|
||||
gnc-lot.c
|
||||
gnc-numeric.cpp
|
||||
|
86
libgnucash/engine/gnc-hooks-scm.c
Normal file
86
libgnucash/engine/gnc-hooks-scm.c
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* gnc-hooks-scm.c -- helpers for using Glib hook functions in guile
|
||||
* Copyright (C) 2005 David Hampton <hampton@employees.org>
|
||||
* Derek Atkins <derek@ihtfp.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, contact:
|
||||
*
|
||||
* Free Software Foundation Voice: +1-617-542-5942
|
||||
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
|
||||
* Boston, MA 02110-1301, USA gnu@gnu.org
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#include "gnc-hooks.h"
|
||||
#include "gnc-hooks-scm.h"
|
||||
#include "gnc-engine.h"
|
||||
#include <libguile.h>
|
||||
#include "swig-runtime.h"
|
||||
#include <guile-mappings.h>
|
||||
|
||||
static QofLogModule log_module = GNC_MOD_ENGINE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SCM proc;
|
||||
int num_args;
|
||||
} GncScmDangler;
|
||||
|
||||
|
||||
static void
|
||||
delete_scm_hook (gpointer data)
|
||||
{
|
||||
GncScmDangler *scm = data;
|
||||
scm_gc_unprotect_object(scm->proc);
|
||||
g_free(scm);
|
||||
}
|
||||
|
||||
static void
|
||||
scm_hook_cb (gpointer data, GncScmDangler *scm)
|
||||
{
|
||||
ENTER("data %p, cbarg %p", data, scm);
|
||||
|
||||
if (scm->num_args == 0)
|
||||
scm_call_0 (scm->proc);
|
||||
else
|
||||
{
|
||||
// XXX: FIXME: We really should make sure this is a session!!! */
|
||||
scm_call_1 (scm->proc,
|
||||
SWIG_NewPointerObj(data, SWIG_TypeQuery("_p_QofSession"), 0));
|
||||
}
|
||||
|
||||
LEAVE("");
|
||||
}
|
||||
|
||||
void
|
||||
gnc_hook_add_scm_dangler (const gchar *name, SCM proc)
|
||||
{
|
||||
GHook *hook;
|
||||
GncScmDangler *scm;
|
||||
int num_args;
|
||||
|
||||
ENTER("list %s, proc ???", name);
|
||||
num_args = gnc_hook_num_args(name);
|
||||
g_return_if_fail(num_args >= 0);
|
||||
scm = g_new0(GncScmDangler, 1);
|
||||
scm_gc_protect_object(proc);
|
||||
scm->proc = proc;
|
||||
scm->num_args = num_args;
|
||||
gnc_hook_add_dangler(name, (GFunc)scm_hook_cb,
|
||||
(GDestroyNotify) delete_scm_hook, scm);
|
||||
LEAVE("");
|
||||
}
|
@ -25,11 +25,7 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#include <libguile.h>
|
||||
#include "swig-runtime.h"
|
||||
#include <guile-mappings.h>
|
||||
#include "gnc-hooks.h"
|
||||
#include "gnc-hooks-scm.h"
|
||||
#include "gnc-engine.h"
|
||||
|
||||
static QofLogModule log_module = GNC_MOD_ENGINE;
|
||||
@ -39,16 +35,11 @@ static gboolean gnc_hooks_initialized = FALSE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar *desc;
|
||||
GHookList *c_danglers;
|
||||
GHookList *scm_danglers;
|
||||
gint num_args;
|
||||
gchar *desc;
|
||||
GHookList *danglers;
|
||||
gint num_args;
|
||||
} GncHook;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SCM proc;
|
||||
} GncScmDangler;
|
||||
|
||||
gchar *
|
||||
gnc_hook_create (const gchar *name, gint num_args, const gchar *desc)
|
||||
@ -78,11 +69,9 @@ gnc_hook_create (const gchar *name, gint num_args, const gchar *desc)
|
||||
|
||||
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));
|
||||
hook_list->danglers = g_malloc(sizeof(GHookList));
|
||||
g_hook_list_init(hook_list->danglers, sizeof(GHook));
|
||||
hook_list->num_args = num_args;
|
||||
g_hook_list_init(hook_list->scm_danglers, sizeof(GHook));
|
||||
g_hash_table_insert(gnc_hooks_list, (gchar *)name, hook_list);
|
||||
|
||||
LEAVE("created list %s(%p)", name, hook_list);
|
||||
@ -106,8 +95,29 @@ gnc_hook_lookup (const gchar *name)
|
||||
return(hook);
|
||||
}
|
||||
|
||||
int
|
||||
gnc_hook_num_args (const gchar *name)
|
||||
{
|
||||
GncHook *hook;
|
||||
int num_args = -1;
|
||||
|
||||
ENTER("name %s", name);
|
||||
if (gnc_hooks_list == NULL)
|
||||
{
|
||||
PINFO("no hook lists");
|
||||
gnc_hooks_init();
|
||||
}
|
||||
|
||||
hook = g_hash_table_lookup(gnc_hooks_list, name);
|
||||
if (hook)
|
||||
num_args = hook->num_args;
|
||||
LEAVE("hook list %p, num_args %i", hook, num_args);
|
||||
return(num_args);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_hook_add_dangler (const gchar *name, GFunc callback, gpointer cb_arg)
|
||||
gnc_hook_add_dangler (const gchar *name, GFunc callback,
|
||||
GDestroyNotify destroy, gpointer cb_arg)
|
||||
{
|
||||
GncHook *gnc_hook;
|
||||
GHook *hook;
|
||||
@ -115,20 +125,14 @@ gnc_hook_add_dangler (const gchar *name, GFunc callback, gpointer cb_arg)
|
||||
ENTER("list %s, function %p, cbarg %p", name, callback, cb_arg);
|
||||
gnc_hook = gnc_hook_lookup(name);
|
||||
g_return_if_fail(gnc_hook != NULL);
|
||||
hook = g_hook_alloc(gnc_hook->c_danglers);
|
||||
hook = g_hook_alloc(gnc_hook->danglers);
|
||||
hook->func = callback;
|
||||
hook->data = cb_arg;
|
||||
hook->destroy = NULL;
|
||||
g_hook_append(gnc_hook->c_danglers, hook);
|
||||
hook->destroy = destroy;
|
||||
g_hook_append(gnc_hook->danglers, hook);
|
||||
LEAVE("");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
hook_remove_runner (GHook *hook, gpointer data)
|
||||
{
|
||||
return(hook->func == data);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_hook_remove_dangler (const gchar *name, GFunc callback)
|
||||
{
|
||||
@ -143,74 +147,19 @@ gnc_hook_remove_dangler (const gchar *name, GFunc callback)
|
||||
return;
|
||||
}
|
||||
|
||||
hook = g_hook_find(gnc_hook->c_danglers, TRUE, hook_remove_runner, callback);
|
||||
hook = g_hook_find_func(gnc_hook->danglers, TRUE, callback);
|
||||
if (hook == NULL)
|
||||
{
|
||||
LEAVE("Hook %p not found in %s", callback, name);
|
||||
return;
|
||||
}
|
||||
|
||||
g_hook_destroy_link(gnc_hook->c_danglers, hook);
|
||||
g_hook_destroy_link(gnc_hook->danglers, hook);
|
||||
LEAVE("Removed %p from %s", hook, name);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_scm_hook (gpointer data)
|
||||
{
|
||||
GncScmDangler *scm = data;
|
||||
scm_gc_unprotect_object(scm->proc);
|
||||
g_free(scm);
|
||||
}
|
||||
|
||||
static void
|
||||
call_scm_hook (GHook *hook, gpointer data)
|
||||
{
|
||||
GncScmDangler *scm = hook->data;
|
||||
|
||||
ENTER("hook %p, data %p, cbarg %p", hook, data, hook->data);
|
||||
|
||||
scm_call_0 (scm->proc);
|
||||
|
||||
LEAVE("");
|
||||
}
|
||||
|
||||
static void
|
||||
call_scm_hook_1 (GHook *hook, gpointer data)
|
||||
{
|
||||
GncScmDangler *scm = hook->data;
|
||||
|
||||
ENTER("hook %p, data %p, cbarg %p", hook, data, hook->data);
|
||||
|
||||
// XXX: FIXME: We really should make sure this is a session!!! */
|
||||
scm_call_1 (scm->proc,
|
||||
SWIG_NewPointerObj(data, SWIG_TypeQuery("_p_QofSession"), 0));
|
||||
|
||||
LEAVE("");
|
||||
}
|
||||
|
||||
void
|
||||
gnc_hook_add_scm_dangler (const gchar *name, SCM proc)
|
||||
{
|
||||
GncHook *gnc_hook;
|
||||
GHook *hook;
|
||||
GncScmDangler *scm;
|
||||
|
||||
ENTER("list %s, proc ???", name);
|
||||
gnc_hook = gnc_hook_lookup(name);
|
||||
g_return_if_fail(gnc_hook != NULL);
|
||||
scm = g_new0(GncScmDangler, 1);
|
||||
scm_gc_protect_object(proc);
|
||||
scm->proc = proc;
|
||||
hook = g_hook_alloc(gnc_hook->scm_danglers);
|
||||
hook->func = call_scm_hook;
|
||||
hook->data = scm;
|
||||
hook->destroy = delete_scm_hook;
|
||||
g_hook_append(gnc_hook->scm_danglers, hook);
|
||||
LEAVE("");
|
||||
}
|
||||
|
||||
static void
|
||||
call_c_hook (GHook *hook, gpointer data)
|
||||
call_hook (GHook *hook, gpointer data)
|
||||
{
|
||||
ENTER("hook %p (func %p), data %p, cbarg %p", hook, hook->func, data,
|
||||
hook->data);
|
||||
@ -230,11 +179,7 @@ gnc_hook_run (const gchar *name, gpointer data)
|
||||
LEAVE("No such hook list");
|
||||
return;
|
||||
}
|
||||
g_hook_list_marshal(hook->c_danglers, TRUE, call_c_hook, data);
|
||||
if (hook->num_args == 0)
|
||||
g_hook_list_marshal(hook->scm_danglers, TRUE, call_scm_hook, data);
|
||||
else
|
||||
g_hook_list_marshal(hook->scm_danglers, TRUE, call_scm_hook_1, data);
|
||||
g_hook_list_marshal(hook->danglers, TRUE, call_hook, data);
|
||||
LEAVE("");
|
||||
}
|
||||
|
||||
|
@ -36,9 +36,16 @@ gchar * gnc_hook_create(const gchar *name, gint num_args, const gchar *desc);
|
||||
* add and remove C-style dangers from a hook. The callback is called
|
||||
* function(hook_run_data, cb_data)
|
||||
*/
|
||||
void gnc_hook_add_dangler(const gchar *name, GFunc callback, gpointer cb_data);
|
||||
void gnc_hook_add_dangler(const gchar *name, GFunc callback,
|
||||
GDestroyNotify destroy, gpointer cb_data);
|
||||
void gnc_hook_remove_dangler(const gchar *name, GFunc callback);
|
||||
|
||||
/**
|
||||
* helper function to retrieve the number of arguments
|
||||
* a hook expects
|
||||
*/
|
||||
int gnc_hook_num_args (const gchar *name);
|
||||
|
||||
/**
|
||||
* Run the hook danglers.
|
||||
*/
|
||||
|
@ -642,6 +642,7 @@ libgnucash/engine/gncEntry.c
|
||||
libgnucash/engine/gnc-event.c
|
||||
libgnucash/engine/gnc-features.c
|
||||
libgnucash/engine/gnc-hooks.c
|
||||
libgnucash/engine/gnc-hooks-scm.c
|
||||
libgnucash/engine/gncIDSearch.c
|
||||
libgnucash/engine/gnc-int128.cpp
|
||||
libgnucash/engine/gncInvoice.c
|
||||
|
Loading…
Reference in New Issue
Block a user