$search
00001 00010 /***************************************************************************** 00011 ** Ifdefs 00012 *****************************************************************************/ 00013 00014 #ifndef ECL_SIGSLOTS_MANAGER_HPP_ 00015 #define ECL_SIGSLOTS_MANAGER_HPP_ 00016 00017 /***************************************************************************** 00018 ** Includes 00019 *****************************************************************************/ 00020 00021 #include <iostream> 00022 #include <map> 00023 #include <string> 00024 #include <ecl/exceptions/standard_exception.hpp> 00025 #include <ecl/config/macros.hpp> 00026 #include "topic.hpp" 00027 00028 /***************************************************************************** 00029 ** Namespaces 00030 *****************************************************************************/ 00031 00032 namespace ecl { 00033 00034 /***************************************************************************** 00035 ** Interface 00036 *****************************************************************************/ 00047 template<typename Data = Void> 00048 class ECL_PUBLIC SigSlotsManager { 00049 public: 00050 00051 friend class SigSlot<Data>; 00052 00058 ECL_PUBLIC static void printStatistics() { 00059 std::cout << "Topics" << std::endl; 00060 typename std::map< std::string, Topic<Data> >::iterator iter; 00061 for ( iter = topics().begin(); iter != topics().end(); ++iter ) { 00062 std::cout << iter->second; 00063 } 00064 } 00065 00066 private: 00070 typedef typename Topic<Data>::Subscribers Subscribers; 00071 00081 ECL_LOCAL static const Subscribers* connectSignal(const std::string& topic, SigSlot<Data>* sigslot) { 00082 // Try and insert a new topic in case it doesn't already exist 00083 // In any case, we always get the iterator back (to new or existing) 00084 // 00085 // Maybe improve the efficiency of this by specifying position 00086 // refer to http://www.cplusplus.com/reference/stl/map/insert/ 00087 std::pair< typename std::map< std::string, Topic<Data> >::iterator,bool> ret = topics().insert( std::pair< std::string, Topic<Data> >(topic, Topic<Data>(topic)) ); 00088 Topic<Data>& current_topic = (ret.first)->second; 00089 current_topic.addPublisher(sigslot); 00090 return current_topic.subscribers(); 00091 } 00092 00100 ECL_LOCAL static void connectSlot(const std::string& topic, SigSlot<Data>* sigslot) { 00101 // Try and insert a new topic in case it doesn't already exist 00102 // In any case, we always get the iterator back (to new or existing) 00103 // 00104 // Maybe improve the efficiency of this by specifying position 00105 // refer to http://www.cplusplus.com/reference/stl/map/insert/ 00106 std::pair< typename std::map< std::string, Topic<Data> >::iterator,bool> ret = topics().insert(std::pair< std::string, Topic<Data> >(topic, Topic<Data>(topic)) ); 00107 Topic<Data>& current_topic = (ret.first)->second; 00108 current_topic.addSubscriber(sigslot); 00109 } 00110 00119 ECL_LOCAL static void disconnect(const std::string& topic, SigSlot<Data>* sigslot) { 00120 typename std::map<std::string, Topic<Data> >::iterator iter = topics().find(topic); 00121 if ( iter != topics().end() ) { 00122 iter->second.disconnect(sigslot); 00123 } 00124 if ( iter->second.empty() ) { 00125 topics().erase(iter); 00126 } 00127 } 00128 00135 ECL_LOCAL static bool isTopic(const std::string& topic) { 00136 return !( topics().find(topic) == topics().end() ); 00137 } 00138 00146 ECL_PUBLIC static std::map< std::string, Topic<Data> >& topics() { 00147 static std::map< std::string, Topic<Data> > topic_list; 00148 return topic_list; 00149 } 00150 00161 ECL_LOCAL static const Subscribers& subscribers(const std::string& topic) { 00162 typename std::map< std::string, Topic<Data> >::const_iterator iter = topics().find(topic); 00163 /* 00164 * Note that this is called only by SigSlotsManager::connectSignal which 00165 * makes sure the topic name exists, so we don't need to do any error 00166 * handling here. 00167 */ 00168 // ecl_assert_throw( iter != topics().end(), StandardException(LOC,InvalidInputError,std::string("No sigslots topic with name:")+topic) ); 00169 return iter->second.subscribers(); 00170 } 00171 }; 00172 00173 00174 } // namespace ecl 00175 00176 00177 #endif /* ECL_SIGSLOTS_MANAGER_HPP_ */