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
00037 #if defined(__GNUC__) && __GNUC__ > 3
00038 # pragma GCC system_header
00039 #endif
00040
00046 #include <stddef.h>
00047 #include <xplc/core.h>
00048 #include <xplc/IWeakRef.h>
00049
00053 struct UUID_Info {
00055 const UUID* iid;
00056 ptrdiff_t delta;
00058 };
00059
00063 #define UUID_MAP_BEGIN(component) const UUID_Info component::xplc_iobject_uuids[] = {
00064
00068 #define UUID_MAP_ENTRY(iface) { &iface##_IID, reinterpret_cast<ptrdiff_t>(static_cast<iface*>(reinterpret_cast<ThisXPLCComponent*>(1))) - 1 },
00069
00075 #define UUID_MAP_ENTRY_2(iface, iface2) { &iface##_IID, reinterpret_cast<ptrdiff_t>(static_cast<iface2*>(reinterpret_cast<ThisXPLCComponent*>(1))) - 1 },
00076
00080 #define UUID_MAP_END { 0, 0 } };
00081
00082 class WeakRef;
00083
00087 struct IObjectImplInternal {
00091 unsigned int refcount;
00097 WeakRef* weakref;
00098 IObjectImplInternal(): refcount(1), weakref(0) {
00099 }
00103 IObject* getInterface(void* self, const UUID& uuid,
00104 const UUID_Info* uuidlist);
00105 };
00106
00107 #ifndef xplcdelete
00108
00112 #define xplcdelete delete
00113 #endif
00114
00123 #define IMPLEMENT_IOBJECT(component) \
00124 private: \
00125 IObjectImplInternal xplc_iobject_internal; \
00126 static const UUID_Info xplc_iobject_uuids[]; \
00127 typedef component ThisXPLCComponent; \
00128 public: \
00129 virtual unsigned int addRef() { \
00130 return ++xplc_iobject_internal.refcount; \
00131 } \
00132 virtual unsigned int release() { \
00133 if(--xplc_iobject_internal.refcount) \
00134 return xplc_iobject_internal.refcount; \
00135 \
00136 xplc_iobject_internal.refcount = 1; \
00137 if(xplc_iobject_internal.weakref) { \
00138 xplc_iobject_internal.weakref->release(); \
00139 xplc_iobject_internal.weakref->object = 0; \
00140 } \
00141 xplcdelete this; \
00142 return 0; \
00143 } \
00144 virtual IObject* getInterface(const UUID& uuid) { \
00145 return xplc_iobject_internal.getInterface(this, uuid, xplc_iobject_uuids); \
00146 } \
00147 virtual IWeakRef* getWeakRef() { \
00148 if(!xplc_iobject_internal.weakref) \
00149 xplc_iobject_internal.weakref = new WeakRef(reinterpret_cast<IObject*>(reinterpret_cast<ptrdiff_t>(this) + xplc_iobject_uuids->delta)); \
00150 xplc_iobject_internal.weakref->addRef(); \
00151 return xplc_iobject_internal.weakref; \
00152 }
00153
00158 class WeakRef: public IWeakRef {
00159 IMPLEMENT_IOBJECT(WeakRef);
00160 public:
00162 IObject* object;
00163 virtual IObject* getObject() {
00164 if(object)
00165 object->addRef();
00166
00167 return object;
00168 }
00172 WeakRef(IObject* aObj):
00173 object(aObj) {
00174 }
00175 };
00176
00183 template<class Interface>
00184 Interface* get(IObject* aObj) {
00185 if(!aObj)
00186 return 0;
00187
00188 return static_cast<Interface*>(aObj->getInterface(XPLC_IID<Interface>::get()));
00189 }
00190
00197 template<class Interface>
00198 Interface* mutate(IObject* aObj) {
00199 Interface* rv;
00200
00201 if(!aObj)
00202 return 0;
00203
00204 rv = static_cast<Interface*>(aObj->getInterface(XPLC_IID<Interface>::get()));
00205
00206 aObj->release();
00207
00208 return rv;
00209 }
00210
00211 #endif