00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __XN_EVENT_H__
00023 #define __XN_EVENT_H__
00024
00025
00026
00027
00028 #include "XnCallback.h"
00029 #include "XnList.h"
00030 #include "XnTypes.h"
00031 #include "XnOSCpp.h"
00032
00033
00034
00035
00036 class XnEventInterface
00037 {
00038 public:
00039 XnEventInterface() {}
00040 virtual ~XnEventInterface() {}
00041
00042 typedef XnStatus (XN_CALLBACK_TYPE* HandlerPtr)(void* pCookie);
00043
00044 virtual XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) = 0;
00045 virtual XnStatus Unregister(XnCallbackHandle handle) = 0;
00046 };
00047
00048 class XnEvent : public XnEventInterface
00049 {
00050 public:
00051 XnEvent() : m_hLock(0)
00052 {
00053 xnOSCreateCriticalSection(&m_hLock);
00054 }
00055
00056 virtual ~XnEvent()
00057 {
00058 Clear();
00059 xnOSCloseCriticalSection(&m_hLock);
00060 }
00061
00062 XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle)
00063 {
00064 XnStatus nRetVal = XN_STATUS_OK;
00065
00066 XN_VALIDATE_INPUT_PTR(pFunc);
00067
00068 XnCallback* pCallback = NULL;
00069 XN_VALIDATE_NEW(pCallback, XnCallback, (XnFuncPtr)pFunc, pCookie);
00070
00071
00072
00073 {
00074 XnAutoCSLocker lock(m_hLock);
00075 nRetVal = m_ToBeAdded.AddLast(pCallback);
00076 }
00077
00078 if (nRetVal != XN_STATUS_OK)
00079 {
00080 XN_DELETE(pCallback);
00081 return (nRetVal);
00082 }
00083
00084
00085 if (pHandle != NULL)
00086 {
00087 *pHandle = pCallback;
00088 }
00089
00090 return XN_STATUS_OK;
00091 }
00092
00093 XnStatus Unregister(XnCallbackHandle handle)
00094 {
00095 XnStatus nRetVal = XN_STATUS_OK;
00096
00097 XnCallback* pObject = (XnCallback*)handle;
00098
00099
00100
00101 {
00102 XnAutoCSLocker lock(m_hLock);
00103
00104
00105 if (!RemoveCallback(m_ToBeAdded, pObject))
00106 {
00107
00108 nRetVal = m_ToBeRemoved.AddLast(pObject);
00109 }
00110 }
00111 XN_IS_STATUS_OK(nRetVal);
00112
00113 return XN_STATUS_OK;
00114 }
00115
00116 XnStatus Clear()
00117 {
00118 ApplyListChanges();
00119
00120 for (XnCallbackPtrList::ConstIterator it = m_Handlers.begin(); it != m_Handlers.end(); ++it)
00121 {
00122 XnCallback* pCallback = *it;
00123 XN_DELETE(pCallback);
00124 }
00125
00126 m_Handlers.Clear();
00127 m_ToBeRemoved.Clear();
00128 m_ToBeAdded.Clear();
00129 return (XN_STATUS_OK);
00130 }
00131
00132 protected:
00133 XnStatus ApplyListChanges()
00134 {
00135
00136 for (XnCallbackPtrList::ConstIterator it = m_ToBeAdded.begin(); it != m_ToBeAdded.end(); ++it)
00137 {
00138 m_Handlers.AddLast(*it);
00139 }
00140 m_ToBeAdded.Clear();
00141
00142
00143 for (XnCallbackPtrList::ConstIterator it = m_ToBeRemoved.begin(); it != m_ToBeRemoved.end(); ++it)
00144 {
00145 XnCallback* pCallback = *it;
00146 RemoveCallback(m_Handlers, pCallback);
00147 }
00148 m_ToBeRemoved.Clear();
00149
00150 return (XN_STATUS_OK);
00151 }
00152
00153 #if (XN_PLATFORM == XN_PLATFORM_WIN32)
00154 #pragma warning (push)
00155 #pragma warning (disable: 4127)
00156 #endif
00157
00158 XN_DECLARE_LIST(XnCallback*, XnCallbackPtrList)
00159
00160 #if (XN_PLATFORM == XN_PLATFORM_WIN32)
00161 #pragma warning (pop)
00162 #endif
00163
00164 XN_CRITICAL_SECTION_HANDLE m_hLock;
00165 XnCallbackPtrList m_Handlers;
00166 XnCallbackPtrList m_ToBeAdded;
00167 XnCallbackPtrList m_ToBeRemoved;
00168
00169 private:
00170 XnBool RemoveCallback(XnCallbackPtrList& list, XnCallback* pCallback)
00171 {
00172 XnCallbackPtrList::Iterator handlerIt = list.Find(pCallback);
00173 if (handlerIt != list.end())
00174 {
00175 list.Remove(handlerIt);
00176 XN_DELETE(pCallback);
00177 return TRUE;
00178 }
00179
00180 return FALSE;
00181 }
00182 };
00183
00184 #define _XN_RAISE_WITH_RET_CODE(args) \
00185 nRetVal = pFunc(args pCallback->pCookie); \
00186 if (nRetVal != XN_STATUS_OK) \
00187 { \
00188 XnEvent::ApplyListChanges(); \
00189 return (nRetVal); \
00190 }
00191
00192 #define _XN_RAISE_NO_RET_CODE(args) \
00193 pFunc(args pCallback->pCookie);
00194
00199 #define _XN_DECLARE_EVENT_CLASS(_class, _interface, _retVal, _raise, _signature, _raise_sign) \
00200 class _interface : protected XnEvent \
00201 { \
00202 public: \
00203 typedef _retVal (XN_CALLBACK_TYPE* HandlerPtr)(_signature); \
00204 virtual XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) = 0; \
00205 virtual XnStatus Unregister(XnCallbackHandle handle) = 0; \
00206 }; \
00207 class _class : public _interface \
00208 { \
00209 public: \
00210 XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) \
00211 { \
00212 return XnEvent::Register((XnEvent::HandlerPtr)pFunc, pCookie, pHandle); \
00213 } \
00214 XnStatus Unregister(XnCallbackHandle handle) \
00215 { \
00216 return XnEvent::Unregister(handle); \
00217 } \
00218 XnStatus Raise(_raise_sign) \
00219 { \
00220 XnStatus nRetVal = XN_STATUS_OK; \
00221 XnAutoCSLocker lock(m_hLock); \
00222 XnEvent::ApplyListChanges(); \
00223 XnEvent::XnCallbackPtrList::Iterator it = XnEvent::m_Handlers.begin(); \
00224 for (; it != XnEvent::m_Handlers.end(); ++it) \
00225 { \
00226 XnCallback* pCallback = *it; \
00227 HandlerPtr pFunc = (HandlerPtr)pCallback->pFuncPtr; \
00228 _raise \
00229 } \
00230 XnEvent::ApplyListChanges(); \
00231 return (XN_STATUS_OK); \
00232 } \
00233 XnStatus Clear() { return XnEvent::Clear(); } \
00234 };
00235
00236 #define _XN_SIGNATURE_0ARG()
00237 #define _XN_FULL_SIGNATURE_0ARG() void* pCookie
00238 #define _XN_ARGS_0ARG()
00239
00240 #define _XN_SIGNATURE_1ARG(_type1, _name1) _type1 _name1
00241 #define _XN_FULL_SIGNATURE_1ARG(_type1, _name1) _type1 _name1, void* pCookie
00242 #define _XN_ARGS_1ARG(_name1) _name1,
00243
00244 #define _XN_SIGNATURE_2ARG(_type1, _name1, _type2, _name2) _type1 _name1, _type2 _name2
00245 #define _XN_FULL_SIGNATURE_2ARG(_type1, _name1, _type2, _name2) _type1 _name1, _type2 _name2, void* pCookie
00246 #define _XN_ARGS_2ARG(_name1, _name2) _name1, _name2,
00247
00248 #define _XN_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3) _type1 _name1, _type2 _name2, _type3 _name3
00249 #define _XN_FULL_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3) _type1 _name1, _type2 _name2, _type3 _name3, void* pCookie
00250 #define _XN_ARGS_3ARG(_name1, _name2, _name3) _name1, _name2, _name3,
00251
00252 #define _XN_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4
00253 #define _XN_FULL_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4, void* pCookie
00254 #define _XN_ARGS_4ARG(_name1, _name2, _name3, _name4) _name1, _name2, _name3, _name4,
00255
00256 #define _XN_SIGNATURE_5ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4, _type5 _name5
00257 #define _XN_FULL_SIGNATURE_5ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4, _type5 _name5, void* pCookie
00258 #define _XN_ARGS_5ARG(_name1, _name2, _name3, _name4, _name5) _name1, _name2, _name3, _name4, _name5,
00259
00261 #if XN_PLATFORM == XN_PLATFORM_WIN32
00262 #define XN_DECLARE_EVENT_0ARG(_class, _interface) \
00263 __pragma(warning(push))\
00264 __pragma(warning(disable:4189))\
00265 _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_0ARG()), _XN_FULL_SIGNATURE_0ARG(), _XN_SIGNATURE_0ARG())\
00266 __pragma(warning(pop))
00267 #else
00268 #define XN_DECLARE_EVENT_0ARG(_class, _interface) \
00269 _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_0ARG()), _XN_FULL_SIGNATURE_0ARG(), _XN_SIGNATURE_0ARG())
00270 #endif
00271
00272 #define XN_DECLARE_EVENT_0ARG_RETVAL(_class, _interface) \
00273 _XN_DECLARE_EVENT_CLASS(_class, _interface, XnStatus, _XN_RAISE_WITH_RET_CODE(_XN_ARGS_0ARG()), _XN_FULL_SIGNATURE_0ARG(), _XN_SIGNATURE_0ARG())
00274
00275 #define XN_DECLARE_EVENT_1ARG(_class, _interface, _type1, _name1) \
00276 _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_1ARG(_name1)), _XN_FULL_SIGNATURE_1ARG(_type1, _name1), _XN_SIGNATURE_1ARG(_type1, _name1))
00277
00278 #define XN_DECLARE_EVENT_1ARG_RETVAL(_class, _interface, _type1, _name1) \
00279 _XN_DECLARE_EVENT_CLASS(_class, _interface, XnStatus, _XN_RAISE_WITH_RET_CODE(_XN_ARGS_1ARG(_name1)), _XN_FULL_SIGNATURE_1ARG(_type1, _name1), _XN_SIGNATURE_1ARG(_type1, _name1))
00280
00281 #define XN_DECLARE_EVENT_2ARG(_class, _interface, _type1, _name1, _type2, _name2) \
00282 _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_2ARG(_name1, _name2)), _XN_FULL_SIGNATURE_2ARG(_type1, _name1, _type2, _name2), _XN_SIGNATURE_2ARG(_type1, _name1, _type2, _name2))
00283
00284 #define XN_DECLARE_EVENT_2ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2) \
00285 _XN_DECLARE_EVENT_CLASS(_class, _interface, XnStatus, _XN_RAISE_WITH_RET_CODE(_XN_ARGS_2ARG(_name1, _name2)), _XN_FULL_SIGNATURE_2ARG(_type1, _name1, _type2, _name2), _XN_SIGNATURE_2ARG(_type1, _name1, _type2, _name2))
00286
00287 #define XN_DECLARE_EVENT_3ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3) \
00288 _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_3ARG(_name1, _name2, _name3)), _XN_FULL_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3), _XN_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3))
00289
00290 #define XN_DECLARE_EVENT_3ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3) \
00291 _XN_DECLARE_EVENT_CLASS(_class, _interface, XnStatus, _XN_RAISE_WITH_RET_CODE(_XN_ARGS_3ARG(_name1, _name2, _name3)), _XN_FULL_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3), _XN_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3))
00292
00293 #define XN_DECLARE_EVENT_4ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) \
00294 _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_4ARG(_name1, _name2, _name3, _name4)), _XN_FULL_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4), _XN_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4))
00295
00296 #define XN_DECLARE_EVENT_4ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) \
00297 _XN_DECLARE_EVENT_CLASS(_class, _interface, XnStatus, _XN_RAISE_WITH_RET_CODE(_XN_ARGS_4ARG(_name1, _name2, _name3, _name4)), _XN_FULL_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4), _XN_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4))
00298
00299 #define XN_DECLARE_EVENT_5ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) \
00300 _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_5ARG(_name1, _name2, _name3, _name4, _name5)), _XN_FULL_SIGNATURE_5ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5), _XN_SIGNATURE_5ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5))
00301
00302 #define XN_DECLARE_EVENT_5ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) \
00303 _XN_DECLARE_EVENT_CLASS(_class, _interface, XnStatus, _XN_RAISE_WITH_RET_CODE(_XN_ARGS_5ARG(_name1, _name2, _name3, _name4, _name5)), _XN_FULL_SIGNATURE_5ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5), _XN_SIGNATURE_5ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5))
00304
00305 #endif //__XN_EVENT_H__