Created
March 7, 2019 14:17
-
-
Save LucHermitte/f3d52ecdb2aa61dc68ab6a8c9ccafbf4 to your computer and use it in GitHub Desktop.
Old POC: Observer implementation in C++ with mixin layers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // (c) Luc Hermitte, 2008 | |
| // Distributed under Boost Software Licence | |
| #include <algorithm> | |
| #include <list> | |
| #include <iostream> | |
| template <class Super> | |
| class ObservationLayer : public Super | |
| { | |
| protected: | |
| typedef typename Super::event event_type; | |
| public: | |
| class observable; | |
| struct observer : public Super::observer | |
| { | |
| void update(const observable& o, const event_type& e) { | |
| update_(o, e); | |
| } | |
| }; | |
| class observable : public Super::observable | |
| { | |
| typedef std::list<observer *> observers_list_type; | |
| typedef typename std::list<observer *>::iterator observers_iterator; | |
| observers_list_type observers_; | |
| protected: | |
| /*virtual*/ void notify(const event_type& e) { | |
| // std::for_each(observers_.begin(),observers_.end(), | |
| // boost::bind(&observer::update, _1, *this, e)); | |
| for (observers_iterator it = observers_.begin() | |
| ; it != observers_.end(); ++it) { | |
| (*it)->update(*this, e); | |
| } | |
| } | |
| public: | |
| void attach(observer &o) { observers_.push_back(&o); } | |
| void dettach(observer &o) { | |
| typename observers_list_type::iterator it | |
| = std::find(observers_.begin(),observers_.end(), &o); | |
| if (it != observers_.end()) | |
| observers_.erase(it); | |
| } | |
| }; | |
| }; | |
| class ALayer | |
| { | |
| protected: | |
| struct event { | |
| event(const std::string & s) : message(s) {} | |
| std::string message; | |
| }; | |
| public: | |
| class observable; | |
| struct observer | |
| { | |
| virtual ~observer() { } | |
| protected: | |
| void update_(const observable& o, const event& e) { | |
| std::cout << "message sur A: " << e.message <<std::endl; | |
| } | |
| }; | |
| struct observable // aka A | |
| { | |
| virtual ~observable() { } | |
| void f() { notify(event("Execute f")); } | |
| void g() { notify(event("Execute g")); } | |
| protected: | |
| virtual void notify(const event&) {} | |
| }; | |
| }; | |
| class BLayer | |
| { | |
| protected: | |
| struct event { | |
| enum action_type { i_changed, j_changed }; | |
| event(action_type a) : action(a) {} | |
| action_type action; | |
| }; | |
| public: | |
| class observable; | |
| struct observer | |
| { | |
| virtual ~observer() { } | |
| protected: | |
| void update_(const observable& o, const event& e) { | |
| std::cout << "message sur B: " ; | |
| switch (e.action) { | |
| case event::i_changed: | |
| std::cout << "i vaut maintenant : " << o.get_i(); | |
| break; | |
| case event::j_changed: | |
| std::cout << "j vaut maintenant : " << o.get_j(); | |
| break; | |
| } | |
| std::cout <<std::endl; | |
| } | |
| }; | |
| struct observable // aka B | |
| { | |
| int i_; int j_; | |
| virtual ~observable() { } | |
| void set_i(int i) { i_ = i; notify(event(event::i_changed));} | |
| void set_j(int j) { j_ = j; notify(event(event::j_changed));} | |
| int get_i() const {return i_;} | |
| int get_j() const {return j_;} | |
| protected: | |
| virtual void notify(const event&) {} | |
| }; | |
| }; | |
| typedef ObservationLayer<ALayer>::observable A; | |
| typedef ObservationLayer<BLayer>::observable B; | |
| struct main_observer | |
| : public ObservationLayer<ALayer>::observer | |
| , public ObservationLayer<BLayer>::observer | |
| { | |
| virtual ~main_observer() {} | |
| }; | |
| int main (int argc, char **argv) | |
| { | |
| main_observer o; | |
| A a; | |
| a.attach(o); | |
| a.f(); | |
| a.g(); | |
| std::cout << std::endl; | |
| B b; | |
| b.attach(o); | |
| b.set_j(2); | |
| b.set_i(1); | |
| b.set_i(3); | |
| b.set_j(5); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment