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 use_old_handlers = TRUE;
00223
00224 switch (event_id)
00225 {
00226 case QOF_EVENT_NONE:
00227 {
00228
00229 return;
00230 }
00231 }
00232
00233 handler_run_level++;
00234 for (node = handlers; node; node = next_node)
00235 {
00236 HandlerInfo *hi = node->data;
00237
00238 next_node = node->next;
00239 #ifndef QOF_DISABLE_DEPRECATED
00240 if ((hi->old_handler) && (use_old_handlers))
00241 {
00242 PINFO (" deprecated: id=%d hi=%p han=%p", hi->handler_id, hi,
00243 hi->old_handler);
00244 hi->old_handler ((GUID *) & entity->guid, entity->e_type,
00245 event_id, hi->user_data);
00246 }
00247 #endif
00248 if (hi->handler)
00249 {
00250 PINFO ("id=%d type=%s", hi->handler_id, entity->e_type);
00251 hi->handler (entity, event_id, hi->user_data, event_data);
00252 }
00253 }
00254 handler_run_level--;
00255
00256
00257
00258
00259 if (handler_run_level == 0 && pending_deletes)
00260 {
00261 for (node = handlers; node; node = next_node)
00262 {
00263 HandlerInfo *hi = node->data;
00264 next_node = node->next;
00265 if ((hi->handler == NULL)
00266 #ifndef QOF_DISABLE_DEPRECATED
00267 && (hi->old_handler == NULL)
00268 #endif
00269 )
00270 {
00271
00272 handlers = g_list_remove_link (handlers, node);
00273 g_list_free_1 (node);
00274 g_free (hi);
00275 }
00276 }
00277 pending_deletes = 0;
00278 }
00279 }
00280
00281 void
00282 qof_event_force (QofEntity * entity, QofEventId event_id,
00283 gpointer event_data)
00284 {
00285 if (!entity)
00286 return;
00287
00288 qof_event_generate_internal (entity, event_id, event_data);
00289 }
00290
00291 void
00292 qof_event_gen (QofEntity * entity, QofEventId event_id, gpointer event_data)
00293 {
00294 if (!entity)
00295 return;
00296
00297 if (suspend_counter)
00298 return;
00299
00300 qof_event_generate_internal (entity, event_id, event_data);
00301 }
00302
00303
00304 void
00305 qof_event_generate (const GUID * guid, QofIdType e_type, QofEventId event_id)
00306 {
00307 QofEntity ent;
00308 ent.guid = *guid;
00309 ent.e_type = e_type;
00310 if (suspend_counter)
00311 return;
00312
00313 qof_event_generate_internal (&ent, event_id, NULL);
00314 }
00315
00316