#pragma once #include "base/logging.hpp" #include #include #include #include namespace base { class DummyLockable { public: void lock() {} void unlock() {} }; template class ObserverList; /// This alias represents a thread-safe observers list. It allows to /// add/remove observers as well as trigger them all. template using ObserverListSafe = ObserverList; template using ObserverListUnsafe = ObserverList; template class ObserverList { public: bool Add(Observer & observer) { std::lock_guard lock(m_observersLock); auto const it = std::find(m_observers.begin(), m_observers.end(), &observer); if (it != m_observers.end()) { LOG(LWARNING, ("Can't add the same observer twice:", &observer)); return false; } m_observers.push_back(&observer); return true; } bool Remove(Observer const & observer) { std::lock_guard lock(m_observersLock); auto const it = std::find(m_observers.begin(), m_observers.end(), &observer); if (it == m_observers.end()) { LOG(LWARNING, ("Can't remove non-registered observer:", &observer)); return false; } m_observers.erase(it); return true; } template void ForEach(F fn, Args const &... args) { std::lock_guard lock(m_observersLock); for (Observer * observer : m_observers) (observer->*fn)(args...); } private: Mutex m_observersLock; std::vector m_observers; }; } // namespace base