source: rrlib_serialization/PublishedRegisters.h @ 160:a7fa406b8ffc

17.03
Last change on this file since 160:a7fa406b8ffc was 160:a7fa406b8ffc, checked in by Max Reichardt <mreichardt@…>, 6 years ago

Adds check for valid 'uid' parameter to PublishedRegisters::AddListener

File size: 9.1 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/serialization/PublishedRegisters.h
23 *
24 * \author  Max Reichardt
25 *
26 * \date    2017-02-05
27 *
28 * \brief   Contains PublishedRegisters
29 *
30 * \b PublishedRegisters
31 *
32 * Register of tRegisters that are available for auto-publishing mechanism
33 *
34 */
35//----------------------------------------------------------------------
36#ifndef __rrlib__serialization__PublishedRegisters_h__
37#define __rrlib__serialization__PublishedRegisters_h__
38
39//----------------------------------------------------------------------
40// External includes (system with <>, local with "")
41//----------------------------------------------------------------------
42#include <memory>
43#include <atomic>
44#include "rrlib/thread/tLock.h"
45
46//----------------------------------------------------------------------
47// Internal includes with ""
48//----------------------------------------------------------------------
49#include "rrlib/serialization/tSerializationInfo.h"
50#include "rrlib/serialization/tRegister.h"
51
52//----------------------------------------------------------------------
53// Namespace declaration
54//----------------------------------------------------------------------
55namespace rrlib
56{
57namespace serialization
58{
59
60//----------------------------------------------------------------------
61// Forward declarations / typedefs / enums
62//----------------------------------------------------------------------
63
64//----------------------------------------------------------------------
65// Class declaration
66//----------------------------------------------------------------------
67//! Shared registers
68/*!
69 * Register of tRegisters that are available for auto-publishing mechanism
70 */
71class PublishedRegisters
72{
73
74  /*!
75   * For lookup TRemoteType -> Register UID
76   */
77  template <typename TRemoteEntry>
78  struct RemoteEntryRegisterUid
79  {
80    static int& Uid()
81    {
82      static int uid = -1;
83      return uid;
84    }
85  };
86
87  /*! Base class for remote registers */
88  class tRemoteRegisterBase : public tInputStream::tRemoteRegister
89  {
90  public:
91    virtual ~tRemoteRegisterBase();
92    virtual void DeserializeEntries(tInputStream& stream) = 0;
93    virtual const void* GetRemoteElement(size_t index) = 0;
94    const std::atomic<size_t>* size;
95    template <typename TEntry>
96    void SetHandle(TEntry& entry, typename TEntry::tHandle handle)
97    {
98      entry.handle = handle;
99    }
100  };
101
102//----------------------------------------------------------------------
103// Public methods and typedefs
104//----------------------------------------------------------------------
105public:
106
107  /*! Base class for type used as TRemoteEntry (class with identical members work also) */
108  template <typename THandle, typename TLocalRegister>
109  class tRemoteEntryBase
110  {
111  public:
112
113    typedef THandle tHandle;
114    typedef TLocalRegister tLocalRegister;
115
116    /*!
117     * \return Remote handle of entry
118     */
119    tHandle GetHandle() const
120    {
121      return handle;
122    }
123
124  private:
125
126    friend class tRemoteRegisterBase;
127
128    uint handle; //!< Remote handle of entry
129  };
130
131  /*! Base class for remote registers */
132  template <typename TRemoteEntry>
133  class tRemoteRegister : public tRemoteRegisterBase, public concurrent_containers::tRegister<TRemoteEntry, TRemoteEntry::tLocalRegister::cCHUNK_COUNT, TRemoteEntry::tLocalRegister::cCHUNK_SIZE, rrlib::thread::tNoMutex>
134  {
135  };
136
137  /*!
138   * Adds listener to register.
139   *
140   * \param uid Uid of register
141   * \param callback Callback function that will be called whenever a new element is added.
142   * \param address Address of listener. Optional: only required for identification when removing listener.
143   */
144  static void AddListener(uint uid, const std::function<void()>& callback, const void* address = nullptr);
145
146  /*!
147   * \param stream Stream whose (shared) data on remote register to obtain
148   * \return Returns stream's (shared) remote register for type TRemoteEntry
149   */
150  template <typename TRemoteEntry>
151  static const tRemoteRegister<TRemoteEntry>* GetRemoteRegister(tInputStream& stream)
152  {
153    return static_cast<const tRemoteRegister<TRemoteEntry>*>((*stream.shared_serialization_info.remote_registers)[GetRemoteEntryRegisterUid<TRemoteEntry>()].get());
154  }
155
156  /*!
157   * Registers tRegister for use in auto-publishing mechanism.
158   * UIDs must be consistent across all processes that read/write the same serialized data created with the automatic register publishing mechanisms.
159   * Therefore, typically a high-level entity that knows all relevant registers should manage assignment of the UIDs.
160   *
161   * \param r tRegister to register
162   * \param uid Uid to assign to register (must be <= cMAX_PUBLISHED_REGISTERS)
163   * \tparam TRemoteEntry Type to deserialize in remote runtime environment. It needs to be derived from PublishedRegisters::tRemoteEntryBase, default-constructible and have
164   *                      (1) a method for serializing local elements (the handle needn't be serialized)
165   *                      static void SerializeRegisterEntry(tOutputStream& stream, const TEntry& entry);
166   *                      (2) an equivalent method for deserializing element as TRemoteEntry (the handle needn't be deserialized)
167   *                      void DeserializeRegisterEntry(tInputStream& stream);
168   * \throw Throws std::invalid_argument on already occupied uid
169   */
170  template <typename TRemoteEntry>
171  static void Register(const typename TRemoteEntry::tLocalRegister& r, uint uid);
172
173  /*!
174   * Removes listener from tRegister
175   *
176   * \param uid Uid of register
177   * \param address Address of listener
178   */
179  static bool RemoveListener(uint uid, const void* address)
180  {
181    return RegisteredRegisters()[uid]->RemoveListener(address);
182  }
183
184  /*!
185   * \param uid Uid of register
186   * \return Current size of register
187   */
188  static size_t Size(uint uid)
189  {
190    return RegisteredRegisters()[uid]->size->load();
191  }
192
193//----------------------------------------------------------------------
194// Private fields and methods
195//----------------------------------------------------------------------
196private:
197
198  friend class tInputStream;
199  friend class tOutputStream;
200
201  /*! Info on every registered register */
202  struct tPerRegisterInfo
203  {
204    virtual ~tPerRegisterInfo();
205    virtual void AddListener(const std::function<void()>& callback, const void* address) = 0;
206    virtual tRemoteRegisterBase* CreateRemoteRegister() = 0;
207    virtual bool RemoveListener(const void* address) = 0;
208    virtual void SerializeEntries(tOutputStream& stream, uint start_element, uint end_element) = 0;
209    const std::atomic<size_t>* size;
210    const void* raw_register_pointer;
211  };
212
213  /*!
214   * Deserializes remote register entry from input stream
215   *
216   * \param stream Stream to deserialize from
217   * \param register_vector Input stream vector that stored remote registers
218   */
219  template <typename TRemoteType>
220  static const TRemoteType& DeserializeRemoteRegisterEntry(tInputStream& stream, std::array<std::unique_ptr<tInputStream::tRemoteRegister>, cMAX_PUBLISHED_REGISTERS>& register_array);
221
222  /*!
223   * Looks up register uid for type TRemoteEntry
224   *
225   * \return Register uid, -1 if no register for this type has been registered
226   */
227  template <typename TRemoteEntry>
228  static int GetRemoteEntryRegisterUid()
229  {
230    return RemoteEntryRegisterUid<TRemoteEntry>::Uid();
231  }
232
233  /*!
234   * \return Registered registers
235   */
236  static std::array<std::unique_ptr<tPerRegisterInfo>, cMAX_PUBLISHED_REGISTERS>& RegisteredRegisters();
237
238  /*!
239   * Serializes entries from shared register to stream
240   *
241   * \param stream Stream to serialize to
242   * \param uid Uid of register
243   * \param start_element First element to serialize
244   * \param end_element One past the last element to serialize
245   */
246  static void SerializeEntries(tOutputStream& stream, uint uid, uint start_element, uint end_element)
247  {
248    RegisteredRegisters()[uid]->SerializeEntries(stream, start_element, end_element);
249  }
250};
251
252template <typename THandle, typename TLocalRegister>
253inline tOutputStream& operator<<(tOutputStream& stream, const PublishedRegisters::tRemoteEntryBase<THandle, TLocalRegister>& entry)
254{
255  stream << entry.GetHandle();
256  return stream;
257}
258
259//----------------------------------------------------------------------
260// End of namespace declaration
261//----------------------------------------------------------------------
262}
263}
264
265#include "rrlib/serialization/PublishedRegisters.hpp"
266
267
268#endif
Note: See TracBrowser for help on using the repository browser.