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