Skip to content

Instantly share code, notes, and snippets.

@graysonarts
Created September 30, 2015 14:44
Show Gist options
  • Save graysonarts/5230c3593dc320da7140 to your computer and use it in GitHub Desktop.
Save graysonarts/5230c3593dc320da7140 to your computer and use it in GitHub Desktop.
A simple observable implemented using std::weak_ptr
#include <set>
#include <memory>
#include <vector>
template <typename T>
class IObservable;
template <typename T>
class IObserver
{
public:
virtual ~IObserver() = default;
virtual void update(const IObservable<T>& subject, const T&) = 0;
};
template <typename T>
using IObserver_wptr = std::weak_ptr<IObserver<T> >;
template <typename T>
using IObservers = std::set<IObserver_wptr<T>,
std::owner_less<IObserver_wptr<T> > >;
template <typename T>
class Observable
{
public:
Observable()
: m_observers({})
{
}
virtual ~Observable() = default;
void attach(const IObserver_wptr<T> observer)
{
m_observers.insert(observer);
}
void detach(const IObserver_wptr<T> observer)
{
m_observers.erase(observer);
}
protected:
virtual void notify(const T& value)
{
std::vector<IObserver_wptr<T> > toRemove;
for(auto& observer : m_observers)
{
auto lockedObserver = observer.lock();
if (lockedObserver)
{
lockedObserver->update(*this, value);
} else {
toRemove.push_back(observer);
}
}
for(auto& observer : toRemove)
{
detach(observer);
}
}
IObservers<T> m_observers;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment