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