signal.cc

Go to the documentation of this file.
00001 
00003 
00004 //
00005 // Copyright (c) 1999-2004 California Institute of Technology
00006 // Copyright (c) 2004-2007 University of Southern California
00007 // Rob Peters <rjpeters at usc dot edu>
00008 //
00009 // created: Tue May 25 18:39:27 1999
00010 // commit: $Id: signal.cc 10065 2007-04-12 05:54:56Z rjpeters $
00011 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/nub/signal.cc $
00012 //
00013 // --------------------------------------------------------------------
00014 //
00015 // This file is part of GroovX.
00016 //   [http://ilab.usc.edu/rjpeters/groovx/]
00017 //
00018 // GroovX is free software; you can redistribute it and/or modify it
00019 // under the terms of the GNU General Public License as published by
00020 // the Free Software Foundation; either version 2 of the License, or
00021 // (at your option) any later version.
00022 //
00023 // GroovX is distributed in the hope that it will be useful, but
00024 // WITHOUT ANY WARRANTY; without even the implied warranty of
00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026 // General Public License for more details.
00027 //
00028 // You should have received a copy of the GNU General Public License
00029 // along with GroovX; if not, write to the Free Software Foundation,
00030 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00031 //
00033 
00034 #ifndef GROOVX_NUB_SIGNAL_CC_UTC20050626084019_DEFINED
00035 #define GROOVX_NUB_SIGNAL_CC_UTC20050626084019_DEFINED
00036 
00037 #include "signal.h"
00038 
00039 #include "nub/ref.h"
00040 
00041 #include "rutz/demangle.h"
00042 
00043 #include <list>
00044 #include <typeinfo>
00045 
00046 #include "rutz/trace.h"
00047 #include "rutz/debug.h"
00048 GVX_DBG_REGISTER
00049 
00051 //
00052 // slot_base members
00053 //
00055 
00056 nub::slot_base::slot_base()
00057 {
00058 GVX_TRACE("nub::slot_base::slot_base");
00059 }
00060 
00061 nub::slot_base::~slot_base() throw()
00062 {
00063 GVX_TRACE("nub::slot_base::~slot_base");
00064 }
00065 
00066 bool nub::slot_base::exists() const
00067 {
00068 GVX_TRACE("nub::slot_base::exists");
00069   return true;
00070 }
00071 
00073 //
00074 // slot0 members
00075 //
00077 
00078 nub::slot0::slot0()
00079 {
00080 GVX_TRACE("nub::slot0::slot0");
00081 }
00082 
00083 nub::slot0::~slot0() throw()
00084 {
00085 GVX_TRACE("nub::slot0::~slot0");
00086 }
00087 
00088 nub::soft_ref<nub::slot0> nub::slot0::make(void (*free_func)())
00089 {
00090 GVX_TRACE("nub::slot0::make");
00091 
00092   return nub::soft_ref<slot0>(slot_adapter_free_func0::make(free_func));
00093 }
00094 
00095 nub::slot_adapter_free_func0::slot_adapter_free_func0(free_func* f)
00096   : m_free_func(f)
00097 {}
00098 
00099 nub::slot_adapter_free_func0::~slot_adapter_free_func0() throw() {}
00100 
00101 nub::slot_adapter_free_func0*
00102 nub::slot_adapter_free_func0::make(free_func* f)
00103 {
00104   return new slot_adapter_free_func0(f);
00105 }
00106 
00107 void nub::slot_adapter_free_func0::call()
00108 {
00109   (*m_free_func)();
00110 }
00111 
00113 //
00114 // signal_base::impl class
00115 //
00117 
00118 namespace
00119 {
00120   typedef nub::ref<nub::slot_base> slot_ref;
00121 }
00122 
00123 struct nub::signal_base::impl
00124 {
00125 public:
00126   impl() :
00127     slots(),
00128     is_emitting(false)
00129   {}
00130 
00131   virtual ~impl() {}
00132 
00133   typedef std::list<slot_ref> list_type;
00134 
00135   list_type slots;
00136   bool is_emitting;
00137 
00138   class locker
00139   {
00140     locker(const locker&);
00141     locker& operator=(const locker&);
00142 
00143     impl* m_target;
00144 
00145   public:
00146     locker(impl* impl) :
00147       m_target(impl)
00148     {
00149       GVX_ASSERT(m_target->is_emitting == false);
00150       m_target->is_emitting = true;
00151     }
00152 
00153     ~locker()
00154     {
00155       GVX_ASSERT(m_target->is_emitting == true);
00156       m_target->is_emitting = false;
00157     }
00158   };
00159 };
00160 
00161 nub::signal_base::signal_base() :
00162   nub::volatile_object(),
00163   rep(new impl)
00164 {}
00165 
00166 nub::signal_base::~signal_base() throw()
00167 {
00168   delete rep;
00169 }
00170 
00171 void nub::signal_base::do_emit(void* params) const
00172 {
00173 GVX_TRACE("nub::signal_base::do_emit");
00174   if (!rep->is_emitting)
00175     {
00176       impl::locker lock(rep);
00177 
00178       for (impl::list_type::iterator
00179              ii = rep->slots.begin(), end = rep->slots.end();
00180            ii != end;
00181            /* incr in loop */)
00182         {
00183           dbg_eval(3, typeid(**ii).name());
00184           dbg_eval_nl(3, (*ii)->dbg_ref_count());
00185           dbg_eval_nl(3, (*ii)->exists());
00186           if ((*ii)->exists())
00187             {
00188               (*ii)->do_call(params);
00189               ++ii;
00190             }
00191           else
00192             {
00193               impl::list_type::iterator erase_me = ii;
00194               ++ii;
00195               rep->slots.erase(erase_me);
00196             }
00197         }
00198     }
00199 }
00200 
00201 void nub::signal_base::do_disconnect(nub::soft_ref<nub::slot_base> slot)
00202 {
00203 GVX_TRACE("nub::signal_base::do_disconnect");
00204   if (!slot.is_valid()) return;
00205 
00206   rep->slots.remove(slot_ref(slot.get(), nub::PRIVATE));
00207 
00208   dbg_eval_nl(3, rep->slots.size());
00209 }
00210 
00211 void nub::signal_base::do_connect(nub::soft_ref<nub::slot_base> slot)
00212 {
00213 GVX_TRACE("nub::signal_base::do_connect");
00214   if (!slot.is_valid()) return;
00215 
00216   rep->slots.push_back(slot_ref(slot.get(), nub::PRIVATE));
00217 
00218   dbg_eval_nl(3, rep->slots.size());
00219 }
00220 
00222 //
00223 // signal0 method definitions
00224 //
00226 
00227 nub::signal0::signal0() :
00228   signal_base(),
00229   slot_emit_self(slot0::make(this, &nub::signal0::emit))
00230 {
00231 GVX_TRACE("nub::signal0::signal0");
00232 }
00233 
00234 nub::signal0::~signal0() throw()
00235 {
00236 GVX_TRACE("nub::signal0::~signal0");
00237 }
00238 
00239 static const char __attribute__((used)) vcid_groovx_nub_signal_cc_utc20050626084019[] = "$Id: signal.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00240 #endif // !GROOVX_NUB_SIGNAL_CC_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.