Embedded Template Library  1.0
observer.h
Go to the documentation of this file.
1 
3 /******************************************************************************
4 The MIT License(MIT)
5 
6 Embedded Template Library.
7 https://github.com/ETLCPP/etl
8 https://www.etlcpp.com
9 
10 Copyright(c) 2014 jwellbelove
11 
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files(the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions :
18 
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21 
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
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 
61 #undef ETL_FILE
62 #define ETL_FILE "18"
63 
64 namespace etl
65 {
66  //***************************************************************************
69  //***************************************************************************
71  {
72  public:
73 
74  observer_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
75  : exception(reason_, file_name_, line_number_)
76  {
77  }
78  };
79 
80  //***************************************************************************
83  //***************************************************************************
85  {
86  public:
87 
88  observer_list_full(string_type file_name_, numeric_type line_number_)
89  : observer_exception(ETL_ERROR_TEXT("observer:full", ETL_FILE"A"), file_name_, line_number_)
90  {
91  }
92  };
93 
94  //*********************************************************************
99  //*********************************************************************
100  template <typename TObserver, const size_t MAX_OBSERVERS>
102  {
103  private:
104 
105  //***********************************
106  // Item stored in the observer list.
107  //***********************************
108  struct observer_item
109  {
110  observer_item(TObserver& observer_)
111  : p_observer(&observer_)
112  , enabled(true)
113  {
114  }
115 
116  TObserver* p_observer;
117  bool enabled;
118  };
119 
120  //***********************************
121  // How to compare an observer with an observer list item.
122  //***********************************
123  struct compare_observers
124  {
125  compare_observers(TObserver& observer_)
126  : p_observer(&observer_)
127  {
128  }
129 
130  bool operator ()(const observer_item& item) const
131  {
132  return p_observer == item.p_observer;
133  }
134 
135  TObserver* p_observer;
136  };
137 
138  public:
139 
140  typedef size_t size_type;
141 
143 
144  //*****************************************************************
149  //*****************************************************************
150  void add_observer(TObserver& observer)
151  {
152  // See if we already have it in our list.
153  typename Observer_List::iterator i_observer_item = find_observer(observer);
154 
155  // Not there?
156  if (i_observer_item == observer_list.end())
157  {
158  // Is there enough room?
159  ETL_ASSERT(!observer_list.full(), ETL_ERROR(etl::observer_list_full));
160 
161  // Add it.
162  observer_list.push_back(observer_item(observer));
163  }
164  }
165 
166  //*****************************************************************
170  //*****************************************************************
171  bool remove_observer(TObserver& observer)
172  {
173  // See if we have it in our list.
174  typename Observer_List::iterator i_observer_item = find_observer(observer);
175 
176  // Found it?
177  if (i_observer_item != observer_list.end())
178  {
179  // Erase it.
180  observer_list.erase(i_observer_item);
181  return true;
182  }
183  else
184  {
185  return false;
186  }
187  }
188 
189  //*****************************************************************
193  //*****************************************************************
194  void enable_observer(TObserver& observer, bool state = true)
195  {
196  // See if we have it in our list.
197  typename Observer_List::iterator i_observer_item = find_observer(observer);
198 
199  // Found it?
200  if (i_observer_item != observer_list.end())
201  {
202  i_observer_item->enabled = state;
203  }
204  }
205 
206  //*****************************************************************
208  //*****************************************************************
209  void disable_observer(TObserver& observer)
210  {
211  // See if we have it in our list.
212  typename Observer_List::iterator i_observer_item = find_observer(observer);
213 
214  // Found it?
215  if (i_observer_item != observer_list.end())
216  {
217  i_observer_item->enabled = false;
218  }
219  }
220 
221  //*****************************************************************
223  //*****************************************************************
225  {
226  observer_list.clear();
227  }
228 
229  //*****************************************************************
231  //*****************************************************************
232  size_type number_of_observers() const
233  {
234  return observer_list.size();
235  }
236 
237  //*****************************************************************
241  //*****************************************************************
242  template <typename TNotification>
243  void notify_observers(TNotification n)
244  {
245  typename Observer_List::iterator i_observer_item = observer_list.begin();
246 
247  while (i_observer_item != observer_list.end())
248  {
249  if (i_observer_item->enabled)
250  {
251  i_observer_item->p_observer->notification(n);
252  }
253 
254  ++i_observer_item;
255  }
256  }
257 
258  protected:
259 
260  ~observable()
261  {
262  }
263 
264  private:
265 
266  //*****************************************************************
269  //*****************************************************************
270  typename Observer_List::iterator find_observer(TObserver& observer_)
271  {
272  return etl::find_if(observer_list.begin(), observer_list.end(), compare_observers(observer_));
273  }
274 
276  Observer_List observer_list;
277  };
278 
279 #if ETL_CPP11_SUPPORTED && !defined(ETL_OBSERVER_FORCE_CPP03)
280 
281  //*****************************************************************
284  //*****************************************************************
285  template <typename T1, typename... Types>
286  class observer : public observer<T1>, public observer<Types...>
287  {
288  public:
289 
290  using observer<T1>::notification;
291  using observer<Types...>::notification;
292  };
293 
294  //*****************************************************************
297  //*****************************************************************
298  template <typename T1>
299  class observer<T1>
300  {
301  public:
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>
320  class observer
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 #undef ETL_FILE
471 
472 #endif
#define ETL_ASSERT(b, e)
Definition: error_handler.h:290
exception(string_type reason_, string_type file_, numeric_type line_)
Constructor.
Definition: exception.h:67
Definition: exception.h:47
void notify_observers(TNotification n)
Definition: observer.h:243
void disable_observer(TObserver &observer)
Disable an observer.
Definition: observer.h:209
void add_observer(TObserver &observer)
Definition: observer.h:150
bool remove_observer(TObserver &observer)
Definition: observer.h:171
void clear_observers()
Clear all observers from the list.
Definition: observer.h:224
void enable_observer(TObserver &observer, bool state=true)
Definition: observer.h:194
size_type number_of_observers() const
Returns the number of observers.
Definition: observer.h:232
Definition: observer.h:102
Definition: observer.h:321
Definition: observer.h:71
Definition: observer.h:85
iterator begin()
Definition: vector.h:108
void push_back(const_reference value)
Definition: vector.h:408
void clear()
Clears the vector.
Definition: vector.h:398
iterator end()
Definition: vector.h:126
bool full() const
Definition: vector.h:914
size_type size() const
Definition: vector.h:896
iterator erase(iterator i_element)
Definition: vector.h:820
Definition: absolute.h:37