Event.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2011, SRI International (R)
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #pragma once
19 
20 #ifndef __OpenKarto_Event_h__
21 #define __OpenKarto_Event_h__
22 
23 #include <OpenKarto/List.h>
24 #include <OpenKarto/Mutex.h>
25 
26 // Forward declaration for tbb::mutex
27 namespace tbb
28 {
29  class mutex;
30 }
31 
32 namespace karto
33 {
34 
38 
39  // The following code is from the Poco library with the following license
40  // and modified to fit into the KartoSDK
41 
42  // Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
43  // and Contributors.
44  //
45  // Permission is hereby granted, free of charge, to any person or organization
46  // obtaining a copy of the software and accompanying documentation covered by
47  // this license (the "Software") to use, reproduce, display, distribute,
48  // execute, and transmit the Software, and to prepare derivative works of the
49  // Software, and to permit third-parties to whom the Software is furnished to
50  // do so, all subject to the following:
51  //
52  // The copyright notices in the Software and this entire statement, including
53  // the above license grant, this restriction and the following disclaimer,
54  // must be included in all copies of the Software, in whole or in part, and
55  // all derivative works of the Software, unless such copies or derivative
56  // works are solely in the form of machine-executable object code generated by
57  // a source language processor.
58  //
59  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
60  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
61  // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
62  // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
63  // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
64  // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
65  // DEALINGS IN THE SOFTWARE.
66 
70 
72 
73 
74  //@cond EXCLUDE
75 
82  template <class TArgs>
83  class AbstractDelegate
84  {
85  public:
90  AbstractDelegate(void* pTarget)
91  : m_pTarget(pTarget)
92  {
93  assert(m_pTarget != 0);
94  }
95 
100  AbstractDelegate(const AbstractDelegate& rOther)
101  : m_pTarget(rOther.m_pTarget)
102  {
103  assert(m_pTarget != 0);
104  }
105 
109  virtual ~AbstractDelegate()
110  {
111  }
112 
113  public:
119  virtual void Notify(const void* pSender, TArgs& rArguments) = 0;
120 
125  virtual AbstractDelegate* Clone() const = 0;
126 
130  void* GetTarget() const
131  {
132  return m_pTarget;
133  }
134 
135  public:
141  kt_bool operator==(const AbstractDelegate<TArgs>& rOther) const
142  {
143  return m_pTarget == rOther.m_pTarget;
144  }
145 
151  kt_bool operator<(const AbstractDelegate<TArgs>& rOther) const
152  {
153  return m_pTarget < rOther.m_pTarget;
154  }
155 
156  protected:
160  void* m_pTarget;
161  };
162 
166 
167  template <class TObj, class TArgs, bool withSender=true>
168  class Delegate: public AbstractDelegate<TArgs>
169  {
170  public:
171  typedef void (TObj::*NotifyMethod)(const void*, TArgs&);
172 
173  Delegate(TObj* pObject, NotifyMethod method)
174  : AbstractDelegate<TArgs>(pObject)
175  , m_ReceiverObject(pObject)
176  , m_ReceiverMethod(method)
177  {
178  }
179 
183  Delegate(const Delegate& rDelegate)
184  : AbstractDelegate<TArgs>(rDelegate)
185  , m_ReceiverObject(rDelegate.m_ReceiverObject)
186  , m_ReceiverMethod(rDelegate.m_ReceiverMethod)
187  {
188  }
189 
193  virtual ~Delegate()
194  {
195  }
196 
197  public:
198  void Notify(const void* pSender, TArgs& rArguments)
199  {
200  (m_ReceiverObject->*m_ReceiverMethod)(pSender, rArguments);
201  }
202 
203  AbstractDelegate<TArgs>* Clone() const
204  {
205  return new Delegate(*this);
206  }
207 
208  public:
214  Delegate& operator=(const Delegate& rOther)
215  {
216  if (&rOther != this)
217  {
218  this->m_pTarget = rOther.m_pTarget;
219  this->m_ReceiverObject = rOther.m_ReceiverObject;
220  this->m_ReceiverMethod = rOther.m_ReceiverMethod;
221  }
222  return *this;
223  }
224 
225  protected:
226  TObj* m_ReceiverObject;
227  NotifyMethod m_ReceiverMethod;
228 
229  private:
230  Delegate();
231  };
232 
236 
237  template <class TObj, class TArgs>
238  class Delegate<TObj, TArgs, false>: public AbstractDelegate<TArgs>
239  {
240  public:
241  typedef void (TObj::*NotifyMethod)(TArgs&);
242 
243  Delegate(TObj* pObject, NotifyMethod method)
244  : AbstractDelegate<TArgs>(pObject)
245  , m_ReceiverObject(pObject)
246  , m_ReceiverMethod(method)
247  {
248  }
249 
253  Delegate(const Delegate& rDelegate)
254  : AbstractDelegate<TArgs>(rDelegate)
255  , m_ReceiverObject(rDelegate.m_ReceiverObject)
256  , m_ReceiverMethod(rDelegate.m_ReceiverMethod)
257  {
258  }
259 
263  virtual ~Delegate()
264  {
265  }
266 
267  public:
268  void Notify(const void*, TArgs& rArguments)
269  {
270  (m_ReceiverObject->*m_ReceiverMethod)(rArguments);
271  }
272 
273  AbstractDelegate<TArgs>* Clone() const
274  {
275  return new Delegate(*this);
276  }
277 
278  public:
284  Delegate& operator=(const Delegate& rOther)
285  {
286  if (&rOther != this)
287  {
288  this->m_pTarget = rOther.m_pTarget;
289  this->m_ReceiverObject = rOther.m_ReceiverObject;
290  this->m_ReceiverMethod = rOther.m_ReceiverMethod;
291  }
292 
293  return *this;
294  }
295 
296  protected:
297  TObj* m_ReceiverObject;
298  NotifyMethod m_ReceiverMethod;
299 
300  private:
301  Delegate();
302  };
303 
307 
312  template <class TArgs, bool hasSender = true, bool senderIsConst = true>
313  class FunctionDelegate: public AbstractDelegate<TArgs>
314  {
315  public:
319  typedef void (*NotifyMethod)(const void*, TArgs&);
320 
325  FunctionDelegate(NotifyMethod method)
326  : AbstractDelegate<TArgs>(*reinterpret_cast<void**>(&method))
327  , m_ReceiverMethod(method)
328  {
329  }
330 
335  FunctionDelegate(const FunctionDelegate& rOther)
336  : AbstractDelegate<TArgs>(rOther)
337  , m_ReceiverMethod(rOther.m_ReceiverMethod)
338  {
339  }
340 
344  virtual ~FunctionDelegate()
345  {
346  }
347 
348  public:
349  void Notify(const void* pSender, TArgs& rArguments)
350  {
351  (*m_ReceiverMethod)(pSender, rArguments);
352  }
353 
354  AbstractDelegate<TArgs>* Clone() const
355  {
356  return new FunctionDelegate(*this);
357  }
358 
359  public:
365  FunctionDelegate& operator=(const FunctionDelegate& rOther)
366  {
367  if (&rOther != this)
368  {
369  this->m_pTarget = rOther.m_pTarget;
370  this->m_ReceiverMethod = rOther.m_ReceiverMethod;
371  }
372  return *this;
373  }
374 
375  protected:
379  NotifyMethod m_ReceiverMethod;
380 
381  private:
382  FunctionDelegate();
383  };
384 
388 
393  template <class TArgs>
394  class FunctionDelegate<TArgs, true, false>: public AbstractDelegate<TArgs>
395  {
396  public:
400  typedef void (*NotifyMethod)(void*, TArgs&);
401 
406  FunctionDelegate(NotifyMethod method)
407  : AbstractDelegate<TArgs>(*reinterpret_cast<void**>(&method))
408  , m_ReceiverMethod(method)
409  {
410  }
411 
416  FunctionDelegate(const FunctionDelegate& rOther)
417  : AbstractDelegate<TArgs>(rOther)
418  , m_ReceiverMethod(rOther.m_ReceiverMethod)
419  {
420  }
421 
425  virtual ~FunctionDelegate()
426  {
427  }
428 
429  public:
430  void Notify(const void* pSender, TArgs& rArguments)
431  {
432  (*m_ReceiverMethod)(const_cast<void*>(pSender), rArguments);
433  }
434 
435  AbstractDelegate<TArgs>* Clone() const
436  {
437  return new FunctionDelegate(*this);
438  }
439 
440  public:
446  FunctionDelegate& operator=(const FunctionDelegate& rOther)
447  {
448  if (&rOther != this)
449  {
450  this->m_pTarget = rOther.m_pTarget;
451  this->m_ReceiverMethod = rOther.m_ReceiverMethod;
452  }
453  return *this;
454  }
455 
456  protected:
460  NotifyMethod m_ReceiverMethod;
461 
462  private:
463  FunctionDelegate();
464  };
465 
469 
474  template <class TArgs, bool senderIsConst>
475  class FunctionDelegate<TArgs, false, senderIsConst>: public AbstractDelegate<TArgs>
476  {
477  public:
481  typedef void (*NotifyMethod)(TArgs&);
482 
487  FunctionDelegate(NotifyMethod method)
488  : AbstractDelegate<TArgs>(*reinterpret_cast<void**>(&method))
489  , m_ReceiverMethod(method)
490  {
491  }
492 
497  FunctionDelegate(const FunctionDelegate& rOther)
498  : AbstractDelegate<TArgs>(rOther)
499  , m_ReceiverMethod(rOther.m_ReceiverMethod)
500  {
501  }
502 
506  virtual ~FunctionDelegate()
507  {
508  }
509 
510  public:
511  void Notify(const void* /*pSender*/, TArgs& rArguments)
512  {
513  (*m_ReceiverMethod)(rArguments);
514  }
515 
516  AbstractDelegate<TArgs>* Clone() const
517  {
518  return new FunctionDelegate(*this);
519  }
520 
521  public:
527  FunctionDelegate& operator=(const FunctionDelegate& rOther)
528  {
529  if (&rOther != this)
530  {
531  this->m_pTarget = rOther.m_pTarget;
532  this->m_ReceiverMethod = rOther.m_ReceiverMethod;
533  }
534  return *this;
535  }
536 
537  protected:
541  NotifyMethod m_ReceiverMethod;
542 
543  private:
544  FunctionDelegate();
545  };
546 
550 
558  template <class TArgs>
559  class NotificationStrategy
560  {
561  public:
565  NotificationStrategy()
566  {
567  }
568 
572  virtual ~NotificationStrategy()
573  {
574  }
575 
576  public:
580  virtual void Notify(const void* sender, TArgs& arguments) = 0;
581 
585  virtual void Add(const AbstractDelegate<TArgs>& pDelegate) = 0;
586 
590  virtual void Remove(const AbstractDelegate<TArgs>& pDelegate) = 0;
591 
595  virtual void Clear() = 0;
596 
600  virtual bool IsEmpty() const = 0;
601  };
602 
606 
612  template <class TArgs>
613  class DefaultStrategy : public NotificationStrategy<TArgs>
614  {
615  public:
619  typedef karto::List< AbstractDelegate<TArgs>* > DelegateList;
620 
621  public:
625  DefaultStrategy()
626  {
627  }
628 
633  DefaultStrategy(const DefaultStrategy& rOther)
634  {
635  operator = (rOther);
636  }
637 
641  virtual ~DefaultStrategy()
642  {
643  Clear();
644  }
645 
646  public:
647  void Notify(const void* pSender, TArgs& rArguments)
648  {
649  karto_forEach(typename DelegateList, &m_Observers)
650  {
651  (*iter)->Notify(pSender, rArguments);
652  }
653  }
654 
655  void Add(const AbstractDelegate<TArgs>& rDelegate)
656  {
657  Remove(rDelegate);
658 
659  AbstractDelegate<TArgs>* pDelegate = rDelegate.Clone();
660  m_Observers.Add(pDelegate);
661  }
662 
663  void Remove(const AbstractDelegate<TArgs>& rDelegate)
664  {
665  kt_bool found = false;
666  kt_int32s index = 0;
667  karto_forEach(typename DelegateList, &m_Observers)
668  {
669  if (*(*iter) == rDelegate)
670  {
671  delete *iter;
672  found = true;
673  break;
674  }
675 
676  index++;
677  }
678 
679  if (found == true)
680  {
681  m_Observers.RemoveAt(index);
682  }
683  }
684 
685  void Clear()
686  {
687  karto_forEach(typename DelegateList, &m_Observers)
688  {
689  delete *iter;
690  }
691  m_Observers.Clear();
692  }
693 
694  kt_bool IsEmpty() const
695  {
696  return m_Observers.IsEmpty();
697  }
698 
699  public:
703  DefaultStrategy& operator=(const DefaultStrategy& rOther)
704  {
705  if (this != &rOther)
706  {
707  karto_const_forEach(typename DelegateList, &(rOther.m_Observers))
708  {
709  Add(**iter);
710  }
711  }
712  return *this;
713  }
714 
715  protected:
719  DelegateList m_Observers;
720  };
721 
722  // @endcond
723 
727 
805  template <class TArgs>
807  {
808  public:
813  : m_Enabled(true)
814  {
815  }
816 
821  AbstractEvent(const DefaultStrategy<TArgs>& rStrategy)
822  : m_Enabled(true)
823  , m_Strategy(rStrategy)
824  {
825  }
826 
830  virtual ~AbstractEvent()
831  {
832  }
833 
843  void operator+=(const AbstractDelegate<TArgs>& rDelegate)
844  {
845  Mutex::ScopedLock lock(m_Mutex);
846  m_Strategy.Add(rDelegate);
847  }
848 
855  void operator-=(const AbstractDelegate<TArgs>& rDelegate)
856  {
857  Mutex::ScopedLock lock(m_Mutex);
858  m_Strategy.Remove(rDelegate);
859  }
860 
864  void operator()(const void* pSender, TArgs& args)
865  {
866  Notify(pSender, args);
867  }
868 
879  void Notify(const void* pSender, TArgs& rArgs)
880  {
881  DefaultStrategy<TArgs>* pStrats = NULL;
882  kt_bool enabled = false;
883 
884  {
885  Mutex::ScopedLock lock(m_Mutex);
886  enabled = m_Enabled;
887 
888  if (m_Enabled)
889  {
890  // thread-safeness:
891  // copy should be faster and safer than blocking until execution ends
892  pStrats = new DefaultStrategy<TArgs>(m_Strategy);
893  }
894  }
895 
896  if (enabled)
897  {
898  pStrats->Notify(pSender, rArgs);
899  }
900 
901  delete pStrats;
902  }
903 
907  void Enable()
908  {
909  Mutex::ScopedLock lock(m_Mutex);
910  m_Enabled = true;
911  }
912 
917  void Disable()
918  {
919  Mutex::ScopedLock lock(m_Mutex);
920  m_Enabled = false;
921  }
922 
927  {
928  Mutex::ScopedLock lock(m_Mutex);
929  return m_Enabled;
930  }
931 
935  void Clear()
936  {
937  Mutex::ScopedLock lock(m_Mutex);
938  m_Strategy.Clear();
939  }
940 
944  kt_bool IsEmpty() const
945  {
946  Mutex::ScopedLock lock(m_Mutex);
947  return m_Strategy.IsEmpty();
948  }
949 
950  protected:
955 
959  DefaultStrategy<TArgs> m_Strategy;
960 
964  mutable Mutex m_Mutex;
965 
966  private:
967  AbstractEvent(const AbstractEvent& rOther);
968  AbstractEvent& operator=(const AbstractEvent& rOther);
969  };
970 
974 
989  template <class TArgs>
990  class BasicEvent : public AbstractEvent <TArgs >
991  {
992  public:
994  {
995  }
996 
997  virtual ~BasicEvent()
998  {
999  }
1000 
1001  private:
1002  BasicEvent(const BasicEvent& e);
1003  BasicEvent& operator=(const BasicEvent& e);
1004  };
1005 
1009 
1018  {
1019  public:
1020  EventArguments();
1021  virtual ~EventArguments();
1022 
1023  public:
1029  {
1030  static EventArguments dummy;
1031 
1032  return dummy;
1033  }
1034  }; // class EventArguments
1035 
1036 #ifdef WIN32
1037 #define EXPORT_KARTO_EVENT(declspec, T) \
1038  template class declspec karto::BasicEvent<T>;
1039 
1040  EXPORT_KARTO_EVENT(KARTO_EXPORT, EventArguments)
1041 #endif
1042 
1046 
1047  template <class TObj, class TArgs>
1048  static Delegate<TObj, TArgs, true> delegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*, TArgs&))
1049  {
1050  return Delegate<TObj, TArgs, true>(pObj, NotifyMethod);
1051  }
1052 
1053  template <class TObj, class TArgs>
1054  static Delegate<TObj, TArgs, false> delegate(TObj* pObj, void (TObj::*NotifyMethod)(TArgs&))
1055  {
1056  return Delegate<TObj, TArgs, false>(pObj, NotifyMethod);
1057  }
1058 
1059  template <class TArgs>
1060  static FunctionDelegate<TArgs, true, true> delegate(void (*NotifyMethod)(const void*, TArgs&))
1061  {
1062  return FunctionDelegate<TArgs, true, true>(NotifyMethod);
1063  }
1064 
1065  template <class TArgs>
1066  static FunctionDelegate<TArgs, true, false> delegate(void (*NotifyMethod)(void*, TArgs&))
1067  {
1068  return FunctionDelegate<TArgs, true, false>(NotifyMethod);
1069  }
1070 
1071  template <class TArgs>
1072  static FunctionDelegate<TArgs, false> delegate(void (*NotifyMethod)(TArgs&))
1073  {
1074  return FunctionDelegate<TArgs, false>(NotifyMethod);
1075  }
1076 
1078 
1079 }
1080 
1081 #endif // __OpenKarto_Event_h__
bool kt_bool
Definition: Types.h:145
void operator-=(const AbstractDelegate< TArgs > &rDelegate)
Definition: Event.h:855
TFSIMD_FORCE_INLINE bool operator==(const Matrix3x3 &m1, const Matrix3x3 &m2)
kt_bool m_Enabled
Definition: Event.h:954
virtual ~AbstractEvent()
Definition: Event.h:830
#define KARTO_EXPORT
Definition: Macros.h:78
static EventArguments & Empty()
Definition: Event.h:1028
DefaultStrategy< TArgs > m_Strategy
Definition: Event.h:959
void operator+=(const AbstractDelegate< TArgs > &rDelegate)
Definition: Event.h:843
virtual ~BasicEvent()
Definition: Event.h:997
static FunctionDelegate< TArgs, false > delegate(void(*NotifyMethod)(TArgs &))
Definition: Event.h:1072
void operator()(const void *pSender, TArgs &args)
Definition: Event.h:864
#define karto_forEach(listtype, list)
Definition: Macros.h:124
int32_t kt_int32s
Definition: Types.h:106
void Notify(const void *pSender, TArgs &rArgs)
Definition: Event.h:879
kt_bool IsEnabled() const
Definition: Event.h:926
kt_bool IsEmpty() const
Definition: Event.h:944
Definition: Event.h:27
AbstractEvent(const DefaultStrategy< TArgs > &rStrategy)
Definition: Event.h:821
Definition: Any.cpp:20
#define karto_const_forEach(listtype, list)
Definition: Macros.h:136


nav2d_karto
Author(s): Sebastian Kasperski
autogenerated on Tue Nov 7 2017 06:02:36