Program Listing for File manager.hpp
↰ Return to documentation for file (include/ecl/sigslots/manager.hpp
)
/*****************************************************************************
** Ifdefs
*****************************************************************************/
#ifndef ECL_SIGSLOTS_MANAGER_HPP_
#define ECL_SIGSLOTS_MANAGER_HPP_
/*****************************************************************************
** Includes
*****************************************************************************/
#include <iostream>
#include <map>
#include <string>
#include <ecl/exceptions/standard_exception.hpp>
#include <ecl/config/macros.hpp>
#include <ecl/utilities/void.hpp>
#include "topic.hpp"
/*****************************************************************************
** Namespaces
*****************************************************************************/
namespace ecl {
/*****************************************************************************
** Interface
*****************************************************************************/
template<typename Data = Void>
class SigSlotsManager {
public:
friend class SigSlot<Data>;
static void printStatistics() {
std::cout << "Topics" << std::endl;
typename std::map< std::string, Topic<Data> >::iterator iter;
for ( iter = topics().begin(); iter != topics().end(); ++iter ) {
std::cout << iter->second;
}
}
private:
typedef typename Topic<Data>::Subscribers Subscribers;
static const Subscribers* connectSignal(const std::string& topic, SigSlot<Data>* sigslot) {
// Try and insert a new topic in case it doesn't already exist
// In any case, we always get the iterator back (to new or existing)
//
// Maybe improve the efficiency of this by specifying position
// refer to http://www.cplusplus.com/reference/stl/map/insert/
std::pair< typename std::map< std::string, Topic<Data> >::iterator,bool> ret = topics().insert( std::pair< std::string, Topic<Data> >(topic, Topic<Data>(topic)) );
Topic<Data>& current_topic = (ret.first)->second;
current_topic.addPublisher(sigslot);
return current_topic.subscribers();
}
static void connectSlot(const std::string& topic, SigSlot<Data>* sigslot) {
// Try and insert a new topic in case it doesn't already exist
// In any case, we always get the iterator back (to new or existing)
//
// Maybe improve the efficiency of this by specifying position
// refer to http://www.cplusplus.com/reference/stl/map/insert/
std::pair< typename std::map< std::string, Topic<Data> >::iterator,bool> ret = topics().insert(std::pair< std::string, Topic<Data> >(topic, Topic<Data>(topic)) );
Topic<Data>& current_topic = (ret.first)->second;
current_topic.addSubscriber(sigslot);
}
static void disconnect(const std::string& topic, SigSlot<Data>* sigslot) {
typename std::map<std::string, Topic<Data> >::iterator iter = topics().find(topic);
if ( iter != topics().end() ) {
iter->second.disconnect(sigslot);
}
if ( iter->second.empty() ) {
topics().erase(iter);
}
}
static bool isTopic(const std::string& topic) {
return !( topics().find(topic) == topics().end() );
}
static std::map< std::string, Topic<Data> >& topics() {
static std::map< std::string, Topic<Data> > topic_list;
return topic_list;
}
static const Subscribers& subscribers(const std::string& topic) {
typename std::map< std::string, Topic<Data> >::const_iterator iter = topics().find(topic);
/*
* Note that this is called only by SigSlotsManager::connectSignal which
* makes sure the topic name exists, so we don't need to do any error
* handling here.
*/
// ecl_assert_throw( iter != topics().end(), StandardException(LOC,InvalidInputError,std::string("No sigslots topic with name:")+topic) );
return *iter->second.subscribers();
}
};
} // namespace ecl
#endif /* ECL_SIGSLOTS_MANAGER_HPP_ */