/*
* 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