00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _XN_EVENT_T_H_
00023 #define _XN_EVENT_T_H_
00024
00025
00026
00027
00028 #include "XnOSCpp.h"
00029 #include "XnListT.h"
00030 #include "XnTypes.h"
00031
00032
00033
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
00079
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
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
00104
00105 {
00106 XnAutoCSLocker locker(m_hLock);
00107
00108
00109 if (!RemoveCallback(m_toAdd, pCallback))
00110 {
00111
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
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
00140 XnAutoCSLocker otherLocker(other.m_hLock);
00141
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
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
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
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
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_