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