Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <pcl/pcl_config.h>
00036
00037 #ifndef __PCL_IO_GRABBER__
00038 #define __PCL_IO_GRABBER__
00039
00040
00041 #include <map>
00042 #include <iostream>
00043 #include <string>
00044 #include <boost/signals2.hpp>
00045 #include <boost/signals2/slot.hpp>
00046 #include <typeinfo>
00047 #include <vector>
00048 #include <sstream>
00049 #include <pcl/pcl_macros.h>
00050 #include <pcl/io/pcl_io_exception.h>
00051
00052 namespace pcl
00053 {
00054
00059 class PCL_EXPORTS Grabber
00060 {
00061 public:
00062
00064 Grabber () : signals_ (), connections_ (), shared_connections_ () {}
00065
00067 virtual inline ~Grabber () throw ();
00068
00073 template<typename T> boost::signals2::connection
00074 registerCallback (const boost::function<T>& callback);
00075
00079 template<typename T> bool
00080 providesCallback () const;
00081
00085 virtual void
00086 start () = 0;
00087
00091 virtual void
00092 stop () = 0;
00093
00097 virtual std::string
00098 getName () const = 0;
00099
00103 virtual bool
00104 isRunning () const = 0;
00105
00107 virtual float
00108 getFramesPerSecond () const = 0;
00109
00110 protected:
00111
00112 virtual void
00113 signalsChanged () { }
00114
00115 template<typename T> boost::signals2::signal<T>*
00116 find_signal () const;
00117
00118 template<typename T> int
00119 num_slots () const;
00120
00121 template<typename T> void
00122 disconnect_all_slots ();
00123
00124 template<typename T> void
00125 block_signal ();
00126
00127 template<typename T> void
00128 unblock_signal ();
00129
00130 inline void
00131 block_signals ();
00132
00133 inline void
00134 unblock_signals ();
00135
00136 template<typename T> boost::signals2::signal<T>*
00137 createSignal ();
00138
00139 std::map<std::string, boost::signals2::signal_base*> signals_;
00140 std::map<std::string, std::vector<boost::signals2::connection> > connections_;
00141 std::map<std::string, std::vector<boost::signals2::shared_connection_block> > shared_connections_;
00142 } ;
00143
00144 Grabber::~Grabber () throw ()
00145 {
00146 for (std::map<std::string, boost::signals2::signal_base*>::iterator signal_it = signals_.begin (); signal_it != signals_.end (); ++signal_it)
00147 delete signal_it->second;
00148 }
00149
00150 template<typename T> boost::signals2::signal<T>*
00151 Grabber::find_signal () const
00152 {
00153 typedef boost::signals2::signal<T> Signal;
00154
00155 std::map<std::string, boost::signals2::signal_base*>::const_iterator signal_it = signals_.find (typeid (T).name ());
00156 if (signal_it != signals_.end ())
00157 return (dynamic_cast<Signal*> (signal_it->second));
00158
00159 return (NULL);
00160 }
00161
00162 template<typename T> void
00163 Grabber::disconnect_all_slots ()
00164 {
00165 typedef boost::signals2::signal<T> Signal;
00166
00167 if (signals_.find (typeid (T).name ()) != signals_.end ())
00168 {
00169 Signal* signal = dynamic_cast<Signal*> (signals_[typeid (T).name ()]);
00170 signal->disconnect_all_slots ();
00171 }
00172 }
00173
00174 template<typename T> void
00175 Grabber::block_signal ()
00176 {
00177 if (connections_.find (typeid (T).name ()) != connections_.end ())
00178 for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[typeid (T).name ()].begin (); cIt != shared_connections_[typeid (T).name ()].end (); ++cIt)
00179 cIt->block ();
00180 }
00181
00182 template<typename T> void
00183 Grabber::unblock_signal ()
00184 {
00185 if (connections_.find (typeid (T).name ()) != connections_.end ())
00186 for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[typeid (T).name ()].begin (); cIt != shared_connections_[typeid (T).name ()].end (); ++cIt)
00187 cIt->unblock ();
00188 }
00189
00190 void
00191 Grabber::block_signals ()
00192 {
00193 for (std::map<std::string, boost::signals2::signal_base*>::iterator signal_it = signals_.begin (); signal_it != signals_.end (); ++signal_it)
00194 for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[signal_it->first].begin (); cIt != shared_connections_[signal_it->first].end (); ++cIt)
00195 cIt->block ();
00196 }
00197
00198 void
00199 Grabber::unblock_signals ()
00200 {
00201 for (std::map<std::string, boost::signals2::signal_base*>::iterator signal_it = signals_.begin (); signal_it != signals_.end (); ++signal_it)
00202 for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[signal_it->first].begin (); cIt != shared_connections_[signal_it->first].end (); ++cIt)
00203 cIt->unblock ();
00204 }
00205
00206 template<typename T> int
00207 Grabber::num_slots () const
00208 {
00209 typedef boost::signals2::signal<T> Signal;
00210
00211
00212 std::map<std::string, boost::signals2::signal_base*>::const_iterator signal_it = signals_.find (typeid (T).name ());
00213 if (signal_it != signals_.end ())
00214 {
00215 Signal* signal = dynamic_cast<Signal*> (signal_it->second);
00216 return (static_cast<int> (signal->num_slots ()));
00217 }
00218 return (0);
00219 }
00220
00221 template<typename T> boost::signals2::signal<T>*
00222 Grabber::createSignal ()
00223 {
00224 typedef boost::signals2::signal<T> Signal;
00225
00226 if (signals_.find (typeid (T).name ()) == signals_.end ())
00227 {
00228 Signal* signal = new Signal ();
00229 signals_[typeid (T).name ()] = signal;
00230 return (signal);
00231 }
00232 return (0);
00233 }
00234
00235 template<typename T> boost::signals2::connection
00236 Grabber::registerCallback (const boost::function<T> & callback)
00237 {
00238 typedef boost::signals2::signal<T> Signal;
00239 if (signals_.find (typeid (T).name ()) == signals_.end ())
00240 {
00241 std::stringstream sstream;
00242
00243 sstream << "no callback for type:" << typeid (T).name ();
00244
00245
00246
00247
00248
00249
00250
00251
00252 THROW_PCL_IO_EXCEPTION ("[%s] %s", getName ().c_str (), sstream.str ().c_str ());
00253
00254 }
00255 Signal* signal = dynamic_cast<Signal*> (signals_[typeid (T).name ()]);
00256 boost::signals2::connection ret = signal->connect (callback);
00257
00258 connections_[typeid (T).name ()].push_back (ret);
00259 shared_connections_[typeid (T).name ()].push_back (boost::signals2::shared_connection_block (connections_[typeid (T).name ()].back (), false));
00260 signalsChanged ();
00261 return (ret);
00262 }
00263
00264 template<typename T> bool
00265 Grabber::providesCallback () const
00266 {
00267 if (signals_.find (typeid (T).name ()) == signals_.end ())
00268 return (false);
00269 return (true);
00270 }
00271
00272 }
00273
00274 #endif