Point Cloud Library (PCL)  1.9.1-dev
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 #pragma once
36 
37 #include <pcl/pcl_config.h>
38 
39 // needed for the grabber interface / observers
40 #include <map>
41 #include <iostream>
42 #include <string>
43 #include <typeinfo>
44 #include <vector>
45 #include <sstream>
46 #include <pcl/pcl_macros.h>
47 #include <pcl/io/boost.h>
48 #include <pcl/exceptions.h>
49 
50 namespace pcl
51 {
52 
53  /** \brief Grabber interface for PCL 1.x device drivers
54  * \author Suat Gedikli <gedikli@willowgarage.com>
55  * \ingroup io
56  */
57  class PCL_EXPORTS Grabber
58  {
59  public:
60 
61  /** \brief Constructor. */
62  Grabber () {}
63 
64  /** \brief virtual destructor. */
65  virtual inline ~Grabber () throw ();
66 
67  /** \brief registers a callback function/method to a signal with the corresponding signature
68  * \param[in] callback: the callback function/method
69  * \return Connection object, that can be used to disconnect the callback method from the signal again.
70  */
71  template<typename T> boost::signals2::connection
72  registerCallback (const boost::function<T>& callback);
73 
74  /** \brief indicates whether a signal with given parameter-type exists or not
75  * \return true if signal exists, false otherwise
76  */
77  template<typename T> bool
78  providesCallback () const;
79 
80  /** \brief For devices that are streaming, the streams are started by calling this method.
81  * Trigger-based devices, just trigger the device once for each call of start.
82  */
83  virtual void
84  start () = 0;
85 
86  /** \brief For devices that are streaming, the streams are stopped.
87  * This method has no effect for triggered devices.
88  */
89  virtual void
90  stop () = 0;
91 
92  /** \brief returns the name of the concrete subclass.
93  * \return the name of the concrete driver.
94  */
95  virtual std::string
96  getName () const = 0;
97 
98  /** \brief Indicates whether the grabber is streaming or not. This value is not defined for triggered devices.
99  * \return true if grabber is running / streaming. False otherwise.
100  */
101  virtual bool
102  isRunning () const = 0;
103 
104  /** \brief returns fps. 0 if trigger based. */
105  virtual float
106  getFramesPerSecond () const = 0;
107 
108  protected:
109 
110  virtual void
112 
113  template<typename T> boost::signals2::signal<T>*
114  find_signal () const;
115 
116  template<typename T> int
117  num_slots () const;
118 
119  template<typename T> void
120  disconnect_all_slots ();
121 
122  template<typename T> void
123  block_signal ();
124 
125  template<typename T> void
126  unblock_signal ();
127 
128  inline void
129  block_signals ();
130 
131  inline void
132  unblock_signals ();
133 
134  template<typename T> boost::signals2::signal<T>*
135  createSignal ();
136 
137  std::map<std::string, boost::signals2::signal_base*> signals_;
138  std::map<std::string, std::vector<boost::signals2::connection> > connections_;
139  std::map<std::string, std::vector<boost::signals2::shared_connection_block> > shared_connections_;
140  } ;
141 
142  Grabber::~Grabber () throw ()
143  {
144  for (auto &signal : signals_)
145  delete signal.second;
146  }
147 
148  template<typename T> boost::signals2::signal<T>*
150  {
151  typedef boost::signals2::signal<T> Signal;
152 
153  std::map<std::string, boost::signals2::signal_base*>::const_iterator signal_it = signals_.find (typeid (T).name ());
154  if (signal_it != signals_.end ())
155  return (dynamic_cast<Signal*> (signal_it->second));
156 
157  return (NULL);
158  }
159 
160  template<typename T> void
162  {
163  typedef boost::signals2::signal<T> Signal;
164 
165  if (signals_.find (typeid (T).name ()) != signals_.end ())
166  {
167  Signal* signal = dynamic_cast<Signal*> (signals_[typeid (T).name ()]);
168  signal->disconnect_all_slots ();
169  }
170  }
171 
172  template<typename T> void
174  {
175  if (connections_.find (typeid (T).name ()) != connections_.end ())
176  for (auto &connection : shared_connections_[typeid (T).name ()])
177  connection.block ();
178  }
179 
180  template<typename T> void
182  {
183  if (connections_.find (typeid (T).name ()) != connections_.end ())
184  for (auto &connection : shared_connections_[typeid (T).name ()])
185  connection.unblock ();
186  }
187 
188  void
190  {
191  for (const auto &signal : signals_)
192  for (auto &connection : shared_connections_[signal.first])
193  connection.block ();
194  }
195 
196  void
198  {
199  for (const auto &signal : signals_)
200  for (auto &connection : shared_connections_[signal.first])
201  connection.unblock ();
202  }
203 
204  template<typename T> int
206  {
207  typedef boost::signals2::signal<T> Signal;
208 
209  // see if we have a signal for this type
210  std::map<std::string, boost::signals2::signal_base*>::const_iterator signal_it = signals_.find (typeid (T).name ());
211  if (signal_it != signals_.end ())
212  {
213  Signal* signal = dynamic_cast<Signal*> (signal_it->second);
214  return (static_cast<int> (signal->num_slots ()));
215  }
216  return (0);
217  }
218 
219  template<typename T> boost::signals2::signal<T>*
221  {
222  typedef boost::signals2::signal<T> Signal;
223 
224  if (signals_.find (typeid (T).name ()) == signals_.end ())
225  {
226  Signal* signal = new Signal ();
227  signals_[typeid (T).name ()] = signal;
228  return (signal);
229  }
230  return (nullptr);
231  }
232 
233  template<typename T> boost::signals2::connection
234  Grabber::registerCallback (const boost::function<T> & callback)
235  {
236  typedef boost::signals2::signal<T> Signal;
237  if (signals_.find (typeid (T).name ()) == signals_.end ())
238  {
239  std::stringstream sstream;
240 
241  sstream << "no callback for type:" << typeid (T).name ();
242 
243  PCL_THROW_EXCEPTION (pcl::IOException, "[" << getName () << "] " << sstream.str ());
244  //return (boost::signals2::connection ());
245  }
246  Signal* signal = dynamic_cast<Signal*> (signals_[typeid (T).name ()]);
247  boost::signals2::connection ret = signal->connect (callback);
248 
249  connections_[typeid (T).name ()].push_back (ret);
250  shared_connections_[typeid (T).name ()].push_back (boost::signals2::shared_connection_block (connections_[typeid (T).name ()].back (), false));
251  signalsChanged ();
252  return (ret);
253  }
254 
255  template<typename T> bool
257  {
258  if (signals_.find (typeid (T).name ()) == signals_.end ())
259  return (false);
260  return (true);
261  }
262 
263 } // namespace
void block_signal()
Definition: grabber.h:173
This file defines compatibility wrappers for low level I/O functions.
Definition: convolution.h:44
std::map< std::string, std::vector< boost::signals2::connection > > connections_
Definition: grabber.h:138
bool providesCallback() const
indicates whether a signal with given parameter-type exists or not
Definition: grabber.h:256
Grabber interface for PCL 1.x device drivers.
Definition: grabber.h:57
virtual ~Grabber()
virtual destructor.
Definition: grabber.h:142
boost::signals2::signal< T > * createSignal()
Definition: grabber.h:220
int num_slots() const
Definition: grabber.h:205
void unblock_signals()
Definition: grabber.h:197
std::map< std::string, boost::signals2::signal_base * > signals_
Definition: grabber.h:137
virtual void signalsChanged()
Definition: grabber.h:111
An exception that is thrown during an IO error (typical read/write errors)
Definition: exceptions.h:179
Grabber()
Constructor.
Definition: grabber.h:62
void disconnect_all_slots()
Definition: grabber.h:161
void block_signals()
Definition: grabber.h:189
std::map< std::string, std::vector< boost::signals2::shared_connection_block > > shared_connections_
Definition: grabber.h:139
boost::signals2::connection registerCallback(const boost::function< T > &callback)
registers a callback function/method to a signal with the corresponding signature ...
Definition: grabber.h:234
boost::signals2::signal< T > * find_signal() const
Definition: grabber.h:149
void unblock_signal()
Definition: grabber.h:181