RefleX
Build DDS Applications in Modern C++ without IDL
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
generic_dr.h
Go to the documentation of this file.
1 /*********************************************************************************************
2 (c) 2005-2014 Copyright, Real-Time Innovations, Inc. All rights reserved.
3 RTI grants Licensee a license to use, modify, compile, and create derivative works
4 of the Software. Licensee has the right to distribute object form only for use with RTI
5 products. The Software is provided "as is", with no warranty of any type, including
6 any warranty for fitness for any purpose. RTI is under no obligation to maintain or
7 support the Software. RTI shall not be liable for any incidental or consequential
8 damages arising out of the use or inability to use the software.
9 **********************************************************************************************/
10 
11 #ifndef RTIREFLEX_GENERIC_DR_H
12 #define RTIREFLEX_GENERIC_DR_H
13 
14 #include "reflex/safe_typecode.h"
15 #include "reflex/auto_dd.h"
16 #include "reflex/dd2tuple.h"
17 #include "reflex/dllexport.h"
18 #include "reflex/sample.h"
19 #include "reflex/reflex_fwd.h"
20 #include "reflex/enable_if.h"
21 #include "reflex/type_manager.h"
22 
23 #include <memory>
24 
25 namespace reflex {
26 
27  namespace sub {
28 
29  template <class T>
31 
32  template <class T>
34 
35  } // namespace sub
36 
37  namespace detail {
38 
40  std::shared_ptr<DDSDynamicDataReader> initialize_reader(DDSDomainParticipant *participant,
41  const DDS_DataReaderQos & drqos,
42  const char * topic_name,
43  const char * type_name,
44  DDSDynamicDataTypeSupport * support,
45  DDSDataReaderListener * listener,
46  DDS_DynamicDataTypeProperty_t props);
47 
48  REFLEX_DLL_EXPORT void dr_deleter(DDSDynamicDataReader * ddReader) throw();
49 
50  template <class T>
51  DDS_ReturnCode_t take_impl(
52  std::shared_ptr<DDSDynamicDataReader> dr,
53  std::vector<reflex::sub::Sample<T>> & data,
54  int max_samples,
55  DDS_SampleStateMask sample_states,
56  DDS_ViewStateMask view_states,
57  DDS_InstanceStateMask instance_states,
58  DDSReadCondition * cond = 0)
59  {
60  DDS_DynamicDataSeq data_seq;
61  DDS_SampleInfoSeq info_seq;
62  DDS_ReturnCode_t rc;
63 
64  if (cond)
65  rc = dr->take_w_condition(data_seq, info_seq, max_samples, cond);
66  else
67  rc = dr->take(data_seq, info_seq, max_samples,
68  sample_states, view_states, instance_states);
69 
70  if (rc == DDS_RETCODE_NO_DATA) {
71  return rc;
72  }
73  else if (rc != DDS_RETCODE_OK) {
74  std::cerr << "! Unable to take data from data reader, error "
75  << rc << std::endl;
76  return rc;
77  }
78 
79  if (data_seq.length())
80  {
81  data.resize(data_seq.length());
82 
83  for (int i = 0; i < data_seq.length(); ++i)
84  {
85  if (info_seq[i].valid_data)
86  reflex::read_dynamicdata(data[i].data(), data_seq[i]);
87  else
88  {
89  T temp;
90  data[i].data() = temp;
91  }
92  data[i].info() = info_seq[i];
93  }
94  }
95 
96  rc = dr->return_loan(data_seq, info_seq);
97  if (rc != DDS_RETCODE_OK) {
98  std::cerr << "! Unable to return loan, error "
99  << rc << std::endl;
100  }
101  return rc;
102  }
103 
104  template <class T>
105  class DataReaderListenerAdapter : public DDSDataReaderListener
106  {
107  reflex::sub::GenericDataReaderListener<T> * generic_listener_;
108  reflex::sub::GenericDataReader<T> * data_reader_;
109 
110  public:
111 
112  typedef reflex::sub::GenericDataReader<T> DataReaderType;
113 
114  explicit DataReaderListenerAdapter(reflex::sub::GenericDataReaderListener<T> * listener)
115  : generic_listener_(listener),
116  data_reader_(0)
117  {
118  if (!listener)
119  {
120  throw std::runtime_error("DataReaderListenerAdapter: NULL listener");
121  }
122  }
123 
124  void set_datareader(reflex::sub::GenericDataReader<T> * dr)
125  {
126  data_reader_ = dr;
127  }
128 
129  virtual void on_data_available(DDSDataReader *reader)
130  {
131 #ifdef _DEBUG
132  DDSDynamicDataReader *dd_reader = DDSDynamicDataReader::narrow(reader);
133  if (!dd_reader) {
134  std::cerr << "Not a DynamicDataReader!!!\n";
135  }
136 #endif
137  generic_listener_->on_data_available(*data_reader_);
138  }
139  };
140 
141 
142  } // namespace detail
143 
147  namespace sub {
148 
152  template <class T>
153  class GenericDataReaderListener
154  {
155  public:
160  virtual void on_data_available(GenericDataReader<T> & dr) = 0;
161 
163  };
164 
168  template <class T>
169  class GenericDataReader
170  {
171  public:
173 
174  private:
175  reflex::TypeManager<T> type_manager_;
176  std::shared_ptr<detail::DataReaderListenerAdapter<T>> safe_listener_adapter_;
177  std::shared_ptr<DDSDynamicDataReader> safe_datareader_;
178 
179  public:
180 
182  DDSDomainParticipant *participant,
183  const char * topic_name,
184  ListenerType * listener,
185  const char * type_name = 0,
186  DDS_DynamicDataTypeProperty_t props =
187  DDS_DYNAMIC_DATA_TYPE_PROPERTY_DEFAULT)
188 
189  : type_manager_(props),
190  safe_listener_adapter_(listener ? new detail::DataReaderListenerAdapter<T>(listener) : 0),
191  safe_datareader_(detail::initialize_reader(
192  participant,
193  DDS_DATAREADER_QOS_DEFAULT,
194  topic_name,
195  type_name,
196  type_manager_.get_type_support(),
197  safe_listener_adapter_.get(),
198  props))
199  {
200  if (safe_listener_adapter_)
201  safe_listener_adapter_->set_datareader(this);
202  }
203 
205  DDSDomainParticipant *participant,
206  const DDS_DataReaderQos & drqos,
207  const char * topic_name,
208  ListenerType * listener,
209  const char * type_name = 0,
210  DDS_DynamicDataTypeProperty_t props =
211  DDS_DYNAMIC_DATA_TYPE_PROPERTY_DEFAULT)
212 
213  : type_manager_(props),
214  safe_listener_adapter_(listener ? new detail::DataReaderListenerAdapter<T>(listener) : 0),
215  safe_datareader_(detail::initialize_reader(
216  participant,
217  drqos,
218  topic_name,
219  type_name,
220  type_manager_.get_support(),
221  safe_listener_adapter_.get(),
222  props))
223  {
224  if (safe_listener_adapter_)
225  safe_listener_adapter_->set_datareader(this);
226  }
227 
228  DDS_ReturnCode_t take(
229  std::vector<Sample<T>> & data,
230  int max_samples = DDS_LENGTH_UNLIMITED,
231  DDS_SampleStateMask sample_states = DDS_ANY_SAMPLE_STATE,
232  DDS_ViewStateMask view_states = DDS_ANY_VIEW_STATE,
233  DDS_InstanceStateMask instance_states = DDS_ANY_INSTANCE_STATE)
234  {
235  return detail::take_impl<T>(
236  safe_datareader_,
237  data,
238  max_samples,
239  sample_states,
240  view_states,
241  instance_states);
242  }
243 
244  DDS_ReturnCode_t take_w_condition(std::vector<Sample<T>> & data,
245  int max_samples,
246  DDSReadCondition * cond)
247  {
248  if (!cond)
249  return DDS_RETCODE_PRECONDITION_NOT_MET;
250 
251  return detail::take_impl<T>(
252  safe_datareader_,
253  data,
254  max_samples,
255  DDS_ANY_SAMPLE_STATE,
256  DDS_ANY_VIEW_STATE,
257  DDS_ANY_INSTANCE_STATE,
258  cond);
259  }
260 
264  DDSDynamicDataReader * underlying()
265  {
266  return safe_datareader_.get();
267  }
268 
272  DDSDynamicDataReader * operator -> ()
273  {
274  return underlying();
275  }
276 
280  const DDS_DynamicDataTypeProperty_t & get_properties() const
281  {
282  return type_manager_.get_properties();
283  }
284 
289  {
290  return type_manager_.get_safe_typecode();
291  }
292 
296  const DDS_TypeCode* get_typecode() const
297  {
298  return type_manager_.get_typecode();
299  }
300 
304  const DDSDynamicDataTypeSupport * get_type_support() const
305  {
306  return type_manager_.get_type_support();
307  }
308 
309  };
310 
311  } // namespace sub
312 } // namespace reflex
313 
314 #ifndef REFLEX_NO_HEADER_ONLY
315 #include "reflex/../../src/generic_dr.cxx"
316 #endif
317 
318 
319 
320 #endif // RTIREFLEX_GENERIC_DR_H
321 
DDSDynamicDataReader * operator->()
Return the underlying DDSDynamicDataReader.
Definition: generic_dr.h:272
GenericDataReader(DDSDomainParticipant *participant, const DDS_DataReaderQos &drqos, const char *topic_name, ListenerType *listener, const char *type_name=0, DDS_DynamicDataTypeProperty_t props=DDS_DYNAMIC_DATA_TYPE_PROPERTY_DEFAULT)
Definition: generic_dr.h:204
DDS_ReturnCode_t take_w_condition(std::vector< Sample< T >> &data, int max_samples, DDSReadCondition *cond)
Definition: generic_dr.h:244
virtual void on_data_available(GenericDataReader< T > &dr)=0
Callback invoked when new data is available to read from GenericDataReader.
Manage type-specific context, such as typecode, type-support, and dynamic data properties.
Definition: type_manager.h:44
A datareader for adapted aggregate types.
Definition: generic_dr.h:30
const DDS_DynamicDataTypeProperty_t & get_properties() const
Definition: generic_dr.h:280
disable_if_lazy< reflex::type_traits::is_tuple< FusionSeq >::value, at< FusionSeq, I > >::type get(FusionSeq &seq)
Definition: enable_if.h:714
GenericDataReader(DDSDomainParticipant *participant, const char *topic_name, ListenerType *listener, const char *type_name=0, DDS_DynamicDataTypeProperty_t props=DDS_DYNAMIC_DATA_TYPE_PROPERTY_DEFAULT)
Definition: generic_dr.h:181
const DDS_TypeCode * get_typecode() const
Definition: generic_dr.h:296
#define REFLEX_DLL_EXPORT
Definition: dllexport.h:35
void read_dynamicdata(T &dest, const DDS_DynamicData &src)
Extracts data out from the source DDS_DynamicData instance and copies into the destination object of ...
Definition: reflex.h:186
const DDSDynamicDataTypeSupport * get_type_support() const
Definition: generic_dr.h:304
GenericDataReaderListener< T > ListenerType
Definition: generic_dr.h:172
const SafeTypeCode< T > & get_safe_typecode() const
Definition: generic_dr.h:288
DDSDynamicDataReader * underlying()
Return the underlying DDSDynamicDataReader.
Definition: generic_dr.h:264
DDS_ReturnCode_t take(std::vector< Sample< T >> &data, int max_samples=DDS_LENGTH_UNLIMITED, DDS_SampleStateMask sample_states=DDS_ANY_SAMPLE_STATE, DDS_ViewStateMask view_states=DDS_ANY_VIEW_STATE, DDS_InstanceStateMask instance_states=DDS_ANY_INSTANCE_STATE)
Definition: generic_dr.h:228
A type-safe, exception-safe wrapper for DDS TypeCode.
Definition: reflex_fwd.h:27
virtual ~GenericDataReaderListener()
Definition: generic_dr.h:162
Synchornous data listener for GenericDataReader.
Definition: generic_dr.h:33
A valuetype that combines an instance of type T (data) and DDS_SampleInfo.
Definition: sample.h:24