Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <chrono>
- #include <vector>
- #include <unordered_map>
- #include <iostream>
- #include <typeindex>
- #include <algorithm>
- #include <stdexcept>
- #include <functional>
- #include <set>
- #include <utility>
- #include <thread>
- class Subject;
- class Event
- {
- public:
- virtual ~Event(){}
- };
- enum class NotifyAction { Done, UnRegister};
- class Observer
- {
- public:
- virtual ~Observer() {}
- virtual NotifyAction onNotify(Subject& subject, Event const& event) = 0;
- };
- class Subject
- {
- public:
- void registerObserver(Observer& observer)
- {
- if (std::find(std::begin(observers), std::end(observers), &observer) != std::end(observers)) {
- throw std::runtime_error("registerObserver(): observer already registered");
- }
- observers.push_back(&observer);
- }
- void unregisterObserver(Observer& observer)
- {
- observers.erase(std::remove(std::begin(observers), std::end(observers), &observer), std::end(observers));
- }
- void notifyObservers(Event const& event)
- {
- std::vector<Observer*> deadObservers;
- for(Observer* observer: observers) {
- if (observer->onNotify(*this, event) == NotifyAction::UnRegister) {
- deadObservers.push_back(observer);
- }
- }
- // Remove the dead observers.
- auto newEnd = std::end(observers);
- for(Observer* dead:deadObservers) {
- newEnd = std::remove(std::begin(observers), newEnd, dead);
- }
- observers.erase(newEnd, std::end(observers));
- }
- private:
- std::vector<Observer*> observers;
- };
- class EventHandler: public Observer
- {
- public:
- NotifyAction onNotify(Subject& subject, Event const& event) override
- {
- auto find = handlers.find(std::type_index(typeid(event)));
- if (find != handlers.end()) {
- find->second(subject, event);
- }
- return NotifyAction::Done;
- }
- template<typename T>
- void registerEventHandler(std::function<void(Subject&, Event const&)> handler)
- {
- handlers[std::type_index(typeid(T))] = handler;
- }
- private:
- std::unordered_map<std::type_index, std::function<void(Subject&, Event const&)>> handlers;
- };
- class MouseMove: public Event {};
- 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){}};
- std::set<std::pair<unsigned int, unsigned int>> MouseClick::alreadyVisited = std::set<std::pair<unsigned int, unsigned int>>();
- class MouseTick: public Event
- {
- public:
- std::chrono::minutes minutes;
- std::chrono::seconds seconds;
- MouseTick( unsigned int mm, unsigned int ss): minutes(mm), seconds(ss){}
- };
- class MouseHandler: public EventHandler
- {
- private:
- void mouseClick(Subject&, Event const&)
- {
- std::cout << "Mouse Clicked\n";
- }
- public:
- MouseHandler()
- {
- // Register a call to a member method
- // registerEventHandler<MouseClick>(std::bind(&MouseHandler::mouseClick, this, std::placeholders::_1, std::placeholders::_2));
- }
- };
- class Mouse: public Subject
- {
- };
- int main()
- {
- MouseHandler mouseEventHandler;
- // Register a call to a lambda
- mouseEventHandler.registerEventHandler<MouseMove>([](Subject&, Event const&){std::cout << "Mouse Moved\n";});
- mouseEventHandler.registerEventHandler<MouseClick>([](Subject& ss , Event const& ee )
- { MouseClick const& myEvent = dynamic_cast<const MouseClick&>(ee) ;
- std::cout<< " you clicked " << myEvent.xPosition << " " << myEvent.yPosition << " bro !" << std::endl;
- std::pair<unsigned int, unsigned int> pp = std::make_pair( myEvent.xPosition , myEvent.yPosition ) ;
- if( myEvent.alreadyVisited.find(pp) == std::end(myEvent.alreadyVisited))
- std::cout << " welcome for the first time , bro ! " << std::endl;
- myEvent.alreadyVisited.insert(pp);
- });
- unsigned int min = 1;
- unsigned int sec= 17;
- mouseEventHandler.registerEventHandler<MouseTick>([min, sec](Subject& ss , Event const& ee )
- { MouseTick const& myEvent = dynamic_cast<const MouseTick&>(ee);
- if( myEvent.minutes.count() == min && myEvent.seconds.count() == sec)
- std::cout << myEvent.minutes.count() << " minutes has passed and " << myEvent.seconds.count() << "seconds"<< std::endl;
- });
- Mouse mouse;
- MouseClick mMouseClick (44,45);
- MouseTick mMouseTick (3,33);
- mouse.registerObserver(mouseEventHandler);
- mouse.notifyObservers(mMouseClick);
- mouse.notifyObservers(mMouseClick);
- mouse.notifyObservers(mMouseClick);
- std::chrono::seconds ii{1};
- int jj = 0;
- while(true)
- {
- std::this_thread::sleep_for(ii);
- mouse.notifyObservers(MouseTick(jj/60,jj%60));
- jj++;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment