|
Point Cloud Library (PCL)
1.6.0
|
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Copyright (c) 2011, Willow Garage, Inc. 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * * Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * * Redistributions in binary form must reproduce the above 00014 * copyright notice, this list of conditions and the following 00015 * disclaimer in the documentation and/or other materials provided 00016 * with the distribution. 00017 * * Neither the name of Willow Garage, Inc. nor the names of its 00018 * contributors may be used to endorse or promote products derived 00019 * from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00024 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00025 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00026 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00027 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00031 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 * POSSIBILITY OF SUCH DAMAGE. 00033 */ 00034 00035 #include <pcl/pcl_config.h> 00036 00037 #ifndef __PCL_IO_GRABBER__ 00038 #define __PCL_IO_GRABBER__ 00039 00040 // needed for the grabber interface / observers 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 // see if we have a signal for this type 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 sstream << "registered Callbacks are:" << std::endl; 00246 for( std::map<std::string, boost::signals2::signal_base*>::const_iterator cIt = signals_.begin (); 00247 cIt != signals_.end (); ++cIt) 00248 { 00249 sstream << cIt->first << std::endl; 00250 }*/ 00251 00252 THROW_PCL_IO_EXCEPTION ("[%s] %s", getName ().c_str (), sstream.str ().c_str ()); 00253 //return (boost::signals2::connection ()); 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 } // namespace 00273 00274 #endif
1.7.6.1