00001
00002
00003
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 #ifndef MORE_GEN_MULTICLOSURE_H
00032 #define MORE_GEN_MULTICLOSURE_H
00033
00034 #include <list>
00035 #include <more/gen/closure.h>
00036 #include <more/gen/utility.h>
00037
00038 namespace more {
00039 namespace gen {
00040
00041
00042
00043
00044 template< typename R,
00045 template<typename> class Container=std::list >
00046 struct generator_multiclosure
00047 : Container< generator_closure<R> >
00048 {
00049 typedef typename Container< generator_closure<R> >::iterator iterator;
00050 void operator()()
00051 {
00052 for (iterator it = begin(); it != end(); ++it) (*it)();
00053 }
00054 };
00055
00056 template< typename A1, typename R,
00057 template<typename> class Container=std::list >
00058 struct unary_multiclosure
00059 : Container< unary_closure<A1, R> >
00060 {
00061 typedef typename Container< unary_closure<A1, R> >::iterator iterator;
00062 void operator()(A1 x1)
00063 {
00064 for (iterator it = begin(); it != end(); ++it) (*it)(x1);
00065 }
00066 };
00067
00068 template< typename A1, typename A2, typename R,
00069 template<typename> class Container=std::list >
00070 struct binary_multiclosure
00071 : Container< binary_closure<A1, A2, R> >
00072 {
00073 typedef typename Container< binary_closure<A1, A2, R> >::iterator
00074 iterator;
00075 void operator()(A1 x1, A2 x2)
00076 {
00077 for(iterator it = begin(); it != end(); ++it) (*it)(x1, x2);
00078 }
00079 };
00080
00081 template< typename A1, typename A2, typename A3, typename R,
00082 template<typename> class Container=std::list >
00083 struct ternary_multiclosure
00084 : Container< ternary_closure<A1, A2, A3, R> >
00085 {
00086 typedef typename Container< ternary_closure<A1, A2, A3, R> >::iterator
00087 iterator;
00088 void operator()(A1 x1, A2 x2, A3 x3)
00089 {
00090 for(iterator it = begin(); it != end(); ++it) (*it)(x1, x2, x3);
00091 }
00092 };
00093
00094
00095
00096
00097
00098
00099 namespace bits {
00100
00101 struct connection_base : handle_data
00102 {
00103 virtual void enable() = 0;
00104 virtual void disable() = 0;
00105 virtual bool is_enabled() const = 0;
00106 virtual ~connection_base() {};
00107 };
00108
00109 template<typename S, typename F>
00110 struct connection_der : connection_base
00111 {
00112 typedef typename S::iterator iterator;
00113
00114 connection_der(S& s, const F& f)
00115 : slot(s), function(f), it(s.end()) { enable(); }
00116
00117 virtual void enable()
00118 {
00119 if(it == slot.end())
00120 it = slot.insert(slot.end(), function);
00121 }
00122 virtual void disable()
00123 {
00124 if(it != slot.end()) {
00125 slot.erase(it);
00126 it = slot.end();
00127 }
00128 }
00129 virtual bool is_enabled() const { return it != slot.end(); }
00130 virtual ~connection_der() { disable(); }
00131
00132 private:
00133 S& slot;
00134 F function;
00135 iterator it;
00136 };
00137
00138 template<typename S, typename F>
00139 inline connection_base*
00140 new_connection(S& s, const F& f)
00141 {
00142 return new connection_der<S, F>(s, f);
00143 }
00144
00145 }
00146
00147
00148 struct connection
00149 {
00150 void enable() { cc.data()->enable(); }
00151 void disable() { cc.data()->disable(); }
00152 bool is_enabled() const { return cc.data()->is_enabled(); }
00153
00154 ~connection() {}
00155
00156 template< typename MultiClosure, typename Function >
00157 connection(MultiClosure& slot, Function f)
00158 : cc(new bits::connection_der<MultiClosure, Function>(slot, f)) {}
00159
00160 #if 0
00161 template< typename Res, template<typename> class C >
00162 connection(generator_multiclosure<Res, C>& slot, Res (*f)())
00163 : cc(bits::new_connection(slot, generator_closure<Res>(adapt(f))))
00164 {}
00165
00166 template< typename Arg, typename Res, template<typename> class C >
00167 connection(unary_multiclosure<Arg, Res, C>& slot, Res (*f)(Arg))
00168
00169 {
00170 unary_closure<Arg, Res> vf(adapt(f));
00171 typedef bits::connection_der< unary_multiclosure<Arg, Res, C>,
00172 unary_closure<Arg, Res> >
00173 cnn_type;
00174 cc = new cnn_type(slot, f);
00175 }
00176
00177 template< typename Arg1, typename Arg2, typename Res,
00178 template<typename> class C >
00179 connection(binary_multiclosure<Arg1, Arg2, Res, C>& slot,
00180 Res (*f)(Arg1, Arg2))
00181 : cc(bits::new_connection(slot,
00182 binary_closure<Arg1, Arg2, Res>
00183 (adapt(f)))) {}
00184
00185 template< typename Arg1, typename Arg2, typename Arg3, typename Res,
00186 template<typename> class C >
00187 connection(ternary_multiclosure<Arg1, Arg2, Arg3, Res, C>& slot,
00188 Res (*f)(Arg1, Arg2, Arg3))
00189 : cc(bits::new_connection(slot,
00190 ternary_closure<Arg1, Arg2, Arg3, Res>
00191 (adapt(f)))) {}
00192
00193 template< typename Obj, typename Res,
00194 template<typename> class C >
00195 connection(unary_multiclosure<Obj&, Res, C>& slot,
00196 Res (Obj::*f)())
00197 : cc(bits::new_connection(slot, unary_closure<Obj&, Res>
00198 (adapt(f)))) {}
00199
00200 template< typename Obj, typename Arg, typename Res,
00201 template<typename> class C >
00202 connection(binary_multiclosure<Obj&, Arg, Res, C>& slot,
00203 Res (Obj::*f)(Arg))
00204 : cc(bits::new_connection(slot,
00205 binary_closure<Obj&, Arg, Res>
00206 (adapt(f)))) {}
00207
00208 template< typename Obj, typename Arg1, typename Arg2, typename Res,
00209 template<typename> class C >
00210 connection(ternary_multiclosure<Obj&, Arg1, Arg2, Res, C>& slot,
00211 Res (Obj::*f)(Arg1, Arg2))
00212 : cc(bits::new_connection(slot,
00213 ternary_closure<Obj&, Arg1, Arg2, Res>
00214 (adapt(f)))) {}
00215
00216 template< typename Res, typename Obj, template<typename> class C >
00217 connection(generator_multiclosure<Res, C>& slot,
00218 Obj& obj, Res (Obj::*f)())
00219 : cc(bits::new_connection(slot,
00220 generator_closure<Res>
00221 (adapt(obj, f)))) {}
00222
00223 template< typename Res, typename Arg, typename Obj,
00224 template<typename> class C >
00225 connection(unary_multiclosure<Arg, Res, C>& slot,
00226 Obj& obj, Res (Obj::*f)(Arg))
00227 : cc(bits::new_connection(slot,
00228 unary_closure<Arg, Res>
00229 (adapt(obj, f)))) {}
00230
00231 template< typename Res, typename Arg1, typename Arg2, typename Obj,
00232 template<typename> class C >
00233 connection(binary_multiclosure<Arg1, Arg2, Res, C>& slot,
00234 Obj& obj, Res (Obj::*f)(Arg1, Arg2))
00235 : cc(bits::new_connection(slot,
00236 binary_closure<Arg1, Arg2, Res>
00237 (adapt(obj, f)))) {}
00238
00239 template< typename Res, typename Arg1, typename Arg2, typename Arg3,
00240 typename Obj, template<typename> class C >
00241 connection(ternary_multiclosure<Arg1, Arg2, Arg3, Res, C>& slot,
00242 Obj& obj, Res (Obj::*f)(Arg1, Arg2, Arg3))
00243 : cc(bits::new_connection(slot,
00244 ternary_closure<Arg1, Arg2, Arg3, Res>
00245 (adapt(obj, f)))) {}
00246 #endif
00247
00248 private:
00249 instance_counter ic;
00250 handle<bits::connection_base> cc;
00251 };
00252
00253 }}
00254
00255 #endif