00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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* ) { 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 }
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