fork download
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <functional>
  4. #include <vector>
  5. #include <set>
  6.  
  7. class Observer;
  8.  
  9. class IObserverNotifier
  10. {
  11. public:
  12. virtual ~IObserverNotifier() = default;
  13. virtual void UnRegister(Observer&) = 0;
  14. };
  15.  
  16. class Observer
  17. {
  18. public:
  19. explicit Observer() = default;
  20. virtual ~Observer() {
  21. for (auto* abstractObserverNotifier : mAbstractObserverNotifiers)
  22. abstractObserverNotifier->UnRegister(*this);
  23. }
  24.  
  25. Observer(const Observer&) = delete;
  26. Observer(Observer&&) = delete;
  27. Observer& operator=(const Observer&) = delete;
  28. Observer& operator=(Observer&&) = delete;
  29.  
  30. void AddObserverNotifier(IObserverNotifier& observerNotifier)
  31. {
  32. mAbstractObserverNotifiers.insert(&observerNotifier);
  33. }
  34.  
  35. void RemoveObserverNotifier(IObserverNotifier& observerNotifier)
  36. {
  37. mAbstractObserverNotifiers.erase(&observerNotifier);
  38. }
  39.  
  40. private:
  41. std::set<IObserverNotifier*> mAbstractObserverNotifiers;
  42. };
  43.  
  44. template<typename ... Params>
  45. class ObserverNotifier : private IObserverNotifier
  46. {
  47. public:
  48. ObserverNotifier() = default;
  49. ~ObserverNotifier() {
  50. for (const auto& p : mObserverCallbacks) {
  51. p.first->RemoveObserverNotifier(*this);
  52. }
  53. }
  54.  
  55. ObserverNotifier(const ObserverNotifier&) = delete;
  56. ObserverNotifier(ObserverNotifier&&) = delete;
  57.  
  58. ObserverNotifier& operator=(const ObserverNotifier&) = delete;
  59. ObserverNotifier& operator=(ObserverNotifier&&) = delete;
  60.  
  61. void Register(Observer& observer, std::function<void(Params...)> f) {
  62. mObserverCallbacks.emplace_back(&observer, f);
  63. observer.AddObserverNotifier(*this);
  64. }
  65.  
  66. void NotifyObservers(Params... args) const
  67. {
  68. for (const auto& p : mObserverCallbacks)
  69. {
  70. const auto& callback = p.second;
  71.  
  72. callback(args...);
  73. }
  74. }
  75.  
  76. private:
  77. void UnRegister(Observer& observer) override
  78. {
  79. mObserverCallbacks.erase(std::remove_if(mObserverCallbacks.begin(),
  80. mObserverCallbacks.end(),
  81. [&](const auto& p) { return p.first == &observer;}),
  82. mObserverCallbacks.end());
  83. }
  84.  
  85. private:
  86. std::vector<std::pair<Observer*, std::function<void(Params...)>>> mObserverCallbacks;
  87. };
  88.  
  89.  
  90. class Sensor
  91. {
  92. public:
  93. void ChangeTime() {
  94. ++mTime;
  95. mOnTimeChange.NotifyObservers(mTime);
  96. }
  97.  
  98. void ChangeTemperature(double delta) {
  99. mTemperature += delta;
  100. mOnTemperatureChange.NotifyObservers(mTemperature);
  101. }
  102.  
  103. void RegisterTimeChange(Observer& observer, std::function<void(double)> f) { mOnTimeChange.Register(observer, f); }
  104. void RegisterTemperatureChange(Observer& observer, std::function<void(double)> f) { mOnTemperatureChange.Register(observer, f); }
  105.  
  106. private:
  107. ObserverNotifier<int> mOnTimeChange;
  108. ObserverNotifier<double> mOnTemperatureChange;
  109. int mTime = 0;
  110. double mTemperature = 0;
  111. };
  112.  
  113. class Ice : public Observer {
  114. public:
  115.  
  116. void OnTimeChanged(int time) {
  117. mVolume -= mLose;
  118. mOnVolumeChange.NotifyObservers(mVolume);
  119. }
  120.  
  121. void OnTemperatureChanged(double t) {
  122. if (t <= 0) {
  123. mLose = 0;
  124. } else if (t < 15) {
  125. mLose = 5;
  126. } else {
  127. mLose = 21;
  128. }
  129. }
  130.  
  131. void RegisterVolumeChange(Observer& observer, std::function<void(double)> f) { mOnVolumeChange.Register(observer, f); }
  132.  
  133.  
  134. private:
  135. ObserverNotifier<double> mOnVolumeChange;
  136. double mVolume = 42;
  137. double mLose = 0;
  138. };
  139.  
  140. class MyObserver : public Observer {
  141. public:
  142. static void OnTimeChange(int t) {
  143. std::cout << "observer says time is " << t << std::endl;
  144. }
  145.  
  146. static void OnTemperatureChange(double temperature) {
  147. std::cout << "observer says temperature is " << temperature << std::endl;
  148. }
  149.  
  150. static void OnIceChange(double volume) {
  151. std::cout << "observer says Ice volume is " << volume << std::endl;
  152. }
  153.  
  154. };
  155.  
  156. int main()
  157. {
  158. Sensor sensor;
  159. Ice ice;
  160. MyObserver observer;
  161.  
  162. sensor.RegisterTimeChange(observer, &MyObserver::OnTimeChange);
  163. sensor.RegisterTemperatureChange(observer, &MyObserver::OnTemperatureChange);
  164. ice.RegisterVolumeChange(observer, &MyObserver::OnIceChange);
  165. sensor.RegisterTimeChange(ice, [&](int t){ice.OnTimeChanged(t);});
  166. sensor.RegisterTemperatureChange(ice, [&](double t){ice.OnTemperatureChanged(t);});
  167.  
  168. sensor.ChangeTemperature(0);
  169. sensor.ChangeTime();
  170. sensor.ChangeTemperature(10.3);
  171. sensor.ChangeTime();
  172. sensor.ChangeTime();
  173. sensor.ChangeTemperature(42.1);
  174. sensor.ChangeTime();
  175. }
  176.  
Success #stdin #stdout 0s 15256KB
stdin
Standard input is empty
stdout
observer says temperature is 0
observer says time is 1
observer says Ice volume is 42
observer says temperature is 10.3
observer says time is 2
observer says Ice volume is 37
observer says time is 3
observer says Ice volume is 32
observer says temperature is 52.4
observer says time is 4
observer says Ice volume is 11