OutPortBase.cpp
Go to the documentation of this file.
1 // -*- C++ -*-
20 #include <iostream>
21 #include <algorithm>
22 #include <functional>
23 #include <iterator>
24 #include <coil/stringutil.h>
25 
26 #include <rtm/ConnectorBase.h>
29 #include <rtm/OutPortBase.h>
30 #include <rtm/PublisherBase.h>
31 
32 
33 namespace RTC
34 {
43  {
45  : m_factory(OutPortProviderFactory::instance())
46  {
47  }
49  {
51  }
53  };
54 
63  {
65  {
66  }
68  {
69  delete c;
70  }
71  };
72 
73 
81  OutPortBase::OutPortBase(const char* name, const char* data_type)
82  : PortBase(name), m_littleEndian(true)
83  {
84  RTC_DEBUG(("Port name: %s", name));
85 
86  RTC_DEBUG(("setting port.port_type: DataOutPort"));
87  addProperty("port.port_type", "DataOutPort");
88 
89  RTC_DEBUG(("setting dataport.data_type: %s", data_type));
90  addProperty("dataport.data_type", data_type);
91 
92  // publisher list
94  std::string pubs = coil::flatten(factory.getIdentifiers());
95 
96  // blank characters are deleted for RTSE's bug
97  coil::eraseBlank(pubs);
98  RTC_DEBUG(("available subscription_type: %s", pubs.c_str()));
99  addProperty("dataport.subscription_type", pubs.c_str());
100 
101  };
102 
111  {
112  RTC_TRACE(("~OutPortBase()"));
113  // connector のクリーンナップ std::for_each(m_connectors.begin(), m_connectors.end(), connector_cleanup()); } /*! * @if jp * @brief プロパティの初期化 * @else * @brief Initializing properties * @endif */ void OutPortBase::init(coil::Properties& prop) { RTC_TRACE(("init()")); RTC_PARANOID(("given properties:")); RTC_DEBUG_STR((prop)); m_properties << prop; RTC_PARANOID(("updated properties:")); RTC_DEBUG_STR((m_properties)); configure(); initConsumers(); initProviders(); int num(-1); if (!coil::stringTo(num, m_properties.getProperty("connection_limit","-1").c_str())) { RTC_ERROR(("invalid connection_limit value: %s", m_properties.getProperty("connection_limit").c_str())); } setConnectionLimit(num); } /*! * @if jp * @brief プロパティを取得する * @else * @brief Get properties * @endif */ coil::Properties& OutPortBase::properties() { RTC_TRACE(("properties()")); return m_properties; } /*! * @if jp * @brief Connector を取得 * @else * @brief Connector list * @endif */ const std::vector<OutPortConnector*>& OutPortBase::connectors() { RTC_TRACE(("connectors(): size = %d", m_connectors.size())); return m_connectors; } /*! * @if jp * @brief ConnectorProfile を取得 * @else * @brief ConnectorProfile list * @endif */ ConnectorInfoList OutPortBase::getConnectorProfiles() { RTC_TRACE(("getConnectorProfiles(): size = %d", m_connectors.size())); ConnectorInfoList profs; for (int i(0), len(m_connectors.size()); i < len; ++i) { profs.push_back(m_connectors[i]->profile()); } return profs; } /*! * @if jp * @brief ConnectorId を取得 * @else * @brief ConnectorId list * @endif */ coil::vstring OutPortBase::getConnectorIds() { coil::vstring ids; for (int i(0), len(m_connectors.size()); i < len; ++i) { ids.push_back(m_connectors[i]->id()); } RTC_TRACE(("getConnectorIds(): %s", coil::flatten(ids).c_str())); return ids; } /*! * @if jp * @brief Connectorの名前を取得 * @else * @brief Connector name list * @endif */ coil::vstring OutPortBase::getConnectorNames() { coil::vstring names; for (int i(0), len(m_connectors.size()); i < len; ++i) { names.push_back(m_connectors[i]->name()); } RTC_TRACE(("getConnectorNames(): %s", coil::flatten(names).c_str())); return names; } /*! * @if jp * @brief ConnectorをIDで取得 * @else * @brief Getting Connector by ID * @endif */ OutPortConnector* OutPortBase::getConnectorById(const char* id) { RTC_TRACE(("getConnectorById(id = %s)", id)); std::string sid(id); for (int i(0), len(m_connectors.size()); i < len; ++i) { if (sid == m_connectors[i]->id()) { return m_connectors[i]; } } RTC_WARN(("ConnectorProfile with the id(%s) not found.", id)); return 0; } /*! * @if jp * @brief Connectorを名前で取得 * @else * @brief Getting ConnectorProfile by name * @endif */ OutPortConnector* OutPortBase::getConnectorByName(const char* name) { RTC_TRACE(("getConnectorByName(name = %s)", name)); std::string sname(name); for (int i(0), len(m_connectors.size()); i < len; ++i) { if (sname == m_connectors[i]->name()) { return m_connectors[i]; } } RTC_WARN(("ConnectorProfile with the name(%s) not found.", name)); return 0; } /*! * @if jp * @brief ConnectorProfileをIDで取得 * @else * @brief Getting ConnectorProfile by name * @endif */ bool OutPortBase::getConnectorProfileById(const char* id, ConnectorInfo& prof) { RTC_TRACE(("getConnectorProfileById(id = %s)", id)); OutPortConnector* conn(getConnectorById(id)); if (conn == 0) { return false; } prof = conn->profile(); return true; } /*! * @if jp * @brief ConnectorProfileを名前で取得 * @else * @brief Getting ConnectorProfile by name * @endif */ bool OutPortBase::getConnectorProfileByName(const char* name, ConnectorInfo& prof) { RTC_TRACE(("getConnectorProfileByName(name = %s)", name)); OutPortConnector* conn(getConnectorByName(name)); if (conn == 0) { return false; } prof = conn->profile(); return true; } /*! * @if jp * @brief OutPortを activates する * @else * @brief Activate all Port interfaces * @endif */ void OutPortBase::activateInterfaces() { RTC_TRACE(("activateInterfaces()")); for (int i(0), len(m_connectors.size()); i < len; ++i) { m_connectors[i]->activate(); } } /*! * @if jp * @brief 全ての Port のインターフェースを deactivates する * @else * @brief Deactivate all Port interfaces * @endif */ void OutPortBase::deactivateInterfaces() { RTC_TRACE(("deactivateInterfaces()")); for (int i(0), len(m_connectors.size()); i < len; ++i) { m_connectors[i]->deactivate(); } } /*! * @if jp * @brief ConnectorDataListener リスナを追加する * * バッファ書き込みまたは読み出しイベントに関連する各種リスナを設定する。 * * @else * @brief Adding BufferDataListener type listener * * @endif */ void OutPortBase:: addConnectorDataListener(ConnectorDataListenerType type, ConnectorDataListener* listener, bool autoclean) { if (type < CONNECTOR_DATA_LISTENER_NUM) { RTC_TRACE(("addConnectorDataListener(%s)", ConnectorDataListener::toString(type))); m_listeners.connectorData_[type].addListener(listener, autoclean); return; } RTC_ERROR(("addConnectorDataListener(): Unknown Listener Type")); return; } /*! * @if jp * @brief ConnectorDataListener リスナを削除する * * @else * @brief Removing ConnectorDataListener type listener * * @endif */ void OutPortBase:: removeConnectorDataListener(ConnectorDataListenerType type, ConnectorDataListener* listener) { if (type < CONNECTOR_DATA_LISTENER_NUM) { RTC_TRACE(("removeConnectorDataListener(%s)", ConnectorDataListener::toString(type))); m_listeners.connectorData_[type].removeListener(listener); return; } RTC_ERROR(("removeConnectorDataListener(): Unknown Listener Type")); return; } /*! * @if jp * @brief ConnectorListener リスナを追加する * * @else * @brief Adding ConnectorListener type listener * * @endif */ void OutPortBase::addConnectorListener(ConnectorListenerType type, ConnectorListener* listener, bool autoclean) { if (type < CONNECTOR_LISTENER_NUM) { RTC_TRACE(("addConnectorListener(%s)", ConnectorListener::toString(type))); m_listeners.connector_[type].addListener(listener, autoclean); return; } RTC_ERROR(("addConnectorListener(): Unknown Listener Type")); return; } /*! * @if jp * @brief ConnectorListener リスナを削除する * * @else * @brief Removing ConnectorListener type listener * * @endif */ void OutPortBase::removeConnectorListener(ConnectorListenerType type, ConnectorListener* listener) { if (type < CONNECTOR_LISTENER_NUM) { RTC_TRACE(("removeConnectorListener(%s)", ConnectorListener::toString(type))); m_listeners.connector_[type].removeListener(listener); return; } RTC_ERROR(("removeConnectorListener(): Unknown Listener Type")); return; } /*! * @if jp * @brief endian 設定がlittleか否か返す * @else * @brief return it whether endian setting is little * @endif */ bool OutPortBase::isLittleEndian() { return m_littleEndian; } /*! * @if jp * @brief [CORBA interface] Port の接続を行う * @else * @brief [CORBA interface] Connect the Port * @endif */ ReturnCode_t OutPortBase::connect(ConnectorProfile& connector_profile) throw (CORBA::SystemException) { RTC_TRACE(("OutPortBase::connect()")); // endian infomation check CORBA::Long index(NVUtil::find_index(connector_profile.properties, "dataport.serializer.cdr.endian")); if (index < 0) { RTC_TRACE(("ConnectorProfile dataport.serializer.cdr.endian set.")); // endian infomation set CORBA_SeqUtil::push_back(connector_profile.properties, NVUtil::newNV("dataport.serializer.cdr.endian", "little,big")); } return PortBase::connect(connector_profile); } //====================================================================== // protected member functions //====================================================================== /*! * @if jp * @brief OutPortの設定を行う * @else * @brief Configureing outport * @endif */ void OutPortBase::configure() { } /*! * @if jp * @brief Interface情報を公開する * @else * @brief Publish interface information * @endif */ ReturnCode_t OutPortBase::publishInterfaces(ConnectorProfile& cprof) { RTC_TRACE(("publishInterfaces()")); ReturnCode_t returnvalue = _publishInterfaces(); if(returnvalue!=RTC::RTC_OK) { return returnvalue; } // prop: [port.outport]. coil::Properties prop(m_properties); { coil::Properties conn_prop; NVUtil::copyToProperties(conn_prop, cprof.properties); prop << conn_prop.getNode("dataport"); // marge ConnectorProfile /* * marge ConnectorProfile for buffer property. * e.g. * prof[buffer.write.full_policy] * << cprof[dataport.outport.buffer.write.full_policy] */ prop << conn_prop.getNode("dataport.outport"); } RTC_DEBUG(("ConnectorProfile::properties are as follows.")); RTC_PARANOID_STR((prop)); /* * ここで, ConnectorProfile からの properties がマージされたため、 * prop["dataflow_type"]: データフロータイプ * prop["interface_type"]: インターフェースタイプ * などがアクセス可能になる。 */ std::string dflow_type(prop["dataflow_type"]); coil::normalize(dflow_type); if (dflow_type == "push") { RTC_PARANOID(("dataflow_type = push .... do nothing")); return RTC::RTC_OK; } else if (dflow_type == "pull") { RTC_PARANOID(("dataflow_type = pull .... create PullConnector")); OutPortProvider* provider(createProvider(cprof, prop)); if (provider == 0) { return RTC::BAD_PARAMETER; } // create OutPortPullConnector OutPortConnector* connector(createConnector(cprof, prop, provider)); if (connector == 0) { return RTC::RTC_ERROR; } // connector set provider->setConnector(connector); RTC_DEBUG(("publishInterface() successfully finished.")); return RTC::RTC_OK; } RTC_ERROR(("unsupported dataflow_type")); return RTC::BAD_PARAMETER; } /*! * @if jp * @brief Interface情報を取得する * @else * @brief Subscribe interface * @endif */ ReturnCode_t OutPortBase::subscribeInterfaces(const ConnectorProfile& cprof) { RTC_TRACE(("subscribeInterfaces()")); // prop: [port.outport]. coil::Properties prop(m_properties); { coil::Properties conn_prop; NVUtil::copyToProperties(conn_prop, cprof.properties); prop << conn_prop.getNode("dataport"); // marge ConnectorProfile /* * marge ConnectorProfile for buffer property. * e.g. * prof[buffer.write.full_policy] * << cprof[dataport.outport.buffer.write.full_policy] */ prop << conn_prop.getNode("dataport.outport"); } RTC_DEBUG(("ConnectorProfile::properties are as follows.")); RTC_DEBUG_STR((prop)); bool littleEndian; if (!checkEndian(prop, littleEndian)) { RTC_ERROR(("unsupported endian")); return RTC::UNSUPPORTED; } RTC_TRACE(("endian: %s", m_littleEndian ? "little":"big")); /* * ここで, ConnectorProfile からの properties がマージされたため、 * prop["dataflow_type"]: データフロータイプ * prop["interface_type"]: インターフェースタイプ * などがアクセス可能になる。 */ std::string& dflow_type(prop["dataflow_type"]); coil::normalize(dflow_type); if (dflow_type == "push") { RTC_PARANOID(("dataflow_type is push.")); // interface InPortConsumer* consumer(createConsumer(cprof, prop)); if (consumer == 0) { return RTC::BAD_PARAMETER; } // create OutPortPushConnector OutPortConnector* connector(createConnector(cprof, prop, consumer)); if (connector == 0) { return RTC::RTC_ERROR; } RTC_DEBUG(("subscribeInterfaces() successfully finished.")); return RTC::RTC_OK; } else if (dflow_type == "pull") { RTC_PARANOID(("dataflow_type is pull.")); // set endian type OutPortConnector* conn(getConnectorById(cprof.connector_id)); if (conn == 0) { RTC_ERROR(("specified connector not found: %s", (const char*)cprof.connector_id)); return RTC::RTC_ERROR; } conn->setEndian(littleEndian); RTC_DEBUG(("subscribeInterfaces() successfully finished.")); return RTC::RTC_OK; } RTC_ERROR(("unsupported dataflow_type: %s", dflow_type.c_str())); return RTC::BAD_PARAMETER; } /*! * @if jp * @brief 登録されているInterface情報を解除する * @else * @brief Unsubscribe interface * @endif */ void OutPortBase::unsubscribeInterfaces(const ConnectorProfile& connector_profile) { RTC_TRACE(("unsubscribeInterfaces()")); std::string id(connector_profile.connector_id); RTC_PARANOID(("connector_id: %s", id.c_str())); ConnectorList::iterator it(m_connectors.begin()); while (it != m_connectors.end()) { if (id == (*it)->id()) { // Connector's dtor must call disconnect() delete *it; m_connectors.erase(it); RTC_TRACE(("delete connector: %s", id.c_str())); return; } ++it; } RTC_ERROR(("specified connector not found: %s", id.c_str())); return; } /*! * @if jp * @brief OutPort provider の初期化 * @else * @brief OutPort provider initialization * @endif */ void OutPortBase::initProviders() { RTC_TRACE(("initProviders()")); // create OutPort providers OutPortProviderFactory& factory(OutPortProviderFactory::instance()); coil::vstring provider_types(factory.getIdentifiers()); RTC_PARANOID(("available OutPortProviders: %s", coil::flatten(provider_types).c_str())); #ifndef RTC_NO_DATAPORTIF_ACTIVATION_OPTION if (m_properties.hasKey("provider_types") && coil::normalize(m_properties["provider_types"]) != "all") { RTC_DEBUG(("allowed providers: %s", m_properties["provider_types"].c_str())); coil::vstring temp_types(provider_types); provider_types.clear(); coil::vstring active_types(coil::split(m_properties["provider_types"], ",")); std::sort(temp_types.begin(), temp_types.end()); std::sort(active_types.begin(), active_types.end()); std::set_intersection(temp_types.begin(), temp_types.end(), active_types.begin(), active_types.end(), std::back_inserter(provider_types)); } #endif // OutPortProvider supports "pull" dataflow type if (provider_types.size() > 0) { RTC_DEBUG(("dataflow_type pull is supported")); appendProperty("dataport.dataflow_type", "pull"); appendProperty("dataport.interface_type", coil::flatten(provider_types).c_str()); } m_providerTypes = provider_types; } /*! * @if jp * @brief InPort consumer の初期化 * @else * @brief InPort consumer initialization * @endif */ void OutPortBase::initConsumers() { RTC_TRACE(("initConsumers()")); // create InPort consumers InPortConsumerFactory& factory(InPortConsumerFactory::instance()); coil::vstring consumer_types(factory.getIdentifiers()); RTC_PARANOID(("available InPortConsumer: %s", coil::flatten(consumer_types).c_str())); #ifndef RTC_NO_DATAPORTIF_ACTIVATION_OPTION if (m_properties.hasKey("consumer_types") && coil::normalize(m_properties["consumer_types"]) != "all") { RTC_DEBUG(("allowed consumers: %s", m_properties["consumer_types"].c_str())); coil::vstring temp_types(consumer_types); consumer_types.clear(); coil::vstring active_types(coil::split(m_properties["consumer_types"], ",")); std::sort(temp_types.begin(), temp_types.end()); std::sort(active_types.begin(), active_types.end()); std::set_intersection(temp_types.begin(), temp_types.end(), active_types.begin(), active_types.end(), std::back_inserter(consumer_types)); } #endif // InPortConsumer supports "push" dataflow type if (consumer_types.size() > 0) { RTC_PARANOID(("dataflow_type push is supported")); appendProperty("dataport.dataflow_type", "push"); appendProperty("dataport.interface_type", coil::flatten(consumer_types).c_str()); } m_consumerTypes = consumer_types; } /*! * @if jp * @brief シリアライザのエンディアンをチェックする * @else * @brief Checking endian flag of serializer * @endif */ bool OutPortBase::checkEndian(const coil::Properties& prop, bool& littleEndian) { // old version check if(prop.hasKey("serializer") == NULL) { littleEndian = true; return true; } // endian type check std::string endian_type(prop.getProperty("serializer.cdr.endian", "")); RTC_DEBUG(("endian_type: %s", endian_type.c_str())); coil::normalize(endian_type); std::vector<std::string> endian(coil::split(endian_type, ",")); if(endian.empty()) { return false; } if(endian[0] == "little") { littleEndian = true; return true; } else if(endian[0] == "big") { littleEndian = false; return true; } return false; } /*! * @if jp * @brief OutPort provider の生成 * @else * @brief OutPort provider creation * @endif */ OutPortProvider* OutPortBase::createProvider(ConnectorProfile& cprof, coil::Properties& prop) { if (!prop["interface_type"].empty() && !coil::includes((coil::vstring)m_providerTypes, prop["interface_type"])) { RTC_ERROR(("no provider found")); RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); RTC_DEBUG(("interface_types: %s", coil::flatten(m_providerTypes).c_str())); return 0; } RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); OutPortProvider* provider; provider = OutPortProviderFactory:: instance().createObject(prop["interface_type"].c_str()); if (provider != 0) { RTC_TRACE(("provider created")); provider->init(prop.getNode("provider")); #ifndef ORB_IS_RTORB if (!provider->publishInterface(cprof.properties)) { RTC_ERROR(("publishing interface information error")); OutPortProviderFactory::instance().deleteObject(provider); return 0; } #else // ORB_IS_RTORB ::SDOPackage::NVList_ptr prop_ref(cprof.properties); if (!provider->publishInterface(*prop_ref)) { RTC_ERROR(("publishing interface information error")); OutPortProviderFactory::instance().deleteObject(provider); return 0; } #endif // ORB_IS_RTORB return provider; } RTC_ERROR(("provider creation failed")); return 0; } /*! * @if jp * @brief InPort consumer の生成 * @else * @brief InPort consumer creation * @endif */ InPortConsumer* OutPortBase::createConsumer(const ConnectorProfile& cprof, coil::Properties& prop) { if (!prop["interface_type"].empty() && !coil::includes((coil::vstring)m_consumerTypes, prop["interface_type"])) { RTC_ERROR(("no consumer found")); RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); RTC_DEBUG(("interface_types: %s", coil::flatten(m_consumerTypes).c_str())); return 0; } RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); InPortConsumer* consumer; consumer = InPortConsumerFactory:: instance().createObject(prop["interface_type"].c_str()); if (consumer != 0) { RTC_TRACE(("consumer created")); consumer->init(prop.getNode("consumer")); if (!consumer->subscribeInterface(cprof.properties)) { RTC_ERROR(("interface subscription failed.")); InPortConsumerFactory::instance().deleteObject(consumer); return 0; } return consumer; } RTC_ERROR(("consumer creation failed")); return 0; } /*! * @if jp * @brief OutPortPushConnector の生成 * @else * @brief OutPortPushConnector creation * @endif */ OutPortConnector* OutPortBase::createConnector(const ConnectorProfile& cprof, coil::Properties& prop, InPortConsumer* consumer) { #ifndef ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil::refToVstring(cprof.ports), prop); #else // ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil:: refToVstring(RTC::PortServiceList(cprof.ports)), prop); #endif // ORB_IS_RTORB OutPortConnector* connector(0); try { connector = new OutPortPushConnector(profile, consumer, m_listeners); if (connector == 0) { RTC_ERROR(("old compiler? new returned 0;")); return 0; } RTC_TRACE(("OutPortPushConnector created")); // endian type set connector->setEndian(m_littleEndian); m_connectors.push_back(connector); RTC_PARANOID(("connector pushback done: size = %d", m_connectors.size())); return connector; } catch (std::bad_alloc& e) { RTC_ERROR(("OutPortPushConnector creation failed")); return 0; } RTC_FATAL(("never comes here: createConnector()")); return 0; } /*! * @if jp * @brief OutPortPullConnector の生成 * @else * @brief OutPortPullConnector creation * @endif */ OutPortConnector* OutPortBase::createConnector(const ConnectorProfile& cprof, coil::Properties& prop, OutPortProvider* provider) { RTC_VERBOSE(("createConnector()")); #ifndef ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil::refToVstring(cprof.ports), prop); #else // ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil:: refToVstring(RTC::PortServiceList(cprof.ports)), prop); #endif // ORB_IS_RTORB OutPortConnector* connector(0); try { connector = new OutPortPullConnector(profile, provider, m_listeners); if (connector == 0) { RTC_ERROR(("old compiler? new returned 0;")); return 0; } RTC_TRACE(("OutPortPullConnector created")); m_connectors.push_back(connector); RTC_PARANOID(("connector pushback done: size = %d", m_connectors.size())); return connector; } catch (std::bad_alloc& e) { RTC_ERROR(("OutPortPullConnector creation failed")); return 0; } RTC_FATAL(("never comes here: createConnector()")); return 0; } }; // end of namespace RTM
114  std::for_each(m_connectors.begin(),
115  m_connectors.end(),
117  }
118 
127  {
128  RTC_TRACE(("init()"));
129  RTC_PARANOID(("given properties:"));
130  RTC_DEBUG_STR((prop));
131 
132  m_properties << prop;
133 
134  RTC_PARANOID(("updated properties:"));
136 
137  configure();
138 
139  initConsumers();
140  initProviders();
141  int num(-1);
142  if (!coil::stringTo(num,
143  m_properties.getProperty("connection_limit","-1").c_str()))
144  {
145  RTC_ERROR(("invalid connection_limit value: %s",
146  m_properties.getProperty("connection_limit").c_str()));
147  }
148 
149  setConnectionLimit(num);
150  }
151 
160  {
161  RTC_TRACE(("properties()"));
162  return m_properties;
163  }
164 
172  const std::vector<OutPortConnector*>& OutPortBase::connectors()
173  {
174  RTC_TRACE(("connectors(): size = %d", m_connectors.size()));
175  return m_connectors;
176  }
177 
186  {
187  RTC_TRACE(("getConnectorProfiles(): size = %d", m_connectors.size()));
188  ConnectorInfoList profs;
189  for (int i(0), len(m_connectors.size()); i < len; ++i)
190  {
191  profs.push_back(m_connectors[i]->profile());
192  }
193  return profs;
194  }
195 
204  {
205  coil::vstring ids;
206  for (int i(0), len(m_connectors.size()); i < len; ++i)
207  {
208  ids.push_back(m_connectors[i]->id());
209  }
210  RTC_TRACE(("getConnectorIds(): %s", coil::flatten(ids).c_str()));
211  return ids;
212  }
213 
222  {
223  coil::vstring names;
224  for (int i(0), len(m_connectors.size()); i < len; ++i)
225  {
226  names.push_back(m_connectors[i]->name());
227  }
228  RTC_TRACE(("getConnectorNames(): %s", coil::flatten(names).c_str()));
229  return names;
230  }
231 
240  {
241  RTC_TRACE(("getConnectorById(id = %s)", id));
242 
243  std::string sid(id);
244  for (int i(0), len(m_connectors.size()); i < len; ++i)
245  {
246  if (sid == m_connectors[i]->id())
247  {
248  return m_connectors[i];
249  }
250  }
251  RTC_WARN(("ConnectorProfile with the id(%s) not found.", id));
252  return 0;
253  }
254 
263  {
264  RTC_TRACE(("getConnectorByName(name = %s)", name));
265 
266  std::string sname(name);
267  for (int i(0), len(m_connectors.size()); i < len; ++i)
268  {
269  if (sname == m_connectors[i]->name())
270  {
271  return m_connectors[i];
272  }
273  }
274  RTC_WARN(("ConnectorProfile with the name(%s) not found.", name));
275  return 0;
276  }
277 
286  ConnectorInfo& prof)
287  {
288  RTC_TRACE(("getConnectorProfileById(id = %s)", id));
290  if (conn == 0)
291  {
292  return false;
293  }
294  prof = conn->profile();
295  return true;
296  }
297 
306  ConnectorInfo& prof)
307  {
308  RTC_TRACE(("getConnectorProfileByName(name = %s)", name));
310  if (conn == 0)
311  {
312  return false;
313  }
314  prof = conn->profile();
315  return true;
316  }
317 
326  {
327  RTC_TRACE(("activateInterfaces()"));
328 
329  for (int i(0), len(m_connectors.size()); i < len; ++i)
330  {
331  m_connectors[i]->activate();
332  }
333  }
334 
343  {
344  RTC_TRACE(("deactivateInterfaces()"));
345 
346  for (int i(0), len(m_connectors.size()); i < len; ++i)
347  {
348  m_connectors[i]->deactivate();
349  }
350  }
351 
352 
364  void OutPortBase::
366  ConnectorDataListener* listener,
367  bool autoclean)
368  {
369  if (type < CONNECTOR_DATA_LISTENER_NUM)
370  {
371  RTC_TRACE(("addConnectorDataListener(%s)",
373  m_listeners.connectorData_[type].addListener(listener, autoclean);
374  return;
375  }
376  RTC_ERROR(("addConnectorDataListener(): Unknown Listener Type"));
377  return;
378  }
379 
389  void OutPortBase::
391  ConnectorDataListener* listener)
392  {
393  if (type < CONNECTOR_DATA_LISTENER_NUM)
394  {
395  RTC_TRACE(("removeConnectorDataListener(%s)",
397  m_listeners.connectorData_[type].removeListener(listener);
398  return;
399  }
400  RTC_ERROR(("removeConnectorDataListener(): Unknown Listener Type"));
401  return;
402  }
403 
414  ConnectorListener* listener,
415  bool autoclean)
416  {
417  if (type < CONNECTOR_LISTENER_NUM)
418  {
419  RTC_TRACE(("addConnectorListener(%s)",
421  m_listeners.connector_[type].addListener(listener, autoclean);
422  return;
423  }
424  RTC_ERROR(("addConnectorListener(): Unknown Listener Type"));
425  return;
426  }
427 
438  ConnectorListener* listener)
439  {
440  if (type < CONNECTOR_LISTENER_NUM)
441  {
442  RTC_TRACE(("removeConnectorListener(%s)",
444  m_listeners.connector_[type].removeListener(listener);
445  return;
446  }
447  RTC_ERROR(("removeConnectorListener(): Unknown Listener Type"));
448  return;
449  }
450 
459  {
460  return m_littleEndian;
461  }
462 
470  ReturnCode_t OutPortBase::connect(ConnectorProfile& connector_profile)
471  throw (CORBA::SystemException)
472  {
473  RTC_TRACE(("OutPortBase::connect()"));
474 
475  // endian infomation check
476  CORBA::Long index(NVUtil::find_index(connector_profile.properties,
477  "dataport.serializer.cdr.endian"));
478  if (index < 0)
479  {
480  RTC_TRACE(("ConnectorProfile dataport.serializer.cdr.endian set."));
481  // endian infomation set
482  CORBA_SeqUtil::push_back(connector_profile.properties,
483  NVUtil::newNV("dataport.serializer.cdr.endian", "little,big"));
484  }
485  return PortBase::connect(connector_profile);
486  }
487 
488 
489  //======================================================================
490  // protected member functions
491  //======================================================================
500  {
501 
502  }
503 
504 
513  {
514  RTC_TRACE(("publishInterfaces()"));
515 
516  ReturnCode_t returnvalue = _publishInterfaces();
517  if(returnvalue!=RTC::RTC_OK)
518  {
519  return returnvalue;
520  }
521 
522  // prop: [port.outport].
524  {
525  coil::Properties conn_prop;
526  NVUtil::copyToProperties(conn_prop, cprof.properties);
527  prop << conn_prop.getNode("dataport"); // marge ConnectorProfile
528  /*
529  * marge ConnectorProfile for buffer property.
530  * e.g.
531  * prof[buffer.write.full_policy]
532  * << cprof[dataport.outport.buffer.write.full_policy]
533  */
534  prop << conn_prop.getNode("dataport.outport");
535  }
536  RTC_DEBUG(("ConnectorProfile::properties are as follows."));
537  RTC_PARANOID_STR((prop));
538 
539  /*
540  * ここで, ConnectorProfile からの properties がマージされたため、
541  * prop["dataflow_type"]: データフロータイプ * prop["interface_type"]: インターフェースタイプ * などがアクセス可能になる。 */ std::string dflow_type(prop["dataflow_type"]); coil::normalize(dflow_type); if (dflow_type == "push") { RTC_PARANOID(("dataflow_type = push .... do nothing")); return RTC::RTC_OK; } else if (dflow_type == "pull") { RTC_PARANOID(("dataflow_type = pull .... create PullConnector")); OutPortProvider* provider(createProvider(cprof, prop)); if (provider == 0) { return RTC::BAD_PARAMETER; } // create OutPortPullConnector OutPortConnector* connector(createConnector(cprof, prop, provider)); if (connector == 0) { return RTC::RTC_ERROR; } // connector set provider->setConnector(connector); RTC_DEBUG(("publishInterface() successfully finished.")); return RTC::RTC_OK; } RTC_ERROR(("unsupported dataflow_type")); return RTC::BAD_PARAMETER; } /*! * @if jp * @brief Interface情報を取得する * @else * @brief Subscribe interface * @endif */ ReturnCode_t OutPortBase::subscribeInterfaces(const ConnectorProfile& cprof) { RTC_TRACE(("subscribeInterfaces()")); // prop: [port.outport]. coil::Properties prop(m_properties); { coil::Properties conn_prop; NVUtil::copyToProperties(conn_prop, cprof.properties); prop << conn_prop.getNode("dataport"); // marge ConnectorProfile /* * marge ConnectorProfile for buffer property. * e.g. * prof[buffer.write.full_policy] * << cprof[dataport.outport.buffer.write.full_policy] */ prop << conn_prop.getNode("dataport.outport"); } RTC_DEBUG(("ConnectorProfile::properties are as follows.")); RTC_DEBUG_STR((prop)); bool littleEndian; if (!checkEndian(prop, littleEndian)) { RTC_ERROR(("unsupported endian")); return RTC::UNSUPPORTED; } RTC_TRACE(("endian: %s", m_littleEndian ? "little":"big")); /* * ここで, ConnectorProfile からの properties がマージされたため、 * prop["dataflow_type"]: データフロータイプ * prop["interface_type"]: インターフェースタイプ * などがアクセス可能になる。 */ std::string& dflow_type(prop["dataflow_type"]); coil::normalize(dflow_type); if (dflow_type == "push") { RTC_PARANOID(("dataflow_type is push.")); // interface InPortConsumer* consumer(createConsumer(cprof, prop)); if (consumer == 0) { return RTC::BAD_PARAMETER; } // create OutPortPushConnector OutPortConnector* connector(createConnector(cprof, prop, consumer)); if (connector == 0) { return RTC::RTC_ERROR; } RTC_DEBUG(("subscribeInterfaces() successfully finished.")); return RTC::RTC_OK; } else if (dflow_type == "pull") { RTC_PARANOID(("dataflow_type is pull.")); // set endian type OutPortConnector* conn(getConnectorById(cprof.connector_id)); if (conn == 0) { RTC_ERROR(("specified connector not found: %s", (const char*)cprof.connector_id)); return RTC::RTC_ERROR; } conn->setEndian(littleEndian); RTC_DEBUG(("subscribeInterfaces() successfully finished.")); return RTC::RTC_OK; } RTC_ERROR(("unsupported dataflow_type: %s", dflow_type.c_str())); return RTC::BAD_PARAMETER; } /*! * @if jp * @brief 登録されているInterface情報を解除する * @else * @brief Unsubscribe interface * @endif */ void OutPortBase::unsubscribeInterfaces(const ConnectorProfile& connector_profile) { RTC_TRACE(("unsubscribeInterfaces()")); std::string id(connector_profile.connector_id); RTC_PARANOID(("connector_id: %s", id.c_str())); ConnectorList::iterator it(m_connectors.begin()); while (it != m_connectors.end()) { if (id == (*it)->id()) { // Connector's dtor must call disconnect() delete *it; m_connectors.erase(it); RTC_TRACE(("delete connector: %s", id.c_str())); return; } ++it; } RTC_ERROR(("specified connector not found: %s", id.c_str())); return; } /*! * @if jp * @brief OutPort provider の初期化 * @else * @brief OutPort provider initialization * @endif */ void OutPortBase::initProviders() { RTC_TRACE(("initProviders()")); // create OutPort providers OutPortProviderFactory& factory(OutPortProviderFactory::instance()); coil::vstring provider_types(factory.getIdentifiers()); RTC_PARANOID(("available OutPortProviders: %s", coil::flatten(provider_types).c_str())); #ifndef RTC_NO_DATAPORTIF_ACTIVATION_OPTION if (m_properties.hasKey("provider_types") && coil::normalize(m_properties["provider_types"]) != "all") { RTC_DEBUG(("allowed providers: %s", m_properties["provider_types"].c_str())); coil::vstring temp_types(provider_types); provider_types.clear(); coil::vstring active_types(coil::split(m_properties["provider_types"], ",")); std::sort(temp_types.begin(), temp_types.end()); std::sort(active_types.begin(), active_types.end()); std::set_intersection(temp_types.begin(), temp_types.end(), active_types.begin(), active_types.end(), std::back_inserter(provider_types)); } #endif // OutPortProvider supports "pull" dataflow type if (provider_types.size() > 0) { RTC_DEBUG(("dataflow_type pull is supported")); appendProperty("dataport.dataflow_type", "pull"); appendProperty("dataport.interface_type", coil::flatten(provider_types).c_str()); } m_providerTypes = provider_types; } /*! * @if jp * @brief InPort consumer の初期化 * @else * @brief InPort consumer initialization * @endif */ void OutPortBase::initConsumers() { RTC_TRACE(("initConsumers()")); // create InPort consumers InPortConsumerFactory& factory(InPortConsumerFactory::instance()); coil::vstring consumer_types(factory.getIdentifiers()); RTC_PARANOID(("available InPortConsumer: %s", coil::flatten(consumer_types).c_str())); #ifndef RTC_NO_DATAPORTIF_ACTIVATION_OPTION if (m_properties.hasKey("consumer_types") && coil::normalize(m_properties["consumer_types"]) != "all") { RTC_DEBUG(("allowed consumers: %s", m_properties["consumer_types"].c_str())); coil::vstring temp_types(consumer_types); consumer_types.clear(); coil::vstring active_types(coil::split(m_properties["consumer_types"], ",")); std::sort(temp_types.begin(), temp_types.end()); std::sort(active_types.begin(), active_types.end()); std::set_intersection(temp_types.begin(), temp_types.end(), active_types.begin(), active_types.end(), std::back_inserter(consumer_types)); } #endif // InPortConsumer supports "push" dataflow type if (consumer_types.size() > 0) { RTC_PARANOID(("dataflow_type push is supported")); appendProperty("dataport.dataflow_type", "push"); appendProperty("dataport.interface_type", coil::flatten(consumer_types).c_str()); } m_consumerTypes = consumer_types; } /*! * @if jp * @brief シリアライザのエンディアンをチェックする * @else * @brief Checking endian flag of serializer * @endif */ bool OutPortBase::checkEndian(const coil::Properties& prop, bool& littleEndian) { // old version check if(prop.hasKey("serializer") == NULL) { littleEndian = true; return true; } // endian type check std::string endian_type(prop.getProperty("serializer.cdr.endian", "")); RTC_DEBUG(("endian_type: %s", endian_type.c_str())); coil::normalize(endian_type); std::vector<std::string> endian(coil::split(endian_type, ",")); if(endian.empty()) { return false; } if(endian[0] == "little") { littleEndian = true; return true; } else if(endian[0] == "big") { littleEndian = false; return true; } return false; } /*! * @if jp * @brief OutPort provider の生成 * @else * @brief OutPort provider creation * @endif */ OutPortProvider* OutPortBase::createProvider(ConnectorProfile& cprof, coil::Properties& prop) { if (!prop["interface_type"].empty() && !coil::includes((coil::vstring)m_providerTypes, prop["interface_type"])) { RTC_ERROR(("no provider found")); RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); RTC_DEBUG(("interface_types: %s", coil::flatten(m_providerTypes).c_str())); return 0; } RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); OutPortProvider* provider; provider = OutPortProviderFactory:: instance().createObject(prop["interface_type"].c_str()); if (provider != 0) { RTC_TRACE(("provider created")); provider->init(prop.getNode("provider")); #ifndef ORB_IS_RTORB if (!provider->publishInterface(cprof.properties)) { RTC_ERROR(("publishing interface information error")); OutPortProviderFactory::instance().deleteObject(provider); return 0; } #else // ORB_IS_RTORB ::SDOPackage::NVList_ptr prop_ref(cprof.properties); if (!provider->publishInterface(*prop_ref)) { RTC_ERROR(("publishing interface information error")); OutPortProviderFactory::instance().deleteObject(provider); return 0; } #endif // ORB_IS_RTORB return provider; } RTC_ERROR(("provider creation failed")); return 0; } /*! * @if jp * @brief InPort consumer の生成 * @else * @brief InPort consumer creation * @endif */ InPortConsumer* OutPortBase::createConsumer(const ConnectorProfile& cprof, coil::Properties& prop) { if (!prop["interface_type"].empty() && !coil::includes((coil::vstring)m_consumerTypes, prop["interface_type"])) { RTC_ERROR(("no consumer found")); RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); RTC_DEBUG(("interface_types: %s", coil::flatten(m_consumerTypes).c_str())); return 0; } RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); InPortConsumer* consumer; consumer = InPortConsumerFactory:: instance().createObject(prop["interface_type"].c_str()); if (consumer != 0) { RTC_TRACE(("consumer created")); consumer->init(prop.getNode("consumer")); if (!consumer->subscribeInterface(cprof.properties)) { RTC_ERROR(("interface subscription failed.")); InPortConsumerFactory::instance().deleteObject(consumer); return 0; } return consumer; } RTC_ERROR(("consumer creation failed")); return 0; } /*! * @if jp * @brief OutPortPushConnector の生成 * @else * @brief OutPortPushConnector creation * @endif */ OutPortConnector* OutPortBase::createConnector(const ConnectorProfile& cprof, coil::Properties& prop, InPortConsumer* consumer) { #ifndef ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil::refToVstring(cprof.ports), prop); #else // ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil:: refToVstring(RTC::PortServiceList(cprof.ports)), prop); #endif // ORB_IS_RTORB OutPortConnector* connector(0); try { connector = new OutPortPushConnector(profile, consumer, m_listeners); if (connector == 0) { RTC_ERROR(("old compiler? new returned 0;")); return 0; } RTC_TRACE(("OutPortPushConnector created")); // endian type set connector->setEndian(m_littleEndian); m_connectors.push_back(connector); RTC_PARANOID(("connector pushback done: size = %d", m_connectors.size())); return connector; } catch (std::bad_alloc& e) { RTC_ERROR(("OutPortPushConnector creation failed")); return 0; } RTC_FATAL(("never comes here: createConnector()")); return 0; } /*! * @if jp * @brief OutPortPullConnector の生成 * @else * @brief OutPortPullConnector creation * @endif */ OutPortConnector* OutPortBase::createConnector(const ConnectorProfile& cprof, coil::Properties& prop, OutPortProvider* provider) { RTC_VERBOSE(("createConnector()")); #ifndef ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil::refToVstring(cprof.ports), prop); #else // ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil:: refToVstring(RTC::PortServiceList(cprof.ports)), prop); #endif // ORB_IS_RTORB OutPortConnector* connector(0); try { connector = new OutPortPullConnector(profile, provider, m_listeners); if (connector == 0) { RTC_ERROR(("old compiler? new returned 0;")); return 0; } RTC_TRACE(("OutPortPullConnector created")); m_connectors.push_back(connector); RTC_PARANOID(("connector pushback done: size = %d", m_connectors.size())); return connector; } catch (std::bad_alloc& e) { RTC_ERROR(("OutPortPullConnector creation failed")); return 0; } RTC_FATAL(("never comes here: createConnector()")); return 0; } }; // end of namespace RTM
542  * prop["interface_type"]: インターフェースタイプ * などがアクセス可能になる。 */ std::string dflow_type(prop["dataflow_type"]); coil::normalize(dflow_type); if (dflow_type == "push") { RTC_PARANOID(("dataflow_type = push .... do nothing")); return RTC::RTC_OK; } else if (dflow_type == "pull") { RTC_PARANOID(("dataflow_type = pull .... create PullConnector")); OutPortProvider* provider(createProvider(cprof, prop)); if (provider == 0) { return RTC::BAD_PARAMETER; } // create OutPortPullConnector OutPortConnector* connector(createConnector(cprof, prop, provider)); if (connector == 0) { return RTC::RTC_ERROR; } // connector set provider->setConnector(connector); RTC_DEBUG(("publishInterface() successfully finished.")); return RTC::RTC_OK; } RTC_ERROR(("unsupported dataflow_type")); return RTC::BAD_PARAMETER; } /*! * @if jp * @brief Interface情報を取得する * @else * @brief Subscribe interface * @endif */ ReturnCode_t OutPortBase::subscribeInterfaces(const ConnectorProfile& cprof) { RTC_TRACE(("subscribeInterfaces()")); // prop: [port.outport]. coil::Properties prop(m_properties); { coil::Properties conn_prop; NVUtil::copyToProperties(conn_prop, cprof.properties); prop << conn_prop.getNode("dataport"); // marge ConnectorProfile /* * marge ConnectorProfile for buffer property. * e.g. * prof[buffer.write.full_policy] * << cprof[dataport.outport.buffer.write.full_policy] */ prop << conn_prop.getNode("dataport.outport"); } RTC_DEBUG(("ConnectorProfile::properties are as follows.")); RTC_DEBUG_STR((prop)); bool littleEndian; if (!checkEndian(prop, littleEndian)) { RTC_ERROR(("unsupported endian")); return RTC::UNSUPPORTED; } RTC_TRACE(("endian: %s", m_littleEndian ? "little":"big")); /* * ここで, ConnectorProfile からの properties がマージされたため、 * prop["dataflow_type"]: データフロータイプ * prop["interface_type"]: インターフェースタイプ * などがアクセス可能になる。 */ std::string& dflow_type(prop["dataflow_type"]); coil::normalize(dflow_type); if (dflow_type == "push") { RTC_PARANOID(("dataflow_type is push.")); // interface InPortConsumer* consumer(createConsumer(cprof, prop)); if (consumer == 0) { return RTC::BAD_PARAMETER; } // create OutPortPushConnector OutPortConnector* connector(createConnector(cprof, prop, consumer)); if (connector == 0) { return RTC::RTC_ERROR; } RTC_DEBUG(("subscribeInterfaces() successfully finished.")); return RTC::RTC_OK; } else if (dflow_type == "pull") { RTC_PARANOID(("dataflow_type is pull.")); // set endian type OutPortConnector* conn(getConnectorById(cprof.connector_id)); if (conn == 0) { RTC_ERROR(("specified connector not found: %s", (const char*)cprof.connector_id)); return RTC::RTC_ERROR; } conn->setEndian(littleEndian); RTC_DEBUG(("subscribeInterfaces() successfully finished.")); return RTC::RTC_OK; } RTC_ERROR(("unsupported dataflow_type: %s", dflow_type.c_str())); return RTC::BAD_PARAMETER; } /*! * @if jp * @brief 登録されているInterface情報を解除する * @else * @brief Unsubscribe interface * @endif */ void OutPortBase::unsubscribeInterfaces(const ConnectorProfile& connector_profile) { RTC_TRACE(("unsubscribeInterfaces()")); std::string id(connector_profile.connector_id); RTC_PARANOID(("connector_id: %s", id.c_str())); ConnectorList::iterator it(m_connectors.begin()); while (it != m_connectors.end()) { if (id == (*it)->id()) { // Connector's dtor must call disconnect() delete *it; m_connectors.erase(it); RTC_TRACE(("delete connector: %s", id.c_str())); return; } ++it; } RTC_ERROR(("specified connector not found: %s", id.c_str())); return; } /*! * @if jp * @brief OutPort provider の初期化 * @else * @brief OutPort provider initialization * @endif */ void OutPortBase::initProviders() { RTC_TRACE(("initProviders()")); // create OutPort providers OutPortProviderFactory& factory(OutPortProviderFactory::instance()); coil::vstring provider_types(factory.getIdentifiers()); RTC_PARANOID(("available OutPortProviders: %s", coil::flatten(provider_types).c_str())); #ifndef RTC_NO_DATAPORTIF_ACTIVATION_OPTION if (m_properties.hasKey("provider_types") && coil::normalize(m_properties["provider_types"]) != "all") { RTC_DEBUG(("allowed providers: %s", m_properties["provider_types"].c_str())); coil::vstring temp_types(provider_types); provider_types.clear(); coil::vstring active_types(coil::split(m_properties["provider_types"], ",")); std::sort(temp_types.begin(), temp_types.end()); std::sort(active_types.begin(), active_types.end()); std::set_intersection(temp_types.begin(), temp_types.end(), active_types.begin(), active_types.end(), std::back_inserter(provider_types)); } #endif // OutPortProvider supports "pull" dataflow type if (provider_types.size() > 0) { RTC_DEBUG(("dataflow_type pull is supported")); appendProperty("dataport.dataflow_type", "pull"); appendProperty("dataport.interface_type", coil::flatten(provider_types).c_str()); } m_providerTypes = provider_types; } /*! * @if jp * @brief InPort consumer の初期化 * @else * @brief InPort consumer initialization * @endif */ void OutPortBase::initConsumers() { RTC_TRACE(("initConsumers()")); // create InPort consumers InPortConsumerFactory& factory(InPortConsumerFactory::instance()); coil::vstring consumer_types(factory.getIdentifiers()); RTC_PARANOID(("available InPortConsumer: %s", coil::flatten(consumer_types).c_str())); #ifndef RTC_NO_DATAPORTIF_ACTIVATION_OPTION if (m_properties.hasKey("consumer_types") && coil::normalize(m_properties["consumer_types"]) != "all") { RTC_DEBUG(("allowed consumers: %s", m_properties["consumer_types"].c_str())); coil::vstring temp_types(consumer_types); consumer_types.clear(); coil::vstring active_types(coil::split(m_properties["consumer_types"], ",")); std::sort(temp_types.begin(), temp_types.end()); std::sort(active_types.begin(), active_types.end()); std::set_intersection(temp_types.begin(), temp_types.end(), active_types.begin(), active_types.end(), std::back_inserter(consumer_types)); } #endif // InPortConsumer supports "push" dataflow type if (consumer_types.size() > 0) { RTC_PARANOID(("dataflow_type push is supported")); appendProperty("dataport.dataflow_type", "push"); appendProperty("dataport.interface_type", coil::flatten(consumer_types).c_str()); } m_consumerTypes = consumer_types; } /*! * @if jp * @brief シリアライザのエンディアンをチェックする * @else * @brief Checking endian flag of serializer * @endif */ bool OutPortBase::checkEndian(const coil::Properties& prop, bool& littleEndian) { // old version check if(prop.hasKey("serializer") == NULL) { littleEndian = true; return true; } // endian type check std::string endian_type(prop.getProperty("serializer.cdr.endian", "")); RTC_DEBUG(("endian_type: %s", endian_type.c_str())); coil::normalize(endian_type); std::vector<std::string> endian(coil::split(endian_type, ",")); if(endian.empty()) { return false; } if(endian[0] == "little") { littleEndian = true; return true; } else if(endian[0] == "big") { littleEndian = false; return true; } return false; } /*! * @if jp * @brief OutPort provider の生成 * @else * @brief OutPort provider creation * @endif */ OutPortProvider* OutPortBase::createProvider(ConnectorProfile& cprof, coil::Properties& prop) { if (!prop["interface_type"].empty() && !coil::includes((coil::vstring)m_providerTypes, prop["interface_type"])) { RTC_ERROR(("no provider found")); RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); RTC_DEBUG(("interface_types: %s", coil::flatten(m_providerTypes).c_str())); return 0; } RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); OutPortProvider* provider; provider = OutPortProviderFactory:: instance().createObject(prop["interface_type"].c_str()); if (provider != 0) { RTC_TRACE(("provider created")); provider->init(prop.getNode("provider")); #ifndef ORB_IS_RTORB if (!provider->publishInterface(cprof.properties)) { RTC_ERROR(("publishing interface information error")); OutPortProviderFactory::instance().deleteObject(provider); return 0; } #else // ORB_IS_RTORB ::SDOPackage::NVList_ptr prop_ref(cprof.properties); if (!provider->publishInterface(*prop_ref)) { RTC_ERROR(("publishing interface information error")); OutPortProviderFactory::instance().deleteObject(provider); return 0; } #endif // ORB_IS_RTORB return provider; } RTC_ERROR(("provider creation failed")); return 0; } /*! * @if jp * @brief InPort consumer の生成 * @else * @brief InPort consumer creation * @endif */ InPortConsumer* OutPortBase::createConsumer(const ConnectorProfile& cprof, coil::Properties& prop) { if (!prop["interface_type"].empty() && !coil::includes((coil::vstring)m_consumerTypes, prop["interface_type"])) { RTC_ERROR(("no consumer found")); RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); RTC_DEBUG(("interface_types: %s", coil::flatten(m_consumerTypes).c_str())); return 0; } RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); InPortConsumer* consumer; consumer = InPortConsumerFactory:: instance().createObject(prop["interface_type"].c_str()); if (consumer != 0) { RTC_TRACE(("consumer created")); consumer->init(prop.getNode("consumer")); if (!consumer->subscribeInterface(cprof.properties)) { RTC_ERROR(("interface subscription failed.")); InPortConsumerFactory::instance().deleteObject(consumer); return 0; } return consumer; } RTC_ERROR(("consumer creation failed")); return 0; } /*! * @if jp * @brief OutPortPushConnector の生成 * @else * @brief OutPortPushConnector creation * @endif */ OutPortConnector* OutPortBase::createConnector(const ConnectorProfile& cprof, coil::Properties& prop, InPortConsumer* consumer) { #ifndef ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil::refToVstring(cprof.ports), prop); #else // ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil:: refToVstring(RTC::PortServiceList(cprof.ports)), prop); #endif // ORB_IS_RTORB OutPortConnector* connector(0); try { connector = new OutPortPushConnector(profile, consumer, m_listeners); if (connector == 0) { RTC_ERROR(("old compiler? new returned 0;")); return 0; } RTC_TRACE(("OutPortPushConnector created")); // endian type set connector->setEndian(m_littleEndian); m_connectors.push_back(connector); RTC_PARANOID(("connector pushback done: size = %d", m_connectors.size())); return connector; } catch (std::bad_alloc& e) { RTC_ERROR(("OutPortPushConnector creation failed")); return 0; } RTC_FATAL(("never comes here: createConnector()")); return 0; } /*! * @if jp * @brief OutPortPullConnector の生成 * @else * @brief OutPortPullConnector creation * @endif */ OutPortConnector* OutPortBase::createConnector(const ConnectorProfile& cprof, coil::Properties& prop, OutPortProvider* provider) { RTC_VERBOSE(("createConnector()")); #ifndef ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil::refToVstring(cprof.ports), prop); #else // ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil:: refToVstring(RTC::PortServiceList(cprof.ports)), prop); #endif // ORB_IS_RTORB OutPortConnector* connector(0); try { connector = new OutPortPullConnector(profile, provider, m_listeners); if (connector == 0) { RTC_ERROR(("old compiler? new returned 0;")); return 0; } RTC_TRACE(("OutPortPullConnector created")); m_connectors.push_back(connector); RTC_PARANOID(("connector pushback done: size = %d", m_connectors.size())); return connector; } catch (std::bad_alloc& e) { RTC_ERROR(("OutPortPullConnector creation failed")); return 0; } RTC_FATAL(("never comes here: createConnector()")); return 0; } }; // end of namespace RTM
543  * などがアクセス可能になる。
544  */
545  std::string dflow_type(prop["dataflow_type"]);
546  coil::normalize(dflow_type);
547 
548  if (dflow_type == "push")
549  {
550  RTC_PARANOID(("dataflow_type = push .... do nothing"));
551  return RTC::RTC_OK;
552  }
553  else if (dflow_type == "pull")
554  {
555  RTC_PARANOID(("dataflow_type = pull .... create PullConnector"));
556 
557  OutPortProvider* provider(createProvider(cprof, prop));
558  if (provider == 0)
559  {
560  return RTC::BAD_PARAMETER;
561  }
562 
563  // create OutPortPullConnector
564  OutPortConnector* connector(createConnector(cprof, prop, provider));
565  if (connector == 0)
566  {
567  return RTC::RTC_ERROR;
568  }
569 
570  // connector set
571  provider->setConnector(connector);
572 
573  RTC_DEBUG(("publishInterface() successfully finished."));
574  return RTC::RTC_OK;
575  }
576 
577  RTC_ERROR(("unsupported dataflow_type"));
578 
579  return RTC::BAD_PARAMETER;
580  }
581 
589  ReturnCode_t OutPortBase::subscribeInterfaces(const ConnectorProfile& cprof)
590  {
591  RTC_TRACE(("subscribeInterfaces()"));
592 
593  // prop: [port.outport].
595  {
596  coil::Properties conn_prop;
597  NVUtil::copyToProperties(conn_prop, cprof.properties);
598  prop << conn_prop.getNode("dataport"); // marge ConnectorProfile
599  /*
600  * marge ConnectorProfile for buffer property.
601  * e.g.
602  * prof[buffer.write.full_policy]
603  * << cprof[dataport.outport.buffer.write.full_policy]
604  */
605  prop << conn_prop.getNode("dataport.outport");
606  }
607  RTC_DEBUG(("ConnectorProfile::properties are as follows."));
608  RTC_DEBUG_STR((prop));
609 
610  bool littleEndian;
611  if (!checkEndian(prop, littleEndian))
612  {
613  RTC_ERROR(("unsupported endian"));
614  return RTC::UNSUPPORTED;
615  }
616  RTC_TRACE(("endian: %s", m_littleEndian ? "little":"big"));
617 
618  /*
619  * ここで, ConnectorProfile からの properties がマージされたため、
620  * prop["dataflow_type"]: データフロータイプ * prop["interface_type"]: インターフェースタイプ * などがアクセス可能になる。 */ std::string& dflow_type(prop["dataflow_type"]); coil::normalize(dflow_type); if (dflow_type == "push") { RTC_PARANOID(("dataflow_type is push.")); // interface InPortConsumer* consumer(createConsumer(cprof, prop)); if (consumer == 0) { return RTC::BAD_PARAMETER; } // create OutPortPushConnector OutPortConnector* connector(createConnector(cprof, prop, consumer)); if (connector == 0) { return RTC::RTC_ERROR; } RTC_DEBUG(("subscribeInterfaces() successfully finished.")); return RTC::RTC_OK; } else if (dflow_type == "pull") { RTC_PARANOID(("dataflow_type is pull.")); // set endian type OutPortConnector* conn(getConnectorById(cprof.connector_id)); if (conn == 0) { RTC_ERROR(("specified connector not found: %s", (const char*)cprof.connector_id)); return RTC::RTC_ERROR; } conn->setEndian(littleEndian); RTC_DEBUG(("subscribeInterfaces() successfully finished.")); return RTC::RTC_OK; } RTC_ERROR(("unsupported dataflow_type: %s", dflow_type.c_str())); return RTC::BAD_PARAMETER; } /*! * @if jp * @brief 登録されているInterface情報を解除する * @else * @brief Unsubscribe interface * @endif */ void OutPortBase::unsubscribeInterfaces(const ConnectorProfile& connector_profile) { RTC_TRACE(("unsubscribeInterfaces()")); std::string id(connector_profile.connector_id); RTC_PARANOID(("connector_id: %s", id.c_str())); ConnectorList::iterator it(m_connectors.begin()); while (it != m_connectors.end()) { if (id == (*it)->id()) { // Connector's dtor must call disconnect() delete *it; m_connectors.erase(it); RTC_TRACE(("delete connector: %s", id.c_str())); return; } ++it; } RTC_ERROR(("specified connector not found: %s", id.c_str())); return; } /*! * @if jp * @brief OutPort provider の初期化 * @else * @brief OutPort provider initialization * @endif */ void OutPortBase::initProviders() { RTC_TRACE(("initProviders()")); // create OutPort providers OutPortProviderFactory& factory(OutPortProviderFactory::instance()); coil::vstring provider_types(factory.getIdentifiers()); RTC_PARANOID(("available OutPortProviders: %s", coil::flatten(provider_types).c_str())); #ifndef RTC_NO_DATAPORTIF_ACTIVATION_OPTION if (m_properties.hasKey("provider_types") && coil::normalize(m_properties["provider_types"]) != "all") { RTC_DEBUG(("allowed providers: %s", m_properties["provider_types"].c_str())); coil::vstring temp_types(provider_types); provider_types.clear(); coil::vstring active_types(coil::split(m_properties["provider_types"], ",")); std::sort(temp_types.begin(), temp_types.end()); std::sort(active_types.begin(), active_types.end()); std::set_intersection(temp_types.begin(), temp_types.end(), active_types.begin(), active_types.end(), std::back_inserter(provider_types)); } #endif // OutPortProvider supports "pull" dataflow type if (provider_types.size() > 0) { RTC_DEBUG(("dataflow_type pull is supported")); appendProperty("dataport.dataflow_type", "pull"); appendProperty("dataport.interface_type", coil::flatten(provider_types).c_str()); } m_providerTypes = provider_types; } /*! * @if jp * @brief InPort consumer の初期化 * @else * @brief InPort consumer initialization * @endif */ void OutPortBase::initConsumers() { RTC_TRACE(("initConsumers()")); // create InPort consumers InPortConsumerFactory& factory(InPortConsumerFactory::instance()); coil::vstring consumer_types(factory.getIdentifiers()); RTC_PARANOID(("available InPortConsumer: %s", coil::flatten(consumer_types).c_str())); #ifndef RTC_NO_DATAPORTIF_ACTIVATION_OPTION if (m_properties.hasKey("consumer_types") && coil::normalize(m_properties["consumer_types"]) != "all") { RTC_DEBUG(("allowed consumers: %s", m_properties["consumer_types"].c_str())); coil::vstring temp_types(consumer_types); consumer_types.clear(); coil::vstring active_types(coil::split(m_properties["consumer_types"], ",")); std::sort(temp_types.begin(), temp_types.end()); std::sort(active_types.begin(), active_types.end()); std::set_intersection(temp_types.begin(), temp_types.end(), active_types.begin(), active_types.end(), std::back_inserter(consumer_types)); } #endif // InPortConsumer supports "push" dataflow type if (consumer_types.size() > 0) { RTC_PARANOID(("dataflow_type push is supported")); appendProperty("dataport.dataflow_type", "push"); appendProperty("dataport.interface_type", coil::flatten(consumer_types).c_str()); } m_consumerTypes = consumer_types; } /*! * @if jp * @brief シリアライザのエンディアンをチェックする * @else * @brief Checking endian flag of serializer * @endif */ bool OutPortBase::checkEndian(const coil::Properties& prop, bool& littleEndian) { // old version check if(prop.hasKey("serializer") == NULL) { littleEndian = true; return true; } // endian type check std::string endian_type(prop.getProperty("serializer.cdr.endian", "")); RTC_DEBUG(("endian_type: %s", endian_type.c_str())); coil::normalize(endian_type); std::vector<std::string> endian(coil::split(endian_type, ",")); if(endian.empty()) { return false; } if(endian[0] == "little") { littleEndian = true; return true; } else if(endian[0] == "big") { littleEndian = false; return true; } return false; } /*! * @if jp * @brief OutPort provider の生成 * @else * @brief OutPort provider creation * @endif */ OutPortProvider* OutPortBase::createProvider(ConnectorProfile& cprof, coil::Properties& prop) { if (!prop["interface_type"].empty() && !coil::includes((coil::vstring)m_providerTypes, prop["interface_type"])) { RTC_ERROR(("no provider found")); RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); RTC_DEBUG(("interface_types: %s", coil::flatten(m_providerTypes).c_str())); return 0; } RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); OutPortProvider* provider; provider = OutPortProviderFactory:: instance().createObject(prop["interface_type"].c_str()); if (provider != 0) { RTC_TRACE(("provider created")); provider->init(prop.getNode("provider")); #ifndef ORB_IS_RTORB if (!provider->publishInterface(cprof.properties)) { RTC_ERROR(("publishing interface information error")); OutPortProviderFactory::instance().deleteObject(provider); return 0; } #else // ORB_IS_RTORB ::SDOPackage::NVList_ptr prop_ref(cprof.properties); if (!provider->publishInterface(*prop_ref)) { RTC_ERROR(("publishing interface information error")); OutPortProviderFactory::instance().deleteObject(provider); return 0; } #endif // ORB_IS_RTORB return provider; } RTC_ERROR(("provider creation failed")); return 0; } /*! * @if jp * @brief InPort consumer の生成 * @else * @brief InPort consumer creation * @endif */ InPortConsumer* OutPortBase::createConsumer(const ConnectorProfile& cprof, coil::Properties& prop) { if (!prop["interface_type"].empty() && !coil::includes((coil::vstring)m_consumerTypes, prop["interface_type"])) { RTC_ERROR(("no consumer found")); RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); RTC_DEBUG(("interface_types: %s", coil::flatten(m_consumerTypes).c_str())); return 0; } RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); InPortConsumer* consumer; consumer = InPortConsumerFactory:: instance().createObject(prop["interface_type"].c_str()); if (consumer != 0) { RTC_TRACE(("consumer created")); consumer->init(prop.getNode("consumer")); if (!consumer->subscribeInterface(cprof.properties)) { RTC_ERROR(("interface subscription failed.")); InPortConsumerFactory::instance().deleteObject(consumer); return 0; } return consumer; } RTC_ERROR(("consumer creation failed")); return 0; } /*! * @if jp * @brief OutPortPushConnector の生成 * @else * @brief OutPortPushConnector creation * @endif */ OutPortConnector* OutPortBase::createConnector(const ConnectorProfile& cprof, coil::Properties& prop, InPortConsumer* consumer) { #ifndef ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil::refToVstring(cprof.ports), prop); #else // ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil:: refToVstring(RTC::PortServiceList(cprof.ports)), prop); #endif // ORB_IS_RTORB OutPortConnector* connector(0); try { connector = new OutPortPushConnector(profile, consumer, m_listeners); if (connector == 0) { RTC_ERROR(("old compiler? new returned 0;")); return 0; } RTC_TRACE(("OutPortPushConnector created")); // endian type set connector->setEndian(m_littleEndian); m_connectors.push_back(connector); RTC_PARANOID(("connector pushback done: size = %d", m_connectors.size())); return connector; } catch (std::bad_alloc& e) { RTC_ERROR(("OutPortPushConnector creation failed")); return 0; } RTC_FATAL(("never comes here: createConnector()")); return 0; } /*! * @if jp * @brief OutPortPullConnector の生成 * @else * @brief OutPortPullConnector creation * @endif */ OutPortConnector* OutPortBase::createConnector(const ConnectorProfile& cprof, coil::Properties& prop, OutPortProvider* provider) { RTC_VERBOSE(("createConnector()")); #ifndef ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil::refToVstring(cprof.ports), prop); #else // ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil:: refToVstring(RTC::PortServiceList(cprof.ports)), prop); #endif // ORB_IS_RTORB OutPortConnector* connector(0); try { connector = new OutPortPullConnector(profile, provider, m_listeners); if (connector == 0) { RTC_ERROR(("old compiler? new returned 0;")); return 0; } RTC_TRACE(("OutPortPullConnector created")); m_connectors.push_back(connector); RTC_PARANOID(("connector pushback done: size = %d", m_connectors.size())); return connector; } catch (std::bad_alloc& e) { RTC_ERROR(("OutPortPullConnector creation failed")); return 0; } RTC_FATAL(("never comes here: createConnector()")); return 0; } }; // end of namespace RTM
621  * prop["interface_type"]: インターフェースタイプ * などがアクセス可能になる。 */ std::string& dflow_type(prop["dataflow_type"]); coil::normalize(dflow_type); if (dflow_type == "push") { RTC_PARANOID(("dataflow_type is push.")); // interface InPortConsumer* consumer(createConsumer(cprof, prop)); if (consumer == 0) { return RTC::BAD_PARAMETER; } // create OutPortPushConnector OutPortConnector* connector(createConnector(cprof, prop, consumer)); if (connector == 0) { return RTC::RTC_ERROR; } RTC_DEBUG(("subscribeInterfaces() successfully finished.")); return RTC::RTC_OK; } else if (dflow_type == "pull") { RTC_PARANOID(("dataflow_type is pull.")); // set endian type OutPortConnector* conn(getConnectorById(cprof.connector_id)); if (conn == 0) { RTC_ERROR(("specified connector not found: %s", (const char*)cprof.connector_id)); return RTC::RTC_ERROR; } conn->setEndian(littleEndian); RTC_DEBUG(("subscribeInterfaces() successfully finished.")); return RTC::RTC_OK; } RTC_ERROR(("unsupported dataflow_type: %s", dflow_type.c_str())); return RTC::BAD_PARAMETER; } /*! * @if jp * @brief 登録されているInterface情報を解除する * @else * @brief Unsubscribe interface * @endif */ void OutPortBase::unsubscribeInterfaces(const ConnectorProfile& connector_profile) { RTC_TRACE(("unsubscribeInterfaces()")); std::string id(connector_profile.connector_id); RTC_PARANOID(("connector_id: %s", id.c_str())); ConnectorList::iterator it(m_connectors.begin()); while (it != m_connectors.end()) { if (id == (*it)->id()) { // Connector's dtor must call disconnect() delete *it; m_connectors.erase(it); RTC_TRACE(("delete connector: %s", id.c_str())); return; } ++it; } RTC_ERROR(("specified connector not found: %s", id.c_str())); return; } /*! * @if jp * @brief OutPort provider の初期化 * @else * @brief OutPort provider initialization * @endif */ void OutPortBase::initProviders() { RTC_TRACE(("initProviders()")); // create OutPort providers OutPortProviderFactory& factory(OutPortProviderFactory::instance()); coil::vstring provider_types(factory.getIdentifiers()); RTC_PARANOID(("available OutPortProviders: %s", coil::flatten(provider_types).c_str())); #ifndef RTC_NO_DATAPORTIF_ACTIVATION_OPTION if (m_properties.hasKey("provider_types") && coil::normalize(m_properties["provider_types"]) != "all") { RTC_DEBUG(("allowed providers: %s", m_properties["provider_types"].c_str())); coil::vstring temp_types(provider_types); provider_types.clear(); coil::vstring active_types(coil::split(m_properties["provider_types"], ",")); std::sort(temp_types.begin(), temp_types.end()); std::sort(active_types.begin(), active_types.end()); std::set_intersection(temp_types.begin(), temp_types.end(), active_types.begin(), active_types.end(), std::back_inserter(provider_types)); } #endif // OutPortProvider supports "pull" dataflow type if (provider_types.size() > 0) { RTC_DEBUG(("dataflow_type pull is supported")); appendProperty("dataport.dataflow_type", "pull"); appendProperty("dataport.interface_type", coil::flatten(provider_types).c_str()); } m_providerTypes = provider_types; } /*! * @if jp * @brief InPort consumer の初期化 * @else * @brief InPort consumer initialization * @endif */ void OutPortBase::initConsumers() { RTC_TRACE(("initConsumers()")); // create InPort consumers InPortConsumerFactory& factory(InPortConsumerFactory::instance()); coil::vstring consumer_types(factory.getIdentifiers()); RTC_PARANOID(("available InPortConsumer: %s", coil::flatten(consumer_types).c_str())); #ifndef RTC_NO_DATAPORTIF_ACTIVATION_OPTION if (m_properties.hasKey("consumer_types") && coil::normalize(m_properties["consumer_types"]) != "all") { RTC_DEBUG(("allowed consumers: %s", m_properties["consumer_types"].c_str())); coil::vstring temp_types(consumer_types); consumer_types.clear(); coil::vstring active_types(coil::split(m_properties["consumer_types"], ",")); std::sort(temp_types.begin(), temp_types.end()); std::sort(active_types.begin(), active_types.end()); std::set_intersection(temp_types.begin(), temp_types.end(), active_types.begin(), active_types.end(), std::back_inserter(consumer_types)); } #endif // InPortConsumer supports "push" dataflow type if (consumer_types.size() > 0) { RTC_PARANOID(("dataflow_type push is supported")); appendProperty("dataport.dataflow_type", "push"); appendProperty("dataport.interface_type", coil::flatten(consumer_types).c_str()); } m_consumerTypes = consumer_types; } /*! * @if jp * @brief シリアライザのエンディアンをチェックする * @else * @brief Checking endian flag of serializer * @endif */ bool OutPortBase::checkEndian(const coil::Properties& prop, bool& littleEndian) { // old version check if(prop.hasKey("serializer") == NULL) { littleEndian = true; return true; } // endian type check std::string endian_type(prop.getProperty("serializer.cdr.endian", "")); RTC_DEBUG(("endian_type: %s", endian_type.c_str())); coil::normalize(endian_type); std::vector<std::string> endian(coil::split(endian_type, ",")); if(endian.empty()) { return false; } if(endian[0] == "little") { littleEndian = true; return true; } else if(endian[0] == "big") { littleEndian = false; return true; } return false; } /*! * @if jp * @brief OutPort provider の生成 * @else * @brief OutPort provider creation * @endif */ OutPortProvider* OutPortBase::createProvider(ConnectorProfile& cprof, coil::Properties& prop) { if (!prop["interface_type"].empty() && !coil::includes((coil::vstring)m_providerTypes, prop["interface_type"])) { RTC_ERROR(("no provider found")); RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); RTC_DEBUG(("interface_types: %s", coil::flatten(m_providerTypes).c_str())); return 0; } RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); OutPortProvider* provider; provider = OutPortProviderFactory:: instance().createObject(prop["interface_type"].c_str()); if (provider != 0) { RTC_TRACE(("provider created")); provider->init(prop.getNode("provider")); #ifndef ORB_IS_RTORB if (!provider->publishInterface(cprof.properties)) { RTC_ERROR(("publishing interface information error")); OutPortProviderFactory::instance().deleteObject(provider); return 0; } #else // ORB_IS_RTORB ::SDOPackage::NVList_ptr prop_ref(cprof.properties); if (!provider->publishInterface(*prop_ref)) { RTC_ERROR(("publishing interface information error")); OutPortProviderFactory::instance().deleteObject(provider); return 0; } #endif // ORB_IS_RTORB return provider; } RTC_ERROR(("provider creation failed")); return 0; } /*! * @if jp * @brief InPort consumer の生成 * @else * @brief InPort consumer creation * @endif */ InPortConsumer* OutPortBase::createConsumer(const ConnectorProfile& cprof, coil::Properties& prop) { if (!prop["interface_type"].empty() && !coil::includes((coil::vstring)m_consumerTypes, prop["interface_type"])) { RTC_ERROR(("no consumer found")); RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); RTC_DEBUG(("interface_types: %s", coil::flatten(m_consumerTypes).c_str())); return 0; } RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str())); InPortConsumer* consumer; consumer = InPortConsumerFactory:: instance().createObject(prop["interface_type"].c_str()); if (consumer != 0) { RTC_TRACE(("consumer created")); consumer->init(prop.getNode("consumer")); if (!consumer->subscribeInterface(cprof.properties)) { RTC_ERROR(("interface subscription failed.")); InPortConsumerFactory::instance().deleteObject(consumer); return 0; } return consumer; } RTC_ERROR(("consumer creation failed")); return 0; } /*! * @if jp * @brief OutPortPushConnector の生成 * @else * @brief OutPortPushConnector creation * @endif */ OutPortConnector* OutPortBase::createConnector(const ConnectorProfile& cprof, coil::Properties& prop, InPortConsumer* consumer) { #ifndef ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil::refToVstring(cprof.ports), prop); #else // ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil:: refToVstring(RTC::PortServiceList(cprof.ports)), prop); #endif // ORB_IS_RTORB OutPortConnector* connector(0); try { connector = new OutPortPushConnector(profile, consumer, m_listeners); if (connector == 0) { RTC_ERROR(("old compiler? new returned 0;")); return 0; } RTC_TRACE(("OutPortPushConnector created")); // endian type set connector->setEndian(m_littleEndian); m_connectors.push_back(connector); RTC_PARANOID(("connector pushback done: size = %d", m_connectors.size())); return connector; } catch (std::bad_alloc& e) { RTC_ERROR(("OutPortPushConnector creation failed")); return 0; } RTC_FATAL(("never comes here: createConnector()")); return 0; } /*! * @if jp * @brief OutPortPullConnector の生成 * @else * @brief OutPortPullConnector creation * @endif */ OutPortConnector* OutPortBase::createConnector(const ConnectorProfile& cprof, coil::Properties& prop, OutPortProvider* provider) { RTC_VERBOSE(("createConnector()")); #ifndef ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil::refToVstring(cprof.ports), prop); #else // ORB_IS_RTORB ConnectorInfo profile(cprof.name, cprof.connector_id, CORBA_SeqUtil:: refToVstring(RTC::PortServiceList(cprof.ports)), prop); #endif // ORB_IS_RTORB OutPortConnector* connector(0); try { connector = new OutPortPullConnector(profile, provider, m_listeners); if (connector == 0) { RTC_ERROR(("old compiler? new returned 0;")); return 0; } RTC_TRACE(("OutPortPullConnector created")); m_connectors.push_back(connector); RTC_PARANOID(("connector pushback done: size = %d", m_connectors.size())); return connector; } catch (std::bad_alloc& e) { RTC_ERROR(("OutPortPullConnector creation failed")); return 0; } RTC_FATAL(("never comes here: createConnector()")); return 0; } }; // end of namespace RTM
622  * などがアクセス可能になる。
623  */
624  std::string& dflow_type(prop["dataflow_type"]);
625  coil::normalize(dflow_type);
626 
627  if (dflow_type == "push")
628  {
629  RTC_PARANOID(("dataflow_type is push."));
630 
631  // interface
632  InPortConsumer* consumer(createConsumer(cprof, prop));
633  if (consumer == 0)
634  {
635  return RTC::BAD_PARAMETER;
636  }
637 
638  // create OutPortPushConnector
639  OutPortConnector* connector(createConnector(cprof, prop, consumer));
640  if (connector == 0)
641  {
642  return RTC::RTC_ERROR;
643  }
644 
645  RTC_DEBUG(("subscribeInterfaces() successfully finished."));
646  return RTC::RTC_OK;
647  }
648  else if (dflow_type == "pull")
649  {
650  RTC_PARANOID(("dataflow_type is pull."));
651 
652  // set endian type
653  OutPortConnector* conn(getConnectorById(cprof.connector_id));
654  if (conn == 0)
655  {
656  RTC_ERROR(("specified connector not found: %s",
657  (const char*)cprof.connector_id));
658  return RTC::RTC_ERROR;
659  }
660  conn->setEndian(littleEndian);
661  RTC_DEBUG(("subscribeInterfaces() successfully finished."));
662  return RTC::RTC_OK;
663  }
664 
665  RTC_ERROR(("unsupported dataflow_type: %s", dflow_type.c_str()));
666  return RTC::BAD_PARAMETER;
667  }
668 
676  void
677  OutPortBase::unsubscribeInterfaces(const ConnectorProfile& connector_profile)
678  {
679  RTC_TRACE(("unsubscribeInterfaces()"));
680 
681  std::string id(connector_profile.connector_id);
682  RTC_PARANOID(("connector_id: %s", id.c_str()));
683 
684  ConnectorList::iterator it(m_connectors.begin());
685 
686  while (it != m_connectors.end())
687  {
688  if (id == (*it)->id())
689  {
690  // Connector's dtor must call disconnect()
691  delete *it;
692  m_connectors.erase(it);
693  RTC_TRACE(("delete connector: %s", id.c_str()));
694  return;
695  }
696  ++it;
697  }
698  RTC_ERROR(("specified connector not found: %s", id.c_str()));
699  return;
700  }
701 
710  {
711  RTC_TRACE(("initProviders()"));
712 
713  // create OutPort providers
715  coil::vstring provider_types(factory.getIdentifiers());
716  RTC_PARANOID(("available OutPortProviders: %s",
717  coil::flatten(provider_types).c_str()));
718 
719 #ifndef RTC_NO_DATAPORTIF_ACTIVATION_OPTION
720  if (m_properties.hasKey("provider_types") &&
721  coil::normalize(m_properties["provider_types"]) != "all")
722  {
723  RTC_DEBUG(("allowed providers: %s",
724  m_properties["provider_types"].c_str()));
725 
726  coil::vstring temp_types(provider_types);
727  provider_types.clear();
729  active_types(coil::split(m_properties["provider_types"], ","));
730 
731  std::sort(temp_types.begin(), temp_types.end());
732  std::sort(active_types.begin(), active_types.end());
733  std::set_intersection(temp_types.begin(), temp_types.end(),
734  active_types.begin(), active_types.end(),
735  std::back_inserter(provider_types));
736  }
737 #endif
738 
739  // OutPortProvider supports "pull" dataflow type
740  if (provider_types.size() > 0)
741  {
742  RTC_DEBUG(("dataflow_type pull is supported"));
743  appendProperty("dataport.dataflow_type", "pull");
744  appendProperty("dataport.interface_type",
745  coil::flatten(provider_types).c_str());
746  }
747 
748  m_providerTypes = provider_types;
749  }
750 
759  {
760  RTC_TRACE(("initConsumers()"));
761 
762  // create InPort consumers
764  coil::vstring consumer_types(factory.getIdentifiers());
765  RTC_PARANOID(("available InPortConsumer: %s",
766  coil::flatten(consumer_types).c_str()));
767 
768 #ifndef RTC_NO_DATAPORTIF_ACTIVATION_OPTION
769  if (m_properties.hasKey("consumer_types") &&
770  coil::normalize(m_properties["consumer_types"]) != "all")
771  {
772  RTC_DEBUG(("allowed consumers: %s",
773  m_properties["consumer_types"].c_str()));
774 
775  coil::vstring temp_types(consumer_types);
776  consumer_types.clear();
778  active_types(coil::split(m_properties["consumer_types"], ","));
779 
780  std::sort(temp_types.begin(), temp_types.end());
781  std::sort(active_types.begin(), active_types.end());
782  std::set_intersection(temp_types.begin(), temp_types.end(),
783  active_types.begin(), active_types.end(),
784  std::back_inserter(consumer_types));
785  }
786 #endif
787 
788  // InPortConsumer supports "push" dataflow type
789  if (consumer_types.size() > 0)
790  {
791  RTC_PARANOID(("dataflow_type push is supported"));
792  appendProperty("dataport.dataflow_type", "push");
793  appendProperty("dataport.interface_type",
794  coil::flatten(consumer_types).c_str());
795  }
796 
797  m_consumerTypes = consumer_types;
798  }
799 
808  bool& littleEndian)
809  {
810  // old version check
811  if(prop.hasKey("serializer") == NULL)
812  {
813  littleEndian = true;
814  return true;
815  }
816 
817  // endian type check
818  std::string endian_type(prop.getProperty("serializer.cdr.endian", ""));
819  RTC_DEBUG(("endian_type: %s", endian_type.c_str()));
820  coil::normalize(endian_type);
821  std::vector<std::string> endian(coil::split(endian_type, ","));
822 
823  if(endian.empty()) { return false; }
824  if(endian[0] == "little")
825  {
826  littleEndian = true;
827  return true;
828  }
829  else if(endian[0] == "big")
830  {
831  littleEndian = false;
832  return true;
833  }
834  return false;
835  }
836 
846  {
847  if (!prop["interface_type"].empty() &&
848  !coil::includes((coil::vstring)m_providerTypes, prop["interface_type"]))
849  {
850  RTC_ERROR(("no provider found"));
851  RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str()));
852  RTC_DEBUG(("interface_types: %s",
853  coil::flatten(m_providerTypes).c_str()));
854  return 0;
855  }
856 
857  RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str()));
859  provider = OutPortProviderFactory::
860  instance().createObject(prop["interface_type"].c_str());
861 
862  if (provider != 0)
863  {
864  RTC_TRACE(("provider created"));
865  provider->init(prop.getNode("provider"));
866 
867 #ifndef ORB_IS_RTORB
868  if (!provider->publishInterface(cprof.properties))
869  {
870  RTC_ERROR(("publishing interface information error"));
871  OutPortProviderFactory::instance().deleteObject(provider);
872  return 0;
873  }
874 #else // ORB_IS_RTORB
875  ::SDOPackage::NVList_ptr prop_ref(cprof.properties);
876  if (!provider->publishInterface(*prop_ref))
877  {
878  RTC_ERROR(("publishing interface information error"));
879  OutPortProviderFactory::instance().deleteObject(provider);
880  return 0;
881  }
882 #endif // ORB_IS_RTORB
883  return provider;
884  }
885 
886  RTC_ERROR(("provider creation failed"));
887  return 0;
888  }
889 
890 
898  InPortConsumer* OutPortBase::createConsumer(const ConnectorProfile& cprof,
900  {
901  if (!prop["interface_type"].empty() &&
902  !coil::includes((coil::vstring)m_consumerTypes, prop["interface_type"]))
903  {
904  RTC_ERROR(("no consumer found"));
905  RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str()));
906  RTC_DEBUG(("interface_types: %s",
907  coil::flatten(m_consumerTypes).c_str()));
908  return 0;
909  }
910 
911  RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str()));
912  InPortConsumer* consumer;
913  consumer = InPortConsumerFactory::
914  instance().createObject(prop["interface_type"].c_str());
915 
916  if (consumer != 0)
917  {
918  RTC_TRACE(("consumer created"));
919  consumer->init(prop.getNode("consumer"));
920 
921  if (!consumer->subscribeInterface(cprof.properties))
922  {
923  RTC_ERROR(("interface subscription failed."));
924  InPortConsumerFactory::instance().deleteObject(consumer);
925  return 0;
926  }
927 
928  return consumer;
929  }
930 
931  RTC_ERROR(("consumer creation failed"));
932  return 0;
933  }
934 
943  OutPortBase::createConnector(const ConnectorProfile& cprof,
945  InPortConsumer* consumer)
946  {
947 #ifndef ORB_IS_RTORB
948  ConnectorInfo profile(cprof.name,
949  cprof.connector_id,
950  CORBA_SeqUtil::refToVstring(cprof.ports),
951  prop);
952 #else // ORB_IS_RTORB
953  ConnectorInfo profile(cprof.name,
954  cprof.connector_id,
955  CORBA_SeqUtil::
956  refToVstring(RTC::PortServiceList(cprof.ports)),
957  prop);
958 #endif // ORB_IS_RTORB
959 
960  OutPortConnector* connector(0);
961  try
962  {
963  connector = new OutPortPushConnector(profile, consumer, m_listeners);
964 
965  if (connector == 0)
966  {
967  RTC_ERROR(("old compiler? new returned 0;"));
968  return 0;
969  }
970  RTC_TRACE(("OutPortPushConnector created"));
971 
972  // endian type set
973  connector->setEndian(m_littleEndian);
974  m_connectors.push_back(connector);
975  RTC_PARANOID(("connector pushback done: size = %d",
976  m_connectors.size()));
977  return connector;
978  }
979  catch (std::bad_alloc& e)
980  {
981  RTC_ERROR(("OutPortPushConnector creation failed"));
982  return 0;
983  }
984  RTC_FATAL(("never comes here: createConnector()"));
985  return 0;
986  }
987 
996  OutPortBase::createConnector(const ConnectorProfile& cprof,
999  {
1000  RTC_VERBOSE(("createConnector()"));
1001 #ifndef ORB_IS_RTORB
1002  ConnectorInfo profile(cprof.name,
1003  cprof.connector_id,
1004  CORBA_SeqUtil::refToVstring(cprof.ports),
1005  prop);
1006 #else // ORB_IS_RTORB
1007  ConnectorInfo profile(cprof.name,
1008  cprof.connector_id,
1009  CORBA_SeqUtil::
1010  refToVstring(RTC::PortServiceList(cprof.ports)),
1011  prop);
1012 #endif // ORB_IS_RTORB
1013 
1014  OutPortConnector* connector(0);
1015  try
1016  {
1017  connector = new OutPortPullConnector(profile, provider, m_listeners);
1018 
1019  if (connector == 0)
1020  {
1021  RTC_ERROR(("old compiler? new returned 0;"));
1022  return 0;
1023  }
1024  RTC_TRACE(("OutPortPullConnector created"));
1025 
1026  m_connectors.push_back(connector);
1027  RTC_PARANOID(("connector pushback done: size = %d", m_connectors.size()));
1028  return connector;
1029  }
1030  catch (std::bad_alloc& e)
1031  {
1032  RTC_ERROR(("OutPortPullConnector creation failed"));
1033  return 0;
1034  }
1035  RTC_FATAL(("never comes here: createConnector()"));
1036  return 0;
1037  }
1038 
1039 }; // end of namespace RTM
SDOPackage::NameValue newNV(const char *name, Value value)
Create NameValue.
Definition: NVUtil.h:79
void removeListener(ConnectorListener *listener)
Remove the listener.
OutPortConnector * getConnectorById(const char *id)
Getting ConnectorProfile by ID.
void configure()
Configureing outport.
InPortConsumer abstract class.
#define RTC_ERROR(fmt)
Error log output macro.
Definition: SystemLogger.h:422
virtual ~OutPortBase(void)
Destructor.
void initProviders()
OutPort provider initialization.
std::string normalize(std::string &str)
Erase the head/tail blank and replace upper case to lower case.
Definition: stringutil.cpp:303
ConnectorInfoList getConnectorProfiles()
ConnectorProfile list.
void addConnectorDataListener(ConnectorDataListenerType listener_type, ConnectorDataListener *listener, bool autoclean=true)
Adding BufferDataListener type listener.
virtual void init(coil::Properties &prop)=0
Initializing configuration.
coil::vstring getConnectorNames()
Connector name list.
RT-Component.
coil::vstring getConnectorIds()
ConnectorId list.
OutPortConnector * getConnectorByName(const char *name)
Getting Connector by name.
std::vector< OutPortConnector * > m_connectors
Connection list.
Definition: OutPortBase.h:1032
void initConsumers()
InPort consumer initialization.
bool stringTo(To &val, const char *str)
Convert the given std::string to object.
Definition: stringutil.h:597
ConnectorDataListener class.
void addConnectorListener(ConnectorListenerType callback_type, ConnectorListener *listener, bool autoclean=true)
Adding ConnectorListener type listener.
ReturnCode_t
Definition: doil.h:53
void addListener(ConnectorDataListener *listener, bool autoclean)
Add the listener.
ConnectorListenerHolder connector_[CONNECTOR_LISTENER_NUM]
ConnectorListenerType listener array The ConnectorListenerType listener is stored.
virtual void setConnector(OutPortConnector *connector)=0
set Connector
void removeListener(ConnectorDataListener *listener)
Remove the listener.
coil::Properties m_properties
Properties.
Definition: OutPortBase.h:1024
void eraseBlank(std::string &str)
Erase blank characters of string.
Definition: stringutil.cpp:237
void removeConnectorListener(ConnectorListenerType callback_type, ConnectorListener *listener)
Removing BufferDataListener type listener.
virtual void setEndian(const bool endian_type)
Setting an endian type.
ConnectorListeners m_listeners
ConnectorDataListener listener.
Definition: OutPortBase.h:1064
virtual ReturnCode_t connect(ConnectorProfile &connector_profile)
[CORBA interface] Connect the Port
Definition: PortBase.cpp:181
vstring split(const std::string &input, const std::string &delimiter, bool ignore_empty)
Split string by delimiter.
Definition: stringutil.cpp:341
virtual void unsubscribeInterfaces(const ConnectorProfile &connector_profile)
Disconnect the interface connection.
std::vector< ConnectorInfo > ConnectorInfoList
Properties * hasKey(const char *key) const
Check whether key exists in the children.
Definition: Properties.cpp:517
void addListener(ConnectorListener *listener, bool autoclean)
Add the listener.
static GlobalFactory< AbstractClass, Identifier, Compare, Creator, Destructor > & instance()
Create instance.
Definition: Singleton.h:131
bool isLittleEndian()
return it whether endian setting.
GlobalFactory template class.
OutPortConnector * createConnector(const ConnectorProfile &cprof, coil::Properties &prop, InPortConsumer *consumer)
OutPortPushConnector creation.
void operator()(OutPortConnector *c)
Definition: OutPortBase.cpp:67
virtual ReturnCode_t publishInterfaces(ConnectorProfile &connector_profile)
Publish interface information.
#define RTC_WARN(fmt)
Warning log output macro.
Definition: SystemLogger.h:444
#define RTC_FATAL(fmt)
Error log output macro.
Definition: SystemLogger.h:400
#define RTC_DEBUG_STR(str)
Definition: SystemLogger.h:489
#define RTC_PARANOID(fmt)
Paranoid level log output macro.
Definition: SystemLogger.h:555
std::vector< Identifier > getIdentifiers()
Get factory ID list.
std::vector< std::string > vstring
Definition: stringutil.h:37
ConnectorDataListenerType
The types of ConnectorDataListener.
const CORBA::Long find_index(const SDOPackage::NVList &nv, const char *name)
Return the index of element specified by name from NVList.
Definition: NVUtil.cpp:227
static const char * toString(ConnectorListenerType type)
Convert ConnectorListenerType into the string.
Connector base class.
void removeConnectorDataListener(ConnectorDataListenerType listener_type, ConnectorDataListener *listener)
Removing BufferDataListener type listener.
ConnectorDataListenerHolder connectorData_[CONNECTOR_DATA_LISTENER_NUM]
ConnectorDataListenerType listener array The ConnectorDataListenerType listener is stored...
void appendProperty(const char *key, const char *value)
Append NameValue data to PortProfile&#39;s properties.
Definition: PortBase.h:1907
#define RTC_DEBUG(fmt)
Debug level log output macro.
Definition: SystemLogger.h:488
std::string flatten(vstring sv)
Create CSV file from the given string list.
Definition: stringutil.cpp:549
void copyToProperties(coil::Properties &prop, const SDOPackage::NVList &nv)
Copy NVList to the Proeprties.
Definition: NVUtil.cpp:137
#define RTC_TRACE(fmt)
bool getConnectorProfileById(const char *id, ConnectorInfo &prof)
Getting ConnectorProfile by name.
list index
Definition: rtimages.py:10
Push type connector class.
void deleteObject(const Identifier &id, AbstractClass *&obj)
Delete factory object.
bool m_littleEndian
Connected Endian.
Definition: OutPortBase.h:1056
OutPortBase(const char *name, const char *data_type)
Constructor.
Definition: OutPortBase.cpp:81
void init(coil::Properties &prop)
Initializing properties.
virtual ReturnCode_t connect(ConnectorProfile &connector_profile)
[CORBA interface] Connect the Port
OutPortProvider * createProvider(ConnectorProfile &cprof, coil::Properties &prop)
OutPort provider creation.
coil::vstring m_consumerTypes
Available consumers.
Definition: OutPortBase.h:1048
prop
Organization::get_organization_property ();.
Publisher base class.
InPortBase base class.
virtual void init(coil::Properties &prop)
Initializing configuration.
ConnectorListenerType
The types of ConnectorListener.
Functor to delete Providers.
Definition: OutPortBase.cpp:42
Class represents a set of properties.
Definition: Properties.h:101
static const char * toString(ConnectorDataListenerType type)
Convert ConnectorDataListenerType into the string.
bool checkEndian(const coil::Properties &prop, bool &littleEndian)
Checking endian flag of serializer.
std::vector< IPortService * > PortServiceList
Definition: IPortService.h:39
OutPortPull type connector class.
virtual void activateInterfaces()
Activate all Port interfaces.
bool getConnectorProfileByName(const char *name, ConnectorInfo &prof)
Getting ConnectorProfile by name.
coil::vstring m_providerTypes
Available providers.
Definition: OutPortBase.h:1040
virtual bool publishInterface(SDOPackage::NVList &properties)
Publish interface information.
void operator()(OutPortProvider *p)
Definition: OutPortBase.cpp:48
void push_back(CorbaSequence &seq, SequenceElement elem)
Push the new element back to the CORBA sequence.
Functor to delete Connectors.
Definition: OutPortBase.cpp:62
virtual ReturnCode_t subscribeInterfaces(const ConnectorProfile &connector_profile)
Subscribe to the interface.
Properties & getNode(const std::string &key)
Get node of properties.
Definition: Properties.cpp:455
const std::vector< OutPortConnector * > & connectors()
Connector list.
bool includes(const vstring &list, std::string value, bool ignore_case)
Include if a string is included in string list.
Definition: stringutil.cpp:432
InPortConsumer * createConsumer(const ConnectorProfile &cprof, coil::Properties &prop)
InPort consumer creation.
coil::vstring refToVstring(const CorbaRefSequence &objlist)
void addProperty(const char *key, ValueType value)
Add NameValue data to PortProfile&#39;s properties.
Definition: PortBase.h:1876
CORBA IOR helper functions.
virtual void deactivateInterfaces()
Deactivate all Port interfaces.
#define RTC_VERBOSE(fmt)
Verbose level log output macro.
Definition: SystemLogger.h:533
Functor for_each(CorbaSequence &seq, Functor f)
Apply the functor to all CORBA sequence elements.
Definition: CORBA_SeqUtil.h:98
const ConnectorInfo & profile()
Getting Profile.
#define RTC_PARANOID_STR(str)
Definition: SystemLogger.h:556
virtual ReturnCode_t _publishInterfaces(void)
Publish interface information.
Definition: PortBase.cpp:315
OutPortProviderFactory & m_factory
Definition: OutPortBase.cpp:52
virtual void setConnectionLimit(int limit_value)
Set the maximum number of connections.
Definition: PortBase.cpp:700
virtual bool subscribeInterface(const SDOPackage::NVList &properties)=0
Subscribe the data send notification.
const std::string & getProperty(const std::string &key) const
Search for the property with the specified key in this property.
Definition: Properties.cpp:156
coil::Properties & properties()
Get properties.


openrtm_aist
Author(s): Noriaki Ando
autogenerated on Mon Jun 10 2019 14:07:53