OpenRTM  1.0.0
OutPort.h
説明を見る。
1 // -*- C++ -*-
20 #ifndef RTC_OUTPORT_H
21 #define RTC_OUTPORT_H
22 
23 #include <iostream>
24 #include <string>
25 
26 #include <coil/TimeValue.h>
27 #include <coil/Time.h>
28 #include <coil/TimeMeasure.h>
29 #include <coil/OS.h>
30 
31 #include <rtm/RTC.h>
32 #include <rtm/Typename.h>
33 #include <rtm/OutPortBase.h>
34 #include <rtm/CdrBufferBase.h>
35 #include <rtm/PortCallback.h>
36 #include <rtm/OutPortConnector.h>
37 
59 template <class DataType>
60 void setTimestamp(DataType& data)
61 {
62  // set timestamp
64  data.tm.sec = tm.sec();
65  data.tm.nsec = tm.usec() * 1000;
66 }
67 
68 namespace RTC
69 {
105  template <class DataType>
106  class OutPort
107  : public OutPortBase
108  {
109  public:
133  OutPort(const char* name, DataType& value)
134 #if defined(__GNUC__) && (__GNUC__ <= 3 && __GNUC_MINOR__ <= 3)
135  : OutPortBase(name, ::CORBA_Util::toRepositoryIdOfStruct<DataType>()),
136 #else
137  : OutPortBase(name, ::CORBA_Util::toRepositoryId<DataType>()),
138 #endif
139  m_value(value), m_onWrite(0), m_onWriteConvert(0)
140  {
141  }
142 
158  virtual ~OutPort(void)
159  {
160  }
161 
203  virtual bool write(DataType& value)
204  {
205  RTC_TRACE(("DataType write()"));
206 
207  if (m_onWrite != NULL)
208  {
209  (*m_onWrite)(value);
210  RTC_TRACE(("OnWrite called"));
211  }
212 
213  bool result(true);
214  std::vector<const char *> disconnect_ids;
215  {
216  Guard guard(m_connectorsMutex);
217  // check number of connectors
218  size_t conn_size(m_connectors.size());
219  if (!(conn_size > 0)) { return false; }
220 
221  m_status.resize(conn_size);
222 
223  for (size_t i(0), len(conn_size); i < len; ++i)
224  {
225  ReturnCode ret;
226  if (m_onWriteConvert != NULL)
227  {
228  RTC_DEBUG(("m_connectors.OnWriteConvert called"));
229  ret = m_connectors[i]->write(((*m_onWriteConvert)(value)));
230  }
231  else
232  {
233  RTC_DEBUG(("m_connectors.write called"));
234  ret = m_connectors[i]->write(value);
235  }
236  m_status[i] = ret;
237  if (ret == PORT_OK) { continue; }
238 
239  result = false;
240  const char* id(m_connectors[i]->profile().id.c_str());
241  RTC::ConnectorProfile prof(findConnProfile(id));
242 
243  if (ret == CONNECTION_LOST)
244  {
245  RTC_WARN(("connection_lost id: %s", id));
246  if (m_onConnectionLost != 0)
247  {
248  (*m_onConnectionLost)(prof);
249  }
250  disconnect_ids.push_back(id);
251  }
252  }
253  }
254  std::for_each(disconnect_ids.begin(),disconnect_ids.end(),
255  std::bind1st(std::mem_fun(&PortBase::disconnect),this));
256  return result;
257  }
258 
280  bool write()
281  {
282  return write(m_value);
283  }
284 
310  bool operator<<(DataType& value)
311  {
312  return write(value);
313  }
314 
348  {
349  return m_status[index];
350  }
382  {
383  return m_status;
384  }
385 
415  inline void setOnWrite(OnWrite<DataType>* on_write)
416  {
417  m_onWrite = on_write;
418  }
419 
456  inline void setOnWriteConvert(OnWriteConvert<DataType>* on_wconvert)
457  {
458  m_onWriteConvert = on_wconvert;
459  }
460 
461  private:
462  std::string m_typename;
470  DataType& m_value;
471 
479  OnWrite<DataType>* m_onWrite;
480 
488  OnWriteConvert<DataType>* m_onWriteConvert;
489 
490  coil::TimeMeasure m_cdrtime;
491 
492  DataPortStatusList m_status;
493  };
494 }; // namespace RTC
495 
496 #endif // RTC_OUTPORT_H