OpenNI 1.3.2
|
00001 /**************************************************************************** 00002 * * 00003 * OpenNI 1.1 Alpha * 00004 * Copyright (C) 2011 PrimeSense Ltd. * 00005 * * 00006 * This file is part of OpenNI. * 00007 * * 00008 * OpenNI is free software: you can redistribute it and/or modify * 00009 * it under the terms of the GNU Lesser General Public License as published * 00010 * by the Free Software Foundation, either version 3 of the License, or * 00011 * (at your option) any later version. * 00012 * * 00013 * OpenNI is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00016 * GNU Lesser General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU Lesser General Public License * 00019 * along with OpenNI. If not, see <http://www.gnu.org/licenses/>. * 00020 * * 00021 ****************************************************************************/ 00022 #ifndef __XN_EVENT_H__ 00023 #define __XN_EVENT_H__ 00024 00025 //--------------------------------------------------------------------------- 00026 // Includes 00027 //--------------------------------------------------------------------------- 00028 #include "XnCallback.h" 00029 #include "XnList.h" 00030 #include "XnTypes.h" 00031 #include "XnOSCpp.h" 00032 00033 //--------------------------------------------------------------------------- 00034 // Types 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 // always add to list of added (actual list will be updated in Raise method, to allow registering 00072 // from a callback). 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 // return handle 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 // add it to a temp list, to allow unregistering from a callback (actual list will be updated in raise 00100 // function). 00101 { 00102 XnAutoCSLocker lock(m_hLock); 00103 00104 // try to remove it from the ToBeAdded list. 00105 if (!RemoveCallback(m_ToBeAdded, pObject)) 00106 { 00107 // it's not in this list, so it's probably in the main list 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 // first add all 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 // and now remove 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__