gnc-event.c

00001 /********************************************************************
00002  * gnc-event.c -- engine event handling implementation              *
00003  * Copyright 2000 Dave Peticolas <dave@krondo.com>                  *
00004  *                                                                  *
00005  * This program is free software; you can redistribute it and/or    *
00006  * modify it under the terms of the GNU General Public License as   *
00007  * published by the Free Software Foundation; either version 2 of   *
00008  * the License, or (at your option) any later version.              *
00009  *                                                                  *
00010  * This program is distributed in the hope that it will be useful,  *
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00013  * GNU General Public License for more details.                     *
00014  *                                                                  *
00015  * You should have received a copy of the GNU General Public License*
00016  * along with this program; if not, contact:                        *
00017  *                                                                  *
00018  * Free Software Foundation           Voice:  +1-617-542-5942       *
00019  * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
00020  * Boston, MA  02111-1307,  USA       gnu@gnu.org                   *
00021  *                                                                  *
00022  ********************************************************************/
00023 
00024 #include "config.h"
00025 
00026 #include "gnc-event-p.h"
00027 #include "gnc-trace.h"
00028 
00029 /* Declarations ****************************************************/
00030 
00031 typedef struct
00032 {
00033   GNCEngineEventHandler handler;
00034   gpointer user_data;
00035 
00036   gint handler_id;
00037 } HandlerInfo;
00038 
00039 /* Static Variables ************************************************/
00040 static guint  suspend_counter = 0;
00041 static gint   next_handler_id = 1;
00042 static GList *handlers = NULL;
00043 
00044 /* This static indicates the debugging module that this .o belongs to.  */
00045 static QofLogModule log_module = QOF_MOD_ENGINE;
00046 
00047 /* Implementations *************************************************/
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   /* sanity check */
00059   if (!handler)
00060   {
00061     PERR ("no handler specified");
00062     return 0;
00063   }
00064 
00065   /* look for a free handler id */
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   /* Found one, add the handler */
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   /* Update id for next registration */
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     /* Found it, take out of list */ 
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     /* safety */
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 /* =========================== END OF FILE ======================= */

Generated on Fri Oct 21 15:49:54 2005 for QOF by  doxygen 1.4.5