![]() |
User Manual, Developers Guide and API Documentation |
![]() |
00001 /******************************************************************************* 00002 * This file is part of openWNS (open Wireless Network Simulator) 00003 * _____________________________________________________________________________ 00004 * 00005 * Copyright (C) 2004-2007 00006 * Chair of Communication Networks (ComNets) 00007 * Kopernikusstr. 16, D-52074 Aachen, Germany 00008 * phone: ++49-241-80-27910, 00009 * fax: ++49-241-80-22242 00010 * email: info@openwns.org 00011 * www: http://www.openwns.org 00012 * _____________________________________________________________________________ 00013 * 00014 * openWNS is free software; you can redistribute it and/or modify it under the 00015 * terms of the GNU Lesser General Public License version 2 as published by the 00016 * Free Software Foundation; 00017 * 00018 * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY 00019 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00020 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00021 * details. 00022 * 00023 * You should have received a copy of the GNU Lesser General Public License 00024 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00025 * 00026 ******************************************************************************/ 00027 00028 #ifndef WNS_SUBJECT_HPP 00029 #define WNS_SUBJECT_HPP 00030 00031 #include <WNS/Assure.hpp> 00032 #include <WNS/ObserverInterface.hpp> 00033 #include <WNS/SubjectInterface.hpp> 00034 #include <WNS/IOutputStreamable.hpp> 00035 00036 #include <functional> 00037 #include <list> 00038 #include <algorithm> 00039 00040 namespace wns { 00041 00067 template <typename NOTIFICATIONINTERFACE> 00068 class Subject : 00069 public virtual SubjectInterface<ObserverInterface<NOTIFICATIONINTERFACE> > 00070 { 00071 public: 00077 typedef NOTIFICATIONINTERFACE NotificationInterface; 00078 00084 typedef ObserverInterface<NotificationInterface> ObserverType; 00085 00091 typedef SubjectInterface<ObserverType> SubjectType; 00092 00096 Subject() : 00097 observers(), 00098 modificationGuard_(false) 00099 { 00100 } 00101 00105 Subject(const Subject& other) : 00106 SubjectInterface< ObserverInterface<NOTIFICATIONINTERFACE> >(other), 00107 observers(other.observers), 00108 modificationGuard_(other.modificationGuard_) 00109 { 00110 this->forEachObserver( 00111 std::bind2nd( 00112 std::mem_fun(&ObserverType::addSubject), 00113 this)); 00114 } 00115 00119 Subject& 00120 operator=(const Subject& other) 00121 { 00122 // remove own observers 00123 this->forEachObserver( 00124 std::bind2nd( 00125 std::mem_fun( 00126 &ObserverType::removeSubject), 00127 this)); 00128 00129 // copy subjects from other 00130 observers = other.observers; 00131 00132 // observe these subjects 00133 this->forEachObserver( 00134 std::bind2nd( 00135 std::mem_fun(&ObserverType::addSubject), 00136 this)); 00137 00138 return *this; 00139 } 00140 00147 virtual 00148 ~Subject() 00149 { 00150 this->forEachObserver( 00151 std::bind2nd( 00152 std::mem_fun( 00153 &ObserverType::removeSubject), 00154 this)); 00155 } 00156 00166 template <typename NOTIFICATIONFUNCTIONPTR> 00167 void 00168 sendNotifies(const NOTIFICATIONFUNCTIONPTR notificationFunctionPtr) 00169 { 00170 this->forEachObserver(std::mem_fun(notificationFunctionPtr)); 00171 } 00172 00185 template <typename NOTIFICATIONFUNCTIONPTR, typename ARG> 00186 void 00187 sendNotifies(const NOTIFICATIONFUNCTIONPTR notificationFunctionPtr, const ARG& arg) 00188 { 00189 this->forEachObserver(std::bind2nd(std::mem_fun(notificationFunctionPtr), arg)); 00190 } 00191 00200 template <typename FUNCTOR> 00201 FUNCTOR 00202 forEachObserver(const FUNCTOR& functor) 00203 { 00204 ObserverContainer tmp = this->observers; 00205 return std::for_each(tmp.begin(), 00206 tmp.end(), 00207 functor); 00208 } 00209 00222 template <typename FUNCTOR> 00223 FUNCTOR 00224 forEachObserverNoDetachAllowed(const FUNCTOR& functor) 00225 { 00226 this->modificationGuard_ = true; 00227 FUNCTOR f = std::for_each(this->observers.begin(), 00228 this->observers.end(), 00229 functor); 00230 this->modificationGuard_ = false; 00231 return f; 00232 } 00233 00234 bool 00235 hasObservers() const 00236 { 00237 return !observers.empty(); 00238 } 00239 00240 protected: 00242 typedef std::list<ObserverType*> ObserverContainer; 00243 00244 private: 00252 virtual void 00253 addObserver(ObserverType* observer) 00254 { 00255 if (this->modificationGuard_ == true) 00256 { 00257 throw wns::Exception("Tried to modify observer list even though in protected operation"); 00258 } 00259 assureNotNull(observer); 00260 assure( 00261 find(this->observers.begin(), this->observers.end(), observer) == this->observers.end(), 00262 "Already registered"); 00263 this->observers.push_back(observer); 00264 } 00265 00269 virtual void 00270 removeObserver(ObserverType* observer) 00271 { 00272 if (this->modificationGuard_ == true) 00273 { 00274 throw wns::Exception("Tried to modify observer list even though in protected operation"); 00275 } 00276 assureNotNull(observer); 00277 assure( 00278 find(this->observers.begin(), this->observers.end(), observer) != this->observers.end(), 00279 "Not registered"); 00280 00281 this->observers.erase(find(this->observers.begin(), this->observers.end(), observer)); 00282 } 00283 00284 00290 ObserverContainer observers; 00291 bool modificationGuard_; 00292 }; 00293 } 00294 00295 #endif // NOT defined WNS_SUBJECT_HPP
1.5.5