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 <typeinfo>
00045 #include <vector>
00046 #include <sstream>
00047 #include <pcl/pcl_macros.h>
00048 #include <pcl/io/boost.h>
00049 #include <pcl/exceptions.h>
00050
00051 namespace pcl
00052 {
00053
00058 class PCL_EXPORTS Grabber
00059 {
00060 public:
00061
00063 Grabber () : signals_ (), connections_ (), shared_connections_ () {}
00064
00066 virtual inline ~Grabber () throw ();
00067
00072 template<typename T> boost::signals2::connection
00073 registerCallback (const boost::function<T>& callback);
00074
00078 template<typename T> bool
00079 providesCallback () const;
00080
00084 virtual void
00085 start () = 0;
00086
00090 virtual void
00091 stop () = 0;
00092
00096 virtual std::string
00097 getName () const = 0;
00098
00102 virtual bool
00103 isRunning () const = 0;
00104
00106 virtual float
00107 getFramesPerSecond () const = 0;
00108
00109 protected:
00110
00111 virtual void
00112 signalsChanged () { }
00113
00114 template<typename T> boost::signals2::signal<T>*
00115 find_signal () const;
00116
00117 template<typename T> int
00118 num_slots () const;
00119
00120 template<typename T> void
00121 disconnect_all_slots ();
00122
00123 template<typename T> void
00124 block_signal ();
00125
00126 template<typename T> void
00127 unblock_signal ();
00128
00129 inline void
00130 block_signals ();
00131
00132 inline void
00133 unblock_signals ();
00134
00135 template<typename T> boost::signals2::signal<T>*
00136 createSignal ();
00137
00138 std::map<std::string, boost::signals2::signal_base*> signals_;
00139 std::map<std::string, std::vector<boost::signals2::connection> > connections_;
00140 std::map<std::string, std::vector<boost::signals2::shared_connection_block> > shared_connections_;
00141 } ;
00142
00143 Grabber::~Grabber () throw ()
00144 {
00145 for (std::map<std::string, boost::signals2::signal_base*>::iterator signal_it = signals_.begin (); signal_it != signals_.end (); ++signal_it)
00146 delete signal_it->second;
00147 }
00148
00149 template<typename T> boost::signals2::signal<T>*
00150 Grabber::find_signal () const
00151 {
00152 typedef boost::signals2::signal<T> Signal;
00153
00154 std::map<std::string, boost::signals2::signal_base*>::const_iterator signal_it = signals_.find (typeid (T).name ());
00155 if (signal_it != signals_.end ())
00156 return (dynamic_cast<Signal*> (signal_it->second));
00157
00158 return (NULL);
00159 }
00160
00161 template<typename T> void
00162 Grabber::disconnect_all_slots ()
00163 {
00164 typedef boost::signals2::signal<T> Signal;
00165
00166 if (signals_.find (typeid (T).name ()) != signals_.end ())
00167 {
00168 Signal* signal = dynamic_cast<Signal*> (signals_[typeid (T).name ()]);
00169 signal->disconnect_all_slots ();
00170 }
00171 }
00172
00173 template<typename T> void
00174 Grabber::block_signal ()
00175 {
00176 if (connections_.find (typeid (T).name ()) != connections_.end ())
00177 for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[typeid (T).name ()].begin (); cIt != shared_connections_[typeid (T).name ()].end (); ++cIt)
00178 cIt->block ();
00179 }
00180
00181 template<typename T> void
00182 Grabber::unblock_signal ()
00183 {
00184 if (connections_.find (typeid (T).name ()) != connections_.end ())
00185 for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[typeid (T).name ()].begin (); cIt != shared_connections_[typeid (T).name ()].end (); ++cIt)
00186 cIt->unblock ();
00187 }
00188
00189 void
00190 Grabber::block_signals ()
00191 {
00192 for (std::map<std::string, boost::signals2::signal_base*>::iterator signal_it = signals_.begin (); signal_it != signals_.end (); ++signal_it)
00193 for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[signal_it->first].begin (); cIt != shared_connections_[signal_it->first].end (); ++cIt)
00194 cIt->block ();
00195 }
00196
00197 void
00198 Grabber::unblock_signals ()
00199 {
00200 for (std::map<std::string, boost::signals2::signal_base*>::iterator signal_it = signals_.begin (); signal_it != signals_.end (); ++signal_it)
00201 for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[signal_it->first].begin (); cIt != shared_connections_[signal_it->first].end (); ++cIt)
00202 cIt->unblock ();
00203 }
00204
00205 template<typename T> int
00206 Grabber::num_slots () const
00207 {
00208 typedef boost::signals2::signal<T> Signal;
00209
00210
00211 std::map<std::string, boost::signals2::signal_base*>::const_iterator signal_it = signals_.find (typeid (T).name ());
00212 if (signal_it != signals_.end ())
00213 {
00214 Signal* signal = dynamic_cast<Signal*> (signal_it->second);
00215 return (static_cast<int> (signal->num_slots ()));
00216 }
00217 return (0);
00218 }
00219
00220 template<typename T> boost::signals2::signal<T>*
00221 Grabber::createSignal ()
00222 {
00223 typedef boost::signals2::signal<T> Signal;
00224
00225 if (signals_.find (typeid (T).name ()) == signals_.end ())
00226 {
00227 Signal* signal = new Signal ();
00228 signals_[typeid (T).name ()] = signal;
00229 return (signal);
00230 }
00231 return (0);
00232 }
00233
00234 template<typename T> boost::signals2::connection
00235 Grabber::registerCallback (const boost::function<T> & callback)
00236 {
00237 typedef boost::signals2::signal<T> Signal;
00238 if (signals_.find (typeid (T).name ()) == signals_.end ())
00239 {
00240 std::stringstream sstream;
00241
00242 sstream << "no callback for type:" << typeid (T).name ();
00243
00244
00245
00246
00247
00248
00249
00250
00251 PCL_THROW_EXCEPTION (pcl::IOException, "[" << getName () << "] " << sstream.str ());
00252
00253 }
00254 Signal* signal = dynamic_cast<Signal*> (signals_[typeid (T).name ()]);
00255 boost::signals2::connection ret = signal->connect (callback);
00256
00257 connections_[typeid (T).name ()].push_back (ret);
00258 shared_connections_[typeid (T).name ()].push_back (boost::signals2::shared_connection_block (connections_[typeid (T).name ()].back (), false));
00259 signalsChanged ();
00260 return (ret);
00261 }
00262
00263 template<typename T> bool
00264 Grabber::providesCallback () const
00265 {
00266 if (signals_.find (typeid (T).name ()) == signals_.end ())
00267 return (false);
00268 return (true);
00269 }
00270
00271 }
00272
00273 #endif