OpenNI 1.5.4: XnEventT.h Source File

OpenNI

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   doxygen 1.7.5.1