OutputPort.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Thu Oct 22 11:59:08 CEST 2009 OutputPort.hpp
3 
4  OutputPort.hpp - description
5  -------------------
6  begin : Thu October 22 2009
7  copyright : (C) 2009 Sylvain Joyeux
8  email : sylvain.joyeux@m4x.org
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * Lesser General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 
39 #ifndef ORO_OUTPUT_PORT_HPP
40 #define ORO_OUTPUT_PORT_HPP
41 
43 #include "base/DataObject.hpp"
45 #include "internal/Channels.hpp"
46 #include "internal/ConnFactory.hpp"
47 #include "Service.hpp"
48 #include "OperationCaller.hpp"
49 
50 #include "InputPort.hpp"
51 
52 namespace RTT
53 {
69  template<typename T>
71  {
72  private:
73  friend class internal::ConnInputEndpoint<T>;
75 
76  virtual bool connectionAdded( base::ChannelElementBase::shared_ptr channel_input, ConnPolicy const& policy ) {
77  // Initialize the new channel with last written data if requested
78  // (and available)
79 
80  // This this the input channel element of the whole connection
81  typename base::ChannelElement<T>::shared_ptr channel_el_input = channel_input.get()->narrow<T>();
82 
84  {
85  T const& initial_sample = sample->Get();
86  if ( channel_el_input->data_sample(initial_sample, /* reset = */ false) != NotConnected ) {
87  if ( has_last_written_value && policy.init )
88  return ( channel_el_input->write(initial_sample) != NotConnected );
89  return true;
90  } else {
91  Logger::In in("OutputPort");
92  log(Error) << "Failed to pass data sample to data channel. Aborting connection."<<endlog();
93  return false;
94  }
95  }
96 
97  // even if we're not written, test the connection with a default sample.
98  return ( channel_el_input->data_sample( T(), /* reset = */ false ) != NotConnected );
99  }
100 
104  // data_sample or by calling write() with keeps_next_written_value or
105  // keeps_last_written_value to true
108  // This is used to initialize connections with a known sample
111  // This is used to allow the use of the 'init' connection policy option
114 
121  OutputPort( OutputPort const& orig );
122  OutputPort& operator=(OutputPort const& orig);
123 
124  public:
141  OutputPort(std::string const& name = "unnamed", bool keep_last_written_value = true)
143  , endpoint(new internal::ConnInputEndpoint<T>(this))
144  , has_last_written_value(false)
145  , has_initial_sample(false)
146  , keeps_next_written_value(false)
147  , keeps_last_written_value(false)
148  , sample( new base::DataObject<T>() )
149  {
150  if (keep_last_written_value)
151  keepLastWrittenValue(true);
152  }
153 
154  virtual ~OutputPort() { disconnect(); }
155 
156  void keepNextWrittenValue(bool keep)
157  {
158  keeps_next_written_value = keep;
159  }
160 
161  void keepLastWrittenValue(bool keep)
162  {
163  keeps_last_written_value = keep;
164  }
165 
167 
174  {
175  return sample->Get();
176  }
177 
184  bool getLastWrittenValue(T& sample) const
185  {
186  if (has_last_written_value)
187  {
188  this->sample->Get(sample);
189  return true;
190  }
191  return false;
192  }
193 
195  {
196  // we create this on the fly.
198  }
199 
209  void setDataSample(const T& sample)
210  {
211  this->sample->Set(sample);
212  has_initial_sample = true;
213  has_last_written_value = false;
214 
215  if (connected()) {
216  WriteStatus result = getEndpoint()->getWriteEndpoint()->data_sample(sample, /* reset = */ true);
217  if (result == NotConnected) {
218  log(Error) << "A channel of port " << getName() << " has been invalidated during setDataSample(), it will be removed" << endlog();
219  }
220  }
221  }
222 
227  void clear()
228  {
229  has_last_written_value = false;
230  getEndpoint()->getWriteEndpoint()->clear(); // only affects shared pull connections, where getInputEndpoint() would return the port's buffer object
231 
232  // eventually clear shared connection
234  if (shared_connection) {
235  shared_connection->clear();
236  }
237  }
238 
243  WriteStatus write(const T& sample)
244  {
245  if (keeps_last_written_value || keeps_next_written_value)
246  {
247  keeps_next_written_value = false;
248  has_initial_sample = true;
249  this->sample->Set(sample);
250  }
251  has_last_written_value = keeps_last_written_value;
252 
253  WriteStatus result = NotConnected;
254  if (connected()) {
255  traceWrite();
256  result = getEndpoint()->getWriteEndpoint()->write(sample);
257  if (result == NotConnected) {
258  log(Error) << "A channel of port " << getName() << " has been invalidated during write(), it will be removed" << endlog();
259  }
260  }
261 
262  return result;
263  }
264 
266  {
268  boost::dynamic_pointer_cast< internal::AssignableDataSource<T> >(source);
269  if (ds) {
270  traceWrite();
271  return write(ds->rvalue());
272  }
273  else
274  {
276  boost::dynamic_pointer_cast< internal::DataSource<T> >(source);
277  if (ds) {
278  traceWrite();
279  return write(ds->get());
280  }
281  else
282  log(Error) << "trying to write from an incompatible data source" << endlog();
283  }
284  return WriteFailure;
285  }
286 
288  virtual const types::TypeInfo* getTypeInfo() const
290 
294  virtual base::PortInterface* clone() const
295  { return new OutputPort<T>(this->getName()); }
296 
303  { return new InputPort<T>(this->getName()); }
304 
306 
309  virtual bool createConnection(base::InputPortInterface& input_port, ConnPolicy const& policy)
310  {
311  return internal::ConnFactory::createConnection(*this, input_port, policy);
312  }
313 
314  virtual bool createStream(ConnPolicy const& policy)
315  {
316  return internal::ConnFactory::createStream(*this, policy);
317  }
318 
319 #ifndef ORO_DISABLE_PORT_DATA_SCRIPTING
320 
325  {
327  // Force resolution on the overloaded write method
328  typedef WriteStatus (OutputPort<T>::*WriteSample)(T const&);
329  WriteSample write_m = &OutputPort::write;
330  typedef T (OutputPort<T>::*LastSample)() const;
331  LastSample last_m = &OutputPort::getLastWrittenValue;
332  object->addSynchronousOperation("write", write_m, this).doc("Writes a sample on the port.").arg("sample", "");
333  object->addSynchronousOperation("last", last_m, this).doc("Returns last written value to this port.");
334  return object;
335  }
336 #endif
337 
339  {
340  assert(endpoint);
341  return endpoint.get();
342  }
343 
345  {
346  return getEndpoint()->getSharedBuffer();
347  }
348  };
349 
350 }
351 
352 #endif
353 
void setDataSample(const T &sample)
Definition: OutputPort.hpp:209
base::DataObjectInterface< T >::shared_ptr sample
Definition: OutputPort.hpp:113
boost::intrusive_ptr< ChannelElement< T > > shared_ptr
virtual result_t get() const =0
boost::intrusive_ptr< SharedConnectionBase > shared_ptr
WriteStatus write(base::DataSourceBase::shared_ptr source)
Definition: OutputPort.hpp:265
boost::shared_ptr< DataObjectInterface< T > > shared_ptr
boost::intrusive_ptr< ConnInputEndpoint< T > > shared_ptr
OutputPort(std::string const &name="unnamed", bool keep_last_written_value=true)
Definition: OutputPort.hpp:141
virtual const types::TypeInfo * getTypeInfo() const
Definition: OutputPort.hpp:288
bool getLastWrittenValue(T &sample) const
Definition: OutputPort.hpp:184
void keepLastWrittenValue(bool keep)
Definition: OutputPort.hpp:161
bool has_initial_sample
True if sample has been written at least once, either by calling.
Definition: OutputPort.hpp:106
virtual FlowStatus Get(reference_t pull, bool copy_old_data=true) const =0
const std::string & getName() const
virtual base::PortInterface * clone() const
Definition: OutputPort.hpp:294
virtual internal::ConnInputEndpoint< T > * getEndpoint() const
Definition: OutputPort.hpp:338
virtual Service * createPortObject()
Definition: OutputPort.hpp:324
internal::ConnInputEndpoint< T >::shared_ptr endpoint
Definition: OutputPort.hpp:74
bool keeps_next_written_value
If true, the next call to write() will save the sample in sample.
Definition: OutputPort.hpp:109
bool has_last_written_value
True if sample has been set at least once by a call to write()
Definition: OutputPort.hpp:102
bool keeps_last_written_value
If true, all calls to write() will save the sample in sample.
Definition: OutputPort.hpp:112
virtual Service * createPortObject()
virtual const_reference_t rvalue() const =0
virtual bool createStream(ConnPolicy const &policy)
Definition: OutputPort.hpp:314
static bool createStream(OutputPort< T > &output_port, ConnPolicy const &policy)
bool createConnection(InputPortInterface &sink)
virtual bool connectionAdded(base::ChannelElementBase::shared_ptr channel_input, ConnPolicy const &policy)
Definition: OutputPort.hpp:76
bool keepsLastWrittenValue() const
Definition: OutputPort.hpp:166
WriteStatus write(const T &sample)
Definition: OutputPort.hpp:243
boost::intrusive_ptr< ChannelElementBase > shared_ptr
boost::intrusive_ptr< DataSource< T > > shared_ptr
Definition: DataSource.hpp:115
boost::intrusive_ptr< AssignableDataSource< T > > shared_ptr
Definition: DataSource.hpp:198
static const types::TypeInfo * getTypeInfo()
virtual base::ChannelElement< T >::shared_ptr getSharedBuffer() const
Definition: OutputPort.hpp:344
virtual ~OutputPort()
Definition: OutputPort.hpp:154
void keepNextWrittenValue(bool keep)
Definition: OutputPort.hpp:156
internal::ConnectionManager cmanager
virtual WriteStatus data_sample(param_t sample, bool reset=true)
boost::intrusive_ptr< DataSourceBase > shared_ptr
virtual WriteStatus write(param_t sample)
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:53
OutputPort & operator=(OutputPort const &orig)
T getLastWrittenValue() const
Definition: OutputPort.hpp:173
virtual base::DataSourceBase::shared_ptr getDataSource() const
Definition: OutputPort.hpp:194
static Logger & log()
Definition: Logger.hpp:350
static bool createConnection(OutputPort< T > &output_port, base::InputPortInterface &input_port, ConnPolicy const &policy)
virtual base::PortInterface * antiClone() const
Definition: OutputPort.hpp:302
OutputPort(OutputPort const &orig)
static Logger::LogFunction endlog()
Definition: Logger.hpp:362
WriteStatus
Definition: FlowStatus.hpp:66
virtual bool createConnection(base::InputPortInterface &input_port, ConnPolicy const &policy)
Definition: OutputPort.hpp:309
internal::SharedConnectionBase::shared_ptr getSharedConnection() const


rtt
Author(s): RTT Developers
autogenerated on Fri Oct 25 2019 03:59:34