OpenNI 1.0.0
|
00001 /***************************************************************************** 00002 * * 00003 * OpenNI 1.0 Alpha * 00004 * Copyright (C) 2010 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 00023 00024 00025 #ifndef __XN_EVENT_H__ 00026 #define __XN_EVENT_H__ 00027 00028 //--------------------------------------------------------------------------- 00029 // Includes 00030 //--------------------------------------------------------------------------- 00031 #include "XnCallback.h" 00032 #include "XnList.h" 00033 #include "XnTypes.h" 00034 #include "XnOSCpp.h" 00035 00036 //--------------------------------------------------------------------------- 00037 // Types 00038 //--------------------------------------------------------------------------- 00039 class XnEventInterface 00040 { 00041 public: 00042 XnEventInterface() {} 00043 virtual ~XnEventInterface() {} 00044 00045 typedef XnStatus (XN_CALLBACK_TYPE* HandlerPtr)(void* pCookie); 00046 00047 virtual XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) = 0; 00048 virtual XnStatus Unregister(XnCallbackHandle handle) = 0; 00049 }; 00050 00051 class XnEvent : public XnEventInterface 00052 { 00053 public: 00054 XnEvent() : m_hLock(0) 00055 { 00056 xnOSCreateCriticalSection(&m_hLock); 00057 } 00058 00059 ~XnEvent() 00060 { 00061 Clear(); 00062 xnOSCloseCriticalSection(&m_hLock); 00063 } 00064 00065 XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle) 00066 { 00067 XnStatus nRetVal = XN_STATUS_OK; 00068 00069 XN_VALIDATE_INPUT_PTR(pFunc); 00070 00071 XnCallback* pCallback = NULL; 00072 XN_VALIDATE_NEW(pCallback, XnCallback, (void*)pFunc, pCookie); 00073 00074 // always add to list of added (actual list will be updated in Raise method, to allow registering 00075 // from a callback). 00076 { 00077 XnAutoCSLocker lock(m_hLock); 00078 nRetVal = m_ToBeAdded.AddLast(pCallback); 00079 } 00080 00081 if (nRetVal != XN_STATUS_OK) 00082 { 00083 XN_DELETE(pCallback); 00084 return (nRetVal); 00085 } 00086 00087 // return handle 00088 if (pHandle != NULL) 00089 { 00090 *pHandle = pCallback; 00091 } 00092 00093 return XN_STATUS_OK; 00094 } 00095 00096 XnStatus Unregister(XnCallbackHandle handle) 00097 { 00098 XnStatus nRetVal = XN_STATUS_OK; 00099 00100 XnCallback* pObject = (XnCallback*)handle; 00101 00102 // add it to a temp list, to allow unregistering from a callback (actual list will be updated in raise 00103 // function). 00104 { 00105 XnAutoCSLocker lock(m_hLock); 00106 nRetVal = m_ToBeRemoved.AddLast(pObject); 00107 } 00108 XN_IS_STATUS_OK(nRetVal); 00109 00110 return XN_STATUS_OK; 00111 } 00112 00113 XnStatus Clear() 00114 { 00115 ApplyListChanges(); 00116 00117 for (XnCallbackPtrList::ConstIterator it = m_Handlers.begin(); it != m_Handlers.end(); ++it) 00118 { 00119 XnCallback* pCallback = *it; 00120 XN_DELETE(pCallback); 00121 } 00122 00123 m_Handlers.Clear(); 00124 m_ToBeRemoved.Clear(); 00125 m_ToBeAdded.Clear(); 00126 return (XN_STATUS_OK); 00127 } 00128 00129 protected: 00130 XnStatus ApplyListChanges() 00131 { 00132 XnStatus nRetVal = XN_STATUS_OK; 00133 00134 // first add all 00135 for (XnCallbackPtrList::ConstIterator it = m_ToBeAdded.begin(); it != m_ToBeAdded.end(); ++it) 00136 { 00137 m_Handlers.AddLast(*it); 00138 } 00139 m_ToBeAdded.Clear(); 00140 00141 // and now remove 00142 for (XnCallbackPtrList::ConstIterator it = m_ToBeRemoved.begin(); it != m_ToBeRemoved.end(); ++it) 00143 { 00144 XnCallback* pCallback = *it; 00145 00146 // check if it's in the list 00147 XnCallbackPtrList::Iterator handlerIt = m_Handlers.Find(pCallback); 00148 if (handlerIt != m_Handlers.end()) 00149 { 00150 m_Handlers.Remove(handlerIt); 00151 } 00152 00153 XN_DELETE(pCallback); 00154 } 00155 m_ToBeRemoved.Clear(); 00156 00157 return (XN_STATUS_OK); 00158 } 00159 00160 XN_DECLARE_LIST(XnCallback*, XnCallbackPtrList) 00161 00162 XN_CRITICAL_SECTION_HANDLE m_hLock; 00163 XnCallbackPtrList m_Handlers; 00164 XnCallbackPtrList m_ToBeAdded; 00165 XnCallbackPtrList m_ToBeRemoved; 00166 }; 00167 00168 #define _XN_RAISE_WITH_RET_CODE(args) \ 00169 nRetVal = pFunc(args pCallback->pCookie); \ 00170 if (nRetVal != XN_STATUS_OK) \ 00171 { \ 00172 XnEvent::ApplyListChanges(); \ 00173 return (nRetVal); \ 00174 } 00175 00176 #define _XN_RAISE_NO_RET_CODE(args) \ 00177 pFunc(args pCallback->pCookie); 00178 00183 #define _XN_DECLARE_EVENT_CLASS(_class, _interface, _retVal, _raise, _signature, _raise_sign) \ 00184 class _interface : protected XnEvent \ 00185 { \ 00186 public: \ 00187 typedef _retVal (XN_CALLBACK_TYPE* HandlerPtr)(_signature); \ 00188 virtual XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) = 0; \ 00189 virtual XnStatus Unregister(XnCallbackHandle handle) = 0; \ 00190 }; \ 00191 class _class : public _interface \ 00192 { \ 00193 public: \ 00194 XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) \ 00195 { \ 00196 return XnEvent::Register((XnEvent::HandlerPtr)pFunc, pCookie, pHandle); \ 00197 } \ 00198 XnStatus Unregister(XnCallbackHandle handle) \ 00199 { \ 00200 return XnEvent::Unregister(handle); \ 00201 } \ 00202 XnStatus Raise(_raise_sign) \ 00203 { \ 00204 XnStatus nRetVal = XN_STATUS_OK; \ 00205 XnAutoCSLocker lock(m_hLock); \ 00206 XnEvent::ApplyListChanges(); \ 00207 XnEvent::XnCallbackPtrList::Iterator it = XnEvent::m_Handlers.begin(); \ 00208 for (; it != XnEvent::m_Handlers.end(); ++it) \ 00209 { \ 00210 XnCallback* pCallback = *it; \ 00211 HandlerPtr pFunc = (HandlerPtr)pCallback->pFuncPtr; \ 00212 _raise \ 00213 } \ 00214 XnEvent::ApplyListChanges(); \ 00215 return (XN_STATUS_OK); \ 00216 } \ 00217 XnStatus Clear() { return XnEvent::Clear(); } \ 00218 }; 00219 00220 #define _XN_SIGNATURE_0ARG() 00221 #define _XN_FULL_SIGNATURE_0ARG() void* pCookie 00222 #define _XN_ARGS_0ARG() 00223 00224 #define _XN_SIGNATURE_1ARG(_type1, _name1) _type1 _name1 00225 #define _XN_FULL_SIGNATURE_1ARG(_type1, _name1) _type1 _name1, void* pCookie 00226 #define _XN_ARGS_1ARG(_name1) _name1, 00227 00228 #define _XN_SIGNATURE_2ARG(_type1, _name1, _type2, _name2) _type1 _name1, _type2 _name2 00229 #define _XN_FULL_SIGNATURE_2ARG(_type1, _name1, _type2, _name2) _type1 _name1, _type2 _name2, void* pCookie 00230 #define _XN_ARGS_2ARG(_name1, _name2) _name1, _name2, 00231 00232 #define _XN_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3) _type1 _name1, _type2 _name2, _type3 _name3 00233 #define _XN_FULL_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3) _type1 _name1, _type2 _name2, _type3 _name3, void* pCookie 00234 #define _XN_ARGS_3ARG(_name1, _name2, _name3) _name1, _name2, _name3, 00235 00236 #define _XN_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4 00237 #define _XN_FULL_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4, void* pCookie 00238 #define _XN_ARGS_4ARG(_name1, _name2, _name3, _name4) _name1, _name2, _name3, _name4, 00239 00240 #define _XN_SIGNATURE_5ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4, _type5 _name5 00241 #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 00242 #define _XN_ARGS_5ARG(_name1, _name2, _name3, _name4, _name5) _name1, _name2, _name3, _name4, _name5, 00243 00245 #define XN_DECLARE_EVENT_0ARG(_class, _interface) \ 00246 _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_0ARG()), _XN_FULL_SIGNATURE_0ARG(), _XN_SIGNATURE_0ARG()) 00247 00248 #define XN_DECLARE_EVENT_0ARG_RETVAL(_class, _interface) \ 00249 _XN_DECLARE_EVENT_CLASS(_class, _interface, XnStatus, _XN_RAISE_WITH_RET_CODE(_XN_ARGS_0ARG()), _XN_FULL_SIGNATURE_0ARG(), _XN_SIGNATURE_0ARG()) 00250 00251 #define XN_DECLARE_EVENT_1ARG(_class, _interface, _type1, _name1) \ 00252 _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)) 00253 00254 #define XN_DECLARE_EVENT_1ARG_RETVAL(_class, _interface, _type1, _name1) \ 00255 _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)) 00256 00257 #define XN_DECLARE_EVENT_2ARG(_class, _interface, _type1, _name1, _type2, _name2) \ 00258 _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)) 00259 00260 #define XN_DECLARE_EVENT_2ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2) \ 00261 _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)) 00262 00263 #define XN_DECLARE_EVENT_3ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3) \ 00264 _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)) 00265 00266 #define XN_DECLARE_EVENT_3ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3) \ 00267 _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)) 00268 00269 #define XN_DECLARE_EVENT_4ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) \ 00270 _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)) 00271 00272 #define XN_DECLARE_EVENT_4ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) \ 00273 _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)) 00274 00275 #define XN_DECLARE_EVENT_5ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) \ 00276 _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)) 00277 00278 #define XN_DECLARE_EVENT_5ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) \ 00279 _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)) 00280 00281 #endif //__XN_EVENT_H__