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, gpointer user_data)
00075 {
00076 HandlerInfo *hi;
00077 gint handler_id;
00078
00079 ENTER ("(handler=%p, data=%p)", handler, user_data);
00080
00081
00082 if (!handler)
00083 {
00084 PERR ("no handler specified");
00085 return 0;
00086 }
00087 PINFO (" deprecated handler specified");
00088
00089 handler_id = find_next_handler_id();
00090
00091 hi = g_new0 (HandlerInfo, 1);
00092
00093 hi->old_handler = handler;
00094 hi->user_data = user_data;
00095 hi->handler_id = handler_id;
00096
00097 handlers = g_list_prepend (handlers, hi);
00098
00099 LEAVE (" (handler=%p, data=%p) handler_id=%d", handler, user_data, handler_id);
00100 return handler_id;
00101
00102 }
00103 #endif
00104
00105 gint
00106 qof_event_register_handler (QofEventHandler handler, gpointer user_data)
00107 {
00108 HandlerInfo *hi;
00109 gint handler_id;
00110
00111 ENTER ("(handler=%p, data=%p)", handler, user_data);
00112
00113
00114 if (!handler)
00115 {
00116 PERR ("no handler specified");
00117 return 0;
00118 }
00119
00120
00121 handler_id = find_next_handler_id();
00122
00123
00124 hi = g_new0 (HandlerInfo, 1);
00125
00126 hi->handler = handler;
00127 hi->user_data = user_data;
00128 hi->handler_id = handler_id;
00129
00130 handlers = g_list_prepend (handlers, hi);
00131 LEAVE ("(handler=%p, data=%p) handler_id=%d", handler, user_data, handler_id);
00132 return handler_id;
00133 }
00134
00135 void
00136 qof_event_unregister_handler (gint handler_id)
00137 {
00138 GList *node;
00139
00140 ENTER ("(handler_id=%d)", handler_id);
00141 for (node = handlers; node; node = node->next)
00142 {
00143 HandlerInfo *hi = node->data;
00144
00145 if (hi->handler_id != handler_id)
00146 continue;
00147
00148
00149
00150
00151
00152
00153 if(hi->handler)
00154 LEAVE ("(handler_id=%d) handler=%p data=%p", handler_id,
00155 hi->handler, hi->user_data);
00156 #ifndef QOF_DISABLE_DEPRECATED
00157 if(hi->old_handler)
00158 LEAVE ("(handler_id=%d) handler=%p data=%p", handler_id,
00159 hi->old_handler, hi->user_data);
00160 #endif
00161
00162
00163 hi->handler = NULL;
00164 #ifndef QOF_DISABLE_DEPRECATED
00165 hi->old_handler = NULL;
00166 #endif
00167
00168 if (handler_run_level == 0) {
00169 handlers = g_list_remove_link (handlers, node);
00170 g_list_free_1 (node);
00171 g_free (hi);
00172 } else {
00173 pending_deletes++;
00174 }
00175
00176 return;
00177 }
00178
00179 PERR ("no such handler: %d", handler_id);
00180 }
00181
00182 void
00183 qof_event_suspend (void)
00184 {
00185 suspend_counter++;
00186
00187 if (suspend_counter == 0)
00188 {
00189 PERR ("suspend counter overflow");
00190 }
00191 }
00192
00193 void
00194 qof_event_resume (void)
00195 {
00196 if (suspend_counter == 0)
00197 {
00198 PERR ("suspend counter underflow");
00199 return;
00200 }
00201
00202 suspend_counter--;
00203 }
00204
00205 static void
00206 qof_event_generate_internal (QofEntity *entity, QofEventId event_id,
00207 gpointer event_data)
00208 {
00209 GList *node;
00210 GList *next_node = NULL;
00211 gboolean use_old_handlers = FALSE;
00212
00213 g_return_if_fail(entity);
00214
00215 if (event_id <= QOF_EVENT__LAST)
00216 {
00217 use_old_handlers = TRUE;
00218 }
00219
00220 switch (event_id)
00221 {
00222 case QOF_EVENT_NONE: {
00223
00224 return;
00225 }
00226 }
00227
00228 handler_run_level++;
00229 for (node = handlers; node; node = next_node)
00230 {
00231 HandlerInfo *hi = node->data;
00232
00233 next_node = node->next;
00234 #ifndef QOF_DISABLE_DEPRECATED
00235 if ((hi->old_handler) && (use_old_handlers))
00236 {
00237 PINFO(" deprecated: id=%d hi=%p han=%p", hi->handler_id, hi,
00238 hi->old_handler);
00239 hi->old_handler ((GUID *)&entity->guid, entity->e_type,
00240 event_id, hi->user_data);
00241 }
00242 #endif
00243 if (hi->handler)
00244 {
00245 PINFO("id=%d hi=%p han=%p data=%p", hi->handler_id, hi,
00246 hi->handler, event_data);
00247 hi->handler (entity, event_id, hi->user_data, event_data);
00248 }
00249 }
00250 handler_run_level--;
00251
00252
00253
00254
00255 if (handler_run_level == 0 && pending_deletes)
00256 {
00257 for (node = handlers; node; node = next_node)
00258 {
00259 HandlerInfo *hi = node->data;
00260 next_node = node->next;
00261 if ((hi->handler == NULL)
00262 #ifndef QOF_DISABLE_DEPRECATED
00263 &&(hi->old_handler == NULL)
00264 #endif
00265 )
00266 {
00267
00268 handlers = g_list_remove_link (handlers, node);
00269 g_list_free_1 (node);
00270 g_free (hi);
00271 }
00272 }
00273 pending_deletes = 0;
00274 }
00275 }
00276
00277 void
00278 qof_event_force (QofEntity *entity, QofEventId event_id, gpointer event_data)
00279 {
00280 if (!entity)
00281 return;
00282
00283 qof_event_generate_internal (entity, event_id, event_data);
00284 }
00285
00286 void
00287 qof_event_gen (QofEntity *entity, QofEventId event_id, gpointer event_data)
00288 {
00289 if (!entity)
00290 return;
00291
00292 if (suspend_counter)
00293 return;
00294
00295 qof_event_generate_internal (entity, event_id, event_data);
00296 }
00297
00298
00299 void
00300 qof_event_generate (const GUID *guid, QofIdType e_type,
00301 QofEventId event_id)
00302 {
00303 QofEntity ent;
00304 ent.guid = *guid;
00305 ent.e_type = e_type;
00306 if (suspend_counter) return;
00307
00308 qof_event_generate_internal (&ent, event_id, NULL);
00309 }
00310
00311