![]() |
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_T_H_ 00022 #define _XN_EVENT_T_H_ 00023 00024 //--------------------------------------------------------------------------- 00025 // Includes 00026 //--------------------------------------------------------------------------- 00027 #include "XnOSCpp.h" 00028 #include "XnListT.h" 00029 #include "XnTypes.h" 00030 00031 //--------------------------------------------------------------------------- 00032 // Types 00033 //--------------------------------------------------------------------------- 00034 00040 template<typename FuncPtr> 00041 struct XnCallbackT 00042 { 00043 XnCallbackT(FuncPtr func, void* cookie) : pFunc(func), pCookie(cookie) {} 00044 00045 FuncPtr pFunc; 00046 void* pCookie; 00047 }; 00048 00054 template<typename FuncPtr> 00055 class XnEventInterfaceT 00056 { 00057 public: 00058 typedef FuncPtr HandlerPtr; 00059 typedef XnCallbackT<FuncPtr> TCallback; 00060 typedef XnEventInterfaceT TInterface; 00061 00062 ~XnEventInterfaceT() 00063 { 00064 Clear(); 00065 xnOSCloseCriticalSection(&m_hLock); 00066 } 00067 00068 XnStatus Register(FuncPtr pFunc, void* pCookie, XnCallbackHandle& hCallback) 00069 { 00070 XnStatus nRetVal = XN_STATUS_OK; 00071 00072 XN_VALIDATE_INPUT_PTR(pFunc); 00073 00074 TCallback* pCallback = NULL; 00075 XN_VALIDATE_NEW(pCallback, TCallback, pFunc, pCookie); 00076 00077 // always add to list of added (actual list will be updated in Raise method, to allow registering 00078 // from a callback). 00079 { 00080 XnAutoCSLocker locker(m_hLock); 00081 nRetVal = m_toAdd.AddLast(pCallback); 00082 } 00083 00084 if (nRetVal != XN_STATUS_OK) 00085 { 00086 XN_DELETE(pCallback); 00087 return nRetVal; 00088 } 00089 00090 // return handle 00091 hCallback = (XnCallbackHandle)pCallback; 00092 00093 return XN_STATUS_OK; 00094 } 00095 00096 XnStatus Unregister(XnCallbackHandle hCallback) 00097 { 00098 XnStatus nRetVal = XN_STATUS_OK; 00099 00100 TCallback* pCallback = (TCallback*)hCallback; 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 locker(m_hLock); 00106 00107 // try to remove it from the ToBeAdded list. 00108 if (!RemoveCallback(m_toAdd, pCallback)) 00109 { 00110 // it's not in this list, so it's probably in the main list 00111 nRetVal = m_toRemove.AddLast(pCallback); 00112 } 00113 } 00114 XN_IS_STATUS_OK(nRetVal); 00115 00116 return XN_STATUS_OK; 00117 } 00118 00119 protected: 00120 typedef XnListT<TCallback*> CallbackPtrList; 00121 00122 // Constructors are protected, so that this class cannot be instantiated directly. 00123 XnEventInterfaceT() 00124 { 00125 Init(); 00126 } 00127 00128 XnEventInterfaceT(const XnEventInterfaceT& other) 00129 { 00130 Init(); 00131 *this = other; 00132 } 00133 00134 XnEventInterfaceT& operator=(const XnEventInterfaceT& other) 00135 { 00136 Clear(); 00137 00138 // lock other one (so it won't change while being copied) 00139 XnAutoCSLocker otherLocker(other.m_hLock); 00140 // lock this one (we're making changes) 00141 XnAutoCSLocker locker(m_hLock); 00142 00143 m_callbacks = other.m_callbacks; 00144 m_toAdd = other.m_toAdd; 00145 m_toRemove = other.m_toRemove; 00146 00147 ApplyListChanges(); 00148 00149 return *this; 00150 } 00151 00152 XnStatus Clear() 00153 { 00154 XnAutoCSLocker locker(m_hLock); 00155 ApplyListChanges(); 00156 00157 for (typename CallbackPtrList::ConstIterator it = m_callbacks.Begin(); it != m_callbacks.End(); ++it) 00158 { 00159 TCallback* pCallback = *it; 00160 XN_DELETE(pCallback); 00161 } 00162 00163 m_callbacks.Clear(); 00164 m_toRemove.Clear(); 00165 m_toAdd.Clear(); 00166 return (XN_STATUS_OK); 00167 } 00168 00169 XnStatus ApplyListChanges() 00170 { 00171 XnAutoCSLocker locker(m_hLock); 00172 00173 // first add all 00174 for (typename CallbackPtrList::ConstIterator it = m_toAdd.Begin(); it != m_toAdd.End(); ++it) 00175 { 00176 m_callbacks.AddLast(*it); 00177 } 00178 m_toAdd.Clear(); 00179 00180 // and now remove 00181 for (typename CallbackPtrList::ConstIterator it = m_toRemove.Begin(); it != m_toRemove.End(); ++it) 00182 { 00183 TCallback* pCallback = *it; 00184 RemoveCallback(m_callbacks, pCallback); 00185 } 00186 m_toRemove.Clear(); 00187 00188 return (XN_STATUS_OK); 00189 } 00190 00191 XnBool RemoveCallback(CallbackPtrList& list, TCallback* pCallback) 00192 { 00193 typename CallbackPtrList::Iterator it = list.Find(pCallback); 00194 if (it != list.End()) 00195 { 00196 list.Remove(it); 00197 XN_DELETE(pCallback); 00198 return TRUE; 00199 } 00200 00201 return FALSE; 00202 } 00203 00204 XN_CRITICAL_SECTION_HANDLE m_hLock; 00205 CallbackPtrList m_callbacks; 00206 CallbackPtrList m_toAdd; 00207 CallbackPtrList m_toRemove; 00208 00209 private: 00210 void Init() 00211 { 00212 m_hLock = NULL; 00213 XnStatus nRetVal = xnOSCreateCriticalSection(&m_hLock); 00214 if (nRetVal != XN_STATUS_OK) 00215 { 00216 XN_ASSERT(FALSE); 00217 } 00218 } 00219 }; 00220 00221 // Handlers 00222 struct XnHandlerFuncNoArgs 00223 { 00224 typedef void (XN_CALLBACK_TYPE* FuncPtr)(void* pCookie); 00225 }; 00226 00227 template<class TArg1> 00228 struct XnHandlerFunc1Arg 00229 { 00230 typedef void (XN_CALLBACK_TYPE* FuncPtr)(TArg1 arg1, void* pCookie); 00231 }; 00232 00233 template<class TArg1, class TArg2> 00234 struct XnHandlerFunc2Args 00235 { 00236 typedef void (XN_CALLBACK_TYPE* FuncPtr)(TArg1 arg1, TArg2 arg2, void* pCookie); 00237 }; 00238 00239 template<class TArg1, class TArg2, class TArg3> 00240 struct XnHandlerFunc3Args 00241 { 00242 typedef void (XN_CALLBACK_TYPE* FuncPtr)(TArg1 arg1, TArg2 arg2, TArg3 arg3, void* pCookie); 00243 }; 00244 00245 template<class TArg1, class TArg2, class TArg3, class TArg4> 00246 struct XnHandlerFunc4Args 00247 { 00248 typedef void (XN_CALLBACK_TYPE* FuncPtr)(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, void* pCookie); 00249 }; 00250 00251 template<class TArg1, class TArg2, class TArg3, class TArg4, class TArg5> 00252 struct XnHandlerFunc5Args 00253 { 00254 typedef void (XN_CALLBACK_TYPE* FuncPtr)(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, void* pCookie); 00255 }; 00256 00257 // Event classes (there's a class per number of arguments) 00258 class XnEventNoArgs : public XnEventInterfaceT<XnHandlerFuncNoArgs::FuncPtr> 00259 { 00260 public: 00261 XnStatus Raise() 00262 { 00263 XnAutoCSLocker locker(this->m_hLock); 00264 ApplyListChanges(); 00265 00266 for (CallbackPtrList::ConstIterator it = m_callbacks.Begin(); it != m_callbacks.End(); ++it) 00267 { 00268 TCallback* pCallback = *it; 00269 pCallback->pFunc(pCallback->pCookie); 00270 } 00271 00272 ApplyListChanges(); 00273 return (XN_STATUS_OK); 00274 } 00275 }; 00276 00277 00278 template<class TArg1> 00279 class XnEvent1Arg : public XnEventInterfaceT<typename XnHandlerFunc1Arg<TArg1>::FuncPtr> 00280 { 00281 typedef XnEventInterfaceT<typename XnHandlerFunc1Arg<TArg1>::FuncPtr> Base; 00282 00283 public: 00284 XnStatus Raise(TArg1 arg) 00285 { 00286 XnAutoCSLocker locker(this->m_hLock); 00287 this->ApplyListChanges(); 00288 00289 for (typename Base::CallbackPtrList::ConstIterator it = this->m_callbacks.Begin(); it != this->m_callbacks.End(); ++it) 00290 { 00291 typename Base::TCallback* pCallback = *it; 00292 pCallback->pFunc(arg, pCallback->pCookie); 00293 } 00294 00295 this->ApplyListChanges(); 00296 return (XN_STATUS_OK); 00297 } 00298 }; 00299 00300 template<class TEventArgs> 00301 class XnEventT : public XnEvent1Arg<const TEventArgs&> 00302 {}; 00303 00304 template<class TArg1, class TArg2> 00305 class XnEvent2Args : public XnEventInterfaceT<typename XnHandlerFunc2Args<TArg1, TArg2>::FuncPtr> 00306 { 00307 typedef XnEventInterfaceT<typename XnHandlerFunc2Args<TArg1, TArg2>::FuncPtr> Base; 00308 00309 public: 00310 XnStatus Raise(TArg1 arg1, TArg2 arg2) 00311 { 00312 XnAutoCSLocker locker(this->m_hLock); 00313 this->ApplyListChanges(); 00314 00315 for (typename Base::CallbackPtrList::ConstIterator it = this->m_callbacks.Begin(); it != this->m_callbacks.End(); ++it) 00316 { 00317 typename Base::TCallback* pCallback = *it; 00318 pCallback->pFunc(arg1, arg2, pCallback->pCookie); 00319 } 00320 00321 this->ApplyListChanges(); 00322 return (XN_STATUS_OK); 00323 } 00324 }; 00325 00326 template<class TArg1, class TArg2, class TArg3> 00327 class XnEvent3Args : public XnEventInterfaceT<typename XnHandlerFunc3Args<TArg1, TArg2, TArg3>::FuncPtr> 00328 { 00329 typedef XnEventInterfaceT<typename XnHandlerFunc3Args<TArg1, TArg2, TArg3>::FuncPtr> Base; 00330 00331 public: 00332 XnStatus Raise(TArg1 arg1, TArg2 arg2, TArg3 arg3) 00333 { 00334 XnAutoCSLocker locker(this->m_hLock); 00335 this->ApplyListChanges(); 00336 00337 for (typename Base::CallbackPtrList::ConstIterator it = this->m_callbacks.Begin(); it != this->m_callbacks.End(); ++it) 00338 { 00339 typename Base::TCallback* pCallback = *it; 00340 pCallback->pFunc(arg1, arg2, arg3, pCallback->pCookie); 00341 } 00342 00343 this->ApplyListChanges(); 00344 return (XN_STATUS_OK); 00345 } 00346 }; 00347 00348 template<class TArg1, class TArg2, class TArg3, class TArg4> 00349 class XnEvent4Args : public XnEventInterfaceT<typename XnHandlerFunc4Args<TArg1, TArg2, TArg3, TArg4>::FuncPtr> 00350 { 00351 typedef XnEventInterfaceT<typename XnHandlerFunc4Args<TArg1, TArg2, TArg3, TArg4>::FuncPtr> Base; 00352 00353 public: 00354 XnStatus Raise(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4) 00355 { 00356 XnAutoCSLocker locker(this->m_hLock); 00357 this->ApplyListChanges(); 00358 00359 for (typename Base::CallbackPtrList::ConstIterator it = this->m_callbacks.Begin(); it != this->m_callbacks.End(); ++it) 00360 { 00361 typename Base::TCallback* pCallback = *it; 00362 pCallback->pFunc(arg1, arg2, arg3, arg4, pCallback->pCookie); 00363 } 00364 00365 this->ApplyListChanges(); 00366 return (XN_STATUS_OK); 00367 } 00368 }; 00369 00370 template<class TArg1, class TArg2, class TArg3, class TArg4, class TArg5> 00371 class XnEvent5Args : public XnEventInterfaceT<typename XnHandlerFunc5Args<TArg1, TArg2, TArg3, TArg4, TArg5>::FuncPtr> 00372 { 00373 typedef XnEventInterfaceT<typename XnHandlerFunc5Args<TArg1, TArg2, TArg3, TArg4, TArg5>::FuncPtr> Base; 00374 00375 public: 00376 XnStatus Raise(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5) 00377 { 00378 XnAutoCSLocker locker(this->m_hLock); 00379 this->ApplyListChanges(); 00380 00381 for (typename Base::CallbackPtrList::ConstIterator it = this->m_callbacks.Begin(); it != this->m_callbacks.End(); ++it) 00382 { 00383 typename Base::TCallback* pCallback = *it; 00384 pCallback->pFunc(arg1, arg2, arg3, arg4, arg5, pCallback->pCookie); 00385 } 00386 00387 this->ApplyListChanges(); 00388 return (XN_STATUS_OK); 00389 } 00390 }; 00391 00392 #endif // _XN_EVENT_T_H_