Rapicorn - Experimental UI Toolkit - Source Code 10.08.1
rapicornsignaltemplate.hh
Go to the documentation of this file.
00001 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html
00002 
00003 /* this file is used to generate rapicornsignalvariants.hh by mksignals.sh.
00004  * therein, certain phrases like "typename A1, typename A2, typename A3" are
00005  * rewritten into 0, 1, 2, ... 16 argument variants. so make sure all phrases
00006  * involving the signal argument count match those from mksignals.sh.
00007  */
00008 
00009 // === Emission ===
00010 template<class Emitter, typename R0, typename A1, typename A2, typename A3>
00011 struct Emission3 : public EmissionBase {
00012   typedef Trampoline3<R0, A1, A2, A3>           Trampoline;
00013   typedef Trampoline4<R0, Emitter&, A1, A2, A3> TrampolineE;
00014   Emitter *m_emitter;
00015   R0 m_result; A1 m_a1; A2 m_a2; A3 m_a3;
00016   TrampolineLink *m_last_link;
00017   Emission3 (Emitter *emitter, A1 a1, A2 a2, A3 a3) :
00018     m_emitter (emitter), m_result(), m_a1 (a1), m_a2 (a2), m_a3 (a3), m_last_link (NULL)
00019   {}
00020   /* call Trampoline and store result, so trampoline templates need no <void> specialization */
00021   R0 call (TrampolineLink *link)
00022   {
00023     if (m_last_link != link)
00024       {
00025         if (link->with_emitter())
00026           {
00027             TrampolineE *trampoline = trampoline_cast<TrampolineE*> (link);
00028             if (trampoline->callable())
00029               m_result = (*trampoline) (*m_emitter, m_a1, m_a2, m_a3);
00030           }
00031         else
00032           {
00033             Trampoline *trampoline = trampoline_cast<Trampoline*> (link);
00034             if (trampoline->callable())
00035               m_result = (*trampoline) (m_a1, m_a2, m_a3);
00036           }
00037         m_last_link = link;
00038       }
00039     return m_result;
00040   }
00041 };
00042 template<class Emitter, typename A1, typename A2, typename A3>
00043 struct Emission3 <Emitter, void, A1, A2, A3> : public EmissionBase {
00044   typedef Trampoline3<void, A1, A2, A3>           Trampoline;
00045   typedef Trampoline4<void, Emitter&, A1, A2, A3> TrampolineE;
00046   Emitter *m_emitter;
00047   A1 m_a1; A2 m_a2; A3 m_a3;
00048   Emission3 (Emitter *emitter, A1 a1, A2 a2, A3 a3) :
00049     m_emitter (emitter), m_a1 (a1), m_a2 (a2), m_a3 (a3)
00050   {}
00051   /* call the trampoline and ignore result, so trampoline templates need no <void> specialization */
00052   void call (TrampolineLink *link)
00053   {
00054     if (link->with_emitter())
00055       {
00056         TrampolineE *trampoline = trampoline_cast<TrampolineE*> (link);
00057         if (trampoline->callable())
00058           (*trampoline) (*m_emitter, m_a1, m_a2, m_a3);
00059       }
00060     else
00061       {
00062         Trampoline *trampoline = trampoline_cast<Trampoline*> (link);
00063         if (trampoline->callable())
00064           (*trampoline) (m_a1, m_a2, m_a3);
00065       }
00066   }
00067 };
00068 
00069 // === SignalEmittable3 ===
00070 template<class Emitter, typename R0, typename A1, typename A2, typename A3, class Collector, class Ancestor>
00071 struct SignalEmittable3 : public Ancestor {
00072   typedef Emission3 <Emitter, R0, A1, A2, A3> Emission;
00073   typedef typename Collector::result_type     Result;
00074   struct Iterator : public SignalBase::Iterator<Emission> {
00075     Iterator (Emission &emission, TrampolineLink *link) : SignalBase::Iterator<Emission> (emission, link) {}
00076     R0 operator* () { return this->emission.call (this->current); }
00077   };
00078   explicit SignalEmittable3 (Emitter *emitter) : m_emitter (emitter) {}
00079   inline Result emit (A1 a1, A2 a2, A3 a3)
00080   {
00081     ScopeReference<Emitter, Collector> lref (*m_emitter);
00082     Emission emission (m_emitter, a1, a2, a3);
00083     Iterator it (emission, Ancestor::start_link()), last (emission, Ancestor::start_link());
00084     ++it; /* walk from start to first */
00085     Collector collector;
00086     return collector (it, last); // Result may be void
00087   }
00088   inline Emitter* emitter () const { return m_emitter; }
00089 private:
00090   Emitter *m_emitter;
00091 };
00092 
00093 // === Signal3 ===
00094 template<class Emitter, typename R0, typename A1, typename A2, typename A3,
00095          class Collector = CollectorDefault<R0>, class Ancestor  = SignalBase>
00096 struct Signal3 : SignalEmittable3<Emitter, R0, A1, A2, A3, Collector, Ancestor>
00097 {
00098   typedef Emission3 <Emitter, R0, A1, A2, A3>                             Emission;
00099   typedef Slot3 <R0, A1, A2, A3>                                          Slot;
00100   typedef Slot4 <R0, Emitter&, A1, A2, A3>                                SlotE;
00101   typedef SignalEmittable3 <Emitter, R0, A1, A2, A3, Collector, Ancestor> SignalEmittable;
00102   explicit Signal3 (Emitter &emitter) :
00103     SignalEmittable (&emitter)
00104   { RAPICORN_ASSERT (&emitter != NULL); }
00105   explicit Signal3 (Emitter &emitter, R0 (Emitter::*method) (A1, A2, A3)) :
00106     SignalEmittable (&emitter)
00107   {
00108     RAPICORN_ASSERT (&emitter != NULL);
00109     connect (slot (emitter, method));
00110   }
00111   inline ConId connect   (const Slot  &s) { return connect_link (s.get_trampoline_link()); }
00112   inline ConId connect   (const SlotE &s) { return connect_link (s.get_trampoline_link(), true); }
00113   inline uint disconnect (const Slot  &s) { return disconnect_equal_link (*s.get_trampoline_link()); }
00114   inline uint disconnect (const SlotE &s) { return disconnect_equal_link (*s.get_trampoline_link(), true); }
00115   inline uint disconnect (ConId    conid) { return this->disconnect_link_id (conid); }
00116   Signal3&    operator+= (const Slot  &s) { connect (s); return *this; }
00117   Signal3&    operator+= (const SlotE &s) { connect (s); return *this; }
00118   Signal3&    operator+= (R0 (*callback) (A1, A2, A3))            { connect (slot (callback)); return *this; }
00119   Signal3&    operator+= (R0 (*callback) (Emitter&, A1, A2, A3))  { connect (slot (callback)); return *this; }
00120   Signal3&    operator-= (const Slot  &s) { disconnect (s); return *this; }
00121   Signal3&    operator-= (const SlotE &s) { disconnect (s); return *this; }
00122   Signal3&    operator-= (R0 (*callback) (A1, A2, A3))            { disconnect (slot (callback)); return *this; }
00123   Signal3&    operator-= (R0 (*callback) (Emitter&, A1, A2, A3))  { disconnect (slot (callback)); return *this; }
00124 };
00125 
00126 // === Signal<> ===
00127 template<class Emitter, typename R0, typename A1, typename A2, typename A3, class Collector, class Ancestor>
00128 class Signal<Emitter, R0 (A1, A2, A3), Collector, Ancestor> : public Signal3<Emitter, R0, A1, A2, A3, Collector, Ancestor>
00129 {
00130   typedef Signal3<Emitter, R0, A1, A2, A3, Collector, Ancestor> SignalVariant;
00131 public:
00132   explicit Signal (Emitter &emitter) : SignalVariant (emitter) {}
00133   explicit Signal (Emitter &emitter, R0 (Emitter::*method) (A1, A2, A3)) : SignalVariant (emitter, method) {}
00134 };
00135 
00136 // === SignalProxy ===
00137 template<class Emitter, typename R0, typename A1, typename A2, typename A3>
00138 struct SignalProxy<Emitter, R0 (A1, A2, A3)> : SignalProxyBase {
00139   typedef Slot3 <R0, A1, A2, A3>           Slot;
00140   typedef Slot4 <R0, Emitter&, A1, A2, A3> SlotE;
00141   inline ConId connect    (const Slot  &s) { return connect_link (s.get_trampoline_link()); }
00142   inline ConId connect    (const SlotE &s) { return connect_link (s.get_trampoline_link(), true); }
00143   inline uint  disconnect (const Slot  &s) { return disconnect_equal_link (*s.get_trampoline_link()); }
00144   inline uint  disconnect (const SlotE &s) { return disconnect_equal_link (*s.get_trampoline_link(), true); }
00145   inline uint  disconnect (ConId    conid) { return this->disconnect_link_id (conid); }
00146   SignalProxy& operator+= (const Slot  &s) { connect (s); return *this; }
00147   SignalProxy& operator+= (const SlotE &s) { connect (s); return *this; }
00148   SignalProxy& operator+= (R0 (*callback) (A1, A2, A3))           { connect (slot (callback)); return *this; }
00149   SignalProxy& operator+= (R0 (*callback) (Emitter&, A1, A2, A3)) { connect (slot (callback)); return *this; }
00150   SignalProxy& operator-= (const Slot  &s)                        { disconnect (s); return *this; }
00151   SignalProxy& operator-= (const SlotE &s)                        { disconnect (s); return *this; }
00152   SignalProxy& operator-= (R0 (*callback) (A1, A2, A3))           { disconnect (slot (callback)); return *this; }
00153   SignalProxy& operator-= (R0 (*callback) (Emitter&, A1, A2, A3)) { disconnect (slot (callback)); return *this; }
00154   template<class Collector, class Ancestor>
00155   SignalProxy (Signal<Emitter, R0 (A1, A2, A3), Collector, Ancestor> &sig) : SignalProxyBase (sig) {}
00156   SignalProxy (const SignalProxy &other) : SignalProxyBase (other) {}
00157 };
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines