Go to the documentation of this file.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 "../api_core.h"
00035 #include "../System/exception.h"
00036 #include "slot.h"
00037 #include "signals_impl.h"
00038
00039 template<typename RetVal> class CL_Super_0;
00040
00043 template<typename RetVal>
00044 class CL_VirtualCallback_0 : public CL_SlotCallback
00045 {
00046 public:
00047 virtual RetVal invoke(CL_Super_0<RetVal> &super_func) = 0;
00048 };
00049
00052 template<typename RetVal>
00053 class CL_Super_0
00054 {
00055 public:
00056 RetVal invoke()
00057 {
00058 std::vector< CL_SharedPtr<CL_SlotCallback> >::reverse_iterator it = it_super;
00059 while (it != it_end)
00060 {
00061 CL_Super_0<RetVal> parent;
00062 parent.it_super = it;
00063 parent.it_end = it_end;
00064 ++parent.it_super;
00065
00066 if (it->get()->valid && it->get()->enabled)
00067 {
00068 return ((CL_VirtualCallback_0<RetVal> *) it->get())->invoke(parent);
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<typename RetVal>
00101 class CL_VirtualCallback_0_static : public CL_VirtualCallback_0<RetVal>
00102 {
00103 public:
00104 CL_VirtualCallback_0_static(RetVal (*static_func)(CL_Super_0<RetVal> &))
00105 : static_func(static_func) { return; }
00106 RetVal invoke(CL_Super_0<RetVal> &super_func) { return static_func(super_func); }
00107 RetVal (*static_func)(CL_Super_0<RetVal> &);
00108 };
00109
00112 template <typename RetVal, class UserData>
00113 class CL_VirtualCallback_0_static_user : public CL_VirtualCallback_0<RetVal>
00114 {
00115 public:
00116 CL_VirtualCallback_0_static_user(void (*static_func)(UserData, CL_Super_0<RetVal> &), const UserData &user_data)
00117 : static_func(static_func), user_data(user_data) { return; }
00118 RetVal invoke(CL_Super_0<RetVal> &super_func) { return static_func(user_data, super_func); }
00119 RetVal (*static_func)(UserData, CL_Super_0<RetVal> &);
00120 UserData user_data;
00121 };
00122
00125 template <typename RetVal, class InstanceClass>
00126 class CL_VirtualCallback_0_member : public CL_VirtualCallback_0<RetVal>
00127 {
00128 public:
00129 CL_VirtualCallback_0_member(InstanceClass *instance, void (InstanceClass::*member_func)(CL_Super_0<RetVal> &))
00130 : instance(instance), member_func(member_func) { return; }
00131 RetVal invoke(CL_Super_0<RetVal> &super_func) { return (instance->*member_func)(super_func); }
00132 InstanceClass *instance;
00133 RetVal (InstanceClass::*member_func)(CL_Super_0<RetVal> &);
00134 };
00135
00138 template <typename RetVal, class InstanceClass, class UserData>
00139 class CL_VirtualCallback_0_member_user : public CL_VirtualCallback_0<RetVal>
00140 {
00141 public:
00142 CL_VirtualCallback_0_member_user(InstanceClass *instance, void (InstanceClass::*member_func)(UserData, CL_Super_0<RetVal> &), const UserData &user_data)
00143 : instance(instance), member_func(member_func), user_data(user_data) { return; }
00144 RetVal invoke(CL_Super_0<RetVal> &super_func) { return (instance->*member_func)(user_data, super_func); }
00145 InstanceClass *instance;
00146 RetVal (InstanceClass::*member_func)(UserData, CL_Super_0<RetVal> &);
00147 UserData user_data;
00148 };
00149
00152 template <typename RetVal, class Functor>
00153 class CL_VirtualCallback_0_functor : public CL_VirtualCallback_0<RetVal>
00154 {
00155 public:
00156 CL_VirtualCallback_0_functor(const Functor &functor)
00157 : functor(functor) { return; }
00158 RetVal invoke(CL_Super_0<RetVal> &super_func) { return functor(super_func); }
00159 Functor functor;
00160 };
00161
00165 template <typename RetVal>
00166 class CL_VirtualFunction_0
00167 {
00170
00171 public:
00172 CL_VirtualFunction_0()
00173 : impl(new CL_Signal_Impl) { return; }
00174
00175 CL_VirtualFunction_0(const CL_VirtualFunction_0<RetVal> ©)
00176 : impl(copy.impl) { return; }
00177
00178
00182
00183 public:
00184 CL_Slot connect(void (*function)(CL_Super_0<RetVal> &))
00185 {
00186 clean_up();
00187 CL_SharedPtr<CL_SlotCallback> callback(
00188 new CL_VirtualCallback_0_static<RetVal>(function));
00189 impl->connected_slots.push_back(callback);
00190 return CL_Slot(callback);
00191 }
00192
00193 template<class UserData>
00194 CL_Slot connect(RetVal (*function)(CL_Super_0<RetVal> &), const UserData &user_data)
00195 {
00196 clean_up();
00197 CL_SharedPtr<CL_SlotCallback> callback(
00198 new CL_VirtualCallback_0_static_user<RetVal, 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, RetVal (InstanceClass::*function)(CL_Super_0<RetVal> &))
00205 {
00206 clean_up();
00207 CL_SharedPtr<CL_SlotCallback> callback(
00208 new CL_VirtualCallback_0_member<RetVal, 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, RetVal (InstanceClass::*function)(UserData, CL_Super_0<RetVal> &), const UserData &user_data)
00215 {
00216 clean_up();
00217 CL_SharedPtr<CL_SlotCallback> callback(
00218 new CL_VirtualCallback_0_member_user<RetVal, 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_0_functor<RetVal, Functor>(functor));
00229 impl->connected_slots.push_back(callback);
00230 return CL_Slot(callback);
00231 }
00232
00233 RetVal invoke() const
00234 {
00235 std::vector< CL_SharedPtr<CL_SlotCallback> > callbacks = impl->connected_slots;
00236 CL_Super_0<RetVal> s;
00237 s.it_super = callbacks.rbegin();
00238 s.it_end = callbacks.rend();
00239 return s.invoke();
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