#pragma once #include <memory> #include <list> #include <mutex> #include <boost/noncopyable.hpp> namespace dp { template <typename target> class observer : public std::enable_shared_from_this<observer<target>> { public: virtual void on_update(const target&) = 0; }; template <typename target> class observable : public boost::noncopyable { public: typedef observer<target> observer_type; typedef std::weak_ptr<observer_type> observer_ptr; typedef std::lock_guard<std::mutex> lock_guard_type; protected: mutable std::mutex mutex_; std::list<observer_ptr> observers_; public: void register_observer(const observer_ptr& obj) { lock_guard_type lock(mutex_); observers_.push_back(obj); } void notify_observers(const target& target) { lock_guard_type lock(mutex_); auto iter = observers_.begin(); while (iter != observers_.end()) { std::shared_ptr<observer_type> obj(iter->lock()); if (obj) { obj->on_update(target); ++iter; } else { iter = observers_.erase(iter); } } } }; };