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