Point Cloud Library (PCL)
1.3.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 * Author: Suat Gedikli (gedikli@willowgarage.com), Nico Blodow (blodow@cs.tum.edu) 00035 */ 00036 00037 #include "pcl/pcl_config.h" 00038 #ifdef HAVE_OPENNI 00039 00040 #ifndef __PCL_IO_GRABBER__ 00041 #define __PCL_IO_GRABBER__ 00042 00043 // needed for the grabber interface / observers 00044 #include <map> 00045 #include <iostream> 00046 #include <string> 00047 #include <boost/signals2.hpp> 00048 #include <boost/signals2/slot.hpp> 00049 #include <typeinfo> 00050 #include <vector> 00051 #include <sstream> 00052 #include <pcl/io/pcl_io_exception.h> 00053 00054 namespace pcl 00055 { 00056 00060 class Grabber 00061 { 00062 public: 00067 virtual inline ~Grabber () throw (); 00068 00075 template<typename T> boost::signals2::connection registerCallback (const boost::function<T>& callback); 00076 00082 template<typename T> bool providesCallback () const; 00083 00089 virtual void start () = 0 ; 00090 00096 virtual void stop () = 0; 00097 00103 virtual std::string getName () const = 0; 00104 00109 virtual bool isRunning () const = 0; 00110 protected: 00111 virtual void signalsChanged () {} 00112 template<typename T> boost::signals2::signal<T>* find_signal () const; 00113 template<typename T> int num_slots () const; 00114 template<typename T> void disconnect_all_slots (); 00115 template<typename T> void block_signal (); 00116 template<typename T> void unblock_signal (); 00117 inline void block_signals (); 00118 inline void unblock_signals (); 00119 00120 template<typename T> boost::signals2::signal<T>* createSignal (); 00121 std::map<std::string, boost::signals2::signal_base*> signals_; 00122 std::map<std::string, std::vector<boost::signals2::connection> > connections_; 00123 std::map<std::string, std::vector<boost::signals2::shared_connection_block> > shared_connections_; 00124 }; 00125 00126 Grabber::~Grabber () throw () 00127 { 00128 for (std::map<std::string, boost::signals2::signal_base*>::iterator signal_it = signals_.begin (); signal_it != signals_.end (); ++signal_it) 00129 delete signal_it->second; 00130 } 00131 00132 template<typename T> boost::signals2::signal<T>* Grabber::find_signal () const 00133 { 00134 typedef boost::signals2::signal<T> Signal; 00135 00136 std::map<std::string, boost::signals2::signal_base*>::const_iterator signal_it = signals_.find (typeid(T).name()); 00137 if (signal_it != signals_.end ()) 00138 return (dynamic_cast<Signal*> (signal_it->second)); 00139 00140 return (NULL); 00141 } 00142 00143 template<typename T> void Grabber::disconnect_all_slots () 00144 { 00145 typedef boost::signals2::signal<T> Signal; 00146 00147 if (signals_.find (typeid(T).name()) != signals_.end ()) 00148 { 00149 Signal* signal = dynamic_cast<Signal*> (signals_[typeid(T).name()]); 00150 signal->disconnect_all_slots (); 00151 } 00152 } 00153 00154 template<typename T> void Grabber::block_signal () 00155 { 00156 if (connections_.find (typeid(T).name()) != connections_.end ()) 00157 for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[typeid(T).name()].begin(); cIt != shared_connections_[typeid(T).name()].end(); ++cIt) 00158 cIt->block (); 00159 } 00160 00161 template<typename T> void Grabber::unblock_signal () 00162 { 00163 if (connections_.find (typeid(T).name()) != connections_.end ()) 00164 for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[typeid(T).name()].begin(); cIt != shared_connections_[typeid(T).name()].end(); ++cIt) 00165 cIt->unblock (); 00166 } 00167 00168 void Grabber::block_signals () 00169 { 00170 for (std::map<std::string, boost::signals2::signal_base*>::iterator signal_it = signals_.begin (); signal_it != signals_.end (); ++signal_it) 00171 for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[signal_it->first].begin(); cIt != shared_connections_[signal_it->first].end(); ++cIt) 00172 cIt->block (); 00173 } 00174 00175 void Grabber::unblock_signals () 00176 { 00177 for (std::map<std::string, boost::signals2::signal_base*>::iterator signal_it = signals_.begin (); signal_it != signals_.end (); ++signal_it) 00178 for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[signal_it->first].begin(); cIt != shared_connections_[signal_it->first].end(); ++cIt) 00179 cIt->unblock (); 00180 } 00181 00182 template<typename T> int Grabber::num_slots () const 00183 { 00184 typedef boost::signals2::signal<T> Signal; 00185 00186 // see if we have a signal for this type 00187 std::map<std::string, boost::signals2::signal_base*>::const_iterator signal_it = signals_.find (typeid(T).name()); 00188 if (signal_it != signals_.end()) 00189 { 00190 Signal* signal = dynamic_cast<Signal*> (signal_it->second); 00191 return (signal->num_slots ()); 00192 } 00193 return (0); 00194 } 00195 00196 template<typename T> boost::signals2::signal<T>* Grabber::createSignal () 00197 { 00198 typedef boost::signals2::signal<T> Signal; 00199 00200 if (signals_.find (typeid(T).name()) == signals_.end ()) 00201 { 00202 Signal* signal = new Signal (); 00203 signals_[typeid(T).name ()] = signal; 00204 return (signal); 00205 } 00206 return (0); 00207 } 00208 00209 template<typename T> boost::signals2::connection Grabber::registerCallback (const boost::function<T> & callback) 00210 { 00211 typedef boost::signals2::signal<T> Signal; 00212 if (signals_.find (typeid(T).name()) == signals_.end ()) 00213 { 00214 std::stringstream sstream; 00215 00216 sstream << "no callback for type:" << typeid(T).name(); 00217 /* 00218 sstream << "registered Callbacks are:" << std::endl; 00219 for( std::map<std::string, boost::signals2::signal_base*>::const_iterator cIt = signals_.begin (); 00220 cIt != signals_.end (); ++cIt) 00221 { 00222 sstream << cIt->first << std::endl; 00223 }*/ 00224 00225 THROW_PCL_IO_EXCEPTION ("[%s] %s", getName ().c_str (), sstream.str ().c_str ()); 00226 //return (boost::signals2::connection ()); 00227 } 00228 Signal* signal = dynamic_cast<Signal*> (signals_[typeid(T).name()]); 00229 boost::signals2::connection ret = signal->connect (callback); 00230 00231 connections_[typeid(T).name()].push_back(ret); 00232 shared_connections_[typeid(T).name()].push_back(boost::signals2::shared_connection_block(connections_[typeid(T).name()].back())); 00233 signalsChanged (); 00234 return (ret); 00235 } 00236 00237 template<typename T> bool Grabber::providesCallback () const 00238 { 00239 if (signals_.find (typeid(T).name()) == signals_.end ()) 00240 return (false); 00241 return (true); 00242 } 00243 00244 } // namespace 00245 00246 #endif 00247 #endif //HAVE_OPENNI