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