00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "config.h"
00026 #include <glib.h>
00027 #include "qof.h"
00028 #include "qofevent-p.h"
00029
00030
00031 static guint suspend_counter = 0;
00032 static gint next_handler_id = 1;
00033 static guint handler_run_level = 0;
00034 static guint pending_deletes = 0;
00035 static GList *handlers = NULL;
00036
00037
00038 static QofLogModule log_module = QOF_MOD_ENGINE;
00039
00040
00041
00042 static gint
00043 find_next_handler_id (void)
00044 {
00045 HandlerInfo *hi;
00046 gint handler_id;
00047 GList *node;
00048
00049
00050 handler_id = next_handler_id;
00051 node = handlers;
00052
00053 while (node)
00054 {
00055 hi = node->data;
00056
00057 if (hi->handler_id == handler_id)
00058 {
00059 handler_id++;
00060 node = handlers;
00061 continue;
00062 }
00063
00064 node = node->next;
00065 }
00066
00067 next_handler_id = handler_id + 1;
00068 return handler_id;
00069 }
00070
00071
00072 #ifndef QOF_DISABLE_DEPRECATED
00073 gint
00074 qof_event_register_old_handler (GNCEngineEventHandler handler,
00075 gpointer user_data)
00076 {
00077 HandlerInfo *hi;
00078 gint handler_id;
00079
00080 ENTER ("(handler=%p, data=%p)", handler, user_data);
00081
00082
00083 if (!handler)
00084 {
00085 PERR ("no handler specified");
00086 return 0;
00087 }
00088 PINFO (" deprecated handler specified");
00089
00090 handler_id = find_next_handler_id ();
00091
00092 hi = g_new0 (HandlerInfo, 1);
00093
00094 hi->old_handler = handler;
00095 hi->user_data = user_data;
00096 hi->handler_id = handler_id;
00097
00098 handlers = g_list_prepend (handlers, hi);
00099
00100 LEAVE (" (handler=%p, data=%p) handler_id=%d", handler, user_data,
00101 handler_id);
00102 return handler_id;
00103
00104 }
00105 #endif
00106
00107 gint
00108 qof_event_register_handler (QofEventHandler handler, gpointer user_data)
00109 {
00110 HandlerInfo *hi;
00111 gint handler_id;
00112
00113 ENTER ("(handler=%p, data=%p)", handler, user_data);
00114
00115
00116 if (!handler)
00117 {
00118 PERR ("no handler specified");
00119 return 0;
00120 }
00121
00122
00123 handler_id = find_next_handler_id ();
00124
00125
00126 hi = g_new0 (HandlerInfo, 1);
00127
00128 hi->handler = handler;
00129 hi->user_data = user_data;
00130 hi->handler_id = handler_id;
00131
00132 handlers = g_list_prepend (handlers, hi);
00133 LEAVE ("(handler=%p, data=%p) handler_id=%d", handler, user_data,
00134 handler_id);
00135 return handler_id;
00136 }
00137
00138 void
00139 qof_event_unregister_handler (gint handler_id)
00140 {
00141 GList *node;
00142
00143 ENTER ("(handler_id=%d)", handler_id);
00144 for (node = handlers; node; node = node->next)
00145 {
00146 HandlerInfo *hi = node->data;
00147
00148 if (hi->handler_id != handler_id)
00149 continue;
00150
00151
00152
00153
00154
00155
00156 if (hi->handler)
00157 LEAVE ("(handler_id=%d) handler=%p data=%p", handler_id,
00158 hi->handler, hi->user_data);
00159 #ifndef QOF_DISABLE_DEPRECATED
00160 if (hi->old_handler)
00161 LEAVE ("(handler_id=%d) handler=%p data=%p", handler_id,
00162 hi->old_handler, hi->user_data);
00163 #endif
00164
00165
00166 hi->handler = NULL;
00167 #ifndef QOF_DISABLE_DEPRECATED
00168 hi->old_handler = NULL;
00169 #endif
00170
00171 if (handler_run_level == 0)
00172 {
00173 handlers = g_list_remove_link (handlers, node);
00174 g_list_free_1 (node);
00175 g_free (hi);
00176 }
00177 else
00178 {
00179 pending_deletes++;
00180 }
00181
00182 return;
00183 }
00184
00185 PERR ("no such handler: %d", handler_id);
00186 }
00187
00188 void
00189 qof_event_suspend (void)
00190 {
00191 suspend_counter++;
00192
00193 if (suspend_counter == 0)
00194 {
00195 PERR ("suspend counter overflow");
00196 }
00197 }
00198
00199 void
00200 qof_event_resume (void)
00201 {
00202 if (suspend_counter == 0)
00203 {
00204 PERR ("suspend counter underflow");
00205 return;
00206 }
00207
00208 suspend_counter--;
00209 }
00210
00211 static void
00212 qof_event_generate_internal (QofEntity * entity, QofEventId event_id,
00213 gpointer event_data)
00214 {
00215 GList *node;
00216 GList *next_node = NULL;
00217 gboolean use_old_handlers = FALSE;
00218
00219 g_return_if_fail (entity);
00220
00221 if (event_id <= QOF_EVENT__LAST)
00222 {
00223 use_old_handlers = TRUE;
00224 }
00225
00226 switch (event_id)
00227 {
00228 case QOF_EVENT_NONE:
00229 {
00230
00231 return;
00232 }
00233 }
00234
00235 handler_run_level++;
00236 for (node = handlers; node; node = next_node)
00237 {
00238 HandlerInfo *hi = node->data;
00239
00240 next_node = node->next;
00241 #ifndef QOF_DISABLE_DEPRECATED
00242 if ((hi->old_handler) && (use_old_handlers))
00243 {
00244 PINFO (" deprecated: id=%d hi=%p han=%p", hi->handler_id, hi,
00245 hi->old_handler);
00246 hi->old_handler ((GUID *) & entity->guid, entity->e_type,
00247 event_id, hi->user_data);
00248 }
00249 #endif
00250 if (hi->handler)
00251 {
00252 PINFO ("id=%d hi=%p han=%p data=%p", hi->handler_id, hi,
00253 hi->handler, event_data);
00254 hi->handler (entity, event_id, hi->user_data, event_data);
00255 }
00256 }
00257 handler_run_level--;
00258
00259
00260
00261
00262 if (handler_run_level == 0 && pending_deletes)
00263 {
00264 for (node = handlers; node; node = next_node)
00265 {
00266 HandlerInfo *hi = node->data;
00267 next_node = node->next;
00268 if ((hi->handler == NULL)
00269 #ifndef QOF_DISABLE_DEPRECATED
00270 && (hi->old_handler == NULL)
00271 #endif
00272 )
00273 {
00274
00275 handlers = g_list_remove_link (handlers, node);
00276 g_list_free_1 (node);
00277 g_free (hi);
00278 }
00279 }
00280 pending_deletes = 0;
00281 }
00282 }
00283
00284 void
00285 qof_event_force (QofEntity * entity, QofEventId event_id,
00286 gpointer event_data)
00287 {
00288 if (!entity)
00289 return;
00290
00291 qof_event_generate_internal (entity, event_id, event_data);
00292 }
00293
00294 void
00295 qof_event_gen (QofEntity * entity, QofEventId event_id,
00296 gpointer event_data)
00297 {
00298 if (!entity)
00299 return;
00300
00301 if (suspend_counter)
00302 return;
00303
00304 qof_event_generate_internal (entity, event_id, event_data);
00305 }
00306
00307
00308 void
00309 qof_event_generate (const GUID * guid, QofIdType e_type,
00310 QofEventId event_id)
00311 {
00312 QofEntity ent;
00313 ent.guid = *guid;
00314 ent.e_type = e_type;
00315 if (suspend_counter)
00316 return;
00317
00318 qof_event_generate_internal (&ent, event_id, NULL);
00319 }
00320
00321