OpenRTM
1.0.0
|
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 00059 template <class DataType> 00060 void setTimestamp(DataType& data) 00061 { 00062 // set timestamp 00063 coil::TimeValue tm(coil::gettimeofday()); 00064 data.tm.sec = tm.sec(); 00065 data.tm.nsec = tm.usec() * 1000; 00066 } 00067 00068 namespace RTC 00069 { 00105 template <class DataType> 00106 class OutPort 00107 : public OutPortBase 00108 { 00109 public: 00133 OutPort(const char* name, DataType& value) 00134 #if defined(__GNUC__) && (__GNUC__ <= 3 && __GNUC_MINOR__ <= 3) 00135 : OutPortBase(name, ::CORBA_Util::toRepositoryIdOfStruct<DataType>()), 00136 #else 00137 : OutPortBase(name, ::CORBA_Util::toRepositoryId<DataType>()), 00138 #endif 00139 m_value(value), m_onWrite(0), m_onWriteConvert(0) 00140 { 00141 } 00142 00158 virtual ~OutPort(void) 00159 { 00160 } 00161 00203 virtual bool write(DataType& value) 00204 { 00205 RTC_TRACE(("DataType write()")); 00206 00207 if (m_onWrite != NULL) 00208 { 00209 (*m_onWrite)(value); 00210 RTC_TRACE(("OnWrite called")); 00211 } 00212 00213 bool result(true); 00214 std::vector<const char *> disconnect_ids; 00215 { 00216 Guard guard(m_connectorsMutex); 00217 // check number of connectors 00218 size_t conn_size(m_connectors.size()); 00219 if (!(conn_size > 0)) { return false; } 00220 00221 m_status.resize(conn_size); 00222 00223 for (size_t i(0), len(conn_size); i < len; ++i) 00224 { 00225 ReturnCode ret; 00226 if (m_onWriteConvert != NULL) 00227 { 00228 RTC_DEBUG(("m_connectors.OnWriteConvert called")); 00229 ret = m_connectors[i]->write(((*m_onWriteConvert)(value))); 00230 } 00231 else 00232 { 00233 RTC_DEBUG(("m_connectors.write called")); 00234 ret = m_connectors[i]->write(value); 00235 } 00236 m_status[i] = ret; 00237 if (ret == PORT_OK) { continue; } 00238 00239 result = false; 00240 const char* id(m_connectors[i]->profile().id.c_str()); 00241 RTC::ConnectorProfile prof(findConnProfile(id)); 00242 00243 if (ret == CONNECTION_LOST) 00244 { 00245 RTC_WARN(("connection_lost id: %s", id)); 00246 if (m_onConnectionLost != 0) 00247 { 00248 (*m_onConnectionLost)(prof); 00249 } 00250 disconnect_ids.push_back(id); 00251 } 00252 } 00253 } 00254 std::for_each(disconnect_ids.begin(),disconnect_ids.end(), 00255 std::bind1st(std::mem_fun(&PortBase::disconnect),this)); 00256 return result; 00257 } 00258 00280 bool write() 00281 { 00282 return write(m_value); 00283 } 00284 00310 bool operator<<(DataType& value) 00311 { 00312 return write(value); 00313 } 00314 00347 DataPortStatus::Enum getStatus(int index) 00348 { 00349 return m_status[index]; 00350 } 00381 DataPortStatusList getStatusList() 00382 { 00383 return m_status; 00384 } 00385 00415 inline void setOnWrite(OnWrite<DataType>* on_write) 00416 { 00417 m_onWrite = on_write; 00418 } 00419 00456 inline void setOnWriteConvert(OnWriteConvert<DataType>* on_wconvert) 00457 { 00458 m_onWriteConvert = on_wconvert; 00459 } 00460 00461 private: 00462 std::string m_typename; 00470 DataType& m_value; 00471 00479 OnWrite<DataType>* m_onWrite; 00480 00488 OnWriteConvert<DataType>* m_onWriteConvert; 00489 00490 coil::TimeMeasure m_cdrtime; 00491 00492 DataPortStatusList m_status; 00493 }; 00494 }; // namespace RTC 00495 00496 #endif // RTC_OUTPORT_H