00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "config.h"
00025
00026 #include "gnc-event-p.h"
00027 #include "gnc-trace.h"
00028
00029
00030
00031 typedef struct
00032 {
00033 GNCEngineEventHandler handler;
00034 gpointer user_data;
00035
00036 gint handler_id;
00037 } HandlerInfo;
00038
00039
00040 static guint suspend_counter = 0;
00041 static gint next_handler_id = 1;
00042 static GList *handlers = NULL;
00043
00044
00045 static QofLogModule log_module = QOF_MOD_ENGINE;
00046
00047
00048
00049 gint
00050 gnc_engine_register_event_handler (GNCEngineEventHandler handler,
00051 gpointer user_data)
00052 {
00053 HandlerInfo *hi;
00054 gint handler_id;
00055 GList *node;
00056
00057 ENTER ("(handler=%p, data=%p)", handler, user_data);
00058
00059 if (!handler)
00060 {
00061 PERR ("no handler specified");
00062 return 0;
00063 }
00064
00065
00066 handler_id = next_handler_id;
00067 node = handlers;
00068
00069 while (node)
00070 {
00071 hi = node->data;
00072
00073 if (hi->handler_id == handler_id)
00074 {
00075 handler_id++;
00076 node = handlers;
00077 continue;
00078 }
00079
00080 node = node->next;
00081 }
00082
00083
00084 hi = g_new0 (HandlerInfo, 1);
00085
00086 hi->handler = handler;
00087 hi->user_data = user_data;
00088 hi->handler_id = handler_id;
00089
00090 handlers = g_list_prepend (handlers, hi);
00091
00092
00093 next_handler_id = handler_id + 1;
00094
00095 LEAVE ("(handler=%p, data=%p) handler_id=%d", handler, user_data, handler_id);
00096 return handler_id;
00097 }
00098
00099 void
00100 gnc_engine_unregister_event_handler (gint handler_id)
00101 {
00102 GList *node;
00103
00104 ENTER ("(handler_id=%d)", handler_id);
00105 for (node = handlers; node; node = node->next)
00106 {
00107 HandlerInfo *hi = node->data;
00108
00109 if (hi->handler_id != handler_id)
00110 continue;
00111
00112
00113 handlers = g_list_remove_link (handlers, node);
00114
00115 LEAVE ("(handler_id=%d) handler=%p data=%p", handler_id, hi->handler, hi->user_data);
00116
00117 hi->handler = NULL;
00118
00119 g_list_free_1 (node);
00120 g_free (hi);
00121
00122 return;
00123 }
00124
00125 PERR ("no such handler: %d", handler_id);
00126 }
00127
00128 void
00129 gnc_engine_suspend_events (void)
00130 {
00131 suspend_counter++;
00132
00133 if (suspend_counter == 0)
00134 {
00135 PERR ("suspend counter overflow");
00136 }
00137 }
00138
00139 void
00140 gnc_engine_resume_events (void)
00141 {
00142 if (suspend_counter == 0)
00143 {
00144 PERR ("suspend counter underflow");
00145 return;
00146 }
00147
00148 suspend_counter--;
00149 }
00150
00151 static void
00152 gnc_engine_generate_event_internal (QofEntity *entity,
00153 GNCEngineEventType event_type)
00154 {
00155 GList *node;
00156 GList *next_node = NULL;
00157
00158 g_return_if_fail(entity);
00159
00160 switch (event_type)
00161 {
00162 case GNC_EVENT_NONE:
00163 return;
00164
00165 case GNC_EVENT_CREATE:
00166 case GNC_EVENT_MODIFY:
00167 case GNC_EVENT_DESTROY:
00168 case GNC_EVENT_ADD:
00169 case GNC_EVENT_REMOVE:
00170 break;
00171
00172 default:
00173 PERR ("bad event type %d", event_type);
00174 return;
00175 }
00176
00177 for (node = handlers; node; node = next_node)
00178 {
00179 HandlerInfo *hi = node->data;
00180
00181 next_node = node->next;
00182 PINFO ("id=%d hi=%p han=%p", hi->handler_id, hi, hi->handler);
00183 if (hi->handler)
00184 hi->handler ((GUID *)&entity->guid, entity->e_type, event_type, hi->user_data);
00185 }
00186 }
00187
00188 void
00189 gnc_engine_force_event (QofEntity *entity,
00190 GNCEngineEventType event_type)
00191 {
00192 if (!entity)
00193 return;
00194
00195 gnc_engine_generate_event_internal (entity, event_type);
00196 }
00197
00198 void
00199 gnc_engine_gen_event (QofEntity *entity, GNCEngineEventType event_type)
00200 {
00201 if (!entity)
00202 return;
00203
00204 if (suspend_counter)
00205 return;
00206
00207 gnc_engine_generate_event_internal (entity, event_type);
00208 }
00209
00210 void
00211 gnc_engine_generate_event (const GUID *guid, QofIdType e_type,
00212 GNCEngineEventType event_type)
00213 {
00214 QofEntity ent;
00215 ent.guid = *guid;
00216 ent.e_type = e_type;
00217 if (suspend_counter) return;
00218 gnc_engine_generate_event_internal (&ent, event_type);
00219 }
00220
00221