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
00029
00030
00031
00032
00033
00034 #ifndef __XPLC_UTILS_H__
00035 #define __XPLC_UTILS_H__
00036
00042 #include <stddef.h>
00043 #include <xplc/core.h>
00044 #include <xplc/IWeakRef.h>
00045
00049 struct UUID_Info {
00051 const UUID* iid;
00052 ptrdiff_t delta;
00054 };
00055
00059 #define UUID_MAP_BEGIN(component) const UUID_Info component::xplc_iobject_uuids[] = {
00060
00064 #define UUID_MAP_ENTRY(iface) { &iface##_IID, reinterpret_cast<ptrdiff_t>(static_cast<iface*>(reinterpret_cast<ThisXPLCComponent*>(1))) - 1 },
00065
00071 #define UUID_MAP_ENTRY_2(iface, iface2) { &iface##_IID, reinterpret_cast<ptrdiff_t>(static_cast<iface2*>(reinterpret_cast<ThisXPLCComponent*>(1))) - 1 },
00072
00076 #define UUID_MAP_END { 0, 0 } };
00077
00078 class WeakRef;
00079
00083 struct IObjectImplInternal {
00087 unsigned int refcount;
00093 WeakRef* weakref;
00094 IObjectImplInternal(): refcount(1), weakref(0) {
00095 }
00099 IObject* getInterface(void* self, const UUID& uuid,
00100 const UUID_Info* uuidlist);
00101 };
00102
00103 #ifndef xplcdelete
00104
00108 #define xplcdelete delete
00109 #endif
00110
00119 #define IMPLEMENT_IOBJECT(component) \
00120 private: \
00121 IObjectImplInternal xplc_iobject_internal; \
00122 static const UUID_Info xplc_iobject_uuids[]; \
00123 typedef component ThisXPLCComponent; \
00124 public: \
00125 virtual unsigned int addRef() { \
00126 return ++xplc_iobject_internal.refcount; \
00127 } \
00128 virtual unsigned int release() { \
00129 if(--xplc_iobject_internal.refcount) \
00130 return xplc_iobject_internal.refcount; \
00131 \
00132 xplc_iobject_internal.refcount = 1; \
00133 if(xplc_iobject_internal.weakref) { \
00134 xplc_iobject_internal.weakref->release(); \
00135 xplc_iobject_internal.weakref->object = 0; \
00136 } \
00137 xplcdelete this; \
00138 return 0; \
00139 } \
00140 virtual IObject* getInterface(const UUID& uuid) { \
00141 return xplc_iobject_internal.getInterface(this, uuid, xplc_iobject_uuids); \
00142 } \
00143 virtual IWeakRef* getWeakRef() { \
00144 if(!xplc_iobject_internal.weakref) \
00145 xplc_iobject_internal.weakref = new WeakRef(reinterpret_cast<IObject*>(reinterpret_cast<ptrdiff_t>(this) + xplc_iobject_uuids->delta)); \
00146 xplc_iobject_internal.weakref->addRef(); \
00147 return xplc_iobject_internal.weakref; \
00148 }
00149
00154 class WeakRef: public IWeakRef {
00155 IMPLEMENT_IOBJECT(WeakRef);
00156 public:
00158 IObject* object;
00159 virtual IObject* getObject() {
00160 if(object)
00161 object->addRef();
00162
00163 return object;
00164 }
00168 WeakRef(IObject* aObj):
00169 object(aObj) {
00170 }
00171 };
00172
00179 template<class Interface>
00180 Interface* get(IObject* aObj) {
00181 if(!aObj)
00182 return 0;
00183
00184 return static_cast<Interface*>(aObj->getInterface(XPLC_IID<Interface>::get()));
00185 }
00186
00193 template<class Interface>
00194 Interface* mutate(IObject* aObj) {
00195 Interface* rv;
00196
00197 if(!aObj)
00198 return 0;
00199
00200 rv = static_cast<Interface*>(aObj->getInterface(XPLC_IID<Interface>::get()));
00201
00202 aObj->release();
00203
00204 return rv;
00205 }
00206
00207 #endif