source: finroc_plugins_parameters/tParameter.h @ 93:f23cec48f874

17.03
Last change on this file since 93:f23cec48f874 was 93:f23cec48f874, checked in by Max Reichardt <mreichardt@…>, 10 months ago

Adds ConnectTo method to tParameter class

File size: 9.9 KB
Line 
1//
2// You received this file as part of Finroc
3// A framework for intelligent robot control
4//
5// Copyright (C) Finroc GbR (finroc.org)
6//
7// This program is free software; you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation; either version 2 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License along
18// with this program; if not, write to the Free Software Foundation, Inc.,
19// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20//
21//----------------------------------------------------------------------
22/*!\file    plugins/parameters/tParameter.h
23 *
24 * \author  Max Reichardt
25 *
26 * \date    2012-11-28
27 *
28 * \brief   Contains tParameter
29 *
30 * \b tParameter
31 *
32 * Parameter that can be changed at application runtime.
33 * To deal with issues of concurrency, it is based on tPort.
34 * Parameter values can be set in code, loaded from configuration
35 * files or specified via the command line if set up accordingly.
36 *
37 */
38//----------------------------------------------------------------------
39#ifndef __plugins__parameters__tParameter_h__
40#define __plugins__parameters__tParameter_h__
41
42//----------------------------------------------------------------------
43// External includes (system with <>, local with "")
44//----------------------------------------------------------------------
45
46//----------------------------------------------------------------------
47// Internal includes with ""
48//----------------------------------------------------------------------
49#include "plugins/parameters/internal/tParameterCreationInfo.h"
50#include "plugins/parameters/internal/tParameterImplementation.h"
51#include "plugins/parameters/internal/tParameterInfo.h"
52
53//----------------------------------------------------------------------
54// Namespace declaration
55//----------------------------------------------------------------------
56namespace finroc
57{
58namespace parameters
59{
60
61//----------------------------------------------------------------------
62// Forward declarations / typedefs / enums
63//----------------------------------------------------------------------
64
65//----------------------------------------------------------------------
66// Class declaration
67//----------------------------------------------------------------------
68//! Parameter
69/*!
70 * Parameter that can be changed at application runtime.
71 * To deal with issues of concurrency, it is based on tPort.
72 * Parameter values can be set in code, loaded from configuration
73 * files or specified via the command line if set up accordingly.
74 */
75template <typename T>
76class tParameter
77{
78  typedef internal::tParameterImplementation < T, std::is_arithmetic<T>::value || std::is_same<bool, T>::value > tImplementation;
79
80  typedef data_ports::api::tPortImplementation<T, data_ports::api::tPortImplementationTypeTrait<T>::type> tPortImplementation;
81
82//----------------------------------------------------------------------
83// Public methods and typedefs
84//----------------------------------------------------------------------
85public:
86
87  /*! Should methods passing buffers by-value be available? */
88  enum { cPASS_BY_VALUE = data_ports::tIsCheaplyCopiedType<T>::value };
89
90  /*! Type T */
91  typedef T tDataType;
92
93  /*! Bundles all possible constructor parameters of tParameter */
94  typedef internal::tParameterCreationInfo<T> tConstructorParameters;
95
96  /*! Creates no wrapped parameter */
97  tParameter() : implementation()
98  {}
99
100  /*!
101   * Constructor takes variadic argument list... just any properties you want to assign to parameter.
102   *
103   * The first string is interpreted as parameter name, the second possibly as config entry.
104   * A framework element pointer is interpreted as parent.
105   * tFrameworkElement::tFlags arguments are interpreted as flags.
106   * tBounds<T> are parameter's bounds.
107   * const T& is interpreted as port's default value.
108   * tParameterCreationInfo<T> argument is copied.
109   *
110   * This becomes a little tricky when parameter has numeric or string type.
111   * There we have these rules:
112   *
113   * string type: The second string argument is interpreted as default_value. The third as config entry.
114   * numeric type: The first numeric argument is interpreted as default_value.
115   */
116  template<typename ... ARGS>
117  tParameter(const ARGS&... args) : implementation()
118  {
119    core::tPortWrapperBase::tConstructorArguments<data_ports::tPortCreationInfo<T>> creation_info(args...);
120    if (!(creation_info.flags.Raw() & core::tFrameworkElementFlags(core::tFrameworkElementFlag::DELETED).Raw())) // do not create parameter, if deleted flag is set
121    {
122      implementation = tImplementation(creation_info);
123      implementation.GetWrapped()->AddAnnotation(*(new internal::tParameterInfo()));
124      SetConfigEntry(creation_info.config_entry);
125    }
126  }
127
128  /*!
129   * \param listener Listener to add (see tInputPort.h)
130   */
131  template <typename TListener>
132  void AddListener(TListener& listener)
133  {
134    implementation.AddPortListener(listener);
135  }
136  template <typename TListener>
137  void AddListenerSimple(TListener& listener)
138  {
139    implementation.AddPortListenerSimple(listener);
140  }
141
142  /*!
143   * Connect parameter (see tPortWrapperBase.h for variants)
144   */
145  template <typename TPartner, typename ... TRest>
146  inline void ConnectTo(TPartner& partner, const TRest& ... rest)
147  {
148    implementation.ConnectTo(AsPort(partner), rest...);
149  }
150
151  /*!
152   * Gets parameter's current value.
153   * (only available for 'cheaply copied' types)
154   *
155   * \param v unused dummy parameter for std::enable_if technique
156   * \return Parameter's current value by-value.
157   */
158  template <bool AVAILABLE = cPASS_BY_VALUE>
159  inline T Get(typename std::enable_if<AVAILABLE, void>::type* v = NULL) const
160  {
161    return implementation.Get();
162  }
163
164  /*!
165   * Gets parameter's current value
166   *
167   * (Using this Get()-variant is efficient when using 'cheaply copied' types,
168   * but can be extremely costly with large data types)
169   *
170   * \param result Buffer to (deep) copy parameter's current value to
171   */
172  inline void Get(T& result) const
173  {
174    return implementation.Get(result);
175  }
176
177  /*!
178   * (throws a std::runtime_error if parameter is not bounded)
179   *
180   * \return Bounds as they are currently set
181   */
182  template <bool AVAILABLE = data_ports::IsBoundable<T>::value>
183  inline typename std::enable_if<AVAILABLE, data_ports::tBounds<T>>::type GetBounds() const
184  {
185    return implementation.GetBounds();
186  }
187
188  /*!
189   * \return Place in configuration file this parameter is configured from (nodes are separated with '/')
190   */
191  std::string GetConfigEntry()
192  {
193    internal::tParameterInfo* parameter_info = implementation.GetWrapped()->template GetAnnotation<internal::tParameterInfo>();
194    return parameter_info->GetConfigEntry();
195  }
196
197  /*!
198   * \return Name of wrapped framework element (see tFrameworkElement::GetName())
199   */
200  inline const tString& GetName() const
201  {
202    return implementation.GetName();
203  }
204
205  /*!
206   * Gets Port's current value in buffer
207   *
208   * \return Buffer with port's current value with read lock.
209   */
210  inline data_ports::tPortDataPointer<const T> GetPointer() const
211  {
212    return implementation.GetPointer();
213  }
214
215  /*!
216   * \return Wrapped port. For rare case that someone really needs to access ports.
217   */
218  inline typename tImplementation::tPortBackend* GetWrapped() const
219  {
220    return implementation.GetWrapped();
221  }
222
223  /*!
224   * \return Has parameter changed since last changed-flag-reset?
225   */
226  inline bool HasChanged() const
227  {
228    return implementation.HasChanged();
229  }
230
231  /*!
232   * Initialize this parameter.
233   * This must be called prior to using parameter.
234   *
235   * For parameters created in e.g. component constructor, this is done automatically.
236   * For parameters created dynamically, this usually needs to be called.
237   */
238  inline void Init()
239  {
240    implementation.Init();
241  }
242
243  /*!
244   * Deletes port wrapped by this class.
245   * After calling this method, this object no longer wraps any object.
246   * Unless a new object is assigned, only GetWrapped() may called.
247   */
248  void ManagedDelete()
249  {
250    implementation.ManagedDelete();
251  }
252
253  /*!
254   * Reset changed flag.
255   */
256  inline void ResetChanged()
257  {
258    implementation.ResetChanged();
259  }
260
261  /*!
262   * \param new_value New value of parameter
263   */
264  void Set(const T& new_value)
265  {
266    tPortImplementation::BrowserPublish(*implementation.GetWrapped(), new_value, rrlib::time::cNO_TIME);
267  }
268
269  /*!
270   * \param config_entry New place in configuration file this parameter is configured from (nodes are separated with '/')
271   */
272  void SetConfigEntry(const std::string& config_entry)
273  {
274    internal::tParameterInfo* parameter_info = implementation.GetWrapped()->template GetAnnotation<internal::tParameterInfo>();
275    parameter_info->SetConfigEntry(config_entry);
276  }
277
278//----------------------------------------------------------------------
279// Private fields and methods
280//----------------------------------------------------------------------
281private:
282
283  template <typename U>
284  core::tPortWrapperBase AsPort(tParameter<U>& parameter)
285  {
286    return parameter.GetWrapped();
287  }
288
289  core::tPortWrapperBase AsPort(core::tPortWrapperBase port)
290  {
291    return port;
292  }
293
294  /*! Parameter implementation */
295  tImplementation implementation;
296};
297
298extern template class tParameter<int>;
299extern template class tParameter<long long int>;
300extern template class tParameter<float>;
301extern template class tParameter<double>;
302extern template class tParameter<std::string>;
303extern template class tParameter<bool>;
304
305//----------------------------------------------------------------------
306// End of namespace declaration
307//----------------------------------------------------------------------
308}
309}
310
311
312#endif
Note: See TracBrowser for help on using the repository browser.