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 class CL_Super_v0;
00040
00043 class CL_API_CORE CL_VirtualCallback_v0 : public CL_SlotCallback
00044 {
00045 public:
00046 virtual void invoke(CL_Super_v0 &super_func) = 0;
00047 };
00048
00051 class CL_API_CORE CL_Super_v0
00052 {
00053 public:
00054 void invoke()
00055 {
00056 std::vector< CL_SharedPtr<CL_SlotCallback> >::reverse_iterator it = it_super;
00057 while (it != it_end)
00058 {
00059 CL_Super_v0 parent;
00060 parent.it_super = it;
00061 parent.it_end = it_end;
00062 ++parent.it_super;
00063
00064 if (it->get()->valid && it->get()->enabled)
00065 {
00066 ((CL_VirtualCallback_v0 *) it->get())->invoke(parent);
00067 return;
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 class CL_API_CORE CL_VirtualCallback_v0_static : public CL_VirtualCallback_v0
00100 {
00101 public:
00102 CL_VirtualCallback_v0_static(void (*static_func)(CL_Super_v0 &))
00103 : static_func(static_func) { return; }
00104 void invoke(CL_Super_v0 &super_func) { static_func(super_func); }
00105 void (*static_func)(CL_Super_v0 &);
00106 };
00107
00110 template <class UserData>
00111 class CL_VirtualCallback_v0_static_user : public CL_VirtualCallback_v0
00112 {
00113 public:
00114 CL_VirtualCallback_v0_static_user(void (*static_func)(UserData, CL_Super_v0 &), const UserData &user_data)
00115 : static_func(static_func), user_data(user_data) { return; }
00116 void invoke(CL_Super_v0 &super_func) { static_func(user_data, super_func); }
00117 void (*static_func)(UserData, CL_Super_v0 &);
00118 UserData user_data;
00119 };
00120
00123 template <class InstanceClass>
00124 class CL_VirtualCallback_v0_member : public CL_VirtualCallback_v0
00125 {
00126 public:
00127 CL_VirtualCallback_v0_member(InstanceClass *instance, void (InstanceClass::*member_func)(CL_Super_v0 &))
00128 : instance(instance), member_func(member_func) { return; }
00129 void invoke(CL_Super_v0 &super_func) { (instance->*member_func)(super_func); }
00130 InstanceClass *instance;
00131 void (InstanceClass::*member_func)(CL_Super_v0 &);
00132 };
00133
00136 template <class InstanceClass, class UserData>
00137 class CL_VirtualCallback_v0_member_user : public CL_VirtualCallback_v0
00138 {
00139 public:
00140 CL_VirtualCallback_v0_member_user(InstanceClass *instance, void (InstanceClass::*member_func)(UserData, CL_Super_v0 &), const UserData &user_data)
00141 : instance(instance), member_func(member_func), user_data(user_data) { return; }
00142 void invoke(CL_Super_v0 &super_func) { (instance->*member_func)(user_data, super_func); }
00143 InstanceClass *instance;
00144 void (InstanceClass::*member_func)(UserData, CL_Super_v0 &);
00145 UserData user_data;
00146 };
00147
00150 template <class Functor>
00151 class CL_VirtualCallback_v0_functor : public CL_VirtualCallback_v0
00152 {
00153 public:
00154 CL_VirtualCallback_v0_functor(const Functor &functor)
00155 : functor(functor) { return; }
00156 void invoke(CL_Super_v0 &super_func) { functor(super_func); }
00157 Functor functor;
00158 };
00159
00163 class CL_API_CORE CL_VirtualFunction_v0
00164 {
00167
00168 public:
00169 CL_VirtualFunction_v0()
00170 : impl(new CL_Signal_Impl) { return; }
00171
00172 CL_VirtualFunction_v0(const CL_VirtualFunction_v0 ©)
00173 : impl(copy.impl) { return; }
00174
00175
00179
00180 public:
00181 CL_Slot connect(void (*function)(CL_Super_v0 &))
00182 {
00183 clean_up();
00184 CL_SharedPtr<CL_SlotCallback> callback(
00185 new CL_VirtualCallback_v0_static(function));
00186 impl->connected_slots.push_back(callback);
00187 return CL_Slot(callback);
00188 }
00189
00190 template<class UserData>
00191 CL_Slot connect(void (*function)(CL_Super_v0 &), const UserData &user_data)
00192 {
00193 clean_up();
00194 CL_SharedPtr<CL_SlotCallback> callback(
00195 new CL_VirtualCallback_v0_static_user<UserData>(function, user_data));
00196 impl->connected_slots.push_back(callback);
00197 return CL_Slot(callback);
00198 }
00199
00200 template<class InstanceClass>
00201 CL_Slot connect(InstanceClass *instance, void (InstanceClass::*function)(CL_Super_v0 &))
00202 {
00203 clean_up();
00204 CL_SharedPtr<CL_SlotCallback> callback(
00205 new CL_VirtualCallback_v0_member<InstanceClass>(instance, function));
00206 impl->connected_slots.push_back(callback);
00207 return CL_Slot(callback);
00208 }
00209
00210 template<class InstanceClass, class UserData>
00211 CL_Slot connect(InstanceClass *instance, void (InstanceClass::*function)(UserData, CL_Super_v0 &), const UserData &user_data)
00212 {
00213 clean_up();
00214 CL_SharedPtr<CL_SlotCallback> callback(
00215 new CL_VirtualCallback_v0_member_user<InstanceClass, UserData>(instance, function, user_data));
00216 impl->connected_slots.push_back(callback);
00217 return CL_Slot(callback);
00218 }
00219
00220 template<class Functor>
00221 CL_Slot connect_functor(const Functor &functor)
00222 {
00223 clean_up();
00224 CL_SharedPtr<CL_SlotCallback> callback(
00225 new CL_VirtualCallback_v0_functor<Functor>(functor));
00226 impl->connected_slots.push_back(callback);
00227 return CL_Slot(callback);
00228 }
00229
00230 void invoke() const
00231 {
00232 std::vector< CL_SharedPtr<CL_SlotCallback> > callbacks = impl->connected_slots;
00233 CL_Super_v0 s;
00234 s.it_super = callbacks.rbegin();
00235 s.it_end = callbacks.rend();
00236 s.invoke();
00237 }
00238
00239
00243
00244 private:
00245 void clean_up()
00246 {
00247 std::vector< CL_SharedPtr<CL_SlotCallback> >::size_type i, size;
00248 size = impl->connected_slots.size();
00249 for (i = 0; i < size; i++)
00250 {
00251 if (!impl->connected_slots[i]->valid)
00252 {
00253 impl->connected_slots.erase(impl->connected_slots.begin()+i);
00254 i--;
00255 size--;
00256 }
00257 }
00258 }
00259
00260 CL_SharedPtr<CL_Signal_Impl> impl;
00262 };
00263
00264