source: rrlib_rtti_conversion/tRegisteredConversionOperation.h @ 9:f909044a9f7b

17.03
Last change on this file since 9:f909044a9f7b was 9:f909044a9f7b, checked in by Max Reichardt <mreichardt@…>, 2 years ago

Adds option to specify type conversions operations that are not usually combined (you could call combinations deprecated) and fixes various bugs found with unit test in finroc_plugins_runtime_construction

File size: 12.7 KB
Line 
1//
2// You received this file as part of RRLib
3// Robotics Research Library
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    rrlib/rtti_conversion/tRegisteredConversionOperation.h
23 *
24 * \author  Max Reichardt
25 *
26 * \date    2016-07-15
27 *
28 * \brief   Contains tRegisteredConversionOperation
29 *
30 * \b tRegisteredConversionOperation
31 *
32 * Conversion operation registered for runtime lookup.
33 * Registered operations may be applicable to multiple combinations of data types.
34 * They can always be compiled - and may not be usable directly.
35 *
36 * They must exist until the program shuts down.
37 * If they are allocated via new, they can be flagged to be deleted at shutdown.
38 *
39 */
40//----------------------------------------------------------------------
41#ifndef __rrlib__rtti_conversion__tRegisteredConversionOperation_h__
42#define __rrlib__rtti_conversion__tRegisteredConversionOperation_h__
43
44//----------------------------------------------------------------------
45// External includes (system with <>, local with "")
46//----------------------------------------------------------------------
47#include "rrlib/rtti/rtti.h"
48#include "rrlib/rtti/tParameterDefinition.h"
49#include <atomic>
50
51//----------------------------------------------------------------------
52// Internal includes with ""
53//----------------------------------------------------------------------
54#include "rrlib/thread/tMutex.h"
55
56//----------------------------------------------------------------------
57// Namespace declaration
58//----------------------------------------------------------------------
59namespace rrlib
60{
61namespace rtti
62{
63namespace conversion
64{
65
66//----------------------------------------------------------------------
67// Forward declarations / typedefs / enums
68//----------------------------------------------------------------------
69struct tConversionOption;
70struct tConversionOptionStaticCast;
71
72/*!
73 * Used to encode supported types of tRegisteredConversionOperations for external tools
74 * This enum is to be extended if further filters are needed.
75 */
76enum class tSupportedTypeFilter : uint8_t
77{
78  SINGLE,              //!< Only a single type is supported
79  BINARY_SERIALIZABLE, //!< All binary-serializable types are supported
80  STRING_SERIALIZABLE, //!< All string-serializable types are supported
81  LISTS,               //!< All list types are supported
82  ALL,                 //!< All types are supported
83
84  // Special operations defined in rrlib_rtti_conversion (known in Java tooling)
85  STATIC_CAST,         //!< Types supported by static casts (only used for tStaticCastOperation)
86  FOR_EACH,            //!< Types supported by for-each operation
87  GET_LIST_ELEMENT,    //!< Types supported by get list element
88  ARRAY_TO_VECTOR,     //!< Types supported by array to vector operation
89  GET_TUPLE_ELEMENT    //!< Types supported by get tuple element operation
90};
91
92//----------------------------------------------------------------------
93// Class declaration
94//----------------------------------------------------------------------
95//! Registered conversion operation
96/*!
97 * Conversion operation registered for runtime lookup.
98 * Registered operations may be applicable to multiple combinations of data types.
99 * They can always be compiled - and may not be usable directly.
100 *
101 * They must exist until the program shuts down.
102 * If they are allocated via new, they can be flagged to be deleted at shutdown.
103 */
104class tRegisteredConversionOperation : public rrlib::util::tNoncopyable
105{
106
107//----------------------------------------------------------------------
108// Public methods and typedefs
109//----------------------------------------------------------------------
110public:
111
112  /*! Name of static cast operation */
113  static const char* cSTATIC_CAST_NAME;
114
115  /*! Supported types for one end of cast operation */
116  struct tSupportedTypes
117  {
118    /*! Type filter */
119    tSupportedTypeFilter filter;
120
121    /*! In case 'filter' is SINGLE, contains the single supported type; otherwise it is ignored */
122    rrlib::rtti::tType single_type;
123
124    /*! Constructor for multiple type support */
125    tSupportedTypes(tSupportedTypeFilter filter) : filter(filter), single_type() {}
126
127    /*! Custructor for single type support */
128    tSupportedTypes(const rrlib::rtti::tType& single_type) : filter(tSupportedTypeFilter::SINGLE), single_type(single_type) {}
129
130
131//    /*!
132//     * Is type supported?
133//     *
134//     * \param type Type to check
135//     * \return Whether type is supported
136//     */
137//    bool IsTypeSupported(const rrlib::rtti::tType& type)
138//    {
139//      switch (filter)
140//      {
141//      case tSupportedTypeFilter::SINGLE:
142//        return type == single_type;
143//        break;
144//      case tSupportedTypeFilter::BINARY_SERIALIZABLE:
145//        return type.GetTypeTraits() & trait_flags::cIS_BINARY_SERIALIZABLE;
146//        break;
147//      case tSupportedTypeFilter::STRING_SERIALIZABLE:
148//        return type.GetTypeTraits() & trait_flags::cIS_STRING_SERIALIZABLE;
149//        break;
150//      case tSupportedTypeFilter::STATIC_CAST_SUPPORT:
151//        return // TODO? Do we actually need this method (since type support ;
152//        break;
153//      }
154//    }
155  };
156
157  /*! Data structure for managing registered operations */
158  struct tRegisteredOperations
159  {
160    /*! The list of registered operations */
161    typedef rrlib::serialization::tRegister<const tRegisteredConversionOperation*, 64, 64, uint16_t> tOperationsRegister;
162    tOperationsRegister operations;
163
164    /*! List of operations to auto-delete */
165    typedef rrlib::concurrent_containers::tRegister<std::unique_ptr<const tRegisteredConversionOperation>, 32, 32> tAutoDeleteRegister;
166    tAutoDeleteRegister auto_delete;
167
168    /*! Registered static cast operations */
169    typedef rrlib::serialization::tRegister<const tConversionOptionStaticCast*, 64, 64, uint16_t> tStaticCastRegister;
170    tStaticCastRegister static_casts;
171  };
172
173
174  virtual ~tRegisteredConversionOperation();
175
176  /*!
177   * Deserializes registered conversion operation from input stream and returns any registered operation matching the deserialized data.
178   *
179   * \param stream Stream to deserialize from
180   * \param throw_exception_if_not_found Throw std::runtime_error if no matching registered operation could be found?
181   * \return Registered operation matching the deserialized data. nullptr if no such operation exists.
182   */
183  static const tRegisteredConversionOperation* Deserialize(rrlib::serialization::tInputStream& stream, bool throw_exception_if_not_found = false);
184
185  /*!
186   * Find registered conversion operation with specified name that support specified source and destination types
187   *
188   * \param name Name of conversion operation
189   * \return Registered operation with the specified name. Second indicates whether there are more registered conversion operations with this name.
190   */
191  static std::pair<const tRegisteredConversionOperation*, bool> Find(const std::string& name);
192
193  /*!
194   * Find registered conversion operation with specified name that support specified source and destination types
195   *
196   * \param name Name of conversion operation
197   * \param source_type Source type of operation (optional)
198   * \param destination_type Destination type of operation (optional)
199   * \return Registered operation with the specified name and types.
200   * \throw Throws std::runtime_error if conversion was not found or is ambiguous.
201   */
202  static const tRegisteredConversionOperation& Find(const std::string& name, const tType& source_type, const tType& destination_type);
203
204  /*!
205   * Gets conversion option for converting the specified types.
206   * Needs to be overridden unless single_conversion_option is set.
207   *
208   * \param source_type Source Type
209   * \param destination_type Destination Type
210   * \param parameter Conversion parameter (nullptr means default)
211   * \return Conversion option for the specified types (result's type is tConversionOptionType::NONE if no option for specified types can be provided)
212   */
213  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const;
214
215  /*!
216   * \return Local handle of operation
217   */
218  uint16_t GetHandle() const
219  {
220    return handle;
221  }
222
223  /*!
224   * \return Handle of conversion operation that this one is not usually combined with (0xFFFF if there is no such operation)
225   */
226  uint16_t GetNotUsuallyCombinedWithHandle() const
227  {
228    return not_usually_combined_with_handle;
229  }
230
231  /*!
232   * \return Registered type conversion operations.
233   */
234  static const tRegisteredOperations& GetRegisteredOperations()
235  {
236    return RegisteredOperations();
237  }
238
239  /*!
240   * \return Name of conversion operation
241   */
242  const char* Name() const
243  {
244    return name.Get();
245  }
246
247  /*!
248   * \return Parameter of this conversion operation (possibly empty if operation has no parameter)
249   */
250  const tParameterDefinition& Parameter() const
251  {
252    return parameter;
253  }
254
255  /*!
256   * \return Supported source types of cast operation
257   */
258  const tSupportedTypes& SupportedDestinationTypes() const
259  {
260    return supported_destination_types;
261  }
262
263  /*!
264   * \return Supported source types of cast operation
265   */
266  const tSupportedTypes& SupportedSourceTypes() const
267  {
268    return supported_source_types;
269  }
270
271//----------------------------------------------------------------------
272// Protected types
273//----------------------------------------------------------------------
274protected:
275
276  /*!
277   * \param name Name of conversion operation (must be unique for every supported combination of source and destination types)
278   * \param supported_source_types Supported source types
279   * \param supported_destination_types Supported destination types
280   * \param single_conversion_option If operation provides only a single conversion option - points to this option (otherwise override GetConversionOptions())
281   * \param parameter Any parameter of conversion operation (optional)
282   * \param not_usually_combined_with Conversion operation that this one is not usually combined with (a deprecated combination if you want)
283   */
284  tRegisteredConversionOperation(util::tManagedConstCharPointer name, const tSupportedTypes& supported_source_types, const tSupportedTypes& supported_destination_types,
285                                 const tConversionOption* single_conversion_option = nullptr, const tParameterDefinition& parameter = tParameterDefinition(),
286                                 const tRegisteredConversionOperation* not_usually_combined_with = nullptr);
287
288  /*!
289   * Adds this operation to list of operations that are automatically deleted on shutdown.
290   * This should only be done with operations allocated via new() and not deleted elsewhere.
291   */
292  void AutoDelete();
293
294//----------------------------------------------------------------------
295// Private fields and methods
296//----------------------------------------------------------------------
297private:
298
299  friend class tStaticCastOperation;
300
301  /*! Name of conversion operation (must be unique for every supported combination of source and destination types) */
302  util::tManagedConstCharPointer name;
303
304  /*! Supported source and destination types */
305  const tSupportedTypes supported_source_types, supported_destination_types;
306
307  /*! Parameter for this conversion operation (may be empty) */
308  const tParameterDefinition parameter;
309
310  /*! If operation provides only a single conversion option - points to this option */
311  const tConversionOption* single_conversion_option;
312
313  /*! Local handle of operation */
314  uint16_t handle;
315
316  /*! Handle of conversion operation that this one is not usually combined with (0xFFFF if there is no such operation) */
317  uint16_t not_usually_combined_with_handle;
318
319
320  /*! constructor for tStaticCastOperation */
321  tRegisteredConversionOperation();
322
323  /*!
324   * \return Registered type conversion operations.
325   */
326  static tRegisteredOperations& RegisteredOperations();
327};
328
329
330serialization::tOutputStream& operator << (serialization::tOutputStream& stream, const tRegisteredConversionOperation& operation);
331
332//----------------------------------------------------------------------
333// End of namespace declaration
334//----------------------------------------------------------------------
335}
336}
337}
338
339
340#endif
Note: See TracBrowser for help on using the repository browser.