OpenNI 1.5.4
XnEvent.h
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * OpenNI 1.x 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  { \
186  XnStatus nRetVal = pFunc(args pCallback->pCookie); \
187  if (nRetVal != XN_STATUS_OK) \
188  { \
189  XnEvent::ApplyListChanges(); \
190  return (nRetVal); \
191  } \
192  }
193 
194 #define _XN_RAISE_NO_RET_CODE(args) \
195  pFunc(args pCallback->pCookie);
196 
201 #define _XN_DECLARE_EVENT_CLASS(_class, _interface, _retVal, _raise, _signature, _raise_sign) \
202  XN_PRAGMA_START_DISABLED_WARNING_SECTION(XN_HIDES_PARENT_METHOD_WARNING_ID) \
203  class _interface : protected XnEvent \
204  { \
205  public: \
206  typedef _retVal (XN_CALLBACK_TYPE* HandlerPtr)(_signature); \
207  virtual XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) = 0; \
208  virtual XnStatus Unregister(XnCallbackHandle handle) = 0; \
209  }; \
210  class _class : public _interface \
211  { \
212  public: \
213  XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) \
214  { \
215  return XnEvent::Register((XnEvent::HandlerPtr)pFunc, pCookie, pHandle); \
216  } \
217  XnStatus Unregister(XnCallbackHandle handle) \
218  { \
219  return XnEvent::Unregister(handle); \
220  } \
221  XnStatus Raise(_raise_sign) \
222  { \
223  XnAutoCSLocker lock(m_hLock); \
224  XnEvent::ApplyListChanges(); \
225  XnEvent::XnCallbackPtrList::Iterator it = XnEvent::m_Handlers.begin(); \
226  for (; it != XnEvent::m_Handlers.end(); ++it) \
227  { \
228  XnCallback* pCallback = *it; \
229  HandlerPtr pFunc = (HandlerPtr)pCallback->pFuncPtr; \
230  _raise \
231  } \
232  XnEvent::ApplyListChanges(); \
233  return (XN_STATUS_OK); \
234  } \
235  XnStatus Clear() { return XnEvent::Clear(); } \
236  }; \
237  XN_PRAGMA_STOP_DISABLED_WARNING_SECTION
238 
239 
240 #define _XN_SIGNATURE_0ARG()
241 #define _XN_FULL_SIGNATURE_0ARG() void* pCookie
242 #define _XN_ARGS_0ARG()
243 
244 #define _XN_SIGNATURE_1ARG(_type1, _name1) _type1 _name1
245 #define _XN_FULL_SIGNATURE_1ARG(_type1, _name1) _type1 _name1, void* pCookie
246 #define _XN_ARGS_1ARG(_name1) _name1,
247 
248 #define _XN_SIGNATURE_2ARG(_type1, _name1, _type2, _name2) _type1 _name1, _type2 _name2
249 #define _XN_FULL_SIGNATURE_2ARG(_type1, _name1, _type2, _name2) _type1 _name1, _type2 _name2, void* pCookie
250 #define _XN_ARGS_2ARG(_name1, _name2) _name1, _name2,
251 
252 #define _XN_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3) _type1 _name1, _type2 _name2, _type3 _name3
253 #define _XN_FULL_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3) _type1 _name1, _type2 _name2, _type3 _name3, void* pCookie
254 #define _XN_ARGS_3ARG(_name1, _name2, _name3) _name1, _name2, _name3,
255 
256 #define _XN_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4
257 #define _XN_FULL_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4, void* pCookie
258 #define _XN_ARGS_4ARG(_name1, _name2, _name3, _name4) _name1, _name2, _name3, _name4,
259 
260 #define _XN_SIGNATURE_5ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4, _type5 _name5
261 #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
262 #define _XN_ARGS_5ARG(_name1, _name2, _name3, _name4, _name5) _name1, _name2, _name3, _name4, _name5,
263 
265 #define XN_DECLARE_EVENT_0ARG(_class, _interface) \
266  _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_0ARG()), _XN_FULL_SIGNATURE_0ARG(), _XN_SIGNATURE_0ARG())
267 
268 #define XN_DECLARE_EVENT_0ARG_RETVAL(_class, _interface) \
269  _XN_DECLARE_EVENT_CLASS(_class, _interface, XnStatus, _XN_RAISE_WITH_RET_CODE(_XN_ARGS_0ARG()), _XN_FULL_SIGNATURE_0ARG(), _XN_SIGNATURE_0ARG())
270 
271 #define XN_DECLARE_EVENT_1ARG(_class, _interface, _type1, _name1) \
272  _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))
273 
274 #define XN_DECLARE_EVENT_1ARG_RETVAL(_class, _interface, _type1, _name1) \
275  _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))
276 
277 #define XN_DECLARE_EVENT_2ARG(_class, _interface, _type1, _name1, _type2, _name2) \
278  _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))
279 
280 #define XN_DECLARE_EVENT_2ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2) \
281  _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))
282 
283 #define XN_DECLARE_EVENT_3ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3) \
284  _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))
285 
286 #define XN_DECLARE_EVENT_3ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3) \
287  _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))
288 
289 #define XN_DECLARE_EVENT_4ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) \
290  _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))
291 
292 #define XN_DECLARE_EVENT_4ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) \
293  _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))
294 
295 #define XN_DECLARE_EVENT_5ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) \
296  _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))
297 
298 #define XN_DECLARE_EVENT_5ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) \
299  _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))
300 
301 #endif //__XN_EVENT_H__
void(* XnFuncPtr)()
Definition: XnPlatform.h:101
#define XN_IS_STATUS_OK(x)
Definition: XnMacros.h:60
#define FALSE
Definition: XnPlatform.h:94
Definition: XnCallback.h:31
#define XN_STATUS_OK
Definition: XnStatus.h:37
virtual ~XnEvent()
Definition: XnEvent.h:56
XN_CRITICAL_SECTION_HANDLE m_hLock
Definition: XnEvent.h:164
XnStatus ApplyListChanges()
Definition: XnEvent.h:133
virtual ~XnEventInterface()
Definition: XnEvent.h:40
#define XN_DECLARE_LIST(Type, ClassName)
Definition: XnList.h:745
XnStatus(* HandlerPtr)(void *pCookie)
Definition: XnEvent.h:42
XnCallbackPtrList m_ToBeRemoved
Definition: XnEvent.h:167
#define XN_VALIDATE_NEW(ptr, type,...)
Definition: XnOS.h:168
XnUInt32 XnStatus
Definition: XnStatus.h:34
XnCallbackPtrList m_Handlers
Definition: XnEvent.h:165
XnStatus Clear()
Definition: XnEvent.h:116
XnStatus Unregister(XnCallbackHandle handle)
Definition: XnEvent.h:93
#define TRUE
Definition: XnPlatform.h:90
XnEventInterface()
Definition: XnEvent.h:39
XnCallbackPtrList m_ToBeAdded
Definition: XnEvent.h:166
void * XnCallbackHandle
Definition: XnTypes.h:268
Definition: XnOSCpp.h:33
XnStatus Register(HandlerPtr pFunc, void *pCookie, XnCallbackHandle *pHandle)
Definition: XnEvent.h:62
XN_C_API XnStatus XN_C_DECL xnOSCloseCriticalSection(XN_CRITICAL_SECTION_HANDLE *pCriticalSectionHandle)
#define XN_VALIDATE_INPUT_PTR(x)
Definition: XnOS.h:123
virtual XnStatus Register(HandlerPtr pFunc, void *pCookie, XnCallbackHandle *pHandle=NULL)=0
#define XN_DELETE(p)
Definition: XnOS.h:336
XN_C_API XnStatus XN_C_DECL xnOSCreateCriticalSection(XN_CRITICAL_SECTION_HANDLE *pCriticalSectionHandle)
virtual XnStatus Unregister(XnCallbackHandle handle)=0
XnEvent()
Definition: XnEvent.h:51
Definition: XnEvent.h:48
Definition: XnEvent.h:36