Program Listing for File manager.hpp

Return to documentation for file (/tmp/ws/src/ecl_core/ecl_sigslots/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_ */