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