Observer_safe.cc revision 1bc80516
11bc80516SShuo Chen#include <algorithm>
21bc80516SShuo Chen#include <vector>
31bc80516SShuo Chen#include <stdio.h>
41bc80516SShuo Chen#include "../Mutex.h"
51bc80516SShuo Chen#include <boost/enable_shared_from_this.hpp>
61bc80516SShuo Chen#include <boost/shared_ptr.hpp>
71bc80516SShuo Chen#include <boost/weak_ptr.hpp>
81bc80516SShuo Chen
91bc80516SShuo Chenclass Observable;
101bc80516SShuo Chen
111bc80516SShuo Chenclass Observer : public boost::enable_shared_from_this<Observer>
121bc80516SShuo Chen{
131bc80516SShuo Chen public:
141bc80516SShuo Chen  virtual ~Observer();
151bc80516SShuo Chen  virtual void update() = 0;
161bc80516SShuo Chen
171bc80516SShuo Chen  void observe(Observable* s);
181bc80516SShuo Chen
191bc80516SShuo Chen protected:
201bc80516SShuo Chen  Observable* subject_;
211bc80516SShuo Chen};
221bc80516SShuo Chen
231bc80516SShuo Chenclass Observable
241bc80516SShuo Chen{
251bc80516SShuo Chen public:
261bc80516SShuo Chen  void register_(boost::weak_ptr<Observer> x);
271bc80516SShuo Chen  // void unregister(boost::weak_ptr<Observer> x);
281bc80516SShuo Chen
291bc80516SShuo Chen  void notifyObservers()
301bc80516SShuo Chen  {
311bc80516SShuo Chen    muduo::MutexLockGuard lock(mutex_);
321bc80516SShuo Chen    Iterator it = observers_.begin();
331bc80516SShuo Chen    while (it != observers_.end())
341bc80516SShuo Chen    {
351bc80516SShuo Chen      boost::shared_ptr<Observer> obj(it->lock());
361bc80516SShuo Chen      if (obj)
371bc80516SShuo Chen      {
381bc80516SShuo Chen        obj->update();
391bc80516SShuo Chen        ++it;
401bc80516SShuo Chen      }
411bc80516SShuo Chen      else
421bc80516SShuo Chen      {
431bc80516SShuo Chen        printf("notifyObservers() erase\n");
441bc80516SShuo Chen        it = observers_.erase(it);
451bc80516SShuo Chen      }
461bc80516SShuo Chen    }
471bc80516SShuo Chen  }
481bc80516SShuo Chen
491bc80516SShuo Chen private:
501bc80516SShuo Chen  mutable muduo::MutexLock mutex_;
511bc80516SShuo Chen  std::vector<boost::weak_ptr<Observer> > observers_;
521bc80516SShuo Chen  typedef std::vector<boost::weak_ptr<Observer> >::iterator Iterator;
531bc80516SShuo Chen};
541bc80516SShuo Chen
551bc80516SShuo ChenObserver::~Observer()
561bc80516SShuo Chen{
571bc80516SShuo Chen  // subject_->unregister(this);
581bc80516SShuo Chen}
591bc80516SShuo Chen
601bc80516SShuo Chenvoid Observer::observe(Observable* s)
611bc80516SShuo Chen{
621bc80516SShuo Chen  s->register_(shared_from_this());
631bc80516SShuo Chen  subject_ = s;
641bc80516SShuo Chen}
651bc80516SShuo Chen
661bc80516SShuo Chenvoid Observable::register_(boost::weak_ptr<Observer> x)
671bc80516SShuo Chen{
681bc80516SShuo Chen  observers_.push_back(x);
691bc80516SShuo Chen}
701bc80516SShuo Chen
711bc80516SShuo Chen//void Observable::unregister(boost::weak_ptr<Observer> x)
721bc80516SShuo Chen//{
731bc80516SShuo Chen//  Iterator it = std::find(observers_.begin(), observers_.end(), x);
741bc80516SShuo Chen//  observers_.erase(it);
751bc80516SShuo Chen//}
761bc80516SShuo Chen
771bc80516SShuo Chen// ---------------------
781bc80516SShuo Chen
791bc80516SShuo Chenclass Foo : public Observer
801bc80516SShuo Chen{
811bc80516SShuo Chen  virtual void update()
821bc80516SShuo Chen  {
831bc80516SShuo Chen    printf("Foo::update() %p\n", this);
841bc80516SShuo Chen  }
851bc80516SShuo Chen};
861bc80516SShuo Chen
871bc80516SShuo Chenint main()
881bc80516SShuo Chen{
891bc80516SShuo Chen  Observable subject;
901bc80516SShuo Chen  {
911bc80516SShuo Chen    boost::shared_ptr<Foo> p(new Foo);
921bc80516SShuo Chen    p->observe(&subject);
931bc80516SShuo Chen    subject.notifyObservers();
941bc80516SShuo Chen  }
951bc80516SShuo Chen  subject.notifyObservers();
961bc80516SShuo Chen}
971bc80516SShuo Chen
98