OpenNI 1.3.2
XnEvent.h
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * OpenNI 1.1 Alpha *
4 * Copyright (C) 2011 PrimeSense Ltd. *
5 * *
6 * This file is part of OpenNI. *
7 * *
8 * OpenNI is free software: you can redistribute it and/or modify *
9 * it under the terms of the GNU Lesser General Public License as published *
10 * by the Free Software Foundation, either version 3 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * OpenNI is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public License *
19 * along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
20 * *
21 ****************************************************************************/
22 #ifndef __XN_EVENT_H__
23 #define __XN_EVENT_H__
24 
25 //---------------------------------------------------------------------------
26 // Includes
27 //---------------------------------------------------------------------------
28 #include "XnCallback.h"
29 #include "XnList.h"
30 #include "XnTypes.h"
31 #include "XnOSCpp.h"
32 
33 //---------------------------------------------------------------------------
34 // Types
35 //---------------------------------------------------------------------------
37 {
38 public:
40  virtual ~XnEventInterface() {}
41 
42  typedef XnStatus (XN_CALLBACK_TYPE* HandlerPtr)(void* pCookie);
43 
44  virtual XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) = 0;
45  virtual XnStatus Unregister(XnCallbackHandle handle) = 0;
46 };
47 
48 class XnEvent : public XnEventInterface
49 {
50 public:
51  XnEvent() : m_hLock(0)
52  {
54  }
55 
56  virtual ~XnEvent()
57  {
58  Clear();
60  }
61 
62  XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle)
63  {
64  XnStatus nRetVal = XN_STATUS_OK;
65 
66  XN_VALIDATE_INPUT_PTR(pFunc);
67 
68  XnCallback* pCallback = NULL;
69  XN_VALIDATE_NEW(pCallback, XnCallback, (XnFuncPtr)pFunc, pCookie);
70 
71  // always add to list of added (actual list will be updated in Raise method, to allow registering
72  // from a callback).
73  {
74  XnAutoCSLocker lock(m_hLock);
75  nRetVal = m_ToBeAdded.AddLast(pCallback);
76  }
77 
78  if (nRetVal != XN_STATUS_OK)
79  {
80  XN_DELETE(pCallback);
81  return (nRetVal);
82  }
83 
84  // return handle
85  if (pHandle != NULL)
86  {
87  *pHandle = pCallback;
88  }
89 
90  return XN_STATUS_OK;
91  }
92 
94  {
95  XnStatus nRetVal = XN_STATUS_OK;
96 
97  XnCallback* pObject = (XnCallback*)handle;
98 
99  // add it to a temp list, to allow unregistering from a callback (actual list will be updated in raise
100  // function).
101  {
102  XnAutoCSLocker lock(m_hLock);
103 
104  // try to remove it from the ToBeAdded list.
105  if (!RemoveCallback(m_ToBeAdded, pObject))
106  {
107  // it's not in this list, so it's probably in the main list
108  nRetVal = m_ToBeRemoved.AddLast(pObject);
109  }
110  }
111  XN_IS_STATUS_OK(nRetVal);
112 
113  return XN_STATUS_OK;
114  }
115 
117  {
119 
120  for (XnCallbackPtrList::ConstIterator it = m_Handlers.begin(); it != m_Handlers.end(); ++it)
121  {
122  XnCallback* pCallback = *it;
123  XN_DELETE(pCallback);
124  }
125 
126  m_Handlers.Clear();
127  m_ToBeRemoved.Clear();
128  m_ToBeAdded.Clear();
129  return (XN_STATUS_OK);
130  }
131 
132 protected:
134  {
135  // first add all
136  for (XnCallbackPtrList::ConstIterator it = m_ToBeAdded.begin(); it != m_ToBeAdded.end(); ++it)
137  {
138  m_Handlers.AddLast(*it);
139  }
140  m_ToBeAdded.Clear();
141 
142  // and now remove
143  for (XnCallbackPtrList::ConstIterator it = m_ToBeRemoved.begin(); it != m_ToBeRemoved.end(); ++it)
144  {
145  XnCallback* pCallback = *it;
146  RemoveCallback(m_Handlers, pCallback);
147  }
148  m_ToBeRemoved.Clear();
149 
150  return (XN_STATUS_OK);
151  }
152 
153 #if (XN_PLATFORM == XN_PLATFORM_WIN32)
154 #pragma warning (push)
155 #pragma warning (disable: 4127)
156 #endif
157 
158  XN_DECLARE_LIST(XnCallback*, XnCallbackPtrList)
159 
160 #if (XN_PLATFORM == XN_PLATFORM_WIN32)
161 #pragma warning (pop)
162 #endif
163 
164  XN_CRITICAL_SECTION_HANDLE m_hLock;
165  XnCallbackPtrList m_Handlers;
166  XnCallbackPtrList m_ToBeAdded;
167  XnCallbackPtrList m_ToBeRemoved;
168 
169 private:
170  XnBool RemoveCallback(XnCallbackPtrList& list, XnCallback* pCallback)
171  {
172  XnCallbackPtrList::Iterator handlerIt = list.Find(pCallback);
173  if (handlerIt != list.end())
174  {
175  list.Remove(handlerIt);
176  XN_DELETE(pCallback);
177  return TRUE;
178  }
179 
180  return FALSE;
181  }
182 };
183 
184 #define _XN_RAISE_WITH_RET_CODE(args) \
185  nRetVal = pFunc(args pCallback->pCookie); \
186  if (nRetVal != XN_STATUS_OK) \
187  { \
188  XnEvent::ApplyListChanges(); \
189  return (nRetVal); \
190  }
191 
192 #define _XN_RAISE_NO_RET_CODE(args) \
193  pFunc(args pCallback->pCookie);
194 
199 #define _XN_DECLARE_EVENT_CLASS(_class, _interface, _retVal, _raise, _signature, _raise_sign) \
200  class _interface : protected XnEvent \
201  { \
202  public: \
203  typedef _retVal (XN_CALLBACK_TYPE* HandlerPtr)(_signature); \
204  virtual XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) = 0; \
205  virtual XnStatus Unregister(XnCallbackHandle handle) = 0; \
206  }; \
207  class _class : public _interface \
208  { \
209  public: \
210  XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) \
211  { \
212  return XnEvent::Register((XnEvent::HandlerPtr)pFunc, pCookie, pHandle); \
213  } \
214  XnStatus Unregister(XnCallbackHandle handle) \
215  { \
216  return XnEvent::Unregister(handle); \
217  } \
218  XnStatus Raise(_raise_sign) \
219  { \
220  XnStatus nRetVal = XN_STATUS_OK; \
221  XnAutoCSLocker lock(m_hLock); \
222  XnEvent::ApplyListChanges(); \
223  XnEvent::XnCallbackPtrList::Iterator it = XnEvent::m_Handlers.begin(); \
224  for (; it != XnEvent::m_Handlers.end(); ++it) \
225  { \
226  XnCallback* pCallback = *it; \
227  HandlerPtr pFunc = (HandlerPtr)pCallback->pFuncPtr; \
228  _raise \
229  } \
230  XnEvent::ApplyListChanges(); \
231  return (XN_STATUS_OK); \
232  } \
233  XnStatus Clear() { return XnEvent::Clear(); } \
234  };
235 
236 #define _XN_SIGNATURE_0ARG()
237 #define _XN_FULL_SIGNATURE_0ARG() void* pCookie
238 #define _XN_ARGS_0ARG()
239 
240 #define _XN_SIGNATURE_1ARG(_type1, _name1) _type1 _name1
241 #define _XN_FULL_SIGNATURE_1ARG(_type1, _name1) _type1 _name1, void* pCookie
242 #define _XN_ARGS_1ARG(_name1) _name1,
243 
244 #define _XN_SIGNATURE_2ARG(_type1, _name1, _type2, _name2) _type1 _name1, _type2 _name2
245 #define _XN_FULL_SIGNATURE_2ARG(_type1, _name1, _type2, _name2) _type1 _name1, _type2 _name2, void* pCookie
246 #define _XN_ARGS_2ARG(_name1, _name2) _name1, _name2,
247 
248 #define _XN_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3) _type1 _name1, _type2 _name2, _type3 _name3
249 #define _XN_FULL_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3) _type1 _name1, _type2 _name2, _type3 _name3, void* pCookie
250 #define _XN_ARGS_3ARG(_name1, _name2, _name3) _name1, _name2, _name3,
251 
252 #define _XN_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4
253 #define _XN_FULL_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4, void* pCookie
254 #define _XN_ARGS_4ARG(_name1, _name2, _name3, _name4) _name1, _name2, _name3, _name4,
255 
256 #define _XN_SIGNATURE_5ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4, _type5 _name5
257 #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
258 #define _XN_ARGS_5ARG(_name1, _name2, _name3, _name4, _name5) _name1, _name2, _name3, _name4, _name5,
259 
261 #if XN_PLATFORM == XN_PLATFORM_WIN32
262  #define XN_DECLARE_EVENT_0ARG(_class, _interface) \
263  __pragma(warning(push))\
264  __pragma(warning(disable:4189))\
265  _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_0ARG()), _XN_FULL_SIGNATURE_0ARG(), _XN_SIGNATURE_0ARG())\
266  __pragma(warning(pop))
267 #else
268  #define XN_DECLARE_EVENT_0ARG(_class, _interface) \
269  _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_0ARG()), _XN_FULL_SIGNATURE_0ARG(), _XN_SIGNATURE_0ARG())
270 #endif
271 
272 #define XN_DECLARE_EVENT_0ARG_RETVAL(_class, _interface) \
273  _XN_DECLARE_EVENT_CLASS(_class, _interface, XnStatus, _XN_RAISE_WITH_RET_CODE(_XN_ARGS_0ARG()), _XN_FULL_SIGNATURE_0ARG(), _XN_SIGNATURE_0ARG())
274 
275 #define XN_DECLARE_EVENT_1ARG(_class, _interface, _type1, _name1) \
276  _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))
277 
278 #define XN_DECLARE_EVENT_1ARG_RETVAL(_class, _interface, _type1, _name1) \
279  _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))
280 
281 #define XN_DECLARE_EVENT_2ARG(_class, _interface, _type1, _name1, _type2, _name2) \
282  _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))
283 
284 #define XN_DECLARE_EVENT_2ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2) \
285  _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))
286 
287 #define XN_DECLARE_EVENT_3ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3) \
288  _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))
289 
290 #define XN_DECLARE_EVENT_3ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3) \
291  _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))
292 
293 #define XN_DECLARE_EVENT_4ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) \
294  _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))
295 
296 #define XN_DECLARE_EVENT_4ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) \
297  _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))
298 
299 #define XN_DECLARE_EVENT_5ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) \
300  _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))
301 
302 #define XN_DECLARE_EVENT_5ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) \
303  _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))
304 
305 #endif //__XN_EVENT_H__