~ubuntu-branches/ubuntu/maverick/freecad/maverick

« back to all changes in this revision

Viewing changes to src/Base/Observer.h

  • Committer: Bazaar Package Importer
  • Author(s): Teemu Ikonen
  • Date: 2009-07-16 18:37:41 UTC
  • Revision ID: james.westby@ubuntu.com-20090716183741-oww9kcxqrk991i1n
Tags: upstream-0.8.2237
Import upstream version 0.8.2237

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *   (c) J�rgen Riegel (juergen.riegel@web.de) 2002                        *   
 
3
 *                                                                         *
 
4
 *   This file is part of the FreeCAD CAx development system.              *
 
5
 *                                                                         *
 
6
 *   This program is free software; you can redistribute it and/or modify  *
 
7
 *   it under the terms of the GNU Library General Public License (LGPL)   *
 
8
 *   as published by the Free Software Foundation; either version 2 of     *
 
9
 *   the License, or (at your option) any later version.                   *
 
10
 *   for detail see the LICENCE text file.                                 *
 
11
 *                                                                         *
 
12
 *   FreeCAD is distributed in the hope that it will be useful,            *
 
13
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        * 
 
14
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 
15
 *   GNU Library General Public License for more details.                  *
 
16
 *                                                                         *
 
17
 *   You should have received a copy of the GNU Library General Public     *
 
18
 *   License along with FreeCAD; if not, write to the Free Software        * 
 
19
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
 
20
 *   USA                                                                   *
 
21
 *                                                                         *
 
22
 *   Juergen Riegel 2002                                                   *
 
23
 ***************************************************************************/
 
24
 
 
25
 
 
26
#ifndef BASE_OBSERVER_H
 
27
#define BASE_OBSERVER_H
 
28
 
 
29
// Std. configurations
 
30
 
 
31
#include <assert.h>
 
32
#include <set>
 
33
#include <cstring>
 
34
#include <cstdio>
 
35
 
 
36
 
 
37
namespace Base
 
38
{
 
39
 
 
40
template <class MessageType> class Subject;
 
41
 
 
42
 
 
43
/** Observer class
 
44
 *  Implementation of the well known Observer Design Pattern.
 
45
 *  The observed object, which inherit FCSubject, will call all
 
46
 *  its observers in case of changes. A observer class has to 
 
47
 *  Attach itself to the observed object.
 
48
 *  @see FCSubject
 
49
 */
 
50
template <class _MessageType>
 
51
class Observer
 
52
{
 
53
public:
 
54
 
 
55
  /**
 
56
   * A constructor.
 
57
   * No special function so far.
 
58
   */
 
59
  Observer(){};
 
60
 
 
61
  /**
 
62
   * A destructor.
 
63
   * No special function so far.
 
64
   */
 
65
  virtual ~Observer(){};
 
66
 
 
67
  /**
 
68
   * This method need to be reimplemented from the concrete Observer
 
69
   * and get called by the observed class
 
70
   * @param pCaller a referenc to the calling object
 
71
   */
 
72
  virtual void OnChange(Subject<_MessageType> &rCaller,_MessageType rcReason)=0;
 
73
 
 
74
  /**
 
75
   * This method need to be reimplemented from the concrete Observer
 
76
   * and get called by the observed class
 
77
   * @param pCaller a referenc to the calling object
 
78
   */
 
79
  virtual void OnDestroy(Subject<_MessageType> & /*rCaller*/){}
 
80
 
 
81
  /**
 
82
   * This method can be reimplemented from the concrete Observer
 
83
   * and returns the name of the observer. Needed to use the Get 
 
84
   * Method of the Subject.
 
85
   */
 
86
  virtual const char *Name(void){return 0L;}
 
87
};
 
88
 
 
89
/** Subject class
 
90
 *  Implementation of the well known Observer Design Pattern.
 
91
 *  The observed object, which inherit FCSubject, will call all
 
92
 *  its observers in case of changes. A observer class has to 
 
93
 *  Attach itself to the observed object.
 
94
 *  @see FCObserver
 
95
 */
 
96
template <class _MessageType>
 
97
class Subject
 
98
{
 
99
public:
 
100
 
 
101
  typedef  Observer<_MessageType> ObserverType;
 
102
  typedef  _MessageType             MessageType;
 
103
  typedef  Subject<_MessageType>  SubjectType;   
 
104
     
 
105
  /**
 
106
   * A constructor.
 
107
   * No special function so far.
 
108
   */
 
109
  Subject(){};
 
110
 
 
111
  /**
 
112
   * A destructor.
 
113
   * No special function so far.
 
114
   */
 
115
  virtual ~Subject()
 
116
  {
 
117
    if (_ObserverSet.size() > 0)
 
118
    {
 
119
      printf("Not detached all observers yet\n");
 
120
      assert(0);
 
121
    }
 
122
  }
 
123
 
 
124
  /** Attach an Observer
 
125
   * Attach an Observer to the list of Observers which get   
 
126
   * called when Notify is called.
 
127
   * @param ToObserv A pointer to a concrete Observer
 
128
   * @see Notify
 
129
   */
 
130
  void Attach(Observer<_MessageType> *ToObserv)
 
131
  {
 
132
#ifdef FC_DEBUG
 
133
    size_t count = _ObserverSet.size();
 
134
    printf("Attach observer %p\n", ToObserv);
 
135
    _ObserverSet.insert(ToObserv);
 
136
    if ( _ObserverSet.size() == count )
 
137
      printf("Observer %p already attached\n", ToObserv);
 
138
#else
 
139
    _ObserverSet.insert(ToObserv);
 
140
#endif
 
141
  }
 
142
 
 
143
  /** Detach an Observer
 
144
   * Detach an Observer from the list of Observers which get   
 
145
   * called when Notify is called.
 
146
   * @param ToObserv A pointer to a concrete Observer
 
147
   * @see Notify
 
148
   */
 
149
  void Detach(Observer<_MessageType> *ToObserv)
 
150
  {
 
151
#ifdef FC_DEBUG
 
152
    size_t count = _ObserverSet.size();
 
153
    printf("Detach observer %p\n", ToObserv);
 
154
    _ObserverSet.erase(ToObserv);
 
155
    if ( _ObserverSet.size() == count )
 
156
      printf("Observer %p already detached\n", ToObserv);
 
157
#else
 
158
    _ObserverSet.erase(ToObserv);
 
159
#endif
 
160
  }
 
161
 
 
162
  /** Notify all Observers
 
163
   * Send a message to all Observers attached to this subject.
 
164
   * The Message depends on the implementation of a concrete 
 
165
   * Oberserver and Subject.
 
166
   * @see Notify
 
167
   */
 
168
  void Notify(_MessageType rcReason)
 
169
  {
 
170
    for(typename std::set<Observer<_MessageType> * >::iterator Iter=_ObserverSet.begin();Iter!=_ObserverSet.end();Iter++)
 
171
      (*Iter)->OnChange(*this,rcReason);   // send OnChange-signal
 
172
  }
 
173
 
 
174
  /** Get an Observer by name
 
175
   * Get a observer by name if the observer reimplements the Name() mthode.
 
176
   * @see Observer
 
177
   */
 
178
  Observer<_MessageType> * Get(const char *Name)
 
179
  {
 
180
    const char* OName;
 
181
    for(typename std::set<Observer<_MessageType> * >::iterator Iter=_ObserverSet.begin();Iter!=_ObserverSet.end();Iter++)
 
182
    {
 
183
      OName = (*Iter)->Name();   // get the name
 
184
      if(OName && strcmp(OName,Name) == 0)
 
185
        return *Iter;
 
186
    }
 
187
 
 
188
    return 0L;
 
189
  }
 
190
 
 
191
  /** Clears the list of all registered observers. 
 
192
   * @note Using this function in your code may be an indication of design problems.
 
193
   */
 
194
  void ClearObserver()
 
195
  {
 
196
    _ObserverSet.clear();
 
197
  }
 
198
 
 
199
 
 
200
protected:
 
201
  /// Vector of attached observers
 
202
  std::set<Observer <_MessageType> *> _ObserverSet;
 
203
};
 
204
 
 
205
 
 
206
} //namespace Base
 
207
 
 
208
 
 
209
#endif // BASE_OBSERVER_H