00001 // -*- C++ -*- 00020 #ifndef RTC_OUTPORT_H 00021 #define RTC_OUTPORT_H 00022 00023 #include <iostream> 00024 #include <string> 00025 00026 #include <coil/TimeValue.h> 00027 #include <coil/Time.h> 00028 #include <coil/TimeMeasure.h> 00029 #include <coil/OS.h> 00030 00031 #include <rtm/RTC.h> 00032 #include <rtm/Typename.h> 00033 #include <rtm/OutPortBase.h> 00034 #include <rtm/CdrBufferBase.h> 00035 #include <rtm/PortCallback.h> 00036 #include <rtm/OutPortConnector.h> 00037 00038 template <class DataType> 00039 void setTimestamp(DataType& data) 00040 { 00041 // set timestamp 00042 coil::TimeValue tm(coil::gettimeofday()); 00043 data.tm.sec = tm.sec(); 00044 data.tm.nsec = tm.usec() * 1000; 00045 } 00046 00047 namespace RTC 00048 { 00197 template <class DataType> 00198 class OutPort 00199 : public OutPortBase 00200 { 00201 public: 00225 OutPort(const char* name, DataType& value) 00226 : OutPortBase(name, toTypename<DataType>()), m_value(value), 00227 m_onWrite(0), m_onWriteConvert(0) 00228 { 00229 } 00230 00246 virtual ~OutPort(void) 00247 { 00248 } 00249 00291 virtual bool write(DataType& value) 00292 { 00293 RTC_TRACE(("DataType write()")) 00294 00295 if (m_onWrite != NULL) 00296 { 00297 (*m_onWrite)(value); 00298 RTC_TRACE(("OnWrite called")) 00299 } 00300 00301 // check number of connectors 00302 size_t conn_size(m_connectors.size()); 00303 if (!(conn_size > 0)) { return false; } 00304 00305 bool result(true); 00306 m_status.resize(conn_size); 00307 00308 for (size_t i(0), len(conn_size); i < len; ++i) 00309 { 00310 ReturnCode ret; 00311 if (m_onWriteConvert != NULL) 00312 { 00313 RTC_DEBUG(("m_connectors.OnWriteConvert called")); 00314 ret = m_connectors[i]->write(((*m_onWriteConvert)(value))); 00315 } 00316 else 00317 { 00318 RTC_DEBUG(("m_connectors.write called")); 00319 ret = m_connectors[i]->write(value); 00320 } 00321 m_status[i] = ret; 00322 if (ret == PORT_OK) { continue; } 00323 00324 result = false; 00325 const char* id(m_connectors[i]->profile().id.c_str()); 00326 RTC::ConnectorProfile prof(findConnProfile(id)); 00327 00328 if (ret == CONNECTION_LOST) 00329 { 00330 RTC_WARN(("connection_lost id: %s", m_connectors[i]->profile().id.c_str())); 00331 if (m_onConnectionLost != 0) 00332 { 00333 (*m_onConnectionLost)(prof); 00334 } 00335 disconnect(m_connectors[i]->id()); 00336 } 00337 } 00338 return result; 00339 } 00340 00362 bool write() 00363 { 00364 return write(m_value); 00365 } 00366 00392 bool operator<<(DataType& value) 00393 { 00394 return write(value); 00395 } 00396 00429 DataPortStatus::Enum getStatus(int index) 00430 { 00431 return m_status[index]; 00432 } 00463 DataPortStatusList getStatusList() 00464 { 00465 return m_status; 00466 } 00467 00497 inline void setOnWrite(OnWrite<DataType>* on_write) 00498 { 00499 m_onWrite = on_write; 00500 } 00501 00538 inline void setOnWriteConvert(OnWriteConvert<DataType>* on_wconvert) 00539 { 00540 m_onWriteConvert = on_wconvert; 00541 } 00542 00543 private: 00544 std::string m_typename; 00552 DataType& m_value; 00553 00561 OnWrite<DataType>* m_onWrite; 00562 00570 OnWriteConvert<DataType>* m_onWriteConvert; 00571 00572 coil::TimeMeasure m_cdrtime; 00573 00574 DataPortStatusList m_status; 00575 }; 00576 }; // namespace RTC 00577 00578 #endif // RTC_OUTPORT_H