summaryrefslogtreecommitdiff
path: root/include/mts/MTS_Publisher.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/mts/MTS_Publisher.h')
-rw-r--r--include/mts/MTS_Publisher.h130
1 files changed, 130 insertions, 0 deletions
diff --git a/include/mts/MTS_Publisher.h b/include/mts/MTS_Publisher.h
new file mode 100644
index 0000000..8b0fcee
--- /dev/null
+++ b/include/mts/MTS_Publisher.h
@@ -0,0 +1,130 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*! \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 <mts/MTS_Subscriber.h>
+#include <mts/MTS_AutoPtr.h>
+#include <mts/MTS_Lock.h>
+#include <mts/MTS_Logger.h>
+#include <mts/MTS_NonCopyable.h>
+#include <set>
+
+namespace MTS {
+
+ //! An abstract publisher
+ /*!
+ A template abstract publisher class
+
+ \sa Subscriber
+ */
+ template<class T> class Publisher: NonCopyable {
+
+ public:
+ virtual ~Publisher(); //!< Destructs subscriber
+
+ void addSubscriber(Subscriber<T>& subscriber); //!< Adds a subscriber
+ void removeSubscriber(Subscriber<T>& subscriber); //!< Removes a subscriber
+
+ protected:
+ Publisher(); //!< Constructs publisher
+ virtual void publish(const T& object); //!< Protects publishing operation
+
+ private:
+ typedef std::set<Subscriber<T>*> SubscriberSet;
+
+ AutoPtr<Lock> m_apLock; //!< Guards for thread safety
+ SubscriberSet m_sSubscribers; //!< Set of subscribers
+
+ };
+
+ template<class T> Publisher<T>::Publisher() {
+ m_apLock.reset(new Lock());
+ }
+
+ template<class T> Publisher<T>::~Publisher() {
+ m_apLock.reset();
+ }
+
+ template<class T> void Publisher<T>::addSubscriber(
+ Subscriber<T>& subscriber) {
+
+ m_apLock->lock();
+ m_sSubscribers.insert(&subscriber);
+
+ /*
+
+ //WARNING IF ALREADY PRESENT IN SET
+ pair<set<T>::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<class T> void Publisher<T>::removeSubscriber(
+ Subscriber<T>& 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<class T> void Publisher<T>::publish(const T& object) {
+ m_apLock->lock();
+ SubscriberSet set(m_sSubscribers);
+ for (typename SubscriberSet::iterator i = set.begin(); i != set.end(); i++) {
+ Subscriber<T>* 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