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 true;
00082 ++it;
00083 }
00084 return false;
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