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