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
00031
00032 #pragma once
00033
00034 #include "../System/exception.h"
00035 #include "slot.h"
00036 #include "signals_impl.h"
00037
00038 template <typename Param1, typename Param2, typename Param3, typename Param4> class CL_Super_v4;
00039
00042 template <class Param1, class Param2, class Param3, class Param4>
00043 class CL_VirtualCallback_v4 : public CL_SlotCallback
00044 {
00045 public:
00046 virtual void invoke(Param1 param1, Param2 param2, Param3 param3, Param4 param4, CL_Super_v4<Param1, Param2, Param3, Param4> &super_func) = 0;
00047 };
00048
00051 template <class Param1, class Param2, class Param3, class Param4>
00052 class CL_Super_v4
00053 {
00054 public:
00055 void invoke(Param1 param1, Param2 param2, Param3 param3, Param4 param4)
00056 {
00057 std::vector< CL_SharedPtr<CL_SlotCallback> >::reverse_iterator it = it_super;
00058 while (it != it_end)
00059 {
00060 CL_Super_v4<Param1, Param2, Param3, Param4> parent;
00061 parent.it_super = it;
00062 parent.it_end = it_end;
00063 ++parent.it_super;
00064
00065 if (it->get()->valid && it->get()->enabled)
00066 {
00067 ((CL_VirtualCallback_v4<Param1, Param2, Param3, Param4> *) it->get())->invoke(param1, param2, param3, param4, parent);
00068 return;
00069 }
00070 ++it;
00071 }
00072
00073 throw CL_Exception("Called non-invokable super function");
00074 }
00075
00076 bool is_null() const
00077 {
00078 std::vector< CL_SharedPtr<CL_SlotCallback> >::reverse_iterator it = it_super;
00079 while (it != it_end)
00080 {
00081 if (it->get()->valid && it->get()->enabled)
00082 return false;
00083 ++it;
00084 }
00085 return true;
00086 }
00087
00088 bool is_invokable() const
00089 {
00090 return !is_null();
00091 }
00092
00093 std::vector< CL_SharedPtr<CL_SlotCallback> >::reverse_iterator it_super;
00094
00095 std::vector< CL_SharedPtr<CL_SlotCallback> >::reverse_iterator it_end;
00096 };
00097
00100 template <class Param1, class Param2, class Param3, class Param4>
00101 class CL_VirtualCallback_v4_static : public CL_VirtualCallback_v4<Param1, Param2, Param3, Param4>
00102 {
00103 public:
00104 CL_VirtualCallback_v4_static(void (*static_func)(Param1, Param2, Param3, Param4, CL_Super_v4<Param1, Param2, Param3, Param4> &))
00105 : static_func(static_func) { return; }
00106 void invoke(Param1 param1, Param2 param2, Param3 param3, Param4 param4, CL_Super_v4<Param1, Param2, Param3, Param4> &super_func) { static_func(param1, param2, param3, param4, super_func); }
00107 void (*static_func)(Param1, Param2, Param3, Param4, CL_Super_v4<Param1, Param2, Param3, Param4> &);
00108 };
00109
00112 template <class Param1, class Param2, class Param3, class Param4, class UserData>
00113 class CL_VirtualCallback_v4_static_user : public CL_VirtualCallback_v4<Param1, Param2, Param3, Param4>
00114 {
00115 public:
00116 CL_VirtualCallback_v4_static_user(void (*static_func)(Param1, Param2, Param3, Param4, UserData, CL_Super_v4<Param1, Param2, Param3, Param4> &), const UserData &user_data)
00117 : static_func(static_func), user_data(user_data) { return; }
00118 void invoke(Param1 param1, Param2 param2, Param3 param3, Param4 param4, CL_Super_v4<Param1, Param2, Param3, Param4> &super_func) { static_func(param1, param2, param3, param4, user_data, super_func); }
00119 void (*static_func)(Param1, Param2, Param3, Param4, UserData, CL_Super_v4<Param1, Param2, Param3, Param4> &);
00120 UserData user_data;
00121 };
00122
00125 template <class Param1, class Param2, class Param3, class Param4, class InstanceClass>
00126 class CL_VirtualCallback_v4_member : public CL_VirtualCallback_v4<Param1, Param2, Param3, Param4>
00127 {
00128 public:
00129 CL_VirtualCallback_v4_member(InstanceClass *instance, void (InstanceClass::*member_func)(Param1, Param2, Param3, Param4, CL_Super_v4<Param1, Param2, Param3, Param4> &))
00130 : instance(instance), member_func(member_func) { return; }
00131 void invoke(Param1 param1, Param2 param2, Param3 param3, Param4 param4, CL_Super_v4<Param1, Param2, Param3, Param4> &super_func) { (instance->*member_func)(param1, param2, param3, param4, super_func); }
00132 InstanceClass *instance;
00133 void (InstanceClass::*member_func)(Param1, Param2, Param3, Param4, CL_Super_v4<Param1, Param2, Param3, Param4> &);
00134 };
00135
00138 template <class Param1, class Param2, class Param3, class Param4, class InstanceClass, class UserData>
00139 class CL_VirtualCallback_v4_member_user : public CL_VirtualCallback_v4<Param1, Param2, Param3, Param4>
00140 {
00141 public:
00142 CL_VirtualCallback_v4_member_user(InstanceClass *instance, void (InstanceClass::*member_func)(Param1, Param2, Param3, Param4, UserData, CL_Super_v4<Param1, Param2, Param3, Param4> &), const UserData &user_data)
00143 : instance(instance), member_func(member_func), user_data(user_data) { return; }
00144 void invoke(Param1 param1, Param2 param2, Param3 param3, Param4 param4, CL_Super_v4<Param1, Param2, Param3, Param4> &super_func) { (instance->*member_func)(param1, param2, param3, param4, user_data, super_func); }
00145 InstanceClass *instance;
00146 void (InstanceClass::*member_func)(Param1, Param2, Param3, Param4, UserData, CL_Super_v4<Param1, Param2, Param3, Param4> &);
00147 UserData user_data;
00148 };
00149
00152 template <class Param1, class Param2, class Param3, class Param4, class Functor>
00153 class CL_VirtualCallback_v4_functor : public CL_VirtualCallback_v4<Param1, Param2, Param3, Param4>
00154 {
00155 public:
00156 CL_VirtualCallback_v4_functor(const Functor &functor)
00157 : functor(functor) { return; }
00158 void invoke(Param1 param1, Param2 param2, Param3 param3, Param4 param4, CL_Super_v4<Param1, Param2, Param3, Param4> &super_func) { functor(param1, param2, param3, param4, super_func); }
00159 Functor functor;
00160 };
00161
00165 template <class Param1, class Param2, class Param3, class Param4>
00166 class CL_VirtualFunction_v4
00167 {
00170
00171 public:
00172 CL_VirtualFunction_v4()
00173 : impl(new CL_Signal_Impl) { return; }
00174
00175 CL_VirtualFunction_v4(const CL_VirtualFunction_v4<Param1, Param2, Param3, Param4> ©)
00176 : impl(copy.impl) { return; }
00177
00178
00182
00183 public:
00184 CL_Slot connect(void (*function)(Param1, Param2, Param3, Param4, CL_Super_v4<Param1, Param2, Param3, Param4> &))
00185 {
00186 clean_up();
00187 CL_SharedPtr<CL_SlotCallback> callback(
00188 new CL_VirtualCallback_v4_static<Param1, Param2, Param3, Param4>(function));
00189 impl->connected_slots.push_back(callback);
00190 return CL_Slot(callback);
00191 }
00192
00193 template<class UserData>
00194 CL_Slot connect(void (*function)(Param1, Param2, Param3, Param4, UserData, CL_Super_v4<Param1, Param2, Param3, Param4> &), const UserData &user_data)
00195 {
00196 clean_up();
00197 CL_SharedPtr<CL_SlotCallback> callback(
00198 new CL_VirtualCallback_v4_static_user<Param1, Param2, Param3, Param4, UserData>(function, user_data));
00199 impl->connected_slots.push_back(callback);
00200 return CL_Slot(callback);
00201 }
00202
00203 template<class InstanceClass>
00204 CL_Slot connect(InstanceClass *instance, void (InstanceClass::*function)(Param1, Param2, Param3, Param4, CL_Super_v4<Param1, Param2, Param3, Param4> &))
00205 {
00206 clean_up();
00207 CL_SharedPtr<CL_SlotCallback> callback(
00208 new CL_VirtualCallback_v4_member<Param1, Param2, Param3, Param4, InstanceClass>(instance, function));
00209 impl->connected_slots.push_back(callback);
00210 return CL_Slot(callback);
00211 }
00212
00213 template<class InstanceClass, class UserData>
00214 CL_Slot connect(InstanceClass *instance, void (InstanceClass::*function)(Param1, Param2, Param3, Param4, UserData, CL_Super_v4<Param1, Param2, Param3, Param4> &), const UserData &user_data)
00215 {
00216 clean_up();
00217 CL_SharedPtr<CL_SlotCallback> callback(
00218 new CL_VirtualCallback_v4_member_user<Param1, Param2, Param3, Param4, InstanceClass, UserData>(instance, function, user_data));
00219 impl->connected_slots.push_back(callback);
00220 return CL_Slot(callback);
00221 }
00222
00223 template<class Functor>
00224 CL_Slot connect_functor(const Functor &functor)
00225 {
00226 clean_up();
00227 CL_SharedPtr<CL_SlotCallback> callback(
00228 new CL_VirtualCallback_v4_functor<Param1, Param2, Param3, Param4, Functor>(functor));
00229 impl->connected_slots.push_back(callback);
00230 return CL_Slot(callback);
00231 }
00232
00233 void invoke(Param1 param1, Param2 param2, Param3 param3, Param4 param4) const
00234 {
00235 std::vector< CL_SharedPtr<CL_SlotCallback> > callbacks = impl->connected_slots;
00236 CL_Super_v4<Param1, Param2, Param3, Param4> s;
00237 s.it_super = callbacks.rbegin();
00238 s.it_end = callbacks.rend();
00239 s.invoke(param1, param2, param3, param4);
00240 }
00241
00242
00246
00247 private:
00248 void clean_up()
00249 {
00250 std::vector< CL_SharedPtr<CL_SlotCallback> >::size_type i, size;
00251 size = impl->connected_slots.size();
00252 for (i = 0; i < size; i++)
00253 {
00254 if (!impl->connected_slots[i]->valid)
00255 {
00256 impl->connected_slots.erase(impl->connected_slots.begin()+i);
00257 i--;
00258 size--;
00259 }
00260 }
00261 }
00262
00263 CL_SharedPtr<CL_Signal_Impl> impl;
00265 };
00266
00267