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