GnuCash c935c2f+
Loading...
Searching...
No Matches
gnc-gobject-utils.c
1/*
2 * gnc-gobject-utils.h -- utility functions for working
3 * with GObjects
4 * Copyright (C) 2005 David Hampton <hampton@employees.org>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, contact:
18 *
19 * Free Software Foundation Voice: +1-617-542-5942
20 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
21 * Boston, MA 02110-1301, USA gnu@gnu.org
22 */
23
24#include <config.h>
25
26#include <stdio.h>
27#include "gnc-gobject-utils.h"
28#include <qoflog.h>
29
30#include <gtk/gtk.h> // For gtk_main_quit(). Can't get this to work with
31// a g_source attached to the main glib context.
32
33static const QofLogModule log_module = G_LOG_DOMAIN;
34
35static void gnc_gobject_weak_cb (gpointer user_data, GObject *object);
36
37/************************************************************/
38/* GObject Utilities */
39/************************************************************/
40
41
50static GHashTable*
51gnc_gobject_tracking_table (void)
52{
53 static GHashTable *singleton = NULL;
54
55 if (!singleton)
56 {
57 singleton = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
58 }
59 return singleton;
60}
61
62
71static void
72gnc_gobject_dump_gobject (GObject *object, const gchar *name)
73{
74 //printf("Enter %s: object %p, name %s\n", G_STRFUNC, object, name);
75 PINFO(" object %p, ref count %d", object, object->ref_count);
76 //printf("Leave %s:\n", G_STRFUNC);
77}
78
79
86static gboolean
87gnc_gobject_dump_list (const gchar *name, GList *list, gpointer user_data)
88{
89 //printf("Enter %s: name %s, list %p\n", G_STRFUNC, name, list);
90 PINFO(" %d %s", g_list_length(list), name);
91 g_list_foreach(list, (GFunc)gnc_gobject_dump_gobject, (gpointer)name);
92 //printf("Leave %s:\n", G_STRFUNC);
93 return TRUE;
94}
95
96
103void
105{
106 GHashTable *table;
107
108 //printf("Enter %s:\n", G_STRFUNC);
109 table = gnc_gobject_tracking_table();
110
111 if (g_hash_table_size(table) > 0)
112 {
113 PINFO("The following objects remain alive:");
114 g_hash_table_foreach_remove(table, (GHRFunc)gnc_gobject_dump_list, NULL);
115 }
116 //printf("Leave %s:\n", G_STRFUNC);
117}
118
119
122void
124{
125 g_return_if_fail(G_IS_OBJECT(object));
126
127 GObjectClass *klass = G_OBJECT_GET_CLASS(object);
128 const gchar *name = g_type_name(G_TYPE_FROM_CLASS(klass));
129
130 //printf("Enter %s: object %p of type %s\n", G_STRFUNC, object, name);
131 GHashTable *table = gnc_gobject_tracking_table();
132 GList *list = g_hash_table_lookup(table, name);
133
134 if (g_list_index(list, object) != -1)
135 {
136 g_critical("Object %p is already in list of %s", object, name);
137 //printf("Leave %s: already in list\n", G_STRFUNC);
138 return;
139 }
140
141 list = g_list_append(list, object);
142 g_hash_table_insert(table, g_strdup(name), list);
143
144 g_object_weak_ref(object, gnc_gobject_weak_cb, NULL);
145 //printf("Leave %s:\n", G_STRFUNC);
146}
147
148
149static gboolean
150gnc_gobject_tracking_forget_internal (GObject *object)
151{
152 GHashTable *table;
153 GList *list, *item;
154 const gchar *name;
155
156 g_return_val_if_fail(G_IS_OBJECT(object), FALSE);
157
158 name = G_OBJECT_TYPE_NAME(object);
159 //printf("Enter %s: object %p of type %s\n", G_STRFUNC, object, name);
160 table = gnc_gobject_tracking_table();
161 list = g_hash_table_lookup(table, name);
162 if (!list)
163 {
164 //printf("Leave %s: list for %s objects not found.\n", G_STRFUNC, name);
165 return FALSE;
166 }
167
168 item = g_list_find(list, object);
169 if (!item)
170 {
171 //printf("Leave %s: object %p not in %s object list.\n", G_STRFUNC,
172 // object, name);
173 return FALSE;
174 }
175
176 list = g_list_remove_link(list, item);
177 if (list)
178 {
179 g_hash_table_replace(table, g_strdup(name), list);
180 //printf("Leave %s: object removed.\n", G_STRFUNC);
181 }
182 else
183 {
184 g_hash_table_remove(table, name);
185 //printf("Leave %s: object and list removed.\n", G_STRFUNC);
186 }
187 return TRUE;
188}
189
190
193void
195{
196 if (gnc_gobject_tracking_forget_internal(object))
197 g_object_weak_unref(object, gnc_gobject_weak_cb, NULL);
198}
199
200
210static void
211gnc_gobject_weak_cb (gpointer user_data, GObject *object)
212{
213 gnc_gobject_tracking_forget_internal(object);
214}
215
216
219const GList *
221{
222 GHashTable *table;
223 GList *list;
224
225 //printf("Enter %s: name %s\n", G_STRFUNC, name);
226 table = gnc_gobject_tracking_table();
227 list = g_hash_table_lookup(table, name);
228 //printf("Leave %s: list %p\n", G_STRFUNC, list);
229 return list;
230}
Gobject helper routines.
const GList * gnc_gobject_tracking_get_list(const gchar *name)
Get a list of all known objects of a specified type.
void gnc_gobject_tracking_dump(void)
Dump the entire object tracking database via the g_log() family of functions.
void gnc_gobject_tracking_remember(GObject *object)
Tell gnucash to remember this object in the database.
void gnc_gobject_tracking_forget(GObject *object)
Tell gnucash to remember this object in the database.
#define PINFO(format, args...)
Print an informational note.
Definition qoflog.h:256