OpenNI 1.5.4: XnEvent.h Source File

OpenNI

OpenNI 1.5.4
XnEvent.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_H__
00023 #define __XN_EVENT_H__
00024 
00025 //---------------------------------------------------------------------------
00026 // Includes
00027 //---------------------------------------------------------------------------
00028 #include "XnCallback.h"
00029 #include "XnList.h"
00030 #include "XnTypes.h"
00031 #include "XnOSCpp.h"
00032 
00033 //---------------------------------------------------------------------------
00034 // Types
00035 //---------------------------------------------------------------------------
00036 class XnEventInterface
00037 {
00038 public:
00039     XnEventInterface() {}
00040     virtual ~XnEventInterface() {}
00041 
00042     typedef XnStatus (XN_CALLBACK_TYPE* HandlerPtr)(void* pCookie);
00043 
00044     virtual XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) = 0;
00045     virtual XnStatus Unregister(XnCallbackHandle handle) = 0;
00046 };
00047 
00048 class XnEvent : public XnEventInterface
00049 {
00050 public:
00051     XnEvent() : m_hLock(0) 
00052     {
00053         xnOSCreateCriticalSection(&m_hLock);
00054     }
00055 
00056     virtual ~XnEvent()
00057     {
00058         Clear();
00059         xnOSCloseCriticalSection(&m_hLock);
00060     }
00061 
00062     XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle)
00063     {
00064         XnStatus nRetVal = XN_STATUS_OK;
00065 
00066         XN_VALIDATE_INPUT_PTR(pFunc);
00067 
00068         XnCallback* pCallback = NULL;
00069         XN_VALIDATE_NEW(pCallback, XnCallback, (XnFuncPtr)pFunc, pCookie);
00070 
00071         // always add to list of added (actual list will be updated in Raise method, to allow registering 
00072         // from a callback).
00073         {
00074             XnAutoCSLocker lock(m_hLock);
00075             nRetVal = m_ToBeAdded.AddLast(pCallback);
00076         }
00077 
00078         if (nRetVal != XN_STATUS_OK)
00079         {
00080             XN_DELETE(pCallback);
00081             return (nRetVal);
00082         }
00083 
00084         // return handle
00085         if (pHandle != NULL)
00086         {
00087             *pHandle = pCallback;
00088         }
00089 
00090         return XN_STATUS_OK;
00091     }
00092 
00093     XnStatus Unregister(XnCallbackHandle handle)
00094     {
00095         XnStatus nRetVal = XN_STATUS_OK;
00096 
00097         XnCallback* pObject = (XnCallback*)handle;
00098 
00099         // add it to a temp list, to allow unregistering from a callback (actual list will be updated in raise
00100         // function).
00101         {
00102             XnAutoCSLocker lock(m_hLock);
00103 
00104             // try to remove it from the ToBeAdded list.
00105             if (!RemoveCallback(m_ToBeAdded, pObject))
00106             {
00107                 // it's not in this list, so it's probably in the main list
00108                 nRetVal = m_ToBeRemoved.AddLast(pObject);
00109             }
00110         }
00111         XN_IS_STATUS_OK(nRetVal);
00112 
00113         return XN_STATUS_OK;
00114     }
00115 
00116     XnStatus Clear()
00117     {
00118         ApplyListChanges();
00119 
00120         for (XnCallbackPtrList::ConstIterator it = m_Handlers.begin(); it != m_Handlers.end(); ++it)
00121         {
00122             XnCallback* pCallback = *it;
00123             XN_DELETE(pCallback);
00124         }
00125 
00126         m_Handlers.Clear();
00127         m_ToBeRemoved.Clear();
00128         m_ToBeAdded.Clear();
00129         return (XN_STATUS_OK);
00130     }
00131 
00132 protected:
00133     XnStatus ApplyListChanges()
00134     {
00135         // first add all
00136         for (XnCallbackPtrList::ConstIterator it = m_ToBeAdded.begin(); it != m_ToBeAdded.end(); ++it)
00137         {
00138             m_Handlers.AddLast(*it);
00139         }
00140         m_ToBeAdded.Clear();
00141 
00142         // and now remove
00143         for (XnCallbackPtrList::ConstIterator it = m_ToBeRemoved.begin(); it != m_ToBeRemoved.end(); ++it)
00144         {
00145             XnCallback* pCallback = *it;
00146             RemoveCallback(m_Handlers, pCallback);
00147         }
00148         m_ToBeRemoved.Clear();
00149 
00150         return (XN_STATUS_OK);
00151     }
00152 
00153 #if (XN_PLATFORM == XN_PLATFORM_WIN32)
00154 #pragma warning (push)
00155 #pragma warning (disable: 4127)
00156 #endif
00157 
00158     XN_DECLARE_LIST(XnCallback*, XnCallbackPtrList)
00159 
00160 #if (XN_PLATFORM == XN_PLATFORM_WIN32)
00161 #pragma warning (pop)
00162 #endif
00163 
00164     XN_CRITICAL_SECTION_HANDLE m_hLock;
00165     XnCallbackPtrList m_Handlers;
00166     XnCallbackPtrList m_ToBeAdded;
00167     XnCallbackPtrList m_ToBeRemoved;
00168 
00169 private:
00170     XnBool RemoveCallback(XnCallbackPtrList& list, XnCallback* pCallback)
00171     {
00172         XnCallbackPtrList::Iterator handlerIt = list.Find(pCallback);
00173         if (handlerIt != list.end())
00174         {
00175             list.Remove(handlerIt);
00176             XN_DELETE(pCallback);
00177             return TRUE;
00178         }
00179 
00180         return FALSE;
00181     }
00182 };
00183 
00184 #define _XN_RAISE_WITH_RET_CODE(args)                       \
00185     {                                                       \
00186         XnStatus nRetVal = pFunc(args pCallback->pCookie);  \
00187         if (nRetVal != XN_STATUS_OK)                        \
00188         {                                                   \
00189             XnEvent::ApplyListChanges();                    \
00190             return (nRetVal);                               \
00191         }                                                   \
00192     }
00193 
00194 #define _XN_RAISE_NO_RET_CODE(args)                     \
00195     pFunc(args pCallback->pCookie);
00196 
00201 #define _XN_DECLARE_EVENT_CLASS(_class, _interface, _retVal, _raise, _signature, _raise_sign)               \
00202     XN_PRAGMA_START_DISABLED_WARNING_SECTION(XN_HIDES_PARENT_METHOD_WARNING_ID)                             \
00203     class _interface : protected XnEvent                                                                    \
00204     {                                                                                                       \
00205     public:                                                                                                 \
00206         typedef _retVal (XN_CALLBACK_TYPE* HandlerPtr)(_signature);                                         \
00207         virtual XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) = 0;   \
00208         virtual XnStatus Unregister(XnCallbackHandle handle) = 0;                                           \
00209     };                                                                                                      \
00210     class _class : public _interface                                                                        \
00211     {                                                                                                       \
00212     public:                                                                                                 \
00213         XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL)                \
00214         {                                                                                                   \
00215             return XnEvent::Register((XnEvent::HandlerPtr)pFunc, pCookie, pHandle);                         \
00216         }                                                                                                   \
00217         XnStatus Unregister(XnCallbackHandle handle)                                                        \
00218         {                                                                                                   \
00219             return XnEvent::Unregister(handle);                                                             \
00220         }                                                                                                   \
00221         XnStatus Raise(_raise_sign)                                                                         \
00222         {                                                                                                   \
00223             XnAutoCSLocker lock(m_hLock);                                                                   \
00224             XnEvent::ApplyListChanges();                                                                    \
00225             XnEvent::XnCallbackPtrList::Iterator it = XnEvent::m_Handlers.begin();                          \
00226             for (; it != XnEvent::m_Handlers.end(); ++it)                                                   \
00227             {                                                                                               \
00228                 XnCallback* pCallback = *it;                                                                \
00229                 HandlerPtr pFunc = (HandlerPtr)pCallback->pFuncPtr;                                         \
00230                 _raise                                                                                      \
00231             }                                                                                               \
00232             XnEvent::ApplyListChanges();                                                                    \
00233             return (XN_STATUS_OK);                                                                          \
00234         }                                                                                                   \
00235         XnStatus Clear() { return XnEvent::Clear(); }                                                       \
00236     };                                                                                                      \
00237     XN_PRAGMA_STOP_DISABLED_WARNING_SECTION
00238 
00239 
00240 #define _XN_SIGNATURE_0ARG()
00241 #define _XN_FULL_SIGNATURE_0ARG()   void* pCookie
00242 #define _XN_ARGS_0ARG()
00243 
00244 #define _XN_SIGNATURE_1ARG(_type1, _name1)  _type1 _name1
00245 #define _XN_FULL_SIGNATURE_1ARG(_type1, _name1) _type1 _name1, void* pCookie
00246 #define _XN_ARGS_1ARG(_name1) _name1,
00247 
00248 #define _XN_SIGNATURE_2ARG(_type1, _name1, _type2, _name2)  _type1 _name1, _type2 _name2
00249 #define _XN_FULL_SIGNATURE_2ARG(_type1, _name1, _type2, _name2) _type1 _name1, _type2 _name2, void* pCookie
00250 #define _XN_ARGS_2ARG(_name1, _name2) _name1, _name2,
00251 
00252 #define _XN_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3)  _type1 _name1, _type2 _name2, _type3 _name3
00253 #define _XN_FULL_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3) _type1 _name1, _type2 _name2, _type3 _name3, void* pCookie
00254 #define _XN_ARGS_3ARG(_name1, _name2, _name3) _name1, _name2, _name3,
00255 
00256 #define _XN_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4)  _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4
00257 #define _XN_FULL_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4, void* pCookie
00258 #define _XN_ARGS_4ARG(_name1, _name2, _name3, _name4) _name1, _name2, _name3, _name4,
00259 
00260 #define _XN_SIGNATURE_5ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5)  _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4, _type5 _name5
00261 #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
00262 #define _XN_ARGS_5ARG(_name1, _name2, _name3, _name4, _name5) _name1, _name2, _name3, _name4, _name5,
00263 
00265 #define XN_DECLARE_EVENT_0ARG(_class, _interface)                                           \
00266     _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_0ARG()), _XN_FULL_SIGNATURE_0ARG(), _XN_SIGNATURE_0ARG())
00267 
00268 #define XN_DECLARE_EVENT_0ARG_RETVAL(_class, _interface)                                    \
00269     _XN_DECLARE_EVENT_CLASS(_class, _interface, XnStatus, _XN_RAISE_WITH_RET_CODE(_XN_ARGS_0ARG()), _XN_FULL_SIGNATURE_0ARG(), _XN_SIGNATURE_0ARG())
00270 
00271 #define XN_DECLARE_EVENT_1ARG(_class, _interface, _type1, _name1)                                           \
00272     _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))
00273 
00274 #define XN_DECLARE_EVENT_1ARG_RETVAL(_class, _interface, _type1, _name1)                                    \
00275     _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))
00276 
00277 #define XN_DECLARE_EVENT_2ARG(_class, _interface, _type1, _name1, _type2, _name2)                           \
00278     _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))
00279 
00280 #define XN_DECLARE_EVENT_2ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2)                    \
00281     _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))
00282 
00283 #define XN_DECLARE_EVENT_3ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3)           \
00284     _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))
00285 
00286 #define XN_DECLARE_EVENT_3ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3)    \
00287     _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))
00288 
00289 #define XN_DECLARE_EVENT_4ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4)           \
00290     _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))
00291 
00292 #define XN_DECLARE_EVENT_4ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4)            \
00293     _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))
00294 
00295 #define XN_DECLARE_EVENT_5ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5)           \
00296     _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))
00297 
00298 #define XN_DECLARE_EVENT_5ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5)            \
00299     _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))
00300 
00301 #endif //__XN_EVENT_H__
Generated on Wed May 16 2012 10:16:05 for OpenNI 1.5.4 by   doxygen 1.7.5.1