00001
00020 #ifndef RTC_OUTPORT_H
00021 #define RTC_OUTPORT_H
00022
00023 #include <functional>
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 addProperty("dataport.data_value", m_value);
00142 m_propValueIndex = NVUtil::find_index(m_profile.properties, "dataport.data_value");
00143 }
00144
00160 virtual ~OutPort(void)
00161 {
00162 }
00163
00205 virtual bool write(DataType& value)
00206 {
00207 RTC_TRACE(("DataType write()"));
00208
00209 if (m_onWrite != NULL)
00210 {
00211 (*m_onWrite)(value);
00212 RTC_TRACE(("OnWrite called"));
00213 }
00214 m_profile.properties[m_propValueIndex].value <<= value;
00215
00216 bool result(true);
00217 std::vector<const char *> disconnect_ids;
00218 {
00219 Guard guard(m_connectorsMutex);
00220
00221 size_t conn_size(m_connectors.size());
00222 if (!(conn_size > 0)) { return false; }
00223
00224 m_status.resize(conn_size);
00225
00226 for (size_t i(0), len(conn_size); i < len; ++i)
00227 {
00228 ReturnCode ret;
00229 if (m_onWriteConvert != NULL)
00230 {
00231 RTC_DEBUG(("m_connectors.OnWriteConvert called"));
00232 ret = m_connectors[i]->write(((*m_onWriteConvert)(value)));
00233 }
00234 else
00235 {
00236 RTC_DEBUG(("m_connectors.write called"));
00237 ret = m_connectors[i]->write(value);
00238 }
00239 m_status[i] = ret;
00240 if (ret == PORT_OK) { continue; }
00241
00242 result = false;
00243 const char* id(m_connectors[i]->profile().id.c_str());
00244
00245 if (ret == CONNECTION_LOST)
00246 {
00247 RTC_WARN(("connection_lost id: %s", id));
00248 if (m_onConnectionLost != 0)
00249 {
00250 RTC::ConnectorProfile prof(findConnProfile(id));
00251 (*m_onConnectionLost)(prof);
00252 }
00253 disconnect_ids.push_back(id);
00254 }
00255 }
00256 }
00257 std::for_each(disconnect_ids.begin(),disconnect_ids.end(),
00258 std::bind1st(std::mem_fun(&PortBase::disconnect),this));
00259 return result;
00260 }
00261
00283 bool write()
00284 {
00285 return write(m_value);
00286 }
00287
00313 bool operator<<(DataType& value)
00314 {
00315 return write(value);
00316 }
00317
00350 DataPortStatus::Enum getStatus(int index)
00351 {
00352 return m_status[index];
00353 }
00384 DataPortStatusList getStatusList()
00385 {
00386 return m_status;
00387 }
00388
00418 inline void setOnWrite(OnWrite<DataType>* on_write)
00419 {
00420 m_onWrite = on_write;
00421 }
00422
00459 inline void setOnWriteConvert(OnWriteConvert<DataType>* on_wconvert)
00460 {
00461 m_onWriteConvert = on_wconvert;
00462 }
00463
00464 private:
00465 std::string m_typename;
00473 DataType& m_value;
00474
00482 OnWrite<DataType>* m_onWrite;
00483
00491 OnWriteConvert<DataType>* m_onWriteConvert;
00492
00493 coil::TimeMeasure m_cdrtime;
00494
00495 DataPortStatusList m_status;
00496
00497 CORBA::Long m_propValueIndex;
00498 };
00499 };
00500
00501 #endif // RTC_OUTPORT_H