Skip to content

Instantly share code, notes, and snippets.

@LucHermitte
Created March 7, 2019 14:17
Show Gist options
  • Select an option

  • Save LucHermitte/f3d52ecdb2aa61dc68ab6a8c9ccafbf4 to your computer and use it in GitHub Desktop.

Select an option

Save LucHermitte/f3d52ecdb2aa61dc68ab6a8c9ccafbf4 to your computer and use it in GitHub Desktop.
Old POC: Observer implementation in C++ with mixin layers
// (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