Guest User

Untitled

a guest
Oct 12th, 2025
43
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.96 KB | None | 0 0
  1. #include <chrono>
  2. #include <vector>
  3. #include <unordered_map>
  4. #include <iostream>
  5. #include <typeindex>
  6. #include <algorithm>
  7. #include <stdexcept>
  8. #include <functional>
  9. #include <set>
  10. #include <utility>
  11. #include <thread>
  12.  
  13. class Subject;
  14. class Event
  15. {
  16. public:
  17. virtual ~Event(){}
  18. };
  19.  
  20. enum class NotifyAction { Done, UnRegister};
  21. class Observer
  22. {
  23. public:
  24. virtual ~Observer() {}
  25. virtual NotifyAction onNotify(Subject& subject, Event const& event) = 0;
  26. };
  27. class Subject
  28. {
  29. public:
  30. void registerObserver(Observer& observer)
  31. {
  32. if (std::find(std::begin(observers), std::end(observers), &observer) != std::end(observers)) {
  33. throw std::runtime_error("registerObserver(): observer already registered");
  34. }
  35. observers.push_back(&observer);
  36. }
  37. void unregisterObserver(Observer& observer)
  38. {
  39. observers.erase(std::remove(std::begin(observers), std::end(observers), &observer), std::end(observers));
  40. }
  41. void notifyObservers(Event const& event)
  42. {
  43. std::vector<Observer*> deadObservers;
  44. for(Observer* observer: observers) {
  45. if (observer->onNotify(*this, event) == NotifyAction::UnRegister) {
  46. deadObservers.push_back(observer);
  47. }
  48. }
  49.  
  50. // Remove the dead observers.
  51. auto newEnd = std::end(observers);
  52. for(Observer* dead:deadObservers) {
  53. newEnd = std::remove(std::begin(observers), newEnd, dead);
  54. }
  55. observers.erase(newEnd, std::end(observers));
  56. }
  57. private:
  58. std::vector<Observer*> observers;
  59. };
  60. class EventHandler: public Observer
  61. {
  62. public:
  63. NotifyAction onNotify(Subject& subject, Event const& event) override
  64. {
  65. auto find = handlers.find(std::type_index(typeid(event)));
  66. if (find != handlers.end()) {
  67. find->second(subject, event);
  68. }
  69.  
  70. return NotifyAction::Done;
  71. }
  72. template<typename T>
  73. void registerEventHandler(std::function<void(Subject&, Event const&)> handler)
  74. {
  75. handlers[std::type_index(typeid(T))] = handler;
  76. }
  77.  
  78.  
  79.  
  80. private:
  81. std::unordered_map<std::type_index, std::function<void(Subject&, Event const&)>> handlers;
  82. };
  83. class MouseMove: public Event {};
  84. class MouseClick: public Event { public : unsigned int xPosition ; unsigned int yPosition; static std::set<std::pair<unsigned int, unsigned int>> alreadyVisited ; MouseClick(unsigned int x , unsigned int y ):xPosition(x),yPosition(y){}};
  85. std::set<std::pair<unsigned int, unsigned int>> MouseClick::alreadyVisited = std::set<std::pair<unsigned int, unsigned int>>();
  86.  
  87.  
  88.  
  89.  
  90. class MouseTick: public Event
  91. {
  92. public:
  93. std::chrono::minutes minutes;
  94. std::chrono::seconds seconds;
  95. MouseTick( unsigned int mm, unsigned int ss): minutes(mm), seconds(ss){}
  96. };
  97.  
  98.  
  99. class MouseHandler: public EventHandler
  100. {
  101. private:
  102. void mouseClick(Subject&, Event const&)
  103. {
  104. std::cout << "Mouse Clicked\n";
  105. }
  106. public:
  107. MouseHandler()
  108. {
  109. // Register a call to a member method
  110. // registerEventHandler<MouseClick>(std::bind(&MouseHandler::mouseClick, this, std::placeholders::_1, std::placeholders::_2));
  111. }
  112. };
  113. class Mouse: public Subject
  114. {
  115. };
  116. int main()
  117. {
  118.  
  119. MouseHandler mouseEventHandler;
  120. // Register a call to a lambda
  121. mouseEventHandler.registerEventHandler<MouseMove>([](Subject&, Event const&){std::cout << "Mouse Moved\n";});
  122. mouseEventHandler.registerEventHandler<MouseClick>([](Subject& ss , Event const& ee )
  123. { MouseClick const& myEvent = dynamic_cast<const MouseClick&>(ee) ;
  124. std::cout<< " you clicked " << myEvent.xPosition << " " << myEvent.yPosition << " bro !" << std::endl;
  125. std::pair<unsigned int, unsigned int> pp = std::make_pair( myEvent.xPosition , myEvent.yPosition ) ;
  126. if( myEvent.alreadyVisited.find(pp) == std::end(myEvent.alreadyVisited))
  127. std::cout << " welcome for the first time , bro ! " << std::endl;
  128. myEvent.alreadyVisited.insert(pp);
  129. });
  130. unsigned int min = 1;
  131. unsigned int sec= 17;
  132. mouseEventHandler.registerEventHandler<MouseTick>([min, sec](Subject& ss , Event const& ee )
  133. { MouseTick const& myEvent = dynamic_cast<const MouseTick&>(ee);
  134. if( myEvent.minutes.count() == min && myEvent.seconds.count() == sec)
  135. std::cout << myEvent.minutes.count() << " minutes has passed and " << myEvent.seconds.count() << "seconds"<< std::endl;
  136. });
  137.  
  138.  
  139.  
  140. Mouse mouse;
  141. MouseClick mMouseClick (44,45);
  142. MouseTick mMouseTick (3,33);
  143. mouse.registerObserver(mouseEventHandler);
  144. mouse.notifyObservers(mMouseClick);
  145. mouse.notifyObservers(mMouseClick);
  146. mouse.notifyObservers(mMouseClick);
  147. std::chrono::seconds ii{1};
  148. int jj = 0;
  149. while(true)
  150. {
  151. std::this_thread::sleep_for(ii);
  152. mouse.notifyObservers(MouseTick(jj/60,jj%60));
  153.  
  154.  
  155. jj++;
  156. }
  157.  
  158.  
  159.  
  160. }
  161.  
Advertisement
Add Comment
Please, Sign In to add comment