User Manual, Developers Guide and API Documentation

Subject.hpp

Go to the documentation of this file.
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

Generated on Sat May 26 03:31:53 2012 for openWNS by  doxygen 1.5.5