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
#ifndef UOBJECTSLOTS_HPP
00029
#define UOBJECTSLOTS_HPP
00030
00031
00032
00033
00034
#include "uslot.hpp"
00035
00036
namespace ufo {
00037
00038
class UObject;
00039
00044 namespace internal {
00045
class Yes {
char a[1]; };
00046
class No {
char a[5]; };
00047
00048
template<
class Base>
static Yes canCastTo(Base*);
00049
template<
class Base>
static No canCastTo(...);
00050 }
00051
00053
template<
class Child,
class Base>
00054 class ImplicitCast {
00055
public:
00056
enum {
00057 Exists =
sizeof(internal::canCastTo<Base>(static_cast<Child*>(0))) ==
sizeof(internal::Yes) ? 1 : 0
00058 };
00059 };
00060
00061
00067 struct UObjectSlotNode :
public USlotNode {
00070 typedef void (UObject::*
Method)(
void);
00071
00073 void *
m_object;
00075 UObject *
m_uobject;
00077 Method m_method;
00078
00082
template<
typename Obj>
00083 UObjectSlotNode(ProxyPtr proxy, Obj * object,
Method method)
00084 : USlotNode(proxy)
00085 ,
m_object(object)
00086 ,
m_uobject(NULL)
00087 ,
m_method(method)
00088 {
00089
if (
ImplicitCast<Obj, UObject>::Exists) {
00090
m_uobject = static_cast<UObject*>(object);
00091 }
00092
if (
m_uobject) {
00093
m_uobject->
m_objectSlots.push_back(
this);
00094 }
00095 }
00096
virtual ~
UObjectSlotNode() {
00097
if (m_uobject) {
00098 m_uobject->
m_objectSlots.remove(
this);
00099 }
00100 }
00101
virtual void notify(
bool from_child) {
00102
if (!from_child &&
m_uobject) {
00103
m_uobject->m_objectSlots.remove(
this);
00104 }
00105
m_uobject = NULL;
00106
m_object = NULL;
00107 }
00108
virtual bool died() {
return (
m_object == NULL); }
00109
00110
virtual bool equals(
const USlotNode * node)
const {
00111
if (
const UObjectSlotNode * onode = dynamic_cast<const UObjectSlotNode*>(node)) {
00112
return ((
m_object == onode->m_object) &&
00113 (
m_method == onode->m_method));
00114
00115 }
else {
00116
return false;
00117 }
00118 }
00119 };
00120
00121
00122
00123
00124
00125
00126
template <
typename Obj>
00127
struct UObjectSlot0 {
00128
typedef void (Obj::*Method)();
00129
00130
static void proxy(
void * s) {
00131 UObjectSlotNode* os = (UObjectSlotNode*) s;
00132 ((Obj*)(os->m_object)->*(reinterpret_cast<Method>(os->m_method)))();
00133 }
00134 };
00135
00136
template <
typename Obj>
00137 USlot0
00138 slot(Obj & obj,
void (Obj::*method)()) {
00139
typedef UObjectSlot0<Obj> SType;
00140
00141
return new UObjectSlotNode((FuncPtr)(&SType::proxy),
00142 &obj,
00143 reinterpret_cast<UObjectSlotNode::Method>(method));
00144 }
00145
00146
template <
typename Obj>
00147 USlot0
00148 slot(Obj & obj,
void (Obj::*method)()
const) {
00149
typedef UObjectSlot0<Obj> SType;
00150
00151
return new UObjectSlotNode((FuncPtr)(&SType::proxy),
00152 &obj,
00153 reinterpret_cast<UObjectSlotNode::Method>(method));
00154 }
00155
00156
00157
00158
00159
00160
00161
template <
typename P1,
typename Obj>
00162
struct UObjectSlot1 {
00163
typedef void (Obj::*Method)(P1);
00164
00165
static void proxy(
typename UTrait<P1>::ref p1,
void * s) {
00166 UObjectSlotNode* os = (UObjectSlotNode*)s;
00167 ((Obj*)(os->m_object)->*(reinterpret_cast<Method>(os->m_method)))(p1);
00168 }
00169 };
00170
00171
template <
typename P1,
typename Obj>
00172 USlot1<P1>
00173 slot(Obj & obj,
void (Obj::*method)(P1)) {
00174
typedef UObjectSlot1<P1,Obj> SType;
00175
return new UObjectSlotNode((FuncPtr)(&SType::proxy),
00176 &obj,
00177 reinterpret_cast<UObjectSlotNode::Method>(method));
00178 }
00179
00180
template <
typename P1,
typename Obj>
00181 USlot1<P1>
00182 slot(Obj & obj,
void (Obj::*method)(P1)
const) {
00183
typedef UObjectSlot1<P1,Obj> SType;
00184
return new UObjectSlotNode((FuncPtr)(&SType::proxy),
00185 &obj,
00186 reinterpret_cast<UObjectSlotNode::Method>(method));
00187 }
00188
00189
00190
00191
00192
00193
00194
template <
typename P1,
typename P2,
typename Obj>
00195
struct UObjectSlot2 {
00196
typedef void (Obj::*Method)(P1, P2);
00197
00198
static void proxy(
typename UTrait<P1>::ref p1,
typename UTrait<P2>::ref p2,
void * s) {
00199 UObjectSlotNode* os = (UObjectSlotNode*)s;
00200 ((Obj*)(os->m_object)->*(reinterpret_cast<Method>(os->m_method)))(p1, p2);
00201 }
00202 };
00203
00204
template <
typename P1,
typename P2,
typename Obj>
00205 USlot2<P1, P2>
00206 slot(Obj & obj,
void (Obj::*method)(P1, P2)) {
00207
typedef UObjectSlot2<P1, P2, Obj> SType;
00208
return new UObjectSlotNode((FuncPtr)(&SType::proxy),
00209 &obj,
00210 reinterpret_cast<UObjectSlotNode::Method>(method));
00211 }
00212
00213
template <
typename P1,
typename P2,
typename Obj>
00214 USlot2<P1, P2>
00215 slot(Obj & obj,
void (Obj::*method)(P1, P2)
const) {
00216
typedef UObjectSlot2<P1, P2, Obj> SType;
00217
return new UObjectSlotNode((FuncPtr)(&SType::proxy),
00218 &obj,
00219 reinterpret_cast<UObjectSlotNode::Method>(method));
00220 }
00221
00222
00223
00224
00225
00226
00227
00228
template <
typename P1,
typename P2,
typename P3,
typename Obj>
00229
struct UObjectSlot3 {
00230
typedef void (Obj::*Method)(P1, P2, P3);
00231
00232
static void proxy(
00233
typename UTrait<P1>::ref p1,
00234
typename UTrait<P2>::ref p2,
00235
typename UTrait<P3>::ref p3,
00236
void * s) {
00237 UObjectSlotNode * os = (UObjectSlotNode*)s;
00238 ((Obj*)(os->m_object)->*(reinterpret_cast<Method>(os->m_method)))(p1, p2, p3);
00239 }
00240 };
00241
00242
template <
typename P1,
typename P2,
typename P3,
typename Obj>
00243 USlot3<P1, P2, P3>
00244 slot(Obj & obj,
void (Obj::*method)(P1, P2, P3)) {
00245
typedef UObjectSlot3<P1, P2, P3, Obj> SType;
00246
return new UObjectSlotNode((FuncPtr)(&SType::proxy),
00247 &obj,
00248 reinterpret_cast<UObjectSlotNode::Method>(method));
00249 }
00250
00251
template <
typename P1,
typename P2,
typename P3,
typename Obj>
00252 USlot3<P1, P2, P3>
00253 slot(Obj & obj,
void (Obj::*method)(P1, P2, P3)
const) {
00254
typedef UObjectSlot3<P1, P2, P3, Obj> SType;
00255
return new UObjectSlotNode((FuncPtr)(&SType::proxy),
00256 &obj,
00257 reinterpret_cast<UObjectSlotNode::Method>(method));
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
template <
typename P1,
typename P2,
typename P3,
typename P4,
typename Obj>
00267
struct UObjectSlot4 {
00268
typedef void (Obj::*Method)(P1, P2, P3, P4);
00269
00270
static void proxy(
00271
typename UTrait<P1>::ref p1,
00272
typename UTrait<P2>::ref p2,
00273
typename UTrait<P3>::ref p3,
00274
typename UTrait<P4>::ref p4,
00275
void * s) {
00276 UObjectSlotNode * os = (UObjectSlotNode*)s;
00277 ((Obj*)(os->m_object)->*(reinterpret_cast<Method>(os->m_method)))(p1, p2, p3, p4);
00278 }
00279 };
00280
00281
template <
typename P1,
typename P2,
typename P3,
typename P4,
typename Obj>
00282 USlot4<P1, P2, P3, P4>
00283 slot(Obj & obj,
void (Obj::*method)(P1, P2, P3, P4)) {
00284
typedef UObjectSlot4<P1, P2, P3, P4, Obj> SType;
00285
return new UObjectSlotNode((FuncPtr)(&SType::proxy),
00286 &obj,
00287 reinterpret_cast<UObjectSlotNode::Method>(method));
00288 }
00289
00290
template <
typename P1,
typename P2,
typename P3,
typename P4,
typename Obj>
00291 USlot4<P1, P2, P3, P4>
00292 slot(Obj & obj,
void (Obj::*method)(P1, P2, P3, P4)
const) {
00293
typedef UObjectSlot4<P1, P2, P3, P4, Obj> SType;
00294
return new UObjectSlotNode((FuncPtr)(&SType::proxy),
00295 &obj,
00296 reinterpret_cast<UObjectSlotNode::Method>(method));
00297 }
00298
00299 }
00300
00301
#endif // UOBJECTSLOTS_HPP