mirror of https://github.com/qt/qtdatavis3d.git
302 lines
13 KiB
C++
302 lines
13 KiB
C++
/****************************************************************************
|
|
* *
|
|
* OpenNI 1.x Alpha *
|
|
* Copyright (C) 2011 PrimeSense Ltd. *
|
|
* *
|
|
* This file is part of OpenNI. *
|
|
* *
|
|
* OpenNI is free software: you can redistribute it and/or modify *
|
|
* it under the terms of the GNU Lesser General Public License as published *
|
|
* by the Free Software Foundation, either version 3 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* OpenNI is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU Lesser General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Lesser General Public License *
|
|
* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
|
|
* *
|
|
****************************************************************************/
|
|
#ifndef __XN_EVENT_H__
|
|
#define __XN_EVENT_H__
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Includes
|
|
//---------------------------------------------------------------------------
|
|
#include "XnCallback.h"
|
|
#include "XnList.h"
|
|
#include "XnTypes.h"
|
|
#include "XnOSCpp.h"
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Types
|
|
//---------------------------------------------------------------------------
|
|
class XnEventInterface
|
|
{
|
|
public:
|
|
XnEventInterface() {}
|
|
virtual ~XnEventInterface() {}
|
|
|
|
typedef XnStatus (XN_CALLBACK_TYPE* HandlerPtr)(void* pCookie);
|
|
|
|
virtual XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) = 0;
|
|
virtual XnStatus Unregister(XnCallbackHandle handle) = 0;
|
|
};
|
|
|
|
class XnEvent : public XnEventInterface
|
|
{
|
|
public:
|
|
XnEvent() : m_hLock(0)
|
|
{
|
|
xnOSCreateCriticalSection(&m_hLock);
|
|
}
|
|
|
|
virtual ~XnEvent()
|
|
{
|
|
Clear();
|
|
xnOSCloseCriticalSection(&m_hLock);
|
|
}
|
|
|
|
XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle)
|
|
{
|
|
XnStatus nRetVal = XN_STATUS_OK;
|
|
|
|
XN_VALIDATE_INPUT_PTR(pFunc);
|
|
|
|
XnCallback* pCallback = NULL;
|
|
XN_VALIDATE_NEW(pCallback, XnCallback, (XnFuncPtr)pFunc, pCookie);
|
|
|
|
// always add to list of added (actual list will be updated in Raise method, to allow registering
|
|
// from a callback).
|
|
{
|
|
XnAutoCSLocker lock(m_hLock);
|
|
nRetVal = m_ToBeAdded.AddLast(pCallback);
|
|
}
|
|
|
|
if (nRetVal != XN_STATUS_OK)
|
|
{
|
|
XN_DELETE(pCallback);
|
|
return (nRetVal);
|
|
}
|
|
|
|
// return handle
|
|
if (pHandle != NULL)
|
|
{
|
|
*pHandle = pCallback;
|
|
}
|
|
|
|
return XN_STATUS_OK;
|
|
}
|
|
|
|
XnStatus Unregister(XnCallbackHandle handle)
|
|
{
|
|
XnStatus nRetVal = XN_STATUS_OK;
|
|
|
|
XnCallback* pObject = (XnCallback*)handle;
|
|
|
|
// add it to a temp list, to allow unregistering from a callback (actual list will be updated in raise
|
|
// function).
|
|
{
|
|
XnAutoCSLocker lock(m_hLock);
|
|
|
|
// try to remove it from the ToBeAdded list.
|
|
if (!RemoveCallback(m_ToBeAdded, pObject))
|
|
{
|
|
// it's not in this list, so it's probably in the main list
|
|
nRetVal = m_ToBeRemoved.AddLast(pObject);
|
|
}
|
|
}
|
|
XN_IS_STATUS_OK(nRetVal);
|
|
|
|
return XN_STATUS_OK;
|
|
}
|
|
|
|
XnStatus Clear()
|
|
{
|
|
ApplyListChanges();
|
|
|
|
for (XnCallbackPtrList::ConstIterator it = m_Handlers.begin(); it != m_Handlers.end(); ++it)
|
|
{
|
|
XnCallback* pCallback = *it;
|
|
XN_DELETE(pCallback);
|
|
}
|
|
|
|
m_Handlers.Clear();
|
|
m_ToBeRemoved.Clear();
|
|
m_ToBeAdded.Clear();
|
|
return (XN_STATUS_OK);
|
|
}
|
|
|
|
protected:
|
|
XnStatus ApplyListChanges()
|
|
{
|
|
// first add all
|
|
for (XnCallbackPtrList::ConstIterator it = m_ToBeAdded.begin(); it != m_ToBeAdded.end(); ++it)
|
|
{
|
|
m_Handlers.AddLast(*it);
|
|
}
|
|
m_ToBeAdded.Clear();
|
|
|
|
// and now remove
|
|
for (XnCallbackPtrList::ConstIterator it = m_ToBeRemoved.begin(); it != m_ToBeRemoved.end(); ++it)
|
|
{
|
|
XnCallback* pCallback = *it;
|
|
RemoveCallback(m_Handlers, pCallback);
|
|
}
|
|
m_ToBeRemoved.Clear();
|
|
|
|
return (XN_STATUS_OK);
|
|
}
|
|
|
|
#if (XN_PLATFORM == XN_PLATFORM_WIN32)
|
|
#pragma warning (push)
|
|
#pragma warning (disable: 4127)
|
|
#endif
|
|
|
|
XN_DECLARE_LIST(XnCallback*, XnCallbackPtrList)
|
|
|
|
#if (XN_PLATFORM == XN_PLATFORM_WIN32)
|
|
#pragma warning (pop)
|
|
#endif
|
|
|
|
XN_CRITICAL_SECTION_HANDLE m_hLock;
|
|
XnCallbackPtrList m_Handlers;
|
|
XnCallbackPtrList m_ToBeAdded;
|
|
XnCallbackPtrList m_ToBeRemoved;
|
|
|
|
private:
|
|
XnBool RemoveCallback(XnCallbackPtrList& list, XnCallback* pCallback)
|
|
{
|
|
XnCallbackPtrList::Iterator handlerIt = list.Find(pCallback);
|
|
if (handlerIt != list.end())
|
|
{
|
|
list.Remove(handlerIt);
|
|
XN_DELETE(pCallback);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
};
|
|
|
|
#define _XN_RAISE_WITH_RET_CODE(args) \
|
|
{ \
|
|
XnStatus nRetVal = pFunc(args pCallback->pCookie); \
|
|
if (nRetVal != XN_STATUS_OK) \
|
|
{ \
|
|
XnEvent::ApplyListChanges(); \
|
|
return (nRetVal); \
|
|
} \
|
|
}
|
|
|
|
#define _XN_RAISE_NO_RET_CODE(args) \
|
|
pFunc(args pCallback->pCookie);
|
|
|
|
/**
|
|
* Declares a class inheriting from XnEvent, that can be used as an event with specific signature.
|
|
* It is highly recommended not to use this macro directly.
|
|
*/
|
|
#define _XN_DECLARE_EVENT_CLASS(_class, _interface, _retVal, _raise, _signature, _raise_sign) \
|
|
XN_PRAGMA_START_DISABLED_WARNING_SECTION(XN_HIDES_PARENT_METHOD_WARNING_ID) \
|
|
class _interface : protected XnEvent \
|
|
{ \
|
|
public: \
|
|
typedef _retVal (XN_CALLBACK_TYPE* HandlerPtr)(_signature); \
|
|
virtual XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) = 0; \
|
|
virtual XnStatus Unregister(XnCallbackHandle handle) = 0; \
|
|
}; \
|
|
class _class : public _interface \
|
|
{ \
|
|
public: \
|
|
XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) \
|
|
{ \
|
|
return XnEvent::Register((XnEvent::HandlerPtr)pFunc, pCookie, pHandle); \
|
|
} \
|
|
XnStatus Unregister(XnCallbackHandle handle) \
|
|
{ \
|
|
return XnEvent::Unregister(handle); \
|
|
} \
|
|
XnStatus Raise(_raise_sign) \
|
|
{ \
|
|
XnAutoCSLocker lock(m_hLock); \
|
|
XnEvent::ApplyListChanges(); \
|
|
XnEvent::XnCallbackPtrList::Iterator it = XnEvent::m_Handlers.begin(); \
|
|
for (; it != XnEvent::m_Handlers.end(); ++it) \
|
|
{ \
|
|
XnCallback* pCallback = *it; \
|
|
HandlerPtr pFunc = (HandlerPtr)pCallback->pFuncPtr; \
|
|
_raise \
|
|
} \
|
|
XnEvent::ApplyListChanges(); \
|
|
return (XN_STATUS_OK); \
|
|
} \
|
|
XnStatus Clear() { return XnEvent::Clear(); } \
|
|
}; \
|
|
XN_PRAGMA_STOP_DISABLED_WARNING_SECTION
|
|
|
|
|
|
#define _XN_SIGNATURE_0ARG()
|
|
#define _XN_FULL_SIGNATURE_0ARG() void* pCookie
|
|
#define _XN_ARGS_0ARG()
|
|
|
|
#define _XN_SIGNATURE_1ARG(_type1, _name1) _type1 _name1
|
|
#define _XN_FULL_SIGNATURE_1ARG(_type1, _name1) _type1 _name1, void* pCookie
|
|
#define _XN_ARGS_1ARG(_name1) _name1,
|
|
|
|
#define _XN_SIGNATURE_2ARG(_type1, _name1, _type2, _name2) _type1 _name1, _type2 _name2
|
|
#define _XN_FULL_SIGNATURE_2ARG(_type1, _name1, _type2, _name2) _type1 _name1, _type2 _name2, void* pCookie
|
|
#define _XN_ARGS_2ARG(_name1, _name2) _name1, _name2,
|
|
|
|
#define _XN_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3) _type1 _name1, _type2 _name2, _type3 _name3
|
|
#define _XN_FULL_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3) _type1 _name1, _type2 _name2, _type3 _name3, void* pCookie
|
|
#define _XN_ARGS_3ARG(_name1, _name2, _name3) _name1, _name2, _name3,
|
|
|
|
#define _XN_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4
|
|
#define _XN_FULL_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4, void* pCookie
|
|
#define _XN_ARGS_4ARG(_name1, _name2, _name3, _name4) _name1, _name2, _name3, _name4,
|
|
|
|
#define _XN_SIGNATURE_5ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4, _type5 _name5
|
|
#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
|
|
#define _XN_ARGS_5ARG(_name1, _name2, _name3, _name4, _name5) _name1, _name2, _name3, _name4, _name5,
|
|
|
|
/** Declares an event class */
|
|
#define XN_DECLARE_EVENT_0ARG(_class, _interface) \
|
|
_XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_0ARG()), _XN_FULL_SIGNATURE_0ARG(), _XN_SIGNATURE_0ARG())
|
|
|
|
#define XN_DECLARE_EVENT_0ARG_RETVAL(_class, _interface) \
|
|
_XN_DECLARE_EVENT_CLASS(_class, _interface, XnStatus, _XN_RAISE_WITH_RET_CODE(_XN_ARGS_0ARG()), _XN_FULL_SIGNATURE_0ARG(), _XN_SIGNATURE_0ARG())
|
|
|
|
#define XN_DECLARE_EVENT_1ARG(_class, _interface, _type1, _name1) \
|
|
_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))
|
|
|
|
#define XN_DECLARE_EVENT_1ARG_RETVAL(_class, _interface, _type1, _name1) \
|
|
_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))
|
|
|
|
#define XN_DECLARE_EVENT_2ARG(_class, _interface, _type1, _name1, _type2, _name2) \
|
|
_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))
|
|
|
|
#define XN_DECLARE_EVENT_2ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2) \
|
|
_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))
|
|
|
|
#define XN_DECLARE_EVENT_3ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3) \
|
|
_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))
|
|
|
|
#define XN_DECLARE_EVENT_3ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3) \
|
|
_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))
|
|
|
|
#define XN_DECLARE_EVENT_4ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) \
|
|
_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))
|
|
|
|
#define XN_DECLARE_EVENT_4ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) \
|
|
_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))
|
|
|
|
#define XN_DECLARE_EVENT_5ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) \
|
|
_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))
|
|
|
|
#define XN_DECLARE_EVENT_5ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) \
|
|
_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))
|
|
|
|
#endif //__XN_EVENT_H__
|