Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
observer.h
00001 ///\file 00002 00003 /****************************************************************************** 00004 The MIT License(MIT) 00005 00006 Embedded Template Library. 00007 https://github.com/ETLCPP/etl 00008 http://www.etlcpp.com 00009 00010 Copyright(c) 2014 jwellbelove 00011 00012 Permission is hereby granted, free of charge, to any person obtaining a copy 00013 of this software and associated documentation files(the "Software"), to deal 00014 in the Software without restriction, including without limitation the rights 00015 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 00016 copies of the Software, and to permit persons to whom the Software is 00017 furnished to do so, subject to the following conditions : 00018 00019 The above copyright notice and this permission notice shall be included in all 00020 copies or substantial portions of the Software. 00021 00022 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00023 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00024 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 00025 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00026 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00027 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00028 SOFTWARE. 00029 ******************************************************************************/ 00030 00031 #ifndef __ETL_OBSERVER__ 00032 #define __ETL_OBSERVER__ 00033 00034 //***************************************************************************** 00035 ///\defgroup observer observer 00036 /// A templated implementation to simplify the creation of the observer pattern 00037 /// and attempts to eliminate certain runtime errors by turning them into compile errors. 00038 /// The pattern consists of two template classes. 00039 /// \li <b>Observer</b><br> 00040 /// This template may take up to eight notification types. 00041 /// Each notification type will generate a pure virtual 'notification' 00042 /// function. The class that inherits from this *must* define all 00043 /// of the 'notification' function overloads otherwise the object will 00044 /// remain 'abstract' and will not compile. 00045 /// This ensures that no overload can be forgotten.<br> 00046 /// 00047 /// \li <b>observable</b><br> 00048 /// The class derived from this will be observed by the above class. 00049 /// It keeps a list of registered observers and will notify all 00050 /// of them with the notifications. 00051 ///\ingroup patterns 00052 //***************************************************************************** 00053 00054 #include <algorithm> 00055 00056 #include "platform.h " 00057 #include "vector.h " 00058 #include "exception.h " 00059 #include "error_handler.h " 00060 00061 #undef ETL_FILE 00062 #define ETL_FILE "18" 00063 00064 namespace etl 00065 { 00066 //*************************************************************************** 00067 ///\ingroup observer 00068 /// The base class for observer exceptions. 00069 //*************************************************************************** 00070 class observer_exception : public exception 00071 { 00072 public: 00073 00074 observer_exception(string_type reason_, string_type file_name_, numeric_type line_number_) 00075 : exception(reason_, file_name_, line_number_) 00076 { 00077 } 00078 }; 00079 00080 //*************************************************************************** 00081 ///\ingroup observer 00082 /// The exception thrown when the observer list is full. 00083 //*************************************************************************** 00084 class observer_list_full : public observer_exception 00085 { 00086 public: 00087 00088 observer_list_full(string_type file_name_, numeric_type line_number_) 00089 : observer_exception(ETL_ERROR_TEXT("observer:full", ETL_FILE"A"), file_name_, line_number_) 00090 { 00091 } 00092 }; 00093 00094 //********************************************************************* 00095 /// The object that is being observed. 00096 ///\tparam TObserver The observer type. 00097 ///\tparam MAX_OBSERVERS The maximum number of observers that can be accomodated. 00098 ///\ingroup observer 00099 //********************************************************************* 00100 template <typename TObserver, const size_t MAX_OBSERVERS> 00101 class observable 00102 { 00103 public: 00104 00105 typedef size_t size_type; 00106 00107 typedef etl::vector<TObserver*, MAX_OBSERVERS> Observer_List ; 00108 00109 //***************************************************************** 00110 /// Add an observer to the list. 00111 /// If asserts or exceptions are enabled then an etl::observable_observer_list_full 00112 /// is emitted if the observer list is already full. 00113 ///\param observer A reference to the observer. 00114 //***************************************************************** 00115 void add_observer(TObserver& observer) 00116 { 00117 // See if we already have it in our list. 00118 typename Observer_List::const_iterator i_observer = std::find(observer_list.begin(), 00119 observer_list.end(), 00120 &observer); 00121 00122 // Not there? 00123 if (i_observer == observer_list.end()) 00124 { 00125 // Is there enough room? 00126 ETL_ASSERT(!observer_list.full(), ETL_ERROR(etl::observer_list_full)); 00127 00128 // Add it. 00129 observer_list.push_back(&observer); 00130 } 00131 } 00132 00133 //***************************************************************** 00134 /// Remove a particular observer from the list. 00135 ///\param observer A reference to the observer. 00136 //***************************************************************** 00137 void remove_observer(TObserver& observer) 00138 { 00139 // See if we have it in our list. 00140 typename Observer_List::iterator i_observer = std::find(observer_list.begin(), 00141 observer_list.end(), 00142 &observer); 00143 00144 // Found it? 00145 if (i_observer != observer_list.end()) 00146 { 00147 // Erase it. 00148 observer_list.erase(i_observer); 00149 } 00150 } 00151 00152 //***************************************************************** 00153 /// Clear all observers from the list. 00154 //***************************************************************** 00155 void clear_observers() 00156 { 00157 observer_list.clear(); 00158 } 00159 00160 //***************************************************************** 00161 /// Returns the number of observers. 00162 //***************************************************************** 00163 size_type number_of_observers() const 00164 { 00165 return observer_list.size(); 00166 } 00167 00168 //***************************************************************** 00169 /// Notify all of the observers, sending them the notification. 00170 ///\tparam TNotification the notification type. 00171 ///\param n The notification. 00172 //***************************************************************** 00173 template <typename TNotification> 00174 void notify_observers(TNotification n) 00175 { 00176 for (size_t i = 0; i < observer_list.size(); ++i) 00177 { 00178 observer_list[i]->notification(n); 00179 } 00180 } 00181 00182 private: 00183 00184 /// The list of observers. 00185 Observer_List observer_list; 00186 }; 00187 00188 //********************************************************************* 00189 /// The observer interface for eight notification types. 00190 ///\ingroup observer 00191 //********************************************************************* 00192 template <typename T1, 00193 typename T2 = void, 00194 typename T3 = void, 00195 typename T4 = void, 00196 typename T5 = void, 00197 typename T6 = void, 00198 typename T7 = void, 00199 typename T8 = void> 00200 class observer 00201 { 00202 public: 00203 virtual ~observer() {} 00204 virtual void notification(T1) = 0; 00205 virtual void notification(T2) = 0; 00206 virtual void notification(T3) = 0; 00207 virtual void notification(T4) = 0; 00208 virtual void notification(T5) = 0; 00209 virtual void notification(T6) = 0; 00210 virtual void notification(T7) = 0; 00211 virtual void notification(T8) = 0; 00212 }; 00213 00214 //********************************************************************* 00215 /// The observer interface for seven notification types. 00216 ///\ingroup observer 00217 //********************************************************************* 00218 template <typename T1, 00219 typename T2, 00220 typename T3, 00221 typename T4, 00222 typename T5, 00223 typename T6, 00224 typename T7> 00225 class observer<T1, T2, T3, T4, T5, T6, T7> 00226 { 00227 public: 00228 00229 virtual ~observer() {} 00230 virtual void notification(T1) = 0; 00231 virtual void notification(T2) = 0; 00232 virtual void notification(T3) = 0; 00233 virtual void notification(T4) = 0; 00234 virtual void notification(T5) = 0; 00235 virtual void notification(T6) = 0; 00236 virtual void notification(T7) = 0; 00237 }; 00238 00239 //********************************************************************* 00240 /// The observer interface for six notification types. 00241 ///\ingroup observer 00242 //********************************************************************* 00243 template <typename T1, 00244 typename T2, 00245 typename T3, 00246 typename T4, 00247 typename T5, 00248 typename T6> 00249 class observer<T1, T2, T3, T4, T5, T6> 00250 { 00251 public: 00252 00253 virtual ~observer() {} 00254 virtual void notification(T1) = 0; 00255 virtual void notification(T2) = 0; 00256 virtual void notification(T3) = 0; 00257 virtual void notification(T4) = 0; 00258 virtual void notification(T5) = 0; 00259 virtual void notification(T6) = 0; 00260 }; 00261 00262 //********************************************************************* 00263 /// The observer interface for five notification types. 00264 ///\ingroup observer 00265 //********************************************************************* 00266 template <typename T1, 00267 typename T2, 00268 typename T3, 00269 typename T4, 00270 typename T5> 00271 class observer<T1, T2, T3, T4, T5> 00272 { 00273 public: 00274 00275 virtual ~observer() {} 00276 virtual void notification(T1) = 0; 00277 virtual void notification(T2) = 0; 00278 virtual void notification(T3) = 0; 00279 virtual void notification(T4) = 0; 00280 virtual void notification(T5) = 0; 00281 }; 00282 00283 //********************************************************************* 00284 /// The observer interface for four notification types. 00285 ///\ingroup observer 00286 //********************************************************************* 00287 template <typename T1, 00288 typename T2, 00289 typename T3, 00290 typename T4> 00291 class observer<T1, T2, T3, T4> 00292 { 00293 public: 00294 00295 virtual ~observer() {} 00296 virtual void notification(T1) = 0; 00297 virtual void notification(T2) = 0; 00298 virtual void notification(T3) = 0; 00299 virtual void notification(T4) = 0; 00300 }; 00301 00302 //********************************************************************* 00303 /// The observer interface for three notification types. 00304 ///\ingroup observer 00305 //********************************************************************* 00306 template <typename T1, 00307 typename T2, 00308 typename T3> 00309 class observer<T1, T2, T3> 00310 { 00311 public: 00312 00313 virtual ~observer() {} 00314 virtual void notification(T1) = 0; 00315 virtual void notification(T2) = 0; 00316 virtual void notification(T3) = 0; 00317 }; 00318 00319 //********************************************************************* 00320 /// The observer interface for two notification types. 00321 ///\ingroup observer 00322 //********************************************************************* 00323 template <typename T1, 00324 typename T2> 00325 class observer<T1, T2> 00326 { 00327 public: 00328 00329 virtual ~observer() {} 00330 virtual void notification(T1) = 0; 00331 virtual void notification(T2) = 0; 00332 }; 00333 00334 //********************************************************************* 00335 /// The observer interface for one notification type. 00336 ///\ingroup observer 00337 //********************************************************************* 00338 template <typename T1> 00339 class observer<T1> 00340 { 00341 public: 00342 00343 virtual ~observer() {} 00344 virtual void notification(T1) = 0; 00345 }; 00346 } 00347 00348 #undef ETL_FILE 00349 00350 #endif 00351
Generated on Tue Jul 12 2022 14:05:43 by
