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 "platform.h"
55#include "algorithm.h"
56#include "vector.h"
57#include "exception.h"
58#include "error_handler.h"
59#include "utility.h"
60
61namespace etl
62{
63 //***************************************************************************
66 //***************************************************************************
67 class observer_exception : public exception
68 {
69 public:
70
71 observer_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
72 : exception(reason_, file_name_, line_number_)
73 {
74 }
75 };
76
77 //***************************************************************************
80 //***************************************************************************
81 class observer_list_full : public observer_exception
82 {
83 public:
84
85 observer_list_full(string_type file_name_, numeric_type line_number_)
86 : observer_exception(ETL_ERROR_TEXT("observer:full", ETL_OBSERVER_FILE_ID"A"), file_name_, line_number_)
87 {
88 }
89 };
90
91 //*********************************************************************
96 //*********************************************************************
97 template <typename TObserver, const size_t Max_Observers>
99 {
100 private:
101
102 //***********************************
103 // Item stored in the observer list.
104 //***********************************
105 struct observer_item
106 {
107 observer_item(TObserver& observer_)
108 : p_observer(&observer_)
109 , enabled(true)
110 {
111 }
112
113 TObserver* p_observer;
114 bool enabled;
115 };
116
117 //***********************************
118 // How to compare an observer with an observer list item.
119 //***********************************
120 struct compare_observers
121 {
122 compare_observers(TObserver& observer_)
123 : p_observer(&observer_)
124 {
125 }
126
127 bool operator ()(const observer_item& item) const
128 {
129 return p_observer == item.p_observer;
130 }
131
132 TObserver* p_observer;
133 };
134
135 public:
136
137 typedef size_t size_type;
138
139 typedef etl::vector<observer_item, Max_Observers> Observer_List;
140
141 //*****************************************************************
146 //*****************************************************************
147 void add_observer(TObserver& observer)
148 {
149 // See if we already have it in our list.
150 typename Observer_List::iterator i_observer_item = find_observer(observer);
151
152 // Not there?
153 if (i_observer_item == observer_list.end())
154 {
155 // Is there enough room?
156 ETL_ASSERT_OR_RETURN(!observer_list.full(), ETL_ERROR(etl::observer_list_full));
157
158 // Add it.
159 observer_list.push_back(observer_item(observer));
160 }
161 }
162
163 //*****************************************************************
167 //*****************************************************************
168 bool remove_observer(TObserver& observer)
169 {
170 // See if we have it in our list.
171 typename Observer_List::iterator i_observer_item = find_observer(observer);
172
173 // Found it?
174 if (i_observer_item != observer_list.end())
175 {
176 // Erase it.
177 observer_list.erase(i_observer_item);
178 return true;
179 }
180 else
181 {
182 return false;
183 }
184 }
185
186 //*****************************************************************
190 //*****************************************************************
191 void enable_observer(TObserver& observer, bool state = true)
192 {
193 // See if we have it in our list.
194 typename Observer_List::iterator i_observer_item = find_observer(observer);
195
196 // Found it?
197 if (i_observer_item != observer_list.end())
198 {
199 i_observer_item->enabled = state;
200 }
201 }
202
203 //*****************************************************************
205 //*****************************************************************
206 void disable_observer(TObserver& observer)
207 {
208 // See if we have it in our list.
209 typename Observer_List::iterator i_observer_item = find_observer(observer);
210
211 // Found it?
212 if (i_observer_item != observer_list.end())
213 {
214 i_observer_item->enabled = false;
215 }
216 }
217
218 //*****************************************************************
220 //*****************************************************************
222 {
223 observer_list.clear();
224 }
225
226 //*****************************************************************
228 //*****************************************************************
229 size_type number_of_observers() const
230 {
231 return observer_list.size();
232 }
233
234 //*****************************************************************
238 //*****************************************************************
239 template <typename TNotification>
240 void notify_observers(TNotification n)
241 {
242 typename Observer_List::iterator i_observer_item = observer_list.begin();
243
244 while (i_observer_item != observer_list.end())
245 {
246 if (i_observer_item->enabled)
247 {
248 i_observer_item->p_observer->notification(n);
249 }
250
251 ++i_observer_item;
252 }
253 }
254
255 //*****************************************************************
257 //*****************************************************************
259 {
260 typename Observer_List::iterator i_observer_item = observer_list.begin();
261
262 while (i_observer_item != observer_list.end())
263 {
264 if (i_observer_item->enabled)
265 {
266 i_observer_item->p_observer->notification();
267 }
268
269 ++i_observer_item;
270 }
271 }
272
273 protected:
274
276 {
277 }
278
279 private:
280
281 //*****************************************************************
284 //*****************************************************************
285 typename Observer_List::iterator find_observer(TObserver& observer_)
286 {
287 return etl::find_if(observer_list.begin(), observer_list.end(), compare_observers(observer_));
288 }
289
291 Observer_List observer_list;
292 };
293
294#if ETL_USING_CPP11 && !defined(ETL_OBSERVER_FORCE_CPP03_IMPLEMENTATION)
295 template <typename... TTypes>
296 class observer;
297
298 //*****************************************************************
301 //*****************************************************************
302 template <typename T1, typename... TRest>
303 class observer<T1, TRest...> : public observer<T1>, public observer<TRest...>
304 {
305 public:
306
307 ETL_STATIC_ASSERT((!etl::has_duplicates<T1, TRest...>::value), "Observer has duplicate notification types");
308
309 using observer<T1>::notification;
310 using observer<TRest...>::notification;
311 };
312
313 //*****************************************************************
316 //*****************************************************************
317 template <typename T1>
318 class observer<T1>
319 {
320 public:
321
322 virtual ~observer() = default;
323
324 virtual void notification(T1) = 0;
325 };
326
327 //*****************************************************************
330 //*****************************************************************
331 template <>
332 class observer<void>
333 {
334 public:
335
336 virtual ~observer() = default;
337
338 virtual void notification() = 0;
339 };
340
341#else
342
343 //*********************************************************************
346 //*********************************************************************
347 template <typename T1,
348 typename T2 = void,
349 typename T3 = void,
350 typename T4 = void,
351 typename T5 = void,
352 typename T6 = void,
353 typename T7 = void,
354 typename T8 = void>
355 class observer : public observer<T1>
356 , public observer<T2>
357 , public observer<T3>
358 , public observer<T4>
359 , public observer<T5>
360 , public observer<T6>
361 , public observer<T7>
362 , public observer<T8>
363 {
364 public:
365 virtual ~observer() {}
366
367 using observer<T1>::notification;
368 using observer<T2>::notification;
369 using observer<T3>::notification;
370 using observer<T4>::notification;
371 using observer<T5>::notification;
372 using observer<T6>::notification;
373 using observer<T7>::notification;
374 using observer<T8>::notification;
375 };
376
377 //*********************************************************************
380 //*********************************************************************
381 template <typename T1,
382 typename T2,
383 typename T3,
384 typename T4,
385 typename T5,
386 typename T6,
387 typename T7>
388 class observer<T1, T2, T3, T4, T5, T6, T7> : public observer<T1>
389 , public observer<T2>
390 , public observer<T3>
391 , public observer<T4>
392 , public observer<T5>
393 , public observer<T6>
394 , public observer<T7>
395 {
396 public:
397
398 virtual ~observer() {}
399 using observer<T1>::notification;
400 using observer<T2>::notification;
401 using observer<T3>::notification;
402 using observer<T4>::notification;
403 using observer<T5>::notification;
404 using observer<T6>::notification;
405 using observer<T7>::notification;
406 };
407
408 //*********************************************************************
411 //*********************************************************************
412 template <typename T1,
413 typename T2,
414 typename T3,
415 typename T4,
416 typename T5,
417 typename T6>
418 class observer<T1, T2, T3, T4, T5, T6> : public observer<T1>
419 , public observer<T2>
420 , public observer<T3>
421 , public observer<T4>
422 , public observer<T5>
423 , public observer<T6>
424 {
425 public:
426
427 virtual ~observer() {}
428 using observer<T1>::notification;
429 using observer<T2>::notification;
430 using observer<T3>::notification;
431 using observer<T4>::notification;
432 using observer<T5>::notification;
433 using observer<T6>::notification;
434 };
435
436 //*********************************************************************
439 //*********************************************************************
440 template <typename T1,
441 typename T2,
442 typename T3,
443 typename T4,
444 typename T5>
445 class observer<T1, T2, T3, T4, T5> : public observer<T1>
446 , public observer<T2>
447 , public observer<T3>
448 , public observer<T4>
449 , public observer<T5>
450 {
451 public:
452
453 virtual ~observer() {}
454 using observer<T1>::notification;
455 using observer<T2>::notification;
456 using observer<T3>::notification;
457 using observer<T4>::notification;
458 using observer<T5>::notification;
459 };
460
461 //*********************************************************************
464 //*********************************************************************
465 template <typename T1,
466 typename T2,
467 typename T3,
468 typename T4>
469 class observer<T1, T2, T3, T4> : public observer<T1>
470 , public observer<T2>
471 , public observer<T3>
472 , public observer<T4>
473 {
474 public:
475
476 virtual ~observer() {}
477 using observer<T1>::notification;
478 using observer<T2>::notification;
479 using observer<T3>::notification;
480 using observer<T4>::notification;
481 };
482
483 //*********************************************************************
486 //*********************************************************************
487 template <typename T1,
488 typename T2,
489 typename T3>
490 class observer<T1, T2, T3> : public observer<T1>
491 , public observer<T2>
492 , public observer<T3>
493 {
494 public:
495
496 virtual ~observer() {}
497 using observer<T1>::notification;
498 using observer<T2>::notification;
499 using observer<T3>::notification;
500 };
501
502 //*********************************************************************
505 //*********************************************************************
506 template <typename T1,
507 typename T2>
508 class observer<T1, T2> : public observer<T1>
509 , public observer<T2>
510 {
511 public:
512
513 virtual ~observer() {}
514 using observer<T1>::notification;
515 using observer<T2>::notification;
516 };
517
518 //*********************************************************************
521 //*********************************************************************
522 template <typename T1>
523 class observer<T1>
524 {
525 public:
526
527 virtual ~observer() {}
528 virtual void notification(T1) = 0;
529 };
530
531 //*********************************************************************
534 //*********************************************************************
535 template <>
536 class observer<void>
537 {
538 public:
539
540 virtual ~observer() {}
541 virtual void notification() = 0;
542 };
543
544#endif
545}
546
547#endif
ETL_CONSTEXPR exception(string_type reason_, string_type, numeric_type line_)
Constructor.
Definition exception.h:69
void add_observer(TObserver &observer)
Definition observer.h:147
bool remove_observer(TObserver &observer)
Definition observer.h:168
void notify_observers(TNotification n)
Definition observer.h:240
void notify_observers()
Notify all of the observers, sending them the notification.
Definition observer.h:258
void disable_observer(TObserver &observer)
Disable an observer.
Definition observer.h:206
void enable_observer(TObserver &observer, bool state=true)
Definition observer.h:191
size_type number_of_observers() const
Returns the number of observers.
Definition observer.h:229
void clear_observers()
Clear all observers from the list.
Definition observer.h:221
Definition observer.h:99
Definition observer.h:363
Definition observer.h:82
iterator begin()
Definition vector.h:99
iterator end()
Definition vector.h:117
Definition vector.h:1225
bitset_ext
Definition absolute.h:39