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 {
00218 template <class DataType>
00219 class OutPort
00220 : public OutPortBase
00221 {
00222 public:
00246 OutPort(const char* name, DataType& value)
00247 #if defined(__GNUC__) && (__GNUC__ <= 3 && __GNUC_MINOR__ <= 3)
00248 : OutPortBase(name, ::CORBA_Util::toRepositoryIdOfStruct<DataType>()),
00249 #else
00250 : OutPortBase(name, ::CORBA_Util::toRepositoryId<DataType>()),
00251 #endif
00252 m_value(value), m_onWrite(0), m_onWriteConvert(0)
00253 {
00254 }
00255
00271 virtual ~OutPort(void)
00272 {
00273 }
00274
00316 virtual bool write(DataType& value)
00317 {
00318 RTC_TRACE(("DataType write()"));
00319
00320 if (m_onWrite != NULL)
00321 {
00322 (*m_onWrite)(value);
00323 RTC_TRACE(("OnWrite called"));
00324 }
00325
00326 bool result(true);
00327 std::vector<const char *> disconnect_ids;
00328 {
00329 Guard guard(m_connectorsMutex);
00330
00331 size_t conn_size(m_connectors.size());
00332 if (!(conn_size > 0)) { return false; }
00333
00334 m_status.resize(conn_size);
00335
00336 for (size_t i(0), len(conn_size); i < len; ++i)
00337 {
00338 ReturnCode ret;
00339 if (m_onWriteConvert != NULL)
00340 {
00341 RTC_DEBUG(("m_connectors.OnWriteConvert called"));
00342 ret = m_connectors[i]->write(((*m_onWriteConvert)(value)));
00343 }
00344 else
00345 {
00346 RTC_DEBUG(("m_connectors.write called"));
00347 ret = m_connectors[i]->write(value);
00348 }
00349 m_status[i] = ret;
00350 if (ret == PORT_OK) { continue; }
00351
00352 result = false;
00353 const char* id(m_connectors[i]->profile().id.c_str());
00354 RTC::ConnectorProfile prof(findConnProfile(id));
00355
00356 if (ret == CONNECTION_LOST)
00357 {
00358 RTC_WARN(("connection_lost id: %s", id));
00359 if (m_onConnectionLost != 0)
00360 {
00361 (*m_onConnectionLost)(prof);
00362 }
00363 disconnect_ids.push_back(id);
00364 }
00365 }
00366 }
00367 std::for_each(disconnect_ids.begin(),disconnect_ids.end(),
00368 std::bind1st(std::mem_fun(&PortBase::disconnect),this));
00369 return result;
00370 }
00371
00393 bool write()
00394 {
00395 return write(m_value);
00396 }
00397
00423 bool operator<<(DataType& value)
00424 {
00425 return write(value);
00426 }
00427
00460 DataPortStatus::Enum getStatus(int index)
00461 {
00462 return m_status[index];
00463 }
00494 DataPortStatusList getStatusList()
00495 {
00496 return m_status;
00497 }
00498
00528 inline void setOnWrite(OnWrite<DataType>* on_write)
00529 {
00530 m_onWrite = on_write;
00531 }
00532
00569 inline void setOnWriteConvert(OnWriteConvert<DataType>* on_wconvert)
00570 {
00571 m_onWriteConvert = on_wconvert;
00572 }
00573
00574 private:
00575 std::string m_typename;
00583 DataType& m_value;
00584
00592 OnWrite<DataType>* m_onWrite;
00593
00601 OnWriteConvert<DataType>* m_onWriteConvert;
00602
00603 coil::TimeMeasure m_cdrtime;
00604
00605 DataPortStatusList m_status;
00606 };
00607 };
00608
00609 #endif // RTC_OUTPORT_H