bb_blackboard.cpp

Go to the documentation of this file.
00001 #include "bb_blackboard.h"
00002 
00003 #include "er_errors.h"
00004 
00005 typedef struct {
00006   enum bb_DataType dt;
00007   bb_Closure cb;
00008 } Registrant;
00009 
00010 struct _bb_Blackboard
00011 {
00012   bb_Board board; // any board data
00013   GSList* reg; // of Registrant
00014 };
00015 
00016 extern "C"
00017 bb_Board* bb_Blackboard_board(bb_Blackboard* self)
00018 {
00019   return &(self->board);
00020 }
00021 
00022 extern "C"
00023 bb_Blackboard* bb_Blackboard_new(GError** error)
00024 {
00025   bb_Blackboard* self = g_try_new0(bb_Blackboard, 1);
00026   if (G_UNLIKELY(!self)) {
00027     if (error) *error = gx_error_no_memory;
00028     return NULL;
00029   }
00030   // self->reg is left as NULL, meaning an empty list.
00031   return self;
00032 }
00033 
00034 static void Registrant_free(gpointer self, gpointer dummy)
00035 {
00036   (void)dummy;
00037   g_slice_free(Registrant, self);
00038 }
00039 
00040 extern "C"
00041 void bb_Blackboard_destroy(bb_Blackboard* self)
00042 {
00043   if (self) {
00044     if (self->reg) {
00045       g_slist_foreach(self->reg, Registrant_free, NULL);
00046       g_slist_free(self->reg);
00047     }
00048     g_free(self);
00049   }
00050 }
00051 
00052 static void Registrant_free(Registrant* self)
00053 {
00054   if (self)
00055     g_slice_free(Registrant, self);
00056 }
00057 
00058 extern "C"
00059 gboolean bb_Blackboard_register(bb_Blackboard* self,
00060         enum bb_DataType dt,
00061         bb_Closure cb,
00062         GError** error)
00063 {
00064   Registrant* elem = NULL;
00065 
00066   SET_TRAP_OOM(goto fail);
00067   elem = g_slice_new(Registrant);
00068   elem->dt = dt;
00069   elem->cb = cb;
00070   self->reg = g_slist_prepend(self->reg, elem);
00071   UNSET_TRAP_OOM();
00072 
00073   return TRUE;
00074 
00075 #if HAVE_TRAP_OOM
00076  fail:
00077   Registrant_free(elem);
00078   if (error) *error = gx_error_no_memory;
00079   return FALSE;
00080 #else
00081   (void)error;
00082 #endif
00083 }
00084 
00085 extern "C"
00086 void bb_Blackboard_unregister(bb_Blackboard* self,
00087             bb_Closure cb)
00088 {
00089   GSList* plink = NULL; // previous in chain (if any)
00090   GSList* link = self->reg;
00091   while (link != NULL) {
00092     Registrant* elem = (Registrant*)link->data;
00093     if ((elem->cb.changed == cb.changed) &&
00094   (elem->cb.arg == cb.arg)) {
00095       Registrant_free(elem);
00096       link = g_slist_delete_link(link, link);
00097       if (plink)
00098   plink->next = link;
00099       else
00100   self->reg = link;
00101     } else {
00102       plink = link;
00103       link = link->next;
00104     }
00105   }
00106 }
00107 
00108 extern "C"
00109 void bb_Blackboard_notify(bb_Blackboard* self,
00110         enum bb_DataType dt,
00111         gpointer data, int len)
00112 {
00113   for (GSList* link = self->reg; link != NULL; link = link->next) {
00114     Registrant* elem = (Registrant*)link->data;
00115     if (elem->dt == dt) {
00116       (*(elem->cb.changed))(self, dt, data, len, elem->cb.arg);
00117     }
00118   }
00119 }
00120 
00121 #if defined(__cplusplus) && defined(__SYMBIAN32__)
00122 
00123 static void RHandleFunc(bb_Blackboard* self, enum bb_DataType dt,
00124       gpointer data, int len, gpointer arg)
00125 {
00126   bb::RHandle* handle = (bb::RHandle*)arg;
00127   bb::MObserver* observer = handle->Observer();
00128   TRAPD(errCode, observer->BbChangedL(handle, dt, data, len));
00129   if (errCode)
00130     observer->BbLeave(errCode);
00131 }
00132 
00133 void bb::MObserver::BbLeave(TInt errCode)
00134 {
00135   er_log_symbian(er_FATAL, errCode, "leave in bb::MObserver::BbChangedL");
00136 }
00137 
00138 bb::RHandle::RHandle() : iBoard(NULL), iObserver(NULL)
00139 {
00140   iClosure.changed = RHandleFunc;
00141   iClosure.arg = this;
00142 }
00143 
00144 bb::RHandle::~RHandle()
00145 {
00146   //logh();
00147   Unregister();
00148 }
00149 
00150 void bb::RHandle::Register(bb_Blackboard* aBoard,
00151          enum bb_DataType dt, 
00152          bb::MObserver* aObserver)
00153 {
00154   iBoard = aBoard;
00155   iObserver = aObserver;
00156 
00157   GError* localError = NULL;
00158   if (!bb_Blackboard_register(iBoard, dt, iClosure, &localError)) {
00159     er_log_gerror(er_FATAL|er_FREE, localError, 
00160       "bb_Blackboard_register failed");
00161   }
00162 }
00163     
00164 void bb::RHandle::Unregister()
00165 {
00166   if (iBoard)
00167     bb_Blackboard_unregister(iBoard, iClosure);
00168 }
00169 
00170 #endif
00171 
00172 /**
00173 
00174 Copyright 2010 Helsinki Institute for Information Technology (HIIT)
00175 and the authors. All rights reserved.
00176 
00177 Authors: Tero Hasu <tero.hasu@hut.fi>
00178 
00179 Permission is hereby granted, free of charge, to any person
00180 obtaining a copy of this software and associated documentation files
00181 (the "Software"), to deal in the Software without restriction,
00182 including without limitation the rights to use, copy, modify, merge,
00183 publish, distribute, sublicense, and/or sell copies of the Software,
00184 and to permit persons to whom the Software is furnished to do so,
00185 subject to the following conditions:
00186 
00187 The above copyright notice and this permission notice shall be
00188 included in all copies or substantial portions of the Software.
00189 
00190 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00191 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00192 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00193 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
00194 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
00195 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00196 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00197 SOFTWARE.
00198 
00199  **/

ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:51 2011 by Doxygen 1.6.1