OpenRTM-aist  1.2.1
InPort.h
Go to the documentation of this file.
1 // -*- C++ -*-
20 #ifndef RTC_INPORT_H
21 #define RTC_INPORT_H
22 
23 #include <string>
24 #include <vector>
25 #include <iostream>
26 
27 #include <coil/TimeValue.h>
28 #include <coil/Time.h>
29 #include <coil/OS.h>
30 #include <coil/Mutex.h>
31 #include <coil/Guard.h>
32 
33 #include <rtm/RTC.h>
34 #include <rtm/Typename.h>
35 #include <rtm/InPortBase.h>
36 #include <rtm/CdrBufferBase.h>
37 #include <rtm/PortCallback.h>
38 #include <rtm/InPortConnector.h>
39 #include <rtm/Timestamp.h>
40 #include <rtm/DirectInPortBase.h>
41 
42 
43 
44 namespace RTC
45 {
94  template <class DataType>
95  class InPort
96  : public InPortBase, DirectInPortBase<DataType>
97  {
98  public:
151  InPort(const char* name, DataType& value,
152  int bufsize=64,
153  bool read_block = false, bool write_block = false,
154  int read_timeout = 0, int write_timeout = 0)
155 #if defined(__GNUC__) && (__GNUC__ <= 3 && __GNUC_MINOR__ <= 3)
156  : InPortBase(name, ::CORBA_Util::toRepositoryIdOfStruct<DataType>()),
157 #else
158  : InPortBase(name, ::CORBA_Util::toRepositoryId<DataType>()),
159 #endif
161  m_name(name), m_value(value),
162  m_OnRead(NULL), m_OnReadConvert(NULL),
163  m_status(1), m_directNewData(false)
164  {
166  new Timestamp<DataType>("on_received"));
168  new Timestamp<DataType>("on_read"));
169  m_directport = this;
170  }
171 
187  virtual ~InPort(void){};
188 
208  virtual const char* name()
209  {
210  return m_name.c_str();
211  }
212 
213 
238  virtual bool isNew()
239  {
240  RTC_TRACE(("isNew()"));
241 
242  // In single-buffer mode, all connectors share the same buffer. This
243  // means that we only need to read from the first connector to get data
244  // received by any connector.
245  {
246  Guard gurad(m_valueMutex);
247  if (m_directNewData == true)
248  {
249  RTC_DEBUG(("isNew() returns true because of direct write."));
250  return true;
251  }
252  }
253  size_t r(0);
254  {
255  Guard guard(m_connectorsMutex);
256  if (m_connectors.size() == 0)
257  {
258  RTC_DEBUG(("no connectors"));
259  return false;
260  }
261  r = m_connectors[0]->getBuffer()->readable();
262  }
263 
264  if (r > 0)
265  {
266  RTC_DEBUG(("isNew() = true, readable data: %d", r));
267  return true;
268  }
269 
270  RTC_DEBUG(("isNew() = false, no readable data"));
271  return false;
272  }
273 
297  virtual bool isEmpty()
298  {
299  RTC_TRACE(("isEmpty()"));
300  if (m_directNewData == true) { return false; }
301  size_t r(0);
302 
303  {
304  Guard guard(m_connectorsMutex);
305  if (m_connectors.size() == 0)
306  {
307  RTC_DEBUG(("no connectors"));
308  return true;
309  }
310  // In single-buffer mode, all connectors share the same buffer. This
311  // means that we only need to read from the first connector to get data
312  // received by any connector.
313  r = m_connectors[0]->getBuffer()->readable();
314  }
315 
316  if (r == 0)
317  {
318  RTC_DEBUG(("isEmpty() = true, buffer is empty"));
319  return true;
320  }
321 
322  RTC_DEBUG(("isEmpty() = false, data exists in the buffer"));
323  return false;
324  }
325 
326  virtual void write(const DataType& data)
327  {
328  Guard guard(m_valueMutex);
329  m_value = data;
330  m_directNewData = true;
331  }
332 
407  bool read()
408  {
409  RTC_TRACE(("DataType read()"));
410 
411  if (m_OnRead != NULL)
412  {
413  (*m_OnRead)();
414  RTC_TRACE(("OnRead called"));
415  }
416  // 1) direct connection
417  {
418  Guard guard(m_valueMutex);
419  if (m_directNewData == true)
420  {
421  RTC_DEBUG(("Direct data transfer"));
422  if (m_OnReadConvert != 0)
423  {
424  m_value = (*m_OnReadConvert)(m_value);
425  RTC_DEBUG(("OnReadConvert for direct data called"));
426  return true;
427  }
428  m_directNewData = false;
429  return true;
430  }
431  }
432  // 2) network connection
433  cdrMemoryStream cdr;
434  ReturnCode ret;
435  {
436  Guard guard(m_connectorsMutex);
437  if (m_connectors.size() == 0)
438  {
439  RTC_DEBUG(("no connectors"));
440  return false;
441  }
442 
443 
444  }
445 
446  if (!m_connectors[0]->getDirectData(m_value))
447  {
448  {
449  Guard guard(m_connectorsMutex);
450  // In single-buffer mode, all connectors share the same buffer. This
451  // means that we only need to read from the first connector to get data
452  // received by any connector.
453  ret = m_connectors[0]->read(cdr);
454  }
455  m_status[0] = ret;
456  if (ret == PORT_OK)
457  {
458  Guard guard(m_valueMutex);
459  RTC_DEBUG(("data read succeeded"));
460  m_value <<= cdr;
461  if (m_OnReadConvert != 0)
462  {
463  m_value = (*m_OnReadConvert)(m_value);
464  RTC_DEBUG(("OnReadConvert called"));
465  return true;
466  }
467  return true;
468  }
469  else if (ret == BUFFER_EMPTY)
470  {
471  RTC_WARN(("buffer empty"));
472  return false;
473  }
474  else if (ret == BUFFER_TIMEOUT)
475  {
476  RTC_WARN(("buffer read timeout"));
477  return false;
478  }
479  }
480  else
481  {
482  return true;
483  }
484  RTC_ERROR(("unknown retern value from buffer.read()"));
485  return false;
486  }
487 
488 
511  virtual void update()
512  {
513  this->read();
514  };
515 
536  void operator>>(DataType& rhs)
537  {
538  this->read();
539  rhs = m_value;
540  return;
541  }
542 
576  {
577  return m_status[0];
578  }
610  {
611  return m_status;
612  }
613 
635  inline void setOnRead(OnRead<DataType>* on_read)
636  {
637  m_OnRead = on_read;
638  }
639 
663  inline void setOnReadConvert(OnReadConvert<DataType>* on_rconvert)
664  {
665  m_OnReadConvert = on_rconvert;
666  }
667 
668  private:
669  std::string m_typename;
677  std::string m_name;
678 
686  DataType& m_value;
687  mutable coil::Mutex m_valueMutex;
688 
696  OnRead<DataType>* m_OnRead;
697 
705  OnReadConvert<DataType>* m_OnReadConvert;
706 
714  DataPortStatusList m_status;
715 
723  bool m_directNewData;
724 
725  };
726 }; // End of namesepace RTM
727 
728 #endif // RTC_INPORT_H
virtual void write(const DataType &data)
Definition: InPort.h:326
#define RTC_ERROR(fmt)
Error log output macro.
Definition: SystemLogger.h:500
#define DATAPORTSTATUS_ENUM
Importing RTC::DataPortStatus macro.
Definition: DataPortStatus.h:233
RT-Component.
#define RTC_TRACE(fmt)
Trace level log output macro.
Definition: SystemLogger.h:588
Mutex class.
Definition: Mutex.h:40
coil::Mutex m_connectorsMutex
Definition: PortBase.h:2110
Definition: ConnectorListener.h:146
virtual ~InPort(void)
Destructor.
Definition: InPort.h:187
DATAPORTSTATUS_ENUM InPort(const char *name, DataType &value, int bufsize=64, bool read_block=false, bool write_block=false, int read_timeout=0, int write_timeout=0)
A constructor.
Definition: InPort.h:151
Definition: Timestamp.h:26
virtual const char * name()
Get port name.
Definition: InPort.h:208
PortCallback class.
Typename function.
#define RTC_WARN(fmt)
Warning log output macro.
Definition: SystemLogger.h:522
virtual bool isEmpty()
Check whether the data is newest.
Definition: InPort.h:297
Data convert callback abstract class on read()
Definition: PortCallback.h:385
void setOnReadConvert(OnReadConvert< DataType > *on_rconvert)
Set callback when data is readout to the InPort buffer.
Definition: InPort.h:663
std::vector< DataPortStatus::Enum > DataPortStatusList
Definition: DataPortStatus.h:206
Definition: DirectInPortBase.h:48
#define RTC_DEBUG(fmt)
Debug level log output macro.
Definition: SystemLogger.h:566
InPortConnector base class.
Guard template class.
virtual void update()
Read the newly value to type-T variable which is bound to InPort&#39;s buffer.
Definition: InPort.h:511
InPortBase(const char *name, const char *data_type)
Constructor.
DirectPortBase * m_directport
Definition: PortBase.h:2235
Port for InPort.
Definition: InPortBase.h:74
Definition: ConnectorListener.h:144
Definition: DataPortStatus.h:145
RTC::Port implementation for InPort.
DirectInPortBase class.
InPort template class.
Definition: InPort.h:95
virtual bool isNew()
Check whether the data is newest.
Definition: InPort.h:238
DataPortStatus::Enum getStatus(int index)
Getting specified connector&#39;s writing status.
Definition: InPort.h:575
RTComponent header.
void setOnRead(OnRead< DataType > *on_read)
Set callback when data is read from the InPort buffer.
Definition: InPort.h:635
Timestamp listener class.
DataPortStatusList getStatusList()
Getting specified connector&#39;s writing status list.
Definition: InPort.h:609
Definition: DataPortStatus.h:150
void operator>>(DataType &rhs)
Read the newly value data in InPort to type-T variable.
Definition: InPort.h:536
void addConnectorDataListener(ConnectorDataListenerType listener_type, ConnectorDataListener *listener, bool autoclean=true)
Adding BufferDataListener type listener.
Enum
DataPortStatus return codes.
Definition: DataPortStatus.h:143
ConnectorList m_connectors
Connection list.
Definition: InPortBase.h:880
bool read()
Readout the value from DataPort.
Definition: InPort.h:407
Callback abstract class on read()
Definition: PortCallback.h:323
Definition: DataPortStatus.h:149