Point Cloud Library (PCL)  1.7.1
grabber.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011, Willow Garage, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the copyright holder(s) nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include <pcl/pcl_config.h>
36 
37 #ifndef __PCL_IO_GRABBER__
38 #define __PCL_IO_GRABBER__
39 
40 // needed for the grabber interface / observers
41 #include <map>
42 #include <iostream>
43 #include <string>
44 #include <typeinfo>
45 #include <vector>
46 #include <sstream>
47 #include <pcl/pcl_macros.h>
48 #include <pcl/io/boost.h>
49 #include <pcl/exceptions.h>
50 
51 namespace pcl
52 {
53 
54  /** \brief Grabber interface for PCL 1.x device drivers
55  * \author Suat Gedikli <gedikli@willowgarage.com>
56  * \ingroup io
57  */
58  class PCL_EXPORTS Grabber
59  {
60  public:
61 
62  /** \brief Constructor. */
63  Grabber () : signals_ (), connections_ (), shared_connections_ () {}
64 
65  /** \brief virtual desctructor. */
66  virtual inline ~Grabber () throw ();
67 
68  /** \brief registers a callback function/method to a signal with the corresponding signature
69  * \param[in] callback: the callback function/method
70  * \return Connection object, that can be used to disconnect the callback method from the signal again.
71  */
72  template<typename T> boost::signals2::connection
73  registerCallback (const boost::function<T>& callback);
74 
75  /** \brief indicates whether a signal with given parameter-type exists or not
76  * \return true if signal exists, false otherwise
77  */
78  template<typename T> bool
79  providesCallback () const;
80 
81  /** \brief For devices that are streaming, the streams are started by calling this method.
82  * Trigger-based devices, just trigger the device once for each call of start.
83  */
84  virtual void
85  start () = 0;
86 
87  /** \brief For devices that are streaming, the streams are stopped.
88  * This method has no effect for triggered devices.
89  */
90  virtual void
91  stop () = 0;
92 
93  /** \brief returns the name of the concrete subclass.
94  * \return the name of the concrete driver.
95  */
96  virtual std::string
97  getName () const = 0;
98 
99  /** \brief Indicates whether the grabber is streaming or not. This value is not defined for triggered devices.
100  * \return true if grabber is running / streaming. False otherwise.
101  */
102  virtual bool
103  isRunning () const = 0;
104 
105  /** \brief returns fps. 0 if trigger based. */
106  virtual float
107  getFramesPerSecond () const = 0;
108 
109  protected:
110 
111  virtual void
112  signalsChanged () { }
113 
114  template<typename T> boost::signals2::signal<T>*
115  find_signal () const;
116 
117  template<typename T> int
118  num_slots () const;
119 
120  template<typename T> void
121  disconnect_all_slots ();
122 
123  template<typename T> void
124  block_signal ();
125 
126  template<typename T> void
127  unblock_signal ();
128 
129  inline void
130  block_signals ();
131 
132  inline void
133  unblock_signals ();
134 
135  template<typename T> boost::signals2::signal<T>*
136  createSignal ();
137 
138  std::map<std::string, boost::signals2::signal_base*> signals_;
139  std::map<std::string, std::vector<boost::signals2::connection> > connections_;
140  std::map<std::string, std::vector<boost::signals2::shared_connection_block> > shared_connections_;
141  } ;
142 
143  Grabber::~Grabber () throw ()
144  {
145  for (std::map<std::string, boost::signals2::signal_base*>::iterator signal_it = signals_.begin (); signal_it != signals_.end (); ++signal_it)
146  delete signal_it->second;
147  }
148 
149  template<typename T> boost::signals2::signal<T>*
151  {
152  typedef boost::signals2::signal<T> Signal;
153 
154  std::map<std::string, boost::signals2::signal_base*>::const_iterator signal_it = signals_.find (typeid (T).name ());
155  if (signal_it != signals_.end ())
156  return (dynamic_cast<Signal*> (signal_it->second));
157 
158  return (NULL);
159  }
160 
161  template<typename T> void
163  {
164  typedef boost::signals2::signal<T> Signal;
165 
166  if (signals_.find (typeid (T).name ()) != signals_.end ())
167  {
168  Signal* signal = dynamic_cast<Signal*> (signals_[typeid (T).name ()]);
169  signal->disconnect_all_slots ();
170  }
171  }
172 
173  template<typename T> void
175  {
176  if (connections_.find (typeid (T).name ()) != connections_.end ())
177  for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[typeid (T).name ()].begin (); cIt != shared_connections_[typeid (T).name ()].end (); ++cIt)
178  cIt->block ();
179  }
180 
181  template<typename T> void
183  {
184  if (connections_.find (typeid (T).name ()) != connections_.end ())
185  for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[typeid (T).name ()].begin (); cIt != shared_connections_[typeid (T).name ()].end (); ++cIt)
186  cIt->unblock ();
187  }
188 
189  void
191  {
192  for (std::map<std::string, boost::signals2::signal_base*>::iterator signal_it = signals_.begin (); signal_it != signals_.end (); ++signal_it)
193  for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[signal_it->first].begin (); cIt != shared_connections_[signal_it->first].end (); ++cIt)
194  cIt->block ();
195  }
196 
197  void
199  {
200  for (std::map<std::string, boost::signals2::signal_base*>::iterator signal_it = signals_.begin (); signal_it != signals_.end (); ++signal_it)
201  for (std::vector<boost::signals2::shared_connection_block>::iterator cIt = shared_connections_[signal_it->first].begin (); cIt != shared_connections_[signal_it->first].end (); ++cIt)
202  cIt->unblock ();
203  }
204 
205  template<typename T> int
207  {
208  typedef boost::signals2::signal<T> Signal;
209 
210  // see if we have a signal for this type
211  std::map<std::string, boost::signals2::signal_base*>::const_iterator signal_it = signals_.find (typeid (T).name ());
212  if (signal_it != signals_.end ())
213  {
214  Signal* signal = dynamic_cast<Signal*> (signal_it->second);
215  return (static_cast<int> (signal->num_slots ()));
216  }
217  return (0);
218  }
219 
220  template<typename T> boost::signals2::signal<T>*
222  {
223  typedef boost::signals2::signal<T> Signal;
224 
225  if (signals_.find (typeid (T).name ()) == signals_.end ())
226  {
227  Signal* signal = new Signal ();
228  signals_[typeid (T).name ()] = signal;
229  return (signal);
230  }
231  return (0);
232  }
233 
234  template<typename T> boost::signals2::connection
235  Grabber::registerCallback (const boost::function<T> & callback)
236  {
237  typedef boost::signals2::signal<T> Signal;
238  if (signals_.find (typeid (T).name ()) == signals_.end ())
239  {
240  std::stringstream sstream;
241 
242  sstream << "no callback for type:" << typeid (T).name ();
243  /*
244  sstream << "registered Callbacks are:" << std::endl;
245  for( std::map<std::string, boost::signals2::signal_base*>::const_iterator cIt = signals_.begin ();
246  cIt != signals_.end (); ++cIt)
247  {
248  sstream << cIt->first << std::endl;
249  }*/
250 
251  PCL_THROW_EXCEPTION (pcl::IOException, "[" << getName () << "] " << sstream.str ());
252  //return (boost::signals2::connection ());
253  }
254  Signal* signal = dynamic_cast<Signal*> (signals_[typeid (T).name ()]);
255  boost::signals2::connection ret = signal->connect (callback);
256 
257  connections_[typeid (T).name ()].push_back (ret);
258  shared_connections_[typeid (T).name ()].push_back (boost::signals2::shared_connection_block (connections_[typeid (T).name ()].back (), false));
259  signalsChanged ();
260  return (ret);
261  }
262 
263  template<typename T> bool
265  {
266  if (signals_.find (typeid (T).name ()) == signals_.end ())
267  return (false);
268  return (true);
269  }
270 
271 } // namespace
272 
273 #endif
boost::signals2::signal< T > * createSignal()
Definition: grabber.h:221
boost::signals2::signal< T > * find_signal() const
Definition: grabber.h:150
void block_signals()
Definition: grabber.h:190
int num_slots() const
Definition: grabber.h:206
void unblock_signal()
Definition: grabber.h:182
virtual ~Grabber()
virtual desctructor.
Definition: grabber.h:143
Grabber interface for PCL 1.x device drivers.
Definition: grabber.h:58
std::map< std::string, std::vector< boost::signals2::shared_connection_block > > shared_connections_
Definition: grabber.h:140
std::map< std::string, std::vector< boost::signals2::connection > > connections_
Definition: grabber.h:139
virtual void signalsChanged()
Definition: grabber.h:112
bool providesCallback() const
indicates whether a signal with given parameter-type exists or not
Definition: grabber.h:264
void unblock_signals()
Definition: grabber.h:198
boost::signals2::connection registerCallback(const boost::function< T > &callback)
registers a callback function/method to a signal with the corresponding signature ...
Definition: grabber.h:235
void block_signal()
Definition: grabber.h:174
void disconnect_all_slots()
Definition: grabber.h:162
std::map< std::string, boost::signals2::signal_base * > signals_
Definition: grabber.h:138
Grabber()
Constructor.
Definition: grabber.h:63
An exception that is thrown during an IO error (typical read/write errors)
Definition: exceptions.h:180
virtual std::string getName() const =0
returns the name of the concrete subclass.