Observer.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #ifndef ANKI_UTIL_OBSERVER_H
  2. #define ANKI_UTIL_OBSERVER_H
  3. #include "anki/util/Vector.h"
  4. #include "anki/util/Functions.h"
  5. namespace anki {
  6. /// The observer interface template
  7. template<typename T>
  8. struct Observer
  9. {
  10. typedef T Value; ///< The type of the notification value
  11. virtual ~Observer()
  12. {}
  13. virtual void notify(Value notificationVal) = 0;
  14. };
  15. /// An over-qualified observer
  16. template<typename ObservingType, typename Value,
  17. void (ObservingType::*method)(Value)>
  18. struct SuperObserver: Observer<Value>
  19. {
  20. ObservingType* reveiver;
  21. SuperObserver(ObservingType* reveiver_)
  22. : reveiver(reveiver_)
  23. {}
  24. void notify(Value x)
  25. {
  26. (reveiver->*method)(x);
  27. }
  28. };
  29. /// Basically a container of observers
  30. template<typename T>
  31. class Observable
  32. {
  33. public:
  34. typedef T Value;
  35. typedef Observer<Value> ObserverType;
  36. typedef PtrVector<ObserverType> Container;
  37. /// Add a new observer. The Observable takes ownership of the
  38. /// pointer and its responsible of cleaning
  39. void addNewObserver(ObserverType* x)
  40. {
  41. observers.push_back(x);
  42. }
  43. /// Notify all observers
  44. void notifyAll(Value x)
  45. {
  46. for(typename Container::iterator it = observers.begin();
  47. it != observers.end(); ++it)
  48. {
  49. (*it)->notify(x);
  50. }
  51. }
  52. /// Alias to notifyAll
  53. void operator()(Value x)
  54. {
  55. notifyAll(x);
  56. }
  57. private:
  58. Container observers;
  59. };
  60. /// If a class has slots it should include this
  61. /// @code
  62. /// class Foo {
  63. /// ANKI_HAS_SLOTS(Foo)
  64. /// };
  65. /// @endcode
  66. #define ANKI_HAS_SLOTS(_class) \
  67. typedef _class ObservingType;
  68. /// Define a slot. This should follow the method declaration
  69. /// @code
  70. /// class Foo {
  71. /// ANKI_HAS_SLOTS(Foo)
  72. ///
  73. /// void slot(const float&)
  74. /// {...}
  75. /// ANKI_SLOT(updateZFar, const float&)
  76. /// };
  77. /// @endcode
  78. #define ANKI_SLOT(_name, _type) \
  79. typedef SuperObserver<ObservingType, _type, &ObservingType::_name> \
  80. Observing_##_name;
  81. /// Define a signal
  82. #define ANKI_SIGNAL(_type, _name) \
  83. Observable<_type> _name;
  84. /// It doesn't do anything. Its purpose is to make the code more understandable
  85. #define ANKI_EMIT this->
  86. /// Connect a signal to a slot
  87. /// @note Use RemovePointer so you can be able to use the macro outside of the
  88. /// _receiver body
  89. #define ANKI_CONNECT(_sender, _signal, _receiver, _slot) \
  90. (_sender)->_signal.addNewObserver( new \
  91. RemovePointer<decltype(_receiver)>::Type::Observing_##_slot(_receiver))
  92. } // end namespace anki
  93. #endif