Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
notifier.h
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/******************************************************************************
20*
21* FILE
22* $Archive: /Commando/Code/wwlib/wwNotify.h $
23*
24* DESCRIPTION
25* These templates provide implementation of the Subject-Observer pattern.
26*
27* PROGRAMMER
28* Steve Clinard
29* $Author: Denzil_l $
30*
31* VERSION INFO
32* $Modtime: 11/13/01 10:49a $
33* $Revision: 8 $
34*
35* 06/28/02 KM Notify name change to avoid MAX conflicts *
36******************************************************************************/
37
38#ifndef __NOTIFY_H__
39#define __NOTIFY_H__
40
41// Reduce warning level for STL
42#if defined(_MSC_VER)
43#pragma warning(push, 3)
44#endif
45
46#include <vector>
47#include <algorithm>
48
49#if defined(_MSC_VER)
50#pragma warning(pop)
51#endif
52
53#include <assert.h>
54
55template<typename Event> class Notifier;
56template<typename Event> class Observer;
57
58template<typename Event> class Observer
59 {
60 public:
61 typedef std::vector< Notifier<Event>* > NotifierColl;
62
64 mNotifiers(NULL)
65 {}
66
67 virtual ~Observer()
68 {StopObserving();}
69
71 virtual void HandleNotification(Event&) = 0;
72
74 virtual void NotificationEnded(const Notifier<Event>& notifier)
75 {
76 NotifierColl::iterator pos = std::find(mNotifiers.begin(),
77 mNotifiers.end(), &notifier);
78
79 if (pos != mNotifiers.end())
80 {
81 mNotifiers.erase(pos);
82 }
83 }
84
86 virtual void NotifyMe(Notifier<Event>& notifier)
87 {notifier.AddObserver(*this);}
88
91 {
92 while (mNotifiers.size() > 0)
93 {
94 Notifier<Event>* notifier = mNotifiers.back();
95 assert(notifier && "ERROR: NULL pointer in collection.");
96 notifier->RemoveObserver(*this);
97 }
98 }
99
100 protected:
101 Observer(const Observer<Event>& observer);
103
104 private:
105 friend class Notifier<Event>;
106 NotifierColl mNotifiers;
107 };
108
109
110#define DECLARE_OBSERVER(Event) \
111 virtual void NotifyMe(Notifier<Event>& observer) \
112 {Notifier<Event>::AddObserver(observer);}
113
114
115template<typename Event> class Notifier
116 {
117 public:
118 typedef std::vector< Observer<Event>* > ObserverColl;
119
121 {}
122
123 virtual ~Notifier()
124 {
125 for (int index = mObservers.size(); index--;)
126 {
127 mObservers[index]->NotificationEnded(*this);
128 }
129 }
130
132 virtual void NotifyObservers(Event& event)
133 {
134 for (unsigned int index = 0; index < mObservers.size(); index++)
135 {
136 mObservers[index]->HandleNotification(event);
137 }
138 }
139
141 virtual void AddObserver(Observer<Event>& observer)
142 {
143 ObserverColl::iterator pos = std::find(mObservers.begin(),
144 mObservers.end(), &observer);
145
146 if (pos == mObservers.end())
147 {
148 observer.mNotifiers.push_back(this);
149 mObservers.push_back(&observer);
150 }
151 }
152
154 virtual void RemoveObserver(Observer<Event>& observer)
155 {
156 ObserverColl::iterator pos = std::find(mObservers.begin(),
157 mObservers.end(), &observer);
158
159 if (pos != mObservers.end())
160 {
161 observer.NotificationEnded(*this);
162 mObservers.erase(pos);
163 }
164 }
165
166 virtual bool HasObservers(void) const
167 {return !mObservers.empty();}
168
169 private:
171 ObserverColl mObservers;
172 };
173
174
175#define DECLARE_NOTIFIER(Event) \
176 virtual void NotifyObservers(Event& event) \
177 {Notifier<Event>::NotifyObservers(event);} \
178 virtual void AddObserver(Observer<Event>& observer) \
179 {Notifier<Event>::AddObserver(observer);} \
180 virtual void RemoveObserver(Observer<Event>& observer) \
181 {Notifier<Event>::RemoveObserver(observer);}
182
183
184/*-----------------------------------------------------------------------------
185 * The following templates are useful for defining unique types to use as
186 * Events from types such as strings or integers.
187 *---------------------------------------------------------------------------*/
188
189/* TypedEvent<T. V>
190 *
191 * The first type (T) must be a class or other unique type. This need not
192 * be a "real" class. It could be a forward declared class, which is enough
193 * to make the template class unique.
194 *
195 * The second type (V) is the event data. "UString" and "int" are obvious
196 * choices.
197 *
198 * Typedef'ing the template class is a good thing to do.
199 */
200template<typename T, typename V>
202 {
203 public:
206 {}
207
208 inline V& operator()()
209 {return mValue;}
210
211 inline V& Subject(void)
212 {return mValue;}
213
214 protected:
216 };
217
218template<typename T, typename O>
220 {
221 public:
222 TypedEventPtr(O* subject) :
223 mSubject(subject)
224 {}
225
226 inline O* Subject(void)
227 {return mSubject;}
228
229 inline O* operator()()
230 {return mSubject;}
231
232 protected:
234 };
235
236template<typename A, typename O>
238 public TypedEventPtr<A, O>
239 {
240 public:
241 A GetAction(void) const
242 {return mAction;}
243
244 TypedActionPtr(A action, O* data) :
245 TypedEventPtr<A, O>(data),
246 mAction(action)
247 {}
248
251
252 protected:
254 };
255
256template<typename A, typename B>
258 {
259 public:
260 TypedEventPair(A itemA, B itemB) :
261 mItemA(itemA),
262 mItemB(itemB)
263 {}
264
265 inline A GetItemA(void)
266 {return mItemA;}
267
268 inline B GetItemB(void)
269 {return mItemB;}
270
271 protected:
274 };
275
276#endif // __NOTIFY_H__
#define NULL
Definition BaseType.h:92
void const char * value
virtual void RemoveObserver(Observer< Event > &observer)
Remove an observer of this event.
Definition notifier.h:154
virtual void AddObserver(Observer< Event > &observer)
Add an observer of this event.
Definition notifier.h:141
virtual bool HasObservers(void) const
Definition notifier.h:166
virtual ~Notifier()
Definition notifier.h:123
virtual void NotifyObservers(Event &event)
Send event notification to all observers of this event.
Definition notifier.h:132
std::vector< Observer< Event > * > ObserverColl
Definition notifier.h:118
void StopObserving()
Stop observing event.
Definition notifier.h:90
virtual void NotifyMe(Notifier< Event > &notifier)
Request notification of this event.
Definition notifier.h:86
virtual void HandleNotification(Event &)=0
Handle event notification.
virtual ~Observer()
Definition notifier.h:67
Observer()
Definition notifier.h:63
virtual void NotificationEnded(const Notifier< Event > &notifier)
Notifier has ended notification of this event.
Definition notifier.h:74
Observer(const Observer< Event > &observer)
const Observer< Event > & operator=(const Observer< Event > &)
std::vector< Notifier< Event > * > NotifierColl
Definition notifier.h:61
A GetAction(void) const
Definition notifier.h:241
TypedActionPtr(A action, O *data)
Definition notifier.h:244
TypedEvent(V &value)
Definition notifier.h:204
V & Subject(void)
Definition notifier.h:211
V & operator()()
Definition notifier.h:208
A GetItemA(void)
Definition notifier.h:265
TypedEventPair(A itemA, B itemB)
Definition notifier.h:260
B GetItemB(void)
Definition notifier.h:268
O * operator()()
Definition notifier.h:229
TypedEventPtr(O *subject)
Definition notifier.h:222
O * Subject(void)
Definition notifier.h:226