astra_ros
Parameter.hpp
1 #ifndef _ASTRA_ROS_PARAMETER_HPP_
2 #define _ASTRA_ROS_PARAMETER_HPP_
3 
4 #include <functional>
5 #include <boost/optional.hpp>
6 
7 #include <mutex>
8 
9 namespace astra_ros
10 {
15  template<typename T>
17  {
18  public:
19  typedef T ValueType;
20  typedef std::function<bool (const T &value, const T &previous)> OnChange;
21 
23  : value_(T())
24  {
25  }
26 
27  ParameterImpl(const T &value)
28  : value_(value)
29  {
30  }
31 
32  bool set(const T &value) noexcept
33  {
34  std::lock_guard<std::mutex> lock(mutex_);
35 
36  if (on_change_)
37  {
38  if ((*on_change_)(value, value_))
39  {
40  // Accept the changes
41  value_ = value;
42  return true;
43  }
44 
45  return false;
46  }
47 
48  // No handler, always accept the change
49  value_ = value;
50  return true;
51  }
52 
53  const T &get() const noexcept
54  {
55  std::lock_guard<std::mutex> lock(mutex_);
56  return value_;
57  }
58 
59  void setOnChangeHandler(const boost::optional<OnChange> &on_change)
60  {
61  on_change_ = on_change;
62  }
63 
64  const boost::optional<OnChange> &getOnChangeHandler() const
65  {
66  return on_change_;
67  }
68 
69  private:
70  mutable std::mutex mutex_;
71 
72  T value_;
73  boost::optional<OnChange> on_change_;
74  };
75 
76  // Parameter wraps a value to make it "live"
77  // A listener can register a callback when the value changes
84  template<typename T>
85  class Parameter
86  {
87  public:
88  typedef typename ParameterImpl<T>::ValueType ValueType;
89  typedef typename ParameterImpl<T>::OnChange OnChange;
90 
95  : impl_(std::make_shared<ParameterImpl<T>>())
96  {
97  }
98 
102  Parameter(const T &value)
103  : impl_(std::make_shared<ParameterImpl<T>>(value))
104  {
105  }
106 
110  bool set(const T &value)
111  {
112  return impl_->set(value);
113  }
114 
118  const T &get() const
119  {
120  return impl_->get();
121  }
122 
126  const T &operator *() const
127  {
128  return get();
129  }
130 
135  void setOnChangeHandler(const boost::optional<OnChange> &on_change)
136  {
137  impl_->setOnChangeHandler(on_change);
138  }
139 
143  template<typename F, typename... Args>
144  void bindOnChangeHandler(F &&f, Args &&...args)
145  {
146  setOnChangeHandler(bind(f, args...));
147  }
148 
153  const boost::optional<OnChange> &getOnChangeHandler() const
154  {
155  return impl_->getOnChangeHandler();
156  }
157 
161  template<typename F, typename... Args>
162  static OnChange bind(F &&f, Args &&...args)
163  {
164  return OnChange(std::bind(f, args..., std::placeholders::_1, std::placeholders::_2));
165  }
166 
167  private:
168  std::shared_ptr<ParameterImpl<T>> impl_;
169  };
170 
171 }
172 
173 
174 
175 #endif
astra_ros::ParameterImpl
Internal implementation of a Parameter.
Definition: Parameter.hpp:17
astra_ros::Parameter::get
const T & get() const
Definition: Parameter.hpp:118
astra_ros::Parameter::setOnChangeHandler
void setOnChangeHandler(const boost::optional< OnChange > &on_change)
Definition: Parameter.hpp:135
astra_ros::Parameter::bindOnChangeHandler
void bindOnChangeHandler(F &&f, Args &&...args)
Definition: Parameter.hpp:144
astra_ros::Parameter::Parameter
Parameter(const T &value)
Definition: Parameter.hpp:102
astra_ros::Parameter::bind
static OnChange bind(F &&f, Args &&...args)
Definition: Parameter.hpp:162
astra_ros::Parameter::getOnChangeHandler
const boost::optional< OnChange > & getOnChangeHandler() const
Definition: Parameter.hpp:153
astra_ros::Parameter
A "live" value that can be changed at runtime. Changes are broadcast to a listener.
Definition: Parameter.hpp:86
astra_ros::Parameter::operator*
const T & operator*() const
Definition: Parameter.hpp:126
astra_ros::Parameter::set
bool set(const T &value)
Definition: Parameter.hpp:110
astra_ros::Parameter::Parameter
Parameter()
Definition: Parameter.hpp:94