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
00038 template <class DataType>
00039 void setTimestamp(DataType& data)
00040 {
00041
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 bool result(true);
00302 std::vector<const char *> disconnect_ids;
00303 {
00304 Guard guard(m_connectorsMutex);
00305
00306 size_t conn_size(m_connectors.size());
00307 if (!(conn_size > 0)) { return false; }
00308
00309 m_status.resize(conn_size);
00310
00311 for (size_t i(0), len(conn_size); i < len; ++i)
00312 {
00313 ReturnCode ret;
00314 if (m_onWriteConvert != NULL)
00315 {
00316 RTC_DEBUG(("m_connectors.OnWriteConvert called"));
00317 ret = m_connectors[i]->write(((*m_onWriteConvert)(value)));
00318 }
00319 else
00320 {
00321 RTC_DEBUG(("m_connectors.write called"));
00322 ret = m_connectors[i]->write(value);
00323 }
00324 m_status[i] = ret;
00325 if (ret == PORT_OK) { continue; }
00326
00327 result = false;
00328 const char* id(m_connectors[i]->profile().id.c_str());
00329 RTC::ConnectorProfile prof(findConnProfile(id));
00330
00331 if (ret == CONNECTION_LOST)
00332 {
00333 RTC_WARN(("connection_lost id: %s", id));
00334 if (m_onConnectionLost != 0)
00335 {
00336 (*m_onConnectionLost)(prof);
00337 }
00338 disconnect_ids.push_back(id);
00339 }
00340 }
00341 }
00342 std::for_each(disconnect_ids.begin(),disconnect_ids.end(),
00343 std::bind1st(std::mem_fun(&PortBase::disconnect),this));
00344 return result;
00345 }
00346
00368 bool write()
00369 {
00370 return write(m_value);
00371 }
00372
00398 bool operator<<(DataType& value)
00399 {
00400 return write(value);
00401 }
00402
00435 DataPortStatus::Enum getStatus(int index)
00436 {
00437 return m_status[index];
00438 }
00469 DataPortStatusList getStatusList()
00470 {
00471 return m_status;
00472 }
00473
00503 inline void setOnWrite(OnWrite<DataType>* on_write)
00504 {
00505 m_onWrite = on_write;
00506 }
00507
00544 inline void setOnWriteConvert(OnWriteConvert<DataType>* on_wconvert)
00545 {
00546 m_onWriteConvert = on_wconvert;
00547 }
00548
00549 private:
00550 std::string m_typename;
00558 DataType& m_value;
00559
00567 OnWrite<DataType>* m_onWrite;
00568
00576 OnWriteConvert<DataType>* m_onWriteConvert;
00577
00578 coil::TimeMeasure m_cdrtime;
00579
00580 DataPortStatusList m_status;
00581 };
00582 };
00583
00584 #endif // RTC_OUTPORT_H