Embedded Template Library 1.0
observer.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2014 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_OBSERVER_INCLUDED
32#define ETL_OBSERVER_INCLUDED
33
34//*****************************************************************************
52//*****************************************************************************
53
54#include "algorithm.h"
55
56#include "platform.h"
57#include "vector.h"
58#include "exception.h"
59#include "error_handler.h"
60#include "utility.h"
61
62namespace etl
63{
64 //***************************************************************************
67 //***************************************************************************
69 {
70 public:
71
72 observer_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
73 : exception(reason_, file_name_, line_number_)
74 {
75 }
76 };
77
78 //***************************************************************************
81 //***************************************************************************
83 {
84 public:
85
86 observer_list_full(string_type file_name_, numeric_type line_number_)
87 : observer_exception(ETL_ERROR_TEXT("observer:full", ETL_OBSERVER_FILE_ID"A"), file_name_, line_number_)
88 {
89 }
90 };
91
92 //*********************************************************************
97 //*********************************************************************
98 template <typename TObserver, const size_t MAX_OBSERVERS>
100 {
101 private:
102
103 //***********************************
104 // Item stored in the observer list.
105 //***********************************
106 struct observer_item
107 {
108 observer_item(TObserver& observer_)
109 : p_observer(&observer_)
110 , enabled(true)
111 {
112 }
113
114 TObserver* p_observer;
115 bool enabled;
116 };
117
118 //***********************************
119 // How to compare an observer with an observer list item.
120 //***********************************
121 struct compare_observers
122 {
123 compare_observers(TObserver& observer_)
124 : p_observer(&observer_)
125 {
126 }
127
128 bool operator ()(const observer_item& item) const
129 {
130 return p_observer == item.p_observer;
131 }
132
133 TObserver* p_observer;
134 };
135
136 public:
137
138 typedef size_t size_type;
139
141
142 //*****************************************************************
147 //*****************************************************************
148 void add_observer(TObserver& observer)
149 {
150 // See if we already have it in our list.
151 typename Observer_List::iterator i_observer_item = find_observer(observer);
152
153 // Not there?
154 if (i_observer_item == observer_list.end())
155 {
156 // Is there enough room?
157 ETL_ASSERT_OR_RETURN(!observer_list.full(), ETL_ERROR(etl::observer_list_full));
158
159 // Add it.
160 observer_list.push_back(observer_item(observer));
161 }
162 }
163
164 //*****************************************************************
168 //*****************************************************************
169 bool remove_observer(TObserver& observer)
170 {
171 // See if we have it in our list.
172 typename Observer_List::iterator i_observer_item = find_observer(observer);
173
174 // Found it?
175 if (i_observer_item != observer_list.end())
176 {
177 // Erase it.
178 observer_list.erase(i_observer_item);
179 return true;
180 }
181 else
182 {
183 return false;
184 }
185 }
186
187 //*****************************************************************
191 //*****************************************************************
192 void enable_observer(TObserver& observer, bool state = true)
193 {
194 // See if we have it in our list.
195 typename Observer_List::iterator i_observer_item = find_observer(observer);
196
197 // Found it?
198 if (i_observer_item != observer_list.end())
199 {
200 i_observer_item->enabled = state;
201 }
202 }
203
204 //*****************************************************************
206 //*****************************************************************
207 void disable_observer(TObserver& observer)
208 {
209 // See if we have it in our list.
210 typename Observer_List::iterator i_observer_item = find_observer(observer);
211
212 // Found it?
213 if (i_observer_item != observer_list.end())
214 {
215 i_observer_item->enabled = false;
216 }
217 }
218
219 //*****************************************************************
221 //*****************************************************************
223 {
224 observer_list.clear();
225 }
226
227 //*****************************************************************
229 //*****************************************************************
230 size_type number_of_observers() const
231 {
232 return observer_list.size();
233 }
234
235 //*****************************************************************
239 //*****************************************************************
240 template <typename TNotification>
241 void notify_observers(TNotification n)
242 {
243 typename Observer_List::iterator i_observer_item = observer_list.begin();
244
245 while (i_observer_item != observer_list.end())
246 {
247 if (i_observer_item->enabled)
248 {
249 i_observer_item->p_observer->notification(n);
250 }
251
252 ++i_observer_item;
253 }
254 }
255
256 protected:
257
259 {
260 }
261
262 private:
263
264 //*****************************************************************
267 //*****************************************************************
268 typename Observer_List::iterator find_observer(TObserver& observer_)
269 {
270 return etl::find_if(observer_list.begin(), observer_list.end(), compare_observers(observer_));
271 }
272
274 Observer_List observer_list;
275 };
276
277#if ETL_USING_CPP11 && !defined(ETL_OBSERVER_FORCE_CPP03_IMPLEMENTATION)
278
279 //*****************************************************************
282 //*****************************************************************
283 template <typename T1, typename... Types>
284 class observer : public observer<T1>, public observer<Types...>
285 {
286 public:
287
288 using observer<T1>::notification;
289 using observer<Types...>::notification;
290 };
291
292 //*****************************************************************
295 //*****************************************************************
296 template <typename T1>
297 class observer<T1>
298 {
299 public:
300
301 virtual ~observer() = default;
302
303 virtual void notification(T1) = 0;
304 };
305
306#else
307
308 //*********************************************************************
311 //*********************************************************************
312 template <typename T1,
313 typename T2 = void,
314 typename T3 = void,
315 typename T4 = void,
316 typename T5 = void,
317 typename T6 = void,
318 typename T7 = void,
319 typename T8 = void>
321 {
322 public:
323 virtual ~observer() {}
324 virtual void notification(T1) = 0;
325 virtual void notification(T2) = 0;
326 virtual void notification(T3) = 0;
327 virtual void notification(T4) = 0;
328 virtual void notification(T5) = 0;
329 virtual void notification(T6) = 0;
330 virtual void notification(T7) = 0;
331 virtual void notification(T8) = 0;
332 };
333
334 //*********************************************************************
337 //*********************************************************************
338 template <typename T1,
339 typename T2,
340 typename T3,
341 typename T4,
342 typename T5,
343 typename T6,
344 typename T7>
345 class observer<T1, T2, T3, T4, T5, T6, T7>
346 {
347 public:
348
349 virtual ~observer() {}
350 virtual void notification(T1) = 0;
351 virtual void notification(T2) = 0;
352 virtual void notification(T3) = 0;
353 virtual void notification(T4) = 0;
354 virtual void notification(T5) = 0;
355 virtual void notification(T6) = 0;
356 virtual void notification(T7) = 0;
357 };
358
359 //*********************************************************************
362 //*********************************************************************
363 template <typename T1,
364 typename T2,
365 typename T3,
366 typename T4,
367 typename T5,
368 typename T6>
369 class observer<T1, T2, T3, T4, T5, T6>
370 {
371 public:
372
373 virtual ~observer() {}
374 virtual void notification(T1) = 0;
375 virtual void notification(T2) = 0;
376 virtual void notification(T3) = 0;
377 virtual void notification(T4) = 0;
378 virtual void notification(T5) = 0;
379 virtual void notification(T6) = 0;
380 };
381
382 //*********************************************************************
385 //*********************************************************************
386 template <typename T1,
387 typename T2,
388 typename T3,
389 typename T4,
390 typename T5>
391 class observer<T1, T2, T3, T4, T5>
392 {
393 public:
394
395 virtual ~observer() {}
396 virtual void notification(T1) = 0;
397 virtual void notification(T2) = 0;
398 virtual void notification(T3) = 0;
399 virtual void notification(T4) = 0;
400 virtual void notification(T5) = 0;
401 };
402
403 //*********************************************************************
406 //*********************************************************************
407 template <typename T1,
408 typename T2,
409 typename T3,
410 typename T4>
411 class observer<T1, T2, T3, T4>
412 {
413 public:
414
415 virtual ~observer() {}
416 virtual void notification(T1) = 0;
417 virtual void notification(T2) = 0;
418 virtual void notification(T3) = 0;
419 virtual void notification(T4) = 0;
420 };
421
422 //*********************************************************************
425 //*********************************************************************
426 template <typename T1,
427 typename T2,
428 typename T3>
429 class observer<T1, T2, T3>
430 {
431 public:
432
433 virtual ~observer() {}
434 virtual void notification(T1) = 0;
435 virtual void notification(T2) = 0;
436 virtual void notification(T3) = 0;
437 };
438
439 //*********************************************************************
442 //*********************************************************************
443 template <typename T1,
444 typename T2>
445 class observer<T1, T2>
446 {
447 public:
448
449 virtual ~observer() {}
450 virtual void notification(T1) = 0;
451 virtual void notification(T2) = 0;
452 };
453
454 //*********************************************************************
457 //*********************************************************************
458 template <typename T1>
459 class observer<T1>
460 {
461 public:
462
463 virtual ~observer() {}
464 virtual void notification(T1) = 0;
465 };
466
467#endif
468}
469
470#endif
ETL_CONSTEXPR exception(string_type reason_, string_type, numeric_type line_)
Constructor.
Definition: exception.h:69
Definition: exception.h:47
void notify_observers(TNotification n)
Definition: observer.h:241
void disable_observer(TObserver &observer)
Disable an observer.
Definition: observer.h:207
void add_observer(TObserver &observer)
Definition: observer.h:148
bool remove_observer(TObserver &observer)
Definition: observer.h:169
void clear_observers()
Clear all observers from the list.
Definition: observer.h:222
void enable_observer(TObserver &observer, bool state=true)
Definition: observer.h:192
size_type number_of_observers() const
Returns the number of observers.
Definition: observer.h:230
Definition: observer.h:100
Definition: observer.h:321
Definition: observer.h:69
Definition: observer.h:83
iterator begin()
Definition: vector.h:100
void push_back(const_reference value)
Definition: vector.h:432
void clear()
Clears the vector.
Definition: vector.h:414
iterator end()
Definition: vector.h:118
bool full() const
Definition: vector.h:977
size_type size() const
Definition: vector.h:959
iterator erase(iterator i_element)
Definition: vector.h:865
bitset_ext
Definition: absolute.h:38