Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members | Related Pages | Examples

psignal.h

Go to the documentation of this file.
00001 /*
00002  *   P::Classes - Portable C++ Application Framework
00003  *   Copyright (C) 2000-2004  Christian Prochnow <cproch@seculogix.de>
00004  *
00005  *   This library is free software; you can redistribute it and/or
00006  *   modify it under the terms of the GNU Lesser General Public
00007  *   License as published by the Free Software Foundation; either
00008  *   version 2 of the License, or (at your option) any later version.
00009  *
00010  *   This library is distributed in the hope that it will be useful,
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *   Lesser General Public License for more details.
00014  *
00015  *   You should have received a copy of the GNU Lesser General Public
00016  *   License along with this library; if not, write to the Free Software
00017  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  */
00019 
00020 #ifndef _psignal_h_
00021 #define _psignal_h_
00022 
00023 #include <pclasses/config.h>
00024 #include <pclasses/pslot.h>
00025 #include <pclasses/plocktraits.h>
00026 #include <list>
00027 
00028 namespace P {
00029 
00031 
00038 template <class _SlotT, class _Mutex>
00039 class SignalBase {
00040   public:
00041     typedef _SlotT                SlotType;
00042     typedef std::list<SlotType*>  SlotList;
00043     typedef LockTraits<_Mutex>    LockTraits;
00044 
00045     typedef typename LockTraits::MutexType  MutexType;
00046     typedef typename LockTraits::ReadLock   ReadLock;
00047     typedef typename LockTraits::WriteLock  WriteLock;
00048 
00049     inline SignalBase()
00050     { }
00051 
00052     inline ~SignalBase()
00053     {
00054       /* delete all bound slots ... */
00055       typename SlotList::iterator i = _slots.begin();
00056       while(i != _slots.end())
00057       {
00058         delete *i;
00059         i = _slots.erase(i);
00060       }
00061     }
00062 
00064     inline void bind(SlotType& slot)
00065     {
00066       WriteLock wl(_mutex);
00067       _slots.push_back(slot.clone());
00068     }
00069 
00071     template <class UnbindSlotType>
00072     inline void unbind(UnbindSlotType& slot)
00073     {
00074       WriteLock wl(_mutex);
00075       typename SlotList::iterator i = _slots.begin();
00076       while(i != _slots.end())
00077       {
00078         UnbindSlotType* s = static_cast<UnbindSlotType*>(*i);
00079         if(s && *s == slot)
00080         {
00081           delete *i;
00082           _slots.erase(i);
00083           return;
00084         }
00085         ++i;
00086       }
00087     }
00088 
00089   protected:
00090 
00092     SlotList slotList()
00093     {
00094       ReadLock rl(_mutex);
00095       return _slots;
00096     }
00097 
00098   private:
00099     SignalBase(const SignalBase&);
00100     SignalBase& operator=(const SignalBase&);
00101 
00102     MutexType  _mutex;
00103     SlotList   _slots;
00104 };
00105 
00106 
00108 
00112 template <class _RetT, class _Mutex = VoidMutex>
00113 class Signal0: public SignalBase<Slot0<_RetT>, _Mutex> {
00114   public:
00115     typedef _RetT RetType;
00116 
00117     typedef SignalBase<
00118       Slot0<_RetT>,
00119       _Mutex
00120     > SignalBase;
00121 
00123     RetType emit()
00124     {
00125       typedef typename SignalBase::SlotList SlotList;
00126       RetType ret = RetType();
00127       SlotList slots = slotList();
00128       for(typename SlotList::const_iterator i = slots.begin(); i != slots.end(); ++i) {
00129         ret = (*i)->proxy();
00130         if(ret)
00131           break;
00132       }
00133       return ret;
00134     }
00135 };
00136 
00137 
00138 #ifdef CXX_PARTIAL_SPECIALIZATION
00139 
00141 
00145 template <class _Mutex>
00146 class Signal0<void, _Mutex>: public SignalBase<Slot0<void>, _Mutex> {
00147   public:
00148     typedef SignalBase<
00149       Slot0<void>,
00150       _Mutex
00151     > SignalBase;
00152 
00154     void emit()
00155     {
00156       typedef typename SignalBase::SlotList SlotList;
00157       SlotList slots = slotList();
00158       for(typename SlotList::const_iterator i = slots.begin(); i != slots.end(); ++i)
00159         (*i)->proxy();
00160     }
00161 };
00162 
00163 #endif
00164 
00165 
00167 
00171 template <class _RetT, class _ParamType1, class _Mutex = VoidMutex>
00172 class Signal1: public SignalBase<Slot1<_RetT, _ParamType1>, _Mutex> {
00173   public:
00174     typedef _RetT RetType;
00175 
00176     typedef SignalBase<
00177       Slot1<_RetT, _ParamType1>,
00178       _Mutex
00179     > SignalBase;
00180 
00182     RetType emit(_ParamType1 p1)
00183     {
00184       typedef typename SignalBase::SlotList SlotList;
00185       RetType ret = RetType();
00186       SlotList slots = slotList();
00187       for(typename SlotList::const_iterator i = slots.begin(); i != slots.end(); ++i)
00188       {
00189         ret = (*i)->proxy(p1);
00190         if(ret)
00191           break;
00192       }
00193       return ret;
00194     }
00195 };
00196 
00197 
00198 #ifdef CXX_PARTIAL_SPECIALIZATION
00199 
00201 
00205 template <class _ParamType1, class _Mutex>
00206 class Signal1<void, _ParamType1, _Mutex>:
00207   public SignalBase<Slot1<void, _ParamType1>, _Mutex>
00208 {
00209   public:
00210     typedef SignalBase<
00211       Slot1<void, _ParamType1>,
00212       _Mutex
00213     > SignalBase;
00214 
00216     void emit(_ParamType1 p1)
00217     {
00218       typedef typename SignalBase::SlotList SlotList;
00219       SlotList slots = slotList();
00220       for(typename SlotList::const_iterator i = slots.begin(); i != slots.end(); ++i)
00221         (*i)->proxy(p1);
00222     }
00223 };
00224 
00225 #endif
00226 
00227 
00229 
00233 template <class _RetT, class _ParamType1, class _ParamType2, class _Mutex = VoidMutex>
00234 class Signal2:
00235   public SignalBase<Slot2<_RetT, _ParamType1, _ParamType2>, _Mutex>
00236 {
00237   public:
00238     typedef _RetT RetType;
00239 
00240     typedef SignalBase<
00241       Slot2<_RetT, _ParamType1, _ParamType2>,
00242       _Mutex
00243     > SignalBase;
00244 
00246     RetType emit(_ParamType1 p1, _ParamType2 p2)
00247     {
00248       typedef typename SignalBase::SlotList SlotList;
00249       RetType ret = RetType();
00250       SlotList slots = slotList();
00251       for(typename SlotList::const_iterator i = slots.begin(); i != slots.end(); ++i)
00252       {
00253         ret = (*i)->proxy(p1,p2);
00254         if(ret)
00255           break;
00256       }
00257       return ret;
00258     }
00259 };
00260 
00261 
00262 #ifdef CXX_PARTIAL_SPECIALIZATION
00263 
00265 
00269 template <class _ParamType1, class _ParamType2, class _Mutex>
00270 class Signal2<void, _ParamType1, _ParamType2, _Mutex>:
00271   public SignalBase<Slot2<void, _ParamType1, _ParamType2>, _Mutex>
00272 {
00273   public:
00274     typedef SignalBase<
00275       Slot2<void, _ParamType1, _ParamType2>,
00276       _Mutex
00277     > SignalBase;
00278 
00280     void emit(_ParamType1 p1, _ParamType2 p2)
00281     {
00282       typedef typename SignalBase::SlotList SlotList;
00283       SlotList slots = slotList();
00284       for(typename SlotList::const_iterator i = slots.begin(); i != slots.end(); ++i)
00285         (*i)->proxy(p1,p2);
00286     }
00287 };
00288 
00289 #endif
00290 
00291 
00293 
00297 template <
00298   class _RetT, class _ParamType1, class _ParamType2,
00299   class _ParamType3, class _Mutex = VoidMutex
00300 >
00301 class Signal3:
00302   public SignalBase<Slot3<_RetT, _ParamType1, _ParamType2, _ParamType3>, _Mutex>
00303 {
00304   public:
00305     typedef _RetT RetType;
00306 
00307     typedef SignalBase<
00308       Slot3<_RetT, _ParamType1, _ParamType2, _ParamType3>,
00309       _Mutex
00310     > SignalBase;
00311 
00313     RetType emit(_ParamType1 p1, _ParamType2 p2, _ParamType3 p3)
00314     {
00315       typedef typename SignalBase::SlotList SlotList;
00316       RetType ret = RetType();
00317       SlotList slots = slotList();
00318       for(typename SlotList::const_iterator i = slots.begin(); i != slots.end(); ++i)
00319       {
00320         ret = (*i)->proxy(p1,p2,p3);
00321         if(ret)
00322           break;
00323       }
00324       return ret;
00325     }
00326 };
00327 
00328 
00329 #ifdef CXX_PARTIAL_SPECIALIZATION
00330 
00332 
00336 template <
00337   class _ParamType1, class _ParamType2,
00338   class _ParamType3, class _Mutex
00339 >
00340 class Signal3<void, _ParamType1, _ParamType2, _ParamType3, _Mutex>:
00341   public SignalBase<Slot3<void, _ParamType1, _ParamType2, _ParamType3>, _Mutex>
00342 {
00343   public:
00344     typedef SignalBase<
00345       Slot3<void, _ParamType1, _ParamType2, _ParamType3>,
00346       _Mutex
00347     > SignalBase;
00348 
00350     void emit(_ParamType1 p1, _ParamType2 p2, _ParamType3 p3)
00351     {
00352       typedef typename SignalBase::SlotList SlotList;
00353       SlotList slots = slotList();
00354       for(typename SlotList::const_iterator i = slots.begin(); i != slots.end(); ++i)
00355         (*i)->proxy(p1,p2);
00356     }
00357 };
00358 
00359 #endif
00360 
00361 
00363 
00367 template <class _SignalT, class _SlotT>
00368 void bind(_SignalT& sig, _SlotT slot)
00369 { sig.bind(slot); }
00370 
00372 
00376 template <class _SignalT, class _SlotT>
00377 void unbind(_SignalT& sig, _SlotT slot)
00378 { sig.unbind(slot); }
00379 
00380 }
00381 
00382 #endif

Generated on Fri Mar 12 21:08:31 2004 for P::Classes by doxygen 1.3.3