Observer.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   (c) Jürgen Riegel (juergen.riegel@web.de) 2002                        *   
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This program is free software; you can redistribute it and/or modify  *
00007  *   it under the terms of the GNU Library General Public License (LGPL)   *
00008  *   as published by the Free Software Foundation; either version 2 of     *
00009  *   the License, or (at your option) any later version.                   *
00010  *   for detail see the LICENCE text file.                                 *
00011  *                                                                         *
00012  *   FreeCAD is distributed in the hope that it will be useful,            *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        * 
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU Library General Public License for more details.                  *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU Library General Public     *
00018  *   License along with FreeCAD; if not, write to the Free Software        * 
00019  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
00020  *   USA                                                                   *
00021  *                                                                         *
00022  *   Juergen Riegel 2002                                                   *
00023  ***************************************************************************/
00024 
00025 
00026 #ifndef BASE_OBSERVER_H
00027 #define BASE_OBSERVER_H
00028 
00029 // Std. configurations
00030 
00031 #include <assert.h>
00032 #include <set>
00033 #include <cstring>
00034 #include <cstdio>
00035 
00036 
00037 namespace Base
00038 {
00039 
00040 template <class MessageType> class Subject;
00041 
00042 
00050 template <class _MessageType>
00051 class Observer
00052 {
00053 public:
00054 
00059   Observer(){};
00060 
00065   virtual ~Observer(){};
00066 
00074   virtual void OnChange(Subject<_MessageType>& rCaller,_MessageType rcReason)=0;
00075 
00081   virtual void OnDestroy(Subject<_MessageType> & rCaller){}
00082 
00088   virtual const char *Name(void){return 0L;}
00089 };
00090 
00098 template <class _MessageType>
00099 class Subject
00100 {
00101 public:
00102 
00103   typedef  Observer<_MessageType> ObserverType;
00104   typedef  _MessageType             MessageType;
00105   typedef  Subject<_MessageType>  SubjectType;   
00106      
00111   Subject(){};
00112 
00117   virtual ~Subject()
00118   {
00119     if (_ObserverSet.size() > 0)
00120     {
00121       printf("Not detached all observers yet\n");
00122       assert(0);
00123     }
00124   }
00125 
00132   void Attach(Observer<_MessageType> *ToObserv)
00133   {
00134 #ifdef FC_DEBUG
00135     size_t count = _ObserverSet.size();
00136     printf("Attach observer %p\n", ToObserv);
00137     _ObserverSet.insert(ToObserv);
00138     if ( _ObserverSet.size() == count )
00139       printf("Observer %p already attached\n", ToObserv);
00140 #else
00141     _ObserverSet.insert(ToObserv);
00142 #endif
00143   }
00144 
00151   void Detach(Observer<_MessageType> *ToObserv)
00152   {
00153 #ifdef FC_DEBUG
00154     size_t count = _ObserverSet.size();
00155     printf("Detach observer %p\n", ToObserv);
00156     _ObserverSet.erase(ToObserv);
00157     if ( _ObserverSet.size() == count )
00158       printf("Observer %p already detached\n", ToObserv);
00159 #else
00160     _ObserverSet.erase(ToObserv);
00161 #endif
00162   }
00163 
00170   void Notify(_MessageType rcReason)
00171   {
00172     for(typename std::set<Observer<_MessageType> * >::iterator Iter=_ObserverSet.begin();Iter!=_ObserverSet.end();Iter++)
00173       (*Iter)->OnChange(*this,rcReason);   // send OnChange-signal
00174   }
00175 
00180   Observer<_MessageType> * Get(const char *Name)
00181   {
00182     const char* OName;
00183     for(typename std::set<Observer<_MessageType> * >::iterator Iter=_ObserverSet.begin();Iter!=_ObserverSet.end();Iter++)
00184     {
00185       OName = (*Iter)->Name();   // get the name
00186       if(OName && strcmp(OName,Name) == 0)
00187         return *Iter;
00188     }
00189 
00190     return 0L;
00191   }
00192 
00196   void ClearObserver()
00197   {
00198     _ObserverSet.clear();
00199   }
00200 
00201 
00202 protected:
00204   std::set<Observer <_MessageType> *> _ObserverSet;
00205 };
00206 
00207 
00208 } //namespace Base
00209 
00210 
00211 #endif // BASE_OBSERVER_H

Generated on Wed Nov 23 19:00:24 2011 for FreeCAD by  doxygen 1.6.1