00001 
00002 
00003 #ifndef INCLUDED_WMclass_h_
00004 #define INCLUDED_WMclass_h_
00005 
00006 #include <string>
00007 #include <vector>
00008 #include <iostream>
00009 #include "Events/EventRouter.h"
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 #define WM_max_stringlen 60   //!< Maximum displayed length of a char* or std::string variable.
00049 
00050 class WMentry;
00051 class WMitem_base;
00052 
00053 
00054 
00055 
00056 class WMregistry {
00057 public:
00058   std::string name; 
00059   std::vector<WMentry*> entries; 
00060   bool watched; 
00061   WMregistry* parent; 
00062 
00063 public:
00064 
00065   WMregistry(const std::string &n = "anonymous", WMregistry* p=NULL) : name(n), entries(), watched(0), parent(p) {};
00066   WMregistry(const WMregistry& in) : name(in.name), entries(in.entries), watched(in.watched), parent(in.parent) {} 
00067 
00068 
00069   WMregistry& operator=(const WMregistry& in) {
00070     name=in.name;
00071     entries=in.entries;
00072     watched=in.watched;
00073     parent=in.parent;
00074     return *this;
00075   }
00076 
00077 
00078   void watch(void) { watched = 1; };
00079 
00080 
00081   void unwatch(void) { watched = 0; };
00082 
00083 
00084   void dump(void) const;
00085 
00086 };
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 class WMentry {
00095 public:
00096   std::string const item_name; 
00097   std::string const type_name; 
00098   WMitem_base* const item; 
00099   WMregistry* registry; 
00100   bool watched;
00101 
00102 public:
00103 
00104   WMentry(const std::string &iname, const std::string &tname, WMitem_base* ival, WMregistry* reg = 0) : 
00105     item_name(iname), type_name(tname), item(ival), registry(reg), watched(0) {};
00106   WMentry(const WMentry& in) : item_name(in.item_name), type_name(in.type_name), item(in.item), registry(in.registry), watched(in.watched) {} 
00107 
00108 private:
00109   WMentry operator=(const WMentry&); 
00110 };
00111 
00112 
00113 
00114 
00115 
00116 class WMitem_base {
00117 public:
00118   virtual ~WMitem_base() {} 
00119   void* const         value;    
00120   WMentry*            entry;    
00121   virtual std::string toString(void) const = 0; 
00122 
00123 
00124   WMitem_base(void* const val) : value(val), entry(NULL) {};
00125   WMitem_base(const WMitem_base &in ) : value(in.value), entry(in.entry) {} 
00126 
00127 
00128   void watch(void) const {
00129     entry->watched = 1; 
00130     erouter->postEvent(EventBase::wmVarEGID,reinterpret_cast<size_t>(entry),EventBase::activateETID);
00131   };
00132 
00133 
00134   void unwatch(void) const {
00135     entry->watched = 0;
00136     erouter->postEvent(EventBase::wmVarEGID,reinterpret_cast<size_t>(entry),EventBase::deactivateETID);
00137   };
00138 
00139 private:
00140   WMitem_base& operator=(const WMitem_base & ); 
00141 };
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 template<class T>
00150 class WMitem : public WMitem_base {
00151 public:
00152   WMitem(T* const initval) : WMitem_base(initval)  {} 
00153   WMitem(const WMitem& in) : WMitem_base(in) {} 
00154 
00155   virtual WMitem<T>& operator= (const T &new_value); 
00156   WMitem<T>& operator++ ();                  
00157   WMitem<T>  operator++ (int);               
00158   WMitem<T>& operator-- ();                  
00159   WMitem<T>  operator-- (int);               
00160   WMitem<T>& operator+= (const T &val);      
00161   WMitem<T>& operator-= (const T &val);      
00162   WMitem<T>& operator*= (const T &val);      
00163   WMitem<T>& operator/= (const T &val);      
00164   
00165 
00166   void announce (const T &val);
00167   
00168 
00169   virtual T& get_value(void) const { return *static_cast<T*>(value); };
00170   
00171 
00172   virtual operator T&() const { return  *static_cast<T*>(value); };
00173   
00174 
00175   virtual std::string toString(void) const;    
00176 };
00177 
00178 
00179 
00180 
00181 
00182 #define WMvar(T,name) \
00183   static WMitem<T> name(lookup_WMentry<T>(#name,#T,GlobalWM));
00184 
00185 
00186 #define WMvari(T,name,initval) \
00187   static WMitem<T> name(lookup_WMentry<T>(#name,#T,initval,GlobalWM));
00188 
00189 
00190 #define WMvar_(T,name,registry) \
00191   static WMitem<T> name(lookup_WMentry<T>(#name,#T,registry));
00192 
00193 
00194 #define WMvari_(T,name,initval,registry) \
00195   static WMitem<T> name(lookup_WMentry<T>(#name,#T,initval,registry));
00196 
00197 
00198 #define WMreg(name) \
00199   static WMitem<WMregistry> name(lookup_reg(#name,GlobalWM));
00200 
00201 
00202 #define WMreg_(name,parent) \
00203   static WMitem<WMregistry> name(lookup_reg(#name,parent));
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 template<typename T>
00214 WMitem<T> lookup_WMentry(const std::string &iname,
00215                          const std::string &tname,
00216                          const std::string ®name);
00217 
00218 template<typename T>
00219 WMitem<T> lookup_WMentry(const std::string &iname,
00220                          const std::string &tname, 
00221                          const WMregistry ®);
00222 
00223 template<typename T>
00224 WMitem<T> lookup_WMentry(const std::string &iname,
00225                          const std::string &tname,
00226                          const T &initval, WMregistry ®);
00227 
00228 template<typename T>
00229 WMitem<T> create_WMentry(const std::string &iname, 
00230                          const std::string &tname, 
00231                          const T* const value, WMregistry ®);
00232 
00233 
00234 extern WMregistry GlobalWM;
00235 
00236 WMitem<WMregistry> lookup_reg(const std::string &name, WMregistry ®istry);
00237 
00238 void dump(const WMitem<WMregistry> &wmreg);
00239 
00240 
00241 
00242 
00243 
00244 template<class T>
00245 std::string WMitem<T>::toString(void) const {
00246   char print_buffer[30];
00247   sprintf(print_buffer,"%p",value);
00248   return "<" + entry->type_name + " at 0x" + print_buffer + ">";
00249 }
00250 
00251 
00252 
00253 
00254 template<class T>
00255 WMitem<T>& WMitem<T>::operator= (const T &new_value) {
00256   get_value() = new_value;
00257   
00258   announce (new_value);
00259   return *this;
00260 }
00261 
00262 template<class T>
00263 void WMitem<T>::announce (const T&) {
00264   if (entry->watched) {
00265     erouter->postEvent(EventBase::wmVarEGID,reinterpret_cast<size_t>(entry),EventBase::statusETID);
00266   }
00267   
00268 
00269 
00270 
00271 
00272 
00273 
00274 
00275 
00276 
00277   
00278 
00279 
00280 
00281 
00282 
00283 }
00284 
00285 template<class T>
00286 WMitem<T>& WMitem<T>::operator++ (void) {
00287   announce(++get_value());
00288   return *this;
00289 }
00290 
00291 template<class T>
00292 WMitem<T> WMitem<T>::operator++ (int) {
00293   WMitem<T> temp(*this);
00294   announce(++get_value());
00295   return temp;
00296 }
00297 
00298 template<class T>
00299 WMitem<T>& WMitem<T>::operator-- (void) {
00300   announce(--get_value());
00301   return *this;
00302 }
00303 
00304 template<class T>
00305 WMitem<T> WMitem<T>::operator-- (int) {
00306   WMitem<T> temp(*this);
00307   announce(--get_value());
00308   return temp;
00309 }
00310 
00311 template<class T>
00312 WMitem<T>& WMitem<T>::operator+= (const T &val) {
00313   return operator=(get_value()+val);
00314 }
00315 
00316 template<class T>
00317 WMitem<T>& WMitem<T>::operator-= (const T &val) {
00318   return operator=(get_value()-val);
00319 }
00320 
00321 template<class T>
00322 WMitem<T>& WMitem<T>::operator*= (const T &val) {
00323   return operator=(get_value()*val);
00324 }
00325 
00326 template<class T>
00327 WMitem<T>& WMitem<T>::operator/= (const T &val) {
00328   return operator=(get_value()/val);
00329 }
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 
00338 
00339 template<typename T>
00340 WMitem<T> lookup_WMentry(const std::string &iname,
00341                          const std::string &tname,
00342                          const std::string ®name) {
00343   WMregistry* reg = 0;
00344   for (std::vector<WMentry*>::const_iterator it = GlobalWM.entries.begin(); it != GlobalWM.entries.end(); it++) {
00345     if ( (*it)->item_name == regname ) {
00346       reg = static_cast<WMregistry*>((*it)->item->value);
00347       break;
00348     };
00349   };
00350   if ( reg == 0 ) {
00351     reg = new WMregistry(regname, &GlobalWM);
00352     create_WMentry(regname, "WMregistry", reg, GlobalWM);
00353   };
00354   return lookup_WMentry<T>(iname, tname, *reg);
00355 }
00356 
00357 template<typename T>
00358 WMitem<T> lookup_WMentry(const std::string &iname,
00359                          const std::string &tname, 
00360                          WMregistry ®) {
00361   for (std::vector<WMentry*>::const_iterator it = reg.entries.begin(); it != reg.entries.end(); it++) {
00362     if ( (*it)->item_name == iname )
00363       return *static_cast<WMitem<T> const*>((*it)->item);
00364   };
00365   return create_WMentry(iname, tname, new T, reg);
00366 }
00367 
00368 template<typename T>
00369 WMitem<T> lookup_WMentry(const std::string &iname,
00370                          const std::string &tname,
00371                          T const &initval, WMregistry ®) {
00372   for (std::vector<WMentry*>::const_iterator it = reg.entries.begin(); it != reg.entries.end(); it++) {
00373     if ( (*it)->item_name == iname )
00374       return *static_cast<WMitem<T> const*>((*it)->item);
00375   };
00376   return create_WMentry(iname, tname, new T(initval), reg);
00377 }
00378  
00379 template<typename T>
00380 WMitem<T> create_WMentry(const std::string &iname, 
00381                          const std::string &tname, 
00382                          T* const value, WMregistry ®) {
00383   WMentry* new_entry = new WMentry(iname, tname, new WMitem<T>(value), ®);
00384   new_entry->item->entry = new_entry;
00385   reg.entries.push_back(new_entry);
00386   return *static_cast<WMitem<T> const*>(new_entry->item);
00387 }
00388 
00389 #endif
00390