![]() |
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_OBSERVER_HPP 00029 #define WNS_OBSERVER_HPP 00030 00031 #include <WNS/Assure.hpp> 00032 #include <WNS/SubjectInterface.hpp> 00033 #include <WNS/ObserverInterface.hpp> 00034 00035 #include <list> 00036 #include <algorithm> 00037 namespace wns { 00038 00053 template <typename NOTIFICATIONINTERFACE> 00054 class Observer : 00055 virtual public ObserverInterface<NOTIFICATIONINTERFACE> 00056 { 00057 public: 00063 typedef NOTIFICATIONINTERFACE NotificationInterface; 00064 00070 typedef ObserverInterface<NotificationInterface> ObserverType; 00071 00077 typedef SubjectInterface<ObserverType> SubjectType; 00078 00082 Observer() : 00083 subjects() 00084 { 00085 } 00086 00090 Observer(const Observer& other) : 00091 NotificationInterface(other), 00092 ObserverInterface<NOTIFICATIONINTERFACE>(other), 00093 subjects(other.subjects) 00094 { 00095 this->forEachSubject( 00096 std::bind2nd( 00097 std::mem_fun(&SubjectType::addObserver), 00098 this)); 00099 } 00100 00104 Observer& 00105 operator=(const Observer& other) 00106 { 00107 // remove own observers 00108 this->forEachSubject( 00109 std::bind2nd( 00110 std::mem_fun(&SubjectType::removeObserver), 00111 this)); 00112 00113 // copy subjects from other 00114 subjects = other.subjects; 00115 00116 // observe these subjects 00117 this->forEachSubject( 00118 std::bind2nd( 00119 std::mem_fun(&SubjectType::addObserver), 00120 this)); 00121 00122 return *this; 00123 } 00124 00131 virtual 00132 ~Observer() 00133 { 00134 this->forEachSubject( 00135 std::bind2nd( 00136 std::mem_fun(&SubjectType::removeObserver), 00137 this)); 00138 } 00139 00143 void 00144 startObserving(SubjectType* subject) 00145 { 00146 subject->addObserver(this); 00147 this->addSubject(subject); 00148 } 00149 00153 void 00154 stopObserving(SubjectType* subject) 00155 { 00156 subject->removeObserver(this); 00157 this->removeSubject(subject); 00158 } 00159 00160 private: 00167 virtual void 00168 addSubject(SubjectType* subject) 00169 { 00170 assureNotNull(subject); 00171 assure( 00172 find(this->subjects.begin(), this->subjects.end(), subject) == this->subjects.end(), 00173 "Already registered"); 00174 this->subjects.push_back(subject); 00175 } 00176 00180 virtual void 00181 removeSubject(SubjectType* subject) 00182 { 00183 assureNotNull(subject); 00184 assure( 00185 find(this->subjects.begin(), this->subjects.end(), subject) != this->subjects.end(), 00186 "Not registered"); 00187 00188 this->subjects.erase(find(this->subjects.begin(), this->subjects.end(), subject)); 00189 } 00190 00199 template <typename FUNCTOR> 00200 FUNCTOR 00201 forEachSubject(const FUNCTOR& functor) 00202 { 00203 // copy, so the container gets not corrupted during for_each ... 00204 SubjectContainer tmp = this->subjects; 00205 return std::for_each(tmp.begin(), tmp.end(), functor); 00206 } 00207 00208 typedef std::list<SubjectType*> SubjectContainer; 00209 00215 SubjectContainer subjects; 00216 }; 00217 } // wns 00218 00219 #endif
1.5.5