Orocos Real-Time Toolkit  2.8.3
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  friend class internal::ConnInputEndpoint<T>;
73 
74  bool do_write(typename base::ChannelElement<T>::param_t sample, const internal::ConnectionManager::ChannelDescriptor& descriptor)
75  {
77  = boost::static_pointer_cast< base::ChannelElement<T> >(descriptor.get<1>());
78  if (output->write(sample))
79  return false;
80  else
81  {
82  log(Error) << "A channel of port " << getName() << " has been invalidated during write(), it will be removed" << endlog();
83  return true;
84  }
85  }
86 
87  bool do_init(typename base::ChannelElement<T>::param_t sample, const internal::ConnectionManager::ChannelDescriptor& descriptor)
88  {
90  = boost::static_pointer_cast< base::ChannelElement<T> >(descriptor.get<1>());
91  if (output->data_sample(sample))
92  return false;
93  else
94  {
95  log(Error) << "A channel of port " << getName() << " has been invalidated during setDataSample(), it will be removed" << endlog();
96  return true;
97  }
98  }
99 
100  virtual bool connectionAdded( base::ChannelElementBase::shared_ptr channel_input, ConnPolicy const& policy ) {
101  // Initialize the new channel with last written data if requested
102  // (and available)
103 
104  // This this the input channel element of the whole connection
105  typename base::ChannelElement<T>::shared_ptr channel_el_input =
106  static_cast< base::ChannelElement<T>* >(channel_input.get());
107 
108  if (has_initial_sample)
109  {
110  T const& initial_sample = sample->Get();
111  if ( channel_el_input->data_sample(initial_sample) ) {
112  if ( has_last_written_value && policy.init )
113  return channel_el_input->write(initial_sample);
114  return true;
115  } else {
116  Logger::In in("OutputPort");
117  log(Error) << "Failed to pass data sample to data channel. Aborting connection."<<endlog();
118  return false;
119  }
120  }
121  // even if we're not written, test the connection with a default sample.
122  return channel_el_input->data_sample( T() );
123  }
124 
126  bool has_last_written_value;
128  // data_sample or by calling write() with keeps_next_written_value or
129  // keeps_last_written_value to true
130  bool has_initial_sample;
132  // This is used to initialize connections with a known sample
133  bool keeps_next_written_value;
135  // This is used to allow the use of the 'init' connection policy option
136  bool keeps_last_written_value;
138 
145  OutputPort( OutputPort const& orig );
146  OutputPort& operator=(OutputPort const& orig);
147 
148  public:
165  OutputPort(std::string const& name = "unnamed", bool keep_last_written_value = true)
166  : base::OutputPortInterface(name)
167  , has_last_written_value(false)
168  , has_initial_sample(false)
169  , keeps_next_written_value(false)
170  , keeps_last_written_value(false)
171  , sample( new base::DataObject<T>() )
172  {
173  if (keep_last_written_value)
174  keepLastWrittenValue(true);
175  }
176 
177  void keepNextWrittenValue(bool keep)
178  {
179  keeps_next_written_value = keep;
180  }
181 
182  void keepLastWrittenValue(bool keep)
183  {
184  keeps_last_written_value = keep;
185  }
186 
187  bool keepsLastWrittenValue() const { return keeps_last_written_value; }
188 
195  {
196  return sample->Get();
197  }
198 
205  bool getLastWrittenValue(T& sample) const
206  {
207  if (has_last_written_value)
208  {
209  this->sample->Get(sample);
210  return true;
211  }
212  return false;
213  }
214 
216  {
217  // we create this on the fly.
218  return new internal::DataObjectDataSource<T>( sample );
219  }
220 
230  void setDataSample(const T& sample)
231  {
232  this->sample->Set(sample);
233  has_initial_sample = true;
234  has_last_written_value = false;
235 
236  cmanager.delete_if( boost::bind(
237  &OutputPort<T>::do_init, this, boost::ref(sample), _1 )
238  );
239  }
240 
245  void write(const T& sample)
246  {
247  if (keeps_last_written_value || keeps_next_written_value)
248  {
249  keeps_next_written_value = false;
250  has_initial_sample = true;
251  this->sample->Set(sample);
252  }
253  has_last_written_value = keeps_last_written_value;
254 
255  cmanager.delete_if( boost::bind(
256  &OutputPort<T>::do_write, this, boost::ref(sample), _1 )
257  );
258  }
259 
261  {
263  boost::dynamic_pointer_cast< internal::AssignableDataSource<T> >(source);
264  if (ds)
265  write(ds->rvalue());
266  else
267  {
269  boost::dynamic_pointer_cast< internal::DataSource<T> >(source);
270  if (ds)
271  write(ds->get());
272  else
273  log(Error) << "trying to write from an incompatible data source" << endlog();
274  }
275  }
276 
278  virtual const types::TypeInfo* getTypeInfo() const
280 
284  virtual base::PortInterface* clone() const
285  { return new OutputPort<T>(this->getName()); }
286 
293  { return new InputPort<T>(this->getName()); }
294 
296 
299  virtual bool createConnection(base::InputPortInterface& input_port, ConnPolicy const& policy)
300  {
301  return internal::ConnFactory::createConnection(*this, input_port, policy);
302  }
303 
304  virtual bool createStream(ConnPolicy const& policy)
305  {
306  return internal::ConnFactory::createStream(*this, policy);
307  }
308 
309 #ifndef ORO_DISABLE_PORT_DATA_SCRIPTING
310 
315  {
317  // Force resolution on the overloaded write method
318  typedef void (OutputPort<T>::*WriteSample)(T const&);
319  WriteSample write_m = &OutputPort::write;
320  typedef T (OutputPort<T>::*LastSample)() const;
321  LastSample last_m = &OutputPort::getLastWrittenValue;
322  object->addSynchronousOperation("write", write_m, this).doc("Writes a sample on the port.").arg("sample", "");
323  object->addSynchronousOperation("last", last_m, this).doc("Returns last written value to this port.");
324  return object;
325  }
326 #endif
327  };
328 
329 }
330 
331 #endif
332 
void setDataSample(const T &sample)
Provides this port a data sample that is representative for the samples being used in write()...
Definition: OutputPort.hpp:230
DataSource is a base class representing a generic way to read data of type T.
Definition: DataSource.hpp:94
The base class of the InputPort.
boost::call_traits< T >::param_type param_t
boost::intrusive_ptr< ChannelElement< T > > shared_ptr
virtual result_t get() const =0
Return the data as type T.
This is a channel element that represents the input endpoint of a connection, i.e.
boost::shared_ptr< DataObjectInterface< T > > shared_ptr
Used for shared_ptr management.
OutputPort(std::string const &name="unnamed", bool keep_last_written_value=true)
Creates a named Output port.
Definition: OutputPort.hpp:165
virtual const types::TypeInfo * getTypeInfo() const
Returns the types::TypeInfo object for the port&#39;s type.
Definition: OutputPort.hpp:278
bool getLastWrittenValue(T &sample) const
Reads the last written value written to this port, in case it is kept by this port, otherwise, returns false.
Definition: OutputPort.hpp:205
void keepLastWrittenValue(bool keep)
Change the setting for keeping the last written value.
Definition: OutputPort.hpp:182
const std::string & getName() const
Get the name of this Port.
virtual base::PortInterface * clone() const
Create a clone of this port with the same name.
Definition: OutputPort.hpp:284
A component&#39;s data input port.
Definition: InputPort.hpp:63
internal::ConnectionManager cmanager
virtual bool write(param_t sample)
Writes a new sample on this connection.
A connection policy object describes how a given connection should behave.
Definition: ConnPolicy.hpp:92
The base class of each OutputPort.
We can&#39;t use typedefs since C++ doesn&#39;t allow it for templated classes without specifying all the tem...
virtual Service * createPortObject()
Create accessor Object for this Port, for addition to a TaskContext Object interface.
Definition: OutputPort.hpp:314
This class allows storage and retrieval of operations, ports, attributes and properties provided by a...
Definition: Service.hpp:93
A typed version of ChannelElementBase.
static const types::TypeInfo * getTypeInfo()
Return the typeinfo object.
virtual Service * createPortObject()
Create accessor Object for this Port, for addition to a TaskContext Object interface.
virtual const_reference_t rvalue() const =0
Get a const reference to the value of this DataSource.
virtual bool createStream(ConnPolicy const &policy)
Creates a data stream from or to this port using connection-less transports.
Definition: OutputPort.hpp:304
static bool createStream(OutputPort< T > &output_port, ConnPolicy const &policy)
Creates, attaches and checks an outbound stream to an Output port.
bool createConnection(InputPortInterface &sink)
Connects this write port to the given read port, using as policy the default policy of the sink port...
A class for representing a user type, and which can build instances of that type. ...
Definition: TypeInfo.hpp:66
bool keepsLastWrittenValue() const
Returns true if this port records the last written value.
Definition: OutputPort.hpp:187
boost::tuple< boost::shared_ptr< ConnID >, base::ChannelElementBase::shared_ptr, ConnPolicy > ChannelDescriptor
A Channel (= connection) is described by an opaque ConnID object, the first element of the channel an...
void write(const T &sample)
Writes a new sample to all receivers (if any).
Definition: OutputPort.hpp:245
boost::intrusive_ptr< ChannelElementBase > shared_ptr
boost::intrusive_ptr< DataSource< T > > shared_ptr
Definition: DataSource.hpp:115
boost::intrusive_ptr< AssignableDataSource< T > > shared_ptr
Use this type to store a pointer to an AssignableDataSource.
Definition: DataSource.hpp:198
bool init
If true, one should initialize the connection&#39;s value with the last value written on the writer port...
Definition: ConnPolicy.hpp:150
This object represents the default thread-safe data object implementation used by Orocos objects...
Definition: DataObject.hpp:65
virtual void Get(DataType &pull) const =0
Get a copy of the Data of this data object.
A DataSource which has set() methods.
Definition: DataSource.hpp:184
Notify the Logger in which &#39;module&#39; the message occured.
Definition: Logger.hpp:159
void keepNextWrittenValue(bool keep)
Definition: OutputPort.hpp:177
void write(base::DataSourceBase::shared_ptr source)
Write this port using the value stored in source.
Definition: OutputPort.hpp:260
A component&#39;s data output port.
Definition: OutputPort.hpp:70
boost::intrusive_ptr< DataSourceBase > shared_ptr
Use this type to store a pointer to a DataSourceBase.
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:51
The base class of every data flow port.
T getLastWrittenValue() const
Returns the last written value written to this port, in case it is kept by this port, otherwise, returns a default T().
Definition: OutputPort.hpp:194
virtual base::DataSourceBase::shared_ptr getDataSource() const
Returns a Data source that stores the last written value, or a null pointer if this port does not kee...
Definition: OutputPort.hpp:215
static bool createConnection(OutputPort< T > &output_port, base::InputPortInterface &input_port, ConnPolicy const &policy)
Creates a connection from a local output_port to a local or remote input_port.
A DataSource which is used to read a DataObject.
virtual base::PortInterface * antiClone() const
Create the anti-clone (inverse port) of this port with the same name A port for reading will return a...
Definition: OutputPort.hpp:292
virtual bool data_sample(param_t sample)
Provides a data sample to initialize this connection.
virtual bool createConnection(base::InputPortInterface &input_port, ConnPolicy const &policy)
Connects this write port to the given read port, using the given policy.
Definition: OutputPort.hpp:299