Embedded Template Library 1.0
Loading...
Searching...
No Matches
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 //***************************************************************************
77
78 //***************************************************************************
81 //***************************************************************************
83 {
84 public:
85
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
140 typedef etl::vector<observer_item, MAX_OBSERVERS> Observer_List;
141
142 //*****************************************************************
147 //*****************************************************************
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 //*****************************************************************
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 //*****************************************************************
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 //*****************************************************************
231 {
232 return observer_list.size();
233 }
234
235 //*****************************************************************
239 //*****************************************************************
240 template <typename TNotification>
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
253 }
254 }
255
256 //*****************************************************************
258 //*****************************************************************
260 {
261 typename Observer_List::iterator i_observer_item = observer_list.begin();
262
263 while (i_observer_item != observer_list.end())
264 {
265 if (i_observer_item->enabled)
266 {
267 i_observer_item->p_observer->notification();
268 }
269
271 }
272 }
273
274 protected:
275
277 {
278 }
279
280 private:
281
282 //*****************************************************************
285 //*****************************************************************
286 typename Observer_List::iterator find_observer(TObserver& observer_)
287 {
288 return etl::find_if(observer_list.begin(), observer_list.end(), compare_observers(observer_));
289 }
290
292 Observer_List observer_list;
293 };
294
295#if ETL_USING_CPP11 && !defined(ETL_OBSERVER_FORCE_CPP03_IMPLEMENTATION)
296 template <typename... TTypes>
297 class observer;
298
299 //*****************************************************************
302 //*****************************************************************
303 template <typename T1, typename... TRest>
304 class observer<T1, TRest...> : public observer<T1>, public observer<TRest...>
305 {
306 public:
307
308 ETL_STATIC_ASSERT((!etl::has_duplicates<T1, TRest...>::value), "Observer has duplicate notification types");
309
310 using observer<T1>::notification;
311 using observer<TRest...>::notification;
312 };
313
314 //*****************************************************************
317 //*****************************************************************
318 template <typename T1>
319 class observer<T1>
320 {
321 public:
322
323 virtual ~observer() = default;
324
325 virtual void notification(T1) = 0;
326 };
327
328 //*****************************************************************
331 //*****************************************************************
332 template <>
333 class observer<void>
334 {
335 public:
336
337 virtual ~observer() = default;
338
339 virtual void notification() = 0;
340 };
341
342#else
343
344 //*********************************************************************
347 //*********************************************************************
348 template <typename T1,
349 typename T2 = void,
350 typename T3 = void,
351 typename T4 = void,
352 typename T5 = void,
353 typename T6 = void,
354 typename T7 = void,
355 typename T8 = void>
356 class observer : public observer<T1>
357 , public observer<T2>
358 , public observer<T3>
359 , public observer<T4>
360 , public observer<T5>
361 , public observer<T6>
362 , public observer<T7>
363 , public observer<T8>
364 {
365 public:
366 virtual ~observer() {}
367
368 using observer<T1>::notification;
369 using observer<T2>::notification;
370 using observer<T3>::notification;
371 using observer<T4>::notification;
372 using observer<T5>::notification;
373 using observer<T6>::notification;
374 using observer<T7>::notification;
375 using observer<T8>::notification;
376 };
377
378 //*********************************************************************
381 //*********************************************************************
382 template <typename T1,
383 typename T2,
384 typename T3,
385 typename T4,
386 typename T5,
387 typename T6,
388 typename T7>
389 class observer<T1, T2, T3, T4, T5, T6, T7> : public observer<T1>
390 , public observer<T2>
391 , public observer<T3>
392 , public observer<T4>
393 , public observer<T5>
394 , public observer<T6>
395 , public observer<T7>
396 {
397 public:
398
399 virtual ~observer() {}
400 using observer<T1>::notification;
401 using observer<T2>::notification;
402 using observer<T3>::notification;
403 using observer<T4>::notification;
404 using observer<T5>::notification;
405 using observer<T6>::notification;
406 using observer<T7>::notification;
407 };
408
409 //*********************************************************************
412 //*********************************************************************
413 template <typename T1,
414 typename T2,
415 typename T3,
416 typename T4,
417 typename T5,
418 typename T6>
419 class observer<T1, T2, T3, T4, T5, T6> : public observer<T1>
420 , public observer<T2>
421 , public observer<T3>
422 , public observer<T4>
423 , public observer<T5>
424 , public observer<T6>
425 {
426 public:
427
428 virtual ~observer() {}
429 using observer<T1>::notification;
430 using observer<T2>::notification;
431 using observer<T3>::notification;
432 using observer<T4>::notification;
433 using observer<T5>::notification;
434 using observer<T6>::notification;
435 };
436
437 //*********************************************************************
440 //*********************************************************************
441 template <typename T1,
442 typename T2,
443 typename T3,
444 typename T4,
445 typename T5>
446 class observer<T1, T2, T3, T4, T5> : public observer<T1>
447 , public observer<T2>
448 , public observer<T3>
449 , public observer<T4>
450 , public observer<T5>
451 {
452 public:
453
454 virtual ~observer() {}
455 using observer<T1>::notification;
456 using observer<T2>::notification;
457 using observer<T3>::notification;
458 using observer<T4>::notification;
459 using observer<T5>::notification;
460 };
461
462 //*********************************************************************
465 //*********************************************************************
466 template <typename T1,
467 typename T2,
468 typename T3,
469 typename T4>
470 class observer<T1, T2, T3, T4> : public observer<T1>
471 , public observer<T2>
472 , public observer<T3>
473 , public observer<T4>
474 {
475 public:
476
477 virtual ~observer() {}
478 using observer<T1>::notification;
479 using observer<T2>::notification;
480 using observer<T3>::notification;
481 using observer<T4>::notification;
482 };
483
484 //*********************************************************************
487 //*********************************************************************
488 template <typename T1,
489 typename T2,
490 typename T3>
491 class observer<T1, T2, T3> : public observer<T1>
492 , public observer<T2>
493 , public observer<T3>
494 {
495 public:
496
497 virtual ~observer() {}
498 using observer<T1>::notification;
499 using observer<T2>::notification;
500 using observer<T3>::notification;
501 };
502
503 //*********************************************************************
506 //*********************************************************************
507 template <typename T1,
508 typename T2>
509 class observer<T1, T2> : public observer<T1>
510 , public observer<T2>
511 {
512 public:
513
514 virtual ~observer() {}
515 using observer<T1>::notification;
516 using observer<T2>::notification;
517 };
518
519 //*********************************************************************
522 //*********************************************************************
523 template <typename T1>
525 {
526 public:
527
528 virtual ~observer() {}
529 virtual void notification(T1) = 0;
530 };
531
532 //*********************************************************************
535 //*********************************************************************
536 template <>
538 {
539 public:
540
541 virtual ~observer() {}
542 virtual void notification() = 0;
543 };
544
545#endif
546}
547
548#endif
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
void notify_observers()
Notify all of the observers, sending them the notification.
Definition observer.h:259
Definition observer.h:100
Definition observer.h:364
Definition observer.h:69
Definition observer.h:83
bitset_ext
Definition absolute.h:38
pair holds two objects of arbitrary type
Definition utility.h:164