/* * Copyright (C) 2015 by Multi-Tech Systems * * This file is part of libmts. * * libmts is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * libmts is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libmts. If not, see . * */ /*! \file MTS_Publisher.h \brief An abstract publisher \date 28MAR12 \author Sean Godinez A publisher base class. Requires derived class to handle publishing. */ #ifndef _MTS_PUBLISHER_H_ #define _MTS_PUBLISHER_H_ #include #include #include #include #include #include namespace MTS { //! An abstract publisher /*! A template abstract publisher class \sa Subscriber */ template class Publisher: NonCopyable { public: virtual ~Publisher(); //!< Destructs subscriber void addSubscriber(Subscriber& subscriber); //!< Adds a subscriber void removeSubscriber(Subscriber& subscriber); //!< Removes a subscriber protected: Publisher(); //!< Constructs publisher virtual void publish(const T& object); //!< Protects publishing operation private: typedef std::set*> SubscriberSet; AutoPtr m_apLock; //!< Guards for thread safety SubscriberSet m_sSubscribers; //!< Set of subscribers }; template Publisher::Publisher() { m_apLock.reset(new Lock()); } template Publisher::~Publisher() { m_apLock.reset(); } template void Publisher::addSubscriber( Subscriber& subscriber) { m_apLock->lock(); m_sSubscribers.insert(&subscriber); /* //WARNING IF ALREADY PRESENT IN SET pair::iterator,bool> ret; ret = m_sSubscribers.insert(&subscriber); if (ret.second==false) { Logger::printWarning("subscriber already in set %s (%p)", subscriber->getName().c_str(), subscriber); } */ m_apLock->unlock(); } template void Publisher::removeSubscriber( Subscriber& subscriber) { m_apLock->lock(); m_sSubscribers.erase(&subscriber); /* //WARNING IF SUBSCRIBER WAS NOT IN SET uint32_t count = m_sSubscribers.erase(&subscriber); if (count == 0) { Logger::printWarning("subscriber was not in set %s (%p)", subscriber->getName().c_str(), subscriber); } */ m_apLock->unlock(); } template void Publisher::publish(const T& object) { m_apLock->lock(); SubscriberSet set(m_sSubscribers); for (typename SubscriberSet::iterator i = set.begin(); i != set.end(); i++) { Subscriber* subscriber = *i; try { subscriber->update(object); } catch (...) { printWarning("Publisher| exception caught while updating subscriber %s (%p)", subscriber->getName().c_str(), subscriber); } } m_apLock->unlock(); } } #endif