![]() |
OpenNI 1.5.7
|
00001 /***************************************************************************** 00002 * * 00003 * OpenNI 1.x Alpha * 00004 * Copyright (C) 2012 PrimeSense Ltd. * 00005 * * 00006 * This file is part of OpenNI. * 00007 * * 00008 * Licensed under the Apache License, Version 2.0 (the "License"); * 00009 * you may not use this file except in compliance with the License. * 00010 * You may obtain a copy of the License at * 00011 * * 00012 * http://www.apache.org/licenses/LICENSE-2.0 * 00013 * * 00014 * Unless required by applicable law or agreed to in writing, software * 00015 * distributed under the License is distributed on an "AS IS" BASIS, * 00016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 00017 * See the License for the specific language governing permissions and * 00018 * limitations under the License. * 00019 * * 00020 *****************************************************************************/ 00021 #ifndef __XN_EVENT_H__ 00022 #define __XN_EVENT_H__ 00023 00024 //--------------------------------------------------------------------------- 00025 // Includes 00026 //--------------------------------------------------------------------------- 00027 #include "XnCallback.h" 00028 #include "XnList.h" 00029 #include "XnTypes.h" 00030 #include "XnOSCpp.h" 00031 00032 //--------------------------------------------------------------------------- 00033 // Types 00034 //--------------------------------------------------------------------------- 00035 class XnEventInterface 00036 { 00037 public: 00038 XnEventInterface() {} 00039 virtual ~XnEventInterface() {} 00040 00041 typedef XnStatus (XN_CALLBACK_TYPE* HandlerPtr)(void* pCookie); 00042 00043 virtual XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) = 0; 00044 virtual XnStatus Unregister(XnCallbackHandle handle) = 0; 00045 }; 00046 00047 class XnEvent : public XnEventInterface 00048 { 00049 public: 00050 XnEvent() : m_hLock(0) 00051 { 00052 xnOSCreateCriticalSection(&m_hLock); 00053 } 00054 00055 virtual ~XnEvent() 00056 { 00057 Clear(); 00058 xnOSCloseCriticalSection(&m_hLock); 00059 } 00060 00061 XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle) 00062 { 00063 XnStatus nRetVal = XN_STATUS_OK; 00064 00065 XN_VALIDATE_INPUT_PTR(pFunc); 00066 00067 XnCallback* pCallback = NULL; 00068 XN_VALIDATE_NEW(pCallback, XnCallback, (XnFuncPtr)pFunc, pCookie); 00069 00070 // always add to list of added (actual list will be updated in Raise method, to allow registering 00071 // from a callback). 00072 { 00073 XnAutoCSLocker lock(m_hLock); 00074 nRetVal = m_ToBeAdded.AddLast(pCallback); 00075 } 00076 00077 if (nRetVal != XN_STATUS_OK) 00078 { 00079 XN_DELETE(pCallback); 00080 return (nRetVal); 00081 } 00082 00083 // return handle 00084 if (pHandle != NULL) 00085 { 00086 *pHandle = pCallback; 00087 } 00088 00089 return XN_STATUS_OK; 00090 } 00091 00092 XnStatus Unregister(XnCallbackHandle handle) 00093 { 00094 XnStatus nRetVal = XN_STATUS_OK; 00095 00096 XnCallback* pObject = (XnCallback*)handle; 00097 00098 // add it to a temp list, to allow unregistering from a callback (actual list will be updated in raise 00099 // function). 00100 { 00101 XnAutoCSLocker lock(m_hLock); 00102 00103 // try to remove it from the ToBeAdded list. 00104 if (!RemoveCallback(m_ToBeAdded, pObject)) 00105 { 00106 // it's not in this list, so it's probably in the main list 00107 nRetVal = m_ToBeRemoved.AddLast(pObject); 00108 } 00109 } 00110 XN_IS_STATUS_OK(nRetVal); 00111 00112 return XN_STATUS_OK; 00113 } 00114 00115 XnStatus Clear() 00116 { 00117 ApplyListChanges(); 00118 00119 for (XnCallbackPtrList::ConstIterator it = m_Handlers.begin(); it != m_Handlers.end(); ++it) 00120 { 00121 XnCallback* pCallback = *it; 00122 XN_DELETE(pCallback); 00123 } 00124 00125 m_Handlers.Clear(); 00126 m_ToBeRemoved.Clear(); 00127 m_ToBeAdded.Clear(); 00128 return (XN_STATUS_OK); 00129 } 00130 00131 protected: 00132 XnStatus ApplyListChanges() 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 RemoveCallback(m_Handlers, pCallback); 00146 } 00147 m_ToBeRemoved.Clear(); 00148 00149 return (XN_STATUS_OK); 00150 } 00151 00152 #if (XN_PLATFORM == XN_PLATFORM_WIN32) 00153 #pragma warning (push) 00154 #pragma warning (disable: 4127) 00155 #endif 00156 00157 XN_DECLARE_LIST(XnCallback*, XnCallbackPtrList) 00158 00159 #if (XN_PLATFORM == XN_PLATFORM_WIN32) 00160 #pragma warning (pop) 00161 #endif 00162 00163 XN_CRITICAL_SECTION_HANDLE m_hLock; 00164 XnCallbackPtrList m_Handlers; 00165 XnCallbackPtrList m_ToBeAdded; 00166 XnCallbackPtrList m_ToBeRemoved; 00167 00168 private: 00169 XnBool RemoveCallback(XnCallbackPtrList& list, XnCallback* pCallback) 00170 { 00171 XnCallbackPtrList::Iterator handlerIt = list.Find(pCallback); 00172 if (handlerIt != list.end()) 00173 { 00174 list.Remove(handlerIt); 00175 XN_DELETE(pCallback); 00176 return TRUE; 00177 } 00178 00179 return FALSE; 00180 } 00181 }; 00182 00183 #define _XN_RAISE_WITH_RET_CODE(args) \ 00184 { \ 00185 XnStatus nRetVal = pFunc(args pCallback->pCookie); \ 00186 if (nRetVal != XN_STATUS_OK) \ 00187 { \ 00188 XnEvent::ApplyListChanges(); \ 00189 return (nRetVal); \ 00190 } \ 00191 } 00192 00193 #define _XN_RAISE_NO_RET_CODE(args) \ 00194 pFunc(args pCallback->pCookie); 00195 00200 #define _XN_DECLARE_EVENT_CLASS(_class, _interface, _retVal, _raise, _signature, _raise_sign) \ 00201 XN_PRAGMA_START_DISABLED_WARNING_SECTION(XN_HIDES_PARENT_METHOD_WARNING_ID) \ 00202 class _interface : protected XnEvent \ 00203 { \ 00204 public: \ 00205 typedef _retVal (XN_CALLBACK_TYPE* HandlerPtr)(_signature); \ 00206 virtual XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) = 0; \ 00207 virtual XnStatus Unregister(XnCallbackHandle handle) = 0; \ 00208 }; \ 00209 class _class : public _interface \ 00210 { \ 00211 public: \ 00212 XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) \ 00213 { \ 00214 return XnEvent::Register((XnEvent::HandlerPtr)pFunc, pCookie, pHandle); \ 00215 } \ 00216 XnStatus Unregister(XnCallbackHandle handle) \ 00217 { \ 00218 return XnEvent::Unregister(handle); \ 00219 } \ 00220 XnStatus Raise(_raise_sign) \ 00221 { \ 00222 XnAutoCSLocker lock(m_hLock); \ 00223 XnEvent::ApplyListChanges(); \ 00224 XnEvent::XnCallbackPtrList::Iterator it = XnEvent::m_Handlers.begin(); \ 00225 for (; it != XnEvent::m_Handlers.end(); ++it) \ 00226 { \ 00227 XnCallback* pCallback = *it; \ 00228 HandlerPtr pFunc = (HandlerPtr)pCallback->pFuncPtr; \ 00229 _raise \ 00230 } \ 00231 XnEvent::ApplyListChanges(); \ 00232 return (XN_STATUS_OK); \ 00233 } \ 00234 XnStatus Clear() { return XnEvent::Clear(); } \ 00235 }; \ 00236 XN_PRAGMA_STOP_DISABLED_WARNING_SECTION 00237 00238 00239 #define _XN_SIGNATURE_0ARG() 00240 #define _XN_FULL_SIGNATURE_0ARG() void* pCookie 00241 #define _XN_ARGS_0ARG() 00242 00243 #define _XN_SIGNATURE_1ARG(_type1, _name1) _type1 _name1 00244 #define _XN_FULL_SIGNATURE_1ARG(_type1, _name1) _type1 _name1, void* pCookie 00245 #define _XN_ARGS_1ARG(_name1) _name1, 00246 00247 #define _XN_SIGNATURE_2ARG(_type1, _name1, _type2, _name2) _type1 _name1, _type2 _name2 00248 #define _XN_FULL_SIGNATURE_2ARG(_type1, _name1, _type2, _name2) _type1 _name1, _type2 _name2, void* pCookie 00249 #define _XN_ARGS_2ARG(_name1, _name2) _name1, _name2, 00250 00251 #define _XN_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3) _type1 _name1, _type2 _name2, _type3 _name3 00252 #define _XN_FULL_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3) _type1 _name1, _type2 _name2, _type3 _name3, void* pCookie 00253 #define _XN_ARGS_3ARG(_name1, _name2, _name3) _name1, _name2, _name3, 00254 00255 #define _XN_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4 00256 #define _XN_FULL_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4, void* pCookie 00257 #define _XN_ARGS_4ARG(_name1, _name2, _name3, _name4) _name1, _name2, _name3, _name4, 00258 00259 #define _XN_SIGNATURE_5ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4, _type5 _name5 00260 #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 00261 #define _XN_ARGS_5ARG(_name1, _name2, _name3, _name4, _name5) _name1, _name2, _name3, _name4, _name5, 00262 00264 #define XN_DECLARE_EVENT_0ARG(_class, _interface) \ 00265 _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_0ARG()), _XN_FULL_SIGNATURE_0ARG(), _XN_SIGNATURE_0ARG()) 00266 00267 #define XN_DECLARE_EVENT_0ARG_RETVAL(_class, _interface) \ 00268 _XN_DECLARE_EVENT_CLASS(_class, _interface, XnStatus, _XN_RAISE_WITH_RET_CODE(_XN_ARGS_0ARG()), _XN_FULL_SIGNATURE_0ARG(), _XN_SIGNATURE_0ARG()) 00269 00270 #define XN_DECLARE_EVENT_1ARG(_class, _interface, _type1, _name1) \ 00271 _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)) 00272 00273 #define XN_DECLARE_EVENT_1ARG_RETVAL(_class, _interface, _type1, _name1) \ 00274 _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)) 00275 00276 #define XN_DECLARE_EVENT_2ARG(_class, _interface, _type1, _name1, _type2, _name2) \ 00277 _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)) 00278 00279 #define XN_DECLARE_EVENT_2ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2) \ 00280 _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)) 00281 00282 #define XN_DECLARE_EVENT_3ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3) \ 00283 _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)) 00284 00285 #define XN_DECLARE_EVENT_3ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3) \ 00286 _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)) 00287 00288 #define XN_DECLARE_EVENT_4ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) \ 00289 _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)) 00290 00291 #define XN_DECLARE_EVENT_4ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) \ 00292 _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)) 00293 00294 #define XN_DECLARE_EVENT_5ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) \ 00295 _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)) 00296 00297 #define XN_DECLARE_EVENT_5ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) \ 00298 _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)) 00299 00300 #endif //__XN_EVENT_H__