// Copyright (c) 2011-2016 The Cryptonote developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #pragma once #include #include #include namespace Tools { template class ObserverManager { public: bool add(T* observer) { std::unique_lock lock(m_observersMutex); auto it = std::find(m_observers.begin(), m_observers.end(), observer); if (m_observers.end() == it) { m_observers.push_back(observer); return true; } else { return false; } } bool remove(T* observer) { std::unique_lock lock(m_observersMutex); auto it = std::find(m_observers.begin(), m_observers.end(), observer); if (m_observers.end() == it) { return false; } else { m_observers.erase(it); return true; } } void clear() { std::unique_lock lock(m_observersMutex); m_observers.clear(); } #if defined(_MSC_VER) template void notify(F notification) { std::vector observersCopy; { std::unique_lock lock(m_observersMutex); observersCopy = m_observers; } for (T* observer : observersCopy) { (observer->*notification)(); } } template void notify(F notification, const Arg0& arg0) { std::vector observersCopy; { std::unique_lock lock(m_observersMutex); observersCopy = m_observers; } for (T* observer : observersCopy) { (observer->*notification)(arg0); } } template void notify(F notification, const Arg0& arg0, const Arg1& arg1) { std::vector observersCopy; { std::unique_lock lock(m_observersMutex); observersCopy = m_observers; } for (T* observer : observersCopy) { (observer->*notification)(arg0, arg1); } } template void notify(F notification, const Arg0& arg0, const Arg1& arg1, const Arg2& arg2) { std::vector observersCopy; { std::unique_lock lock(m_observersMutex); observersCopy = m_observers; } for (T* observer : observersCopy) { (observer->*notification)(arg0, arg1, arg2); } } template void notify(F notification, const Arg0& arg0, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) { std::vector observersCopy; { std::unique_lock lock(m_observersMutex); observersCopy = m_observers; } for (T* observer : observersCopy) { (observer->*notification)(arg0, arg1, arg2, arg3); } } template void notify(F notification, const Arg0& arg0, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) { std::vector observersCopy; { std::unique_lock lock(m_observersMutex); observersCopy = m_observers; } for (T* observer : observersCopy) { (observer->*notification)(arg0, arg1, arg2, arg3, arg4); } } template void notify(F notification, const Arg0& arg0, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) { std::vector observersCopy; { std::unique_lock lock(m_observersMutex); observersCopy = m_observers; } for (T* observer : observersCopy) { (observer->*notification)(arg0, arg1, arg2, arg3, arg4, arg5); } } #else template void notify(F notification, Args... args) { std::vector observersCopy; { std::unique_lock lock(m_observersMutex); observersCopy = m_observers; } for (T* observer : observersCopy) { (observer->*notification)(args...); } } #endif private: std::vector m_observers; std::mutex m_observersMutex; }; }