grabber.h
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2011, Willow Garage, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder(s) nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <pcl/pcl_config.h>
// needed for the grabber interface / observers
#include <map>
#include <iostream>
#include <string>
#include <typeinfo>
#include <vector>
#include <sstream>
#include <pcl/pcl_macros.h>
#include <pcl/io/boost.h>
#include <pcl/exceptions.h>
namespace pcl
{
/** \brief Grabber interface for PCL 1.x device drivers
* \author Suat Gedikli <gedikli@willowgarage.com>
* \ingroup io
*/
class PCL_EXPORTS Grabber
{
public:
/** \brief Constructor. */
Grabber () {}
/** \brief virtual destructor. */
virtual inline ~Grabber () throw ();
/** \brief registers a callback function/method to a signal with the corresponding signature
* \param[in] callback: the callback function/method
* \return Connection object, that can be used to disconnect the callback method from the signal again.
*/
template<typename T> boost::signals2::connection
registerCallback (const std::function<T>& callback);
/** \brief registers a callback function/method to a signal with the corresponding signature
* \param[in] callback: the callback function/method
* \return Connection object, that can be used to disconnect the callback method from the signal again.
*/
template<typename T, template<typename> class FunctionT>
[[deprecated ("please assign the callback to a std::function.")]]
boost::signals2::connection
registerCallback (const FunctionT<T>& callback)
{
return registerCallback (std::function<T> (callback));
}
/** \brief indicates whether a signal with given parameter-type exists or not
* \return true if signal exists, false otherwise
*/
template<typename T> bool
providesCallback () const;
/** \brief For devices that are streaming, the streams are started by calling this method.
* Trigger-based devices, just trigger the device once for each call of start.
*/
virtual void
start () = 0;
/** \brief For devices that are streaming, the streams are stopped.
* This method has no effect for triggered devices.
*/
virtual void
stop () = 0;
/** \brief returns the name of the concrete subclass.
* \return the name of the concrete driver.
*/
virtual std::string
getName () const = 0;
/** \brief Indicates whether the grabber is streaming or not. This value is not defined for triggered devices.
* \return true if grabber is running / streaming. False otherwise.
*/
virtual bool
isRunning () const = 0;
/** \brief returns fps. 0 if trigger based. */
virtual float
getFramesPerSecond () const = 0;
protected:
virtual void
signalsChanged () { }
template<typename T> boost::signals2::signal<T>*
find_signal () const;
template<typename T> int
num_slots () const;
template<typename T> void
disconnect_all_slots ();
template<typename T> void
block_signal ();
template<typename T> void
unblock_signal ();
inline void
block_signals ();
inline void
unblock_signals ();
template<typename T> boost::signals2::signal<T>*
createSignal ();
std::map<std::string, boost::signals2::signal_base*> signals_;
std::map<std::string, std::vector<boost::signals2::connection> > connections_;
std::map<std::string, std::vector<boost::signals2::shared_connection_block> > shared_connections_;
} ;
Grabber::~Grabber () throw ()
{
for (auto &signal : signals_)
delete signal.second;
}
template<typename T> boost::signals2::signal<T>*
Grabber::find_signal () const
{
using Signal = boost::signals2::signal<T>;
std::map<std::string, boost::signals2::signal_base*>::const_iterator signal_it = signals_.find (typeid (T).name ());
if (signal_it != signals_.end ())
return (dynamic_cast<Signal*> (signal_it->second));
return (NULL);
}
template<typename T> void
Grabber::disconnect_all_slots ()
{
using Signal = boost::signals2::signal<T>;
if (signals_.find (typeid (T).name ()) != signals_.end ())
{
Signal* signal = dynamic_cast<Signal*> (signals_[typeid (T).name ()]);
signal->disconnect_all_slots ();
}
}
template<typename T> void
Grabber::block_signal ()
{
if (connections_.find (typeid (T).name ()) != connections_.end ())
for (auto &connection : shared_connections_[typeid (T).name ()])
connection.block ();
}
template<typename T> void
Grabber::unblock_signal ()
{
if (connections_.find (typeid (T).name ()) != connections_.end ())
for (auto &connection : shared_connections_[typeid (T).name ()])
connection.unblock ();
}
void
Grabber::block_signals ()
{
for (const auto &signal : signals_)
for (auto &connection : shared_connections_[signal.first])
connection.block ();
}
void
Grabber::unblock_signals ()
{
for (const auto &signal : signals_)
for (auto &connection : shared_connections_[signal.first])
connection.unblock ();
}
template<typename T> int
Grabber::num_slots () const
{
using Signal = boost::signals2::signal<T>;
// see if we have a signal for this type
std::map<std::string, boost::signals2::signal_base*>::const_iterator signal_it = signals_.find (typeid (T).name ());
if (signal_it != signals_.end ())
{
Signal* signal = dynamic_cast<Signal*> (signal_it->second);
return (static_cast<int> (signal->num_slots ()));
}
return (0);
}
template<typename T> boost::signals2::signal<T>*
Grabber::createSignal ()
{
using Signal = boost::signals2::signal<T>;
if (signals_.find (typeid (T).name ()) == signals_.end ())
{
Signal* signal = new Signal ();
signals_[typeid (T).name ()] = signal;
return (signal);
}
return (nullptr);
}
template<typename T> boost::signals2::connection
Grabber::registerCallback (const std::function<T> & callback)
{
using Signal = boost::signals2::signal<T>;
if (signals_.find (typeid (T).name ()) == signals_.end ())
{
std::stringstream sstream;
sstream << "no callback for type:" << typeid (T).name ();
PCL_THROW_EXCEPTION (pcl::IOException, "[" << getName () << "] " << sstream.str ());
//return (boost::signals2::connection ());
}
Signal* signal = dynamic_cast<Signal*> (signals_[typeid (T).name ()]);
boost::signals2::connection ret = signal->connect (callback);
connections_[typeid (T).name ()].push_back (ret);
shared_connections_[typeid (T).name ()].push_back (boost::signals2::shared_connection_block (connections_[typeid (T).name ()].back (), false));
signalsChanged ();
return (ret);
}
template<typename T> bool
Grabber::providesCallback () const
{
if (signals_.find (typeid (T).name ()) == signals_.end ())
return (false);
return (true);
}
} // namespace
pcl_macros.h
Defines all the PCL and non-PCL macros used.
pcl::Grabber::~Grabber
virtual ~Grabber()
virtual destructor.
Definition: grabber.h:154
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:217
pcl::Grabber::unblock_signal
void unblock_signal()
Definition: grabber.h:193
boost
Definition: boost_graph.h:46
pcl::Grabber::signalsChanged
virtual void signalsChanged()
Definition: grabber.h:123
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:246
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:268
pcl::Grabber::connections_
std::map< std::string, std::vector< boost::signals2::connection > > connections_
Definition: grabber.h:150
pcl::Grabber::block_signal
void block_signal()
Definition: grabber.h:185
pcl::Grabber::signals_
std::map< std::string, boost::signals2::signal_base * > signals_
Definition: grabber.h:149
pcl::Grabber::find_signal
boost::signals2::signal< T > * find_signal() const
Definition: grabber.h:161
pcl::Grabber::createSignal
boost::signals2::signal< T > * createSignal()
Definition: grabber.h:232
pcl::Grabber::shared_connections_
std::map< std::string, std::vector< boost::signals2::shared_connection_block > > shared_connections_
Definition: grabber.h:151
pcl::Grabber::unblock_signals
void unblock_signals()
Definition: grabber.h:209
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::Grabber
Grabber()
Constructor.
Definition: grabber.h:62
pcl::Grabber::block_signals
void block_signals()
Definition: grabber.h:201
pcl::Grabber::disconnect_all_slots
void disconnect_all_slots()
Definition: grabber.h:173
PCL_EXPORTS
#define PCL_EXPORTS
Definition: pcl_macros.h:253