|
Point Cloud Library (PCL)
1.5.1
|
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/io/pcl_io_exception.h> 00050 00051 namespace pcl 00052 { 00053 00058 class Grabber 00059 { 00060 public: 00061 00063 virtual inline ~Grabber () throw (); 00064 00069 template<typename T> boost::signals2::connection 00070 registerCallback (const boost::function<T>& callback); 00071 00075 template<typename T> bool 00076 providesCallback () const; 00077 00081 virtual void 00082 start () = 0; 00083 00087 virtual void 00088 stop () = 0; 00089 00093 virtual std::string 00094 getName () const = 0; 00095 00099 virtual bool 00100 isRunning () const = 0; 00101 00103 virtual float 00104 getFramesPerSecond () const = 0; 00105 00106 protected: 00107 00108 virtual void 00109 signalsChanged () { } 00110 00111 template<typename T> boost::signals2::signal<T>* 00112 find_signal () const; 00113 00114 template<typename T> int 00115 num_slots () const; 00116 00117 template<typename T> void 00118 disconnect_all_slots (); 00119 00120 template<typename T> void 00121 block_signal (); 00122 00123 template<typename T> void 00124 unblock_signal (); 00125 00126 inline void 00127 block_signals (); 00128 00129 inline void 00130 unblock_signals (); 00131 00132 template<typename T> boost::signals2::signal<T>* 00133 createSignal (); 00134 00135 std::map<std::string, boost::signals2::signal_base*> signals_; 00136 std::map<std::string, std::vector<boost::signals2::connection> > connections_; 00137 std::map<std::string, std::vector<boost::signals2::shared_connection_block> > shared_connections_; 00138 } ; 00139 00140 Grabber::~Grabber () throw () 00141 { 00142 for (std::map<std::string, boost::signals2::signal_base*>::iterator signal_it = signals_.begin (); signal_it != signals_.end (); ++signal_it) 00143 delete signal_it->second; 00144 } 00145 00146 template<typename T> boost::signals2::signal<T>* 00147 Grabber::find_signal () const 00148 { 00149 typedef boost::signals2::signal<T> Signal; 00150 00151 std::map<std::string, boost::signals2::signal_base*>::const_iterator signal_it = signals_.find (typeid (T).name ()); 00152 if (signal_it != signals_.end ()) 00153 return (dynamic_cast<Signal*> (signal_it->second)); 00154 00155 return (NULL); 00156 } 00157 00158 template<typename T> void 00159 Grabber::disconnect_all_slots () 00160 { 00161 typedef boost::signals2::signal<T> Signal; 00162 00163 if (signals_.find (typeid (T).name ()) != signals_.end ()) 00164 { 00165 Signal* signal = dynamic_cast<Signal*> (signals_[typeid (T).name ()]); 00166 signal->disconnect_all_slots (); 00167 } 00168 } 00169 00170 template<typename T> void 00171 Grabber::block_signal () 00172 { 00173 if (connections_.find (typeid (T).name ()) != connections_.end ()) 00174 for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[typeid (T).name ()].begin (); cIt != shared_connections_[typeid (T).name ()].end (); ++cIt) 00175 cIt->block (); 00176 } 00177 00178 template<typename T> void 00179 Grabber::unblock_signal () 00180 { 00181 if (connections_.find (typeid (T).name ()) != connections_.end ()) 00182 for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[typeid (T).name ()].begin (); cIt != shared_connections_[typeid (T).name ()].end (); ++cIt) 00183 cIt->unblock (); 00184 } 00185 00186 void 00187 Grabber::block_signals () 00188 { 00189 for (std::map<std::string, boost::signals2::signal_base*>::iterator signal_it = signals_.begin (); signal_it != signals_.end (); ++signal_it) 00190 for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[signal_it->first].begin (); cIt != shared_connections_[signal_it->first].end (); ++cIt) 00191 cIt->block (); 00192 } 00193 00194 void 00195 Grabber::unblock_signals () 00196 { 00197 for (std::map<std::string, boost::signals2::signal_base*>::iterator signal_it = signals_.begin (); signal_it != signals_.end (); ++signal_it) 00198 for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[signal_it->first].begin (); cIt != shared_connections_[signal_it->first].end (); ++cIt) 00199 cIt->unblock (); 00200 } 00201 00202 template<typename T> int 00203 Grabber::num_slots () const 00204 { 00205 typedef boost::signals2::signal<T> Signal; 00206 00207 // see if we have a signal for this type 00208 std::map<std::string, boost::signals2::signal_base*>::const_iterator signal_it = signals_.find (typeid (T).name ()); 00209 if (signal_it != signals_.end ()) 00210 { 00211 Signal* signal = dynamic_cast<Signal*> (signal_it->second); 00212 return (signal->num_slots ()); 00213 } 00214 return (0); 00215 } 00216 00217 template<typename T> boost::signals2::signal<T>* 00218 Grabber::createSignal () 00219 { 00220 typedef boost::signals2::signal<T> Signal; 00221 00222 if (signals_.find (typeid (T).name ()) == signals_.end ()) 00223 { 00224 Signal* signal = new Signal (); 00225 signals_[typeid (T).name ()] = signal; 00226 return (signal); 00227 } 00228 return (0); 00229 } 00230 00231 template<typename T> boost::signals2::connection 00232 Grabber::registerCallback (const boost::function<T> & callback) 00233 { 00234 typedef boost::signals2::signal<T> Signal; 00235 if (signals_.find (typeid (T).name ()) == signals_.end ()) 00236 { 00237 std::stringstream sstream; 00238 00239 sstream << "no callback for type:" << typeid (T).name (); 00240 /* 00241 sstream << "registered Callbacks are:" << std::endl; 00242 for( std::map<std::string, boost::signals2::signal_base*>::const_iterator cIt = signals_.begin (); 00243 cIt != signals_.end (); ++cIt) 00244 { 00245 sstream << cIt->first << std::endl; 00246 }*/ 00247 00248 THROW_PCL_IO_EXCEPTION ("[%s] %s", getName ().c_str (), sstream.str ().c_str ()); 00249 //return (boost::signals2::connection ()); 00250 } 00251 Signal* signal = dynamic_cast<Signal*> (signals_[typeid (T).name ()]); 00252 boost::signals2::connection ret = signal->connect (callback); 00253 00254 connections_[typeid (T).name ()].push_back (ret); 00255 shared_connections_[typeid (T).name ()].push_back (boost::signals2::shared_connection_block (connections_[typeid (T).name ()].back (), false)); 00256 signalsChanged (); 00257 return (ret); 00258 } 00259 00260 template<typename T> bool 00261 Grabber::providesCallback () const 00262 { 00263 if (signals_.find (typeid (T).name ()) == signals_.end ()) 00264 return (false); 00265 return (true); 00266 } 00267 00268 } // namespace 00269 00270 #endif
1.8.0