Go to the documentation of this file.00001
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
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
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 };
00495
00496 #endif // RTC_OUTPORT_H