signal.h

Go to the documentation of this file.
00001 
00004 
00005 //
00006 // Copyright (c) 1999-2004 California Institute of Technology
00007 // Copyright (c) 2004-2007 University of Southern California
00008 // Rob Peters <rjpeters at usc dot edu>
00009 //
00010 // created: Tue May 25 18:29:04 1999
00011 // commit: $Id: signal.h 10065 2007-04-12 05:54:56Z rjpeters $
00012 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/nub/signal.h $
00013 //
00014 // --------------------------------------------------------------------
00015 //
00016 // This file is part of GroovX.
00017 //   [http://ilab.usc.edu/rjpeters/groovx/]
00018 //
00019 // GroovX is free software; you can redistribute it and/or modify it
00020 // under the terms of the GNU General Public License as published by
00021 // the Free Software Foundation; either version 2 of the License, or
00022 // (at your option) any later version.
00023 //
00024 // GroovX is distributed in the hope that it will be useful, but
00025 // WITHOUT ANY WARRANTY; without even the implied warranty of
00026 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00027 // General Public License for more details.
00028 //
00029 // You should have received a copy of the GNU General Public License
00030 // along with GroovX; if not, write to the Free Software Foundation,
00031 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00032 //
00034 
00035 #ifndef GROOVX_NUB_SIGNAL_H_UTC20050626084019_DEFINED
00036 #define GROOVX_NUB_SIGNAL_H_UTC20050626084019_DEFINED
00037 
00038 #include "nub/object.h"
00039 #include "nub/ref.h"
00040 #include "nub/volatileobject.h"
00041 
00042 namespace nub
00043 {
00044 #if 0
00045   template <class R>
00046   class marshal
00047   {
00048     R val;
00049 
00050   public:
00051     marshal() : val() {}
00052 
00053     typedef R in_type;
00054     typedef R out_type;
00055 
00056     bool marshal(const in_type& in)
00057     {
00058       val = in;
00059     }
00060 
00061     out_type value() const { return val; }
00062   };
00063 #endif
00064 
00065   //  #######################################################
00066   //  =======================================================
00067 
00069 
00074   class slot_base : public virtual nub::object
00075   {
00076   public:
00078     slot_base();
00079 
00081     virtual ~slot_base() throw();
00082 
00084 
00087     virtual bool exists() const;
00088 
00090     virtual void do_call(void* params) = 0;
00091   };
00092 
00093   //  #######################################################
00094   //  =======================================================
00095 
00097 
00098   class slot0 : public slot_base
00099   {
00100   public:
00102     slot0();
00103 
00105     virtual ~slot0() throw();
00106 
00107     template <class C, class MF>
00108     static nub::soft_ref<slot0> make(C* obj, MF mf);
00109 
00110     static nub::soft_ref<slot0> make(void (*free_func)());
00111 
00112     virtual void call() = 0;
00113 
00115     virtual void do_call(void* /*params*/) { call(); }
00116   };
00117 
00118 
00119   //  #######################################################
00120   //  =======================================================
00121 
00123 
00124   template <class C, class MF>
00125   class slot_adapter_mem_func0 : public slot0
00126   {
00127     nub::soft_ref<C> m_object;
00128     MF m_mem_func;
00129 
00130     slot_adapter_mem_func0(C* obj, MF mf) :
00131       m_object(obj, nub::WEAK, nub::PRIVATE), m_mem_func(mf) {}
00132 
00133     virtual ~slot_adapter_mem_func0() throw() {}
00134 
00135   public:
00136     static slot_adapter_mem_func0<C, MF>* make(C* obj, MF mf)
00137     { return new slot_adapter_mem_func0<C, MF>(obj, mf); }
00138 
00139     virtual bool exists() const { return m_object.is_valid(); }
00140 
00141     virtual void call()
00142     {
00143       if (m_object.is_valid())
00144         (m_object.get()->*m_mem_func)();
00145     }
00146   };
00147 
00148   template <class C, class MF>
00149   inline nub::soft_ref<slot0> slot0::make(C* obj, MF mf)
00150   {
00151     return nub::soft_ref<slot0>
00152       (slot_adapter_mem_func0<C, MF>::make(obj, mf),
00153        nub::STRONG,
00154        nub::PRIVATE);
00155   }
00156 
00157   //  #######################################################
00158   //  =======================================================
00159 
00161 
00162   class slot_adapter_free_func0 : public slot0
00163   {
00164   public:
00165     typedef void (free_func)();
00166 
00167   private:
00168     free_func* m_free_func;
00169 
00170     slot_adapter_free_func0(free_func* f);
00171 
00172     virtual ~slot_adapter_free_func0() throw();
00173 
00174   public:
00175     static slot_adapter_free_func0* make(free_func* f);
00176 
00177     virtual void call();
00178   };
00179 
00180   //  #######################################################
00181   //  =======================================================
00182 
00184 
00185   template <class P1>
00186   struct call_data1
00187   {
00188     call_data1(P1 i1) : p1(i1) {}
00189     P1 p1;
00190   };
00191 
00192   //  #######################################################
00193   //  =======================================================
00194 
00196 
00197   template <class P1>
00198   class slot1 : public slot_base
00199   {
00200   public:
00202     slot1() {}
00203 
00205     virtual ~slot1() throw() {}
00206 
00207     template <class C, class MF>
00208     static nub::soft_ref<slot1<P1> > make(C* obj, MF mf);
00209 
00210     template <class FF>
00211     static nub::soft_ref<slot1<P1> > make(FF f);
00212 
00213     virtual void call(P1 p1) = 0;
00214 
00216     virtual void do_call(void* params)
00217     {
00218       call_data1<P1>* data = static_cast<call_data1<P1>*>(params);
00219       call(data->p1);
00220     }
00221   };
00222 
00223   //  #######################################################
00224   //  =======================================================
00225 
00227 
00228   template <class P1, class C, class MF>
00229   class slot_adapter_mem_func1 : public slot1<P1>
00230   {
00231     nub::soft_ref<C> m_object;
00232     MF m_mem_func;
00233 
00234     slot_adapter_mem_func1(C* obj, MF mf) :
00235       m_object(obj, nub::WEAK, nub::PRIVATE), m_mem_func(mf) {}
00236 
00237     virtual ~slot_adapter_mem_func1() throw() {}
00238 
00239   public:
00240     static slot_adapter_mem_func1<P1, C, MF>* make(C* obj, MF mf)
00241     { return new slot_adapter_mem_func1<P1, C, MF>(obj, mf); }
00242 
00243     virtual bool exists() const { return m_object.is_valid(); }
00244 
00245     virtual void call(P1 p1)
00246     {
00247       if (m_object.is_valid())
00248         (m_object.get()->*m_mem_func)(p1);
00249     }
00250   };
00251 
00252   template <class P1>
00253   template <class C, class MF>
00254   inline nub::soft_ref<slot1<P1> > slot1<P1>::make(C* obj, MF mf)
00255   {
00256     return nub::soft_ref<slot1<P1> >
00257       (slot_adapter_mem_func1<P1, C, MF>::make(obj, mf),
00258        nub::STRONG,
00259        nub::PRIVATE);
00260   }
00261 
00262 
00263   //  #######################################################
00264   //  =======================================================
00265 
00267 
00268   template <class P1, class FF>
00269   class slot_adapter_free_func1 : public slot1<P1>
00270   {
00271     FF m_free_func;
00272 
00273     slot_adapter_free_func1(FF f) : m_free_func(f) {}
00274 
00275     virtual ~slot_adapter_free_func1() throw() {}
00276 
00277   public:
00278     static slot_adapter_free_func1<P1, FF>* make(FF f)
00279     { return new slot_adapter_free_func1<P1, FF>(f); }
00280 
00281     virtual void call(P1 p1)
00282     {
00283       (*m_free_func)(p1);
00284     }
00285   };
00286 
00287   template <class P1>
00288   template <class FF>
00289   inline nub::soft_ref<slot1<P1> > slot1<P1>::make(FF f)
00290   {
00291     return nub::soft_ref<slot1<P1> >
00292       (slot_adapter_free_func1<P1, FF>::make(f),
00293        nub::STRONG,
00294        nub::PRIVATE);
00295   }
00296 
00297 
00298   //  #######################################################
00299   //  =======================================================
00300 
00302 
00309   class signal_base : public nub::volatile_object
00310   {
00311   protected:
00312     signal_base();
00313     virtual ~signal_base() throw();
00314 
00315     void do_emit(void* params) const;
00316 
00318     void do_connect(nub::soft_ref<slot_base> slot);
00319 
00321     void do_disconnect(nub::soft_ref<slot_base> slot);
00322 
00323   private:
00324     signal_base(const signal_base&);
00325     signal_base& operator=(const signal_base&);
00326 
00327     class impl;
00328     impl* rep;
00329   };
00330 
00331 
00332   //  #######################################################
00333   //  =======================================================
00334 
00336 
00337   class signal0 : public signal_base
00338   {
00339   public:
00341     signal0();
00342 
00344     virtual ~signal0() throw();
00345 
00347     nub::soft_ref<slot0> connect(nub::soft_ref<slot0> slot)
00348     { signal_base::do_connect(slot); return slot; }
00349 
00351     nub::soft_ref<slot0> connect(void (*free_func)())
00352     { return connect(slot0::make(free_func)); }
00353 
00355 
00358     template <class C, class MF>
00359     nub::soft_ref<slot0> connect(C* obj, MF mem_func)
00360     { return connect(slot0::make(obj, mem_func)); }
00361 
00363     void disconnect(nub::soft_ref<slot0> slot)
00364     { signal_base::do_disconnect(slot); }
00365 
00367     void emit() const { signal_base::do_emit(static_cast<void*>(0)); }
00368 
00370     nub::soft_ref<slot0> slot() const { return slot_emit_self; }
00371 
00372   private:
00373     signal0(const signal0&);
00374     signal0& operator=(const signal0&);
00375 
00376     nub::ref<nub::slot0> slot_emit_self;
00377   };
00378 
00379 
00380   //  #######################################################
00381   //  =======================================================
00382 
00384 
00385   template <class P1>
00386   class Signal1 : public signal_base
00387   {
00388   public:
00389     Signal1() {}
00390 
00391     virtual ~Signal1() throw() {}
00392 
00393     nub::soft_ref<slot1<P1> > connect(nub::soft_ref<slot1<P1> > slot)
00394     { signal_base::do_connect(slot); return slot; }
00395 
00396     nub::soft_ref<slot1<P1> > connect(void (*free_func)(P1))
00397     { return connect(slot1<P1>::make(free_func)); }
00398 
00399     template <class C, class MF>
00400     nub::soft_ref<slot1<P1> > connect(C* obj, MF mem_func)
00401     { return connect(slot1<P1>::make(obj, mem_func)); }
00402 
00403     void disconnect(nub::soft_ref<slot1<P1> > slot)
00404     { signal_base::do_disconnect(slot); }
00405 
00406     void emit(P1 p1) const
00407     {
00408       call_data1<P1> dat( p1 );
00409       signal_base::do_emit(static_cast<void*>(&dat));
00410     }
00411 
00412   private:
00413     Signal1(const Signal1&);
00414     Signal1& operator=(const Signal1&);
00415   };
00416 
00417 } // end namespace nub
00418 
00419 static const char __attribute__((used)) vcid_groovx_nub_signal_h_utc20050626084019[] = "$Id: signal.h 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00420 #endif // !GROOVX_NUB_SIGNAL_H_UTC20050626084019_DEFINED

The software described here is Copyright (c) 1998-2005, Rob Peters.
This page was generated Wed Dec 3 06:49:40 2008 by Doxygen version 1.5.5.