00001
00019 #include <rtm/RTC.h>
00020 #include <rtm/PeriodicECSharedComposite.h>
00021 #include <rtm/Manager.h>
00022 #include <string>
00023 #include <iostream>
00024 #include <iterator>
00025
00026
00027 static const char* periodicecsharedcomposite_spec[] =
00028 {
00029 "implementation_id", "PeriodicECSharedComposite",
00030 "type_name", "PeriodicECSharedComposite",
00031 "description", "PeriodicECSharedComposite",
00032 "version", "1.0",
00033 "vendor", "jp.go.aist",
00034 "category", "composite.PeriodicECShared",
00035 "activity_type", "DataFlowComponent",
00036 "max_instance", "0",
00037 "language", "C++",
00038 "lang_type", "compile",
00039 "exported_ports", "",
00040 "conf.default.members", "",
00041 "conf.default.exported_ports", "",
00042 ""
00043 };
00044
00045 namespace SDOPackage
00046 {
00054 PeriodicECOrganization::PeriodicECOrganization(::RTC::RTObject_impl* rtobj)
00055 : Organization_impl(rtobj->getObjRef()),
00056 rtclog("PeriodicECOrganization"),
00057 m_rtobj(rtobj),
00058 m_ec(::RTC::ExecutionContext::_nil())
00059 {
00060 }
00061
00069 PeriodicECOrganization::~PeriodicECOrganization()
00070 {
00071 ;
00072 }
00073
00081 CORBA::Boolean PeriodicECOrganization::add_members(const SDOList& sdo_list)
00082 throw (CORBA::SystemException,
00083 InvalidParameter, NotAvailable, InternalError)
00084 {
00085 RTC_DEBUG(("add_members()"));
00086
00087 updateExportedPortsList();
00088
00089 for (::CORBA::ULong i(0), len(sdo_list.length()); i < len; ++i)
00090 {
00091 const SDO_var sdo(sdo_list[i]);
00092 ::OpenRTM::DataFlowComponent_var dfc;
00093 #ifndef ORB_IS_RTORB
00094 if (!sdoToDFC(sdo.in(), dfc.out())) { continue; }
00095 #else // ORB_IS_RTORB
00096 ::OpenRTM::DataFlowComponent_ptr dfc_ptr(dfc.object());
00097 if (!sdoToDFC(sdo.in(), dfc_ptr)) { continue; }
00098 #endif // ORB_IS_RTORB
00099
00100 Member member(dfc.in());
00101 stopOwnedEC(member);
00102 addOrganizationToTarget(member);
00103 addParticipantToEC(member);
00104 addPort(member, m_expPorts);
00105 m_rtcMembers.push_back(member);
00106 }
00107
00108 CORBA::Boolean result;
00109 result = ::SDOPackage::Organization_impl::add_members(sdo_list);
00110
00111 return result;
00112 }
00113
00121 CORBA::Boolean PeriodicECOrganization::set_members(const SDOList& sdo_list)
00122 throw (CORBA::SystemException,
00123 InvalidParameter, NotAvailable, InternalError)
00124 {
00125
00126 RTC_DEBUG(("set_members()"));
00127 removeAllMembers();
00128 updateExportedPortsList();
00129
00130 for (::CORBA::ULong i(0), len(sdo_list.length()); i < len; ++i)
00131 {
00132 #ifndef ORB_IS_RTORB
00133 const SDO_var sdo = sdo_list[i];
00134 ::OpenRTM::DataFlowComponent_var dfc;
00135 if (!sdoToDFC(sdo.in(), dfc.out())) { continue; }
00136 #else // ORB_IS_RTORB
00137 const SDO_var sdo = sdo_list[i].object();
00138
00139 ::OpenRTM::DataFlowComponent_var dfc;
00140 ::OpenRTM::DataFlowComponent_ptr dfc_ptr(dfc);
00141
00142 if (!sdoToDFC(sdo.in(), dfc_ptr)) { continue; }
00143 #endif // ORB_IS_RTORB
00144
00145 Member member(dfc.in());
00146
00147
00148 stopOwnedEC(member);
00149 addOrganizationToTarget(member);
00150 addParticipantToEC(member);
00151 addPort(member, m_expPorts);
00152 m_rtcMembers.push_back(member);
00153 }
00154
00155 CORBA::Boolean result;
00156 result = ::SDOPackage::Organization_impl::set_members(sdo_list);
00157
00158 return result;
00159 }
00160
00168 CORBA::Boolean PeriodicECOrganization::remove_member(const char* id)
00169 throw (CORBA::SystemException,
00170 InvalidParameter, NotAvailable, InternalError)
00171 {
00172 RTC_DEBUG(("remove_member(id = %s)", id));
00173 for (MemIt it(m_rtcMembers.begin()); it != m_rtcMembers.end();)
00174 {
00175 Member& member(*it);
00176 if (strncmp(id, member.profile_->instance_name, strlen(id)))
00177 {
00178 ++it;
00179 continue;
00180 }
00181
00182 removePort(member, m_expPorts);
00183 m_rtobj->getProperties()["conf.default.exported_ports"] =
00184 ::coil::flatten(m_expPorts);
00185
00186 removeParticipantFromEC(member);
00187 removeOrganizationFromTarget(member);
00188 startOwnedEC(member);
00189 it = m_rtcMembers.erase(it);
00190 }
00191
00192 CORBA::Boolean result;
00193 result = ::SDOPackage::Organization_impl::remove_member(id);
00194 return result;
00195 }
00196
00204 void PeriodicECOrganization::removeAllMembers()
00205 {
00206 RTC_TRACE(("removeAllMembers()"));
00207 updateExportedPortsList();
00208 MemIt it(m_rtcMembers.begin());
00209 MemIt it_end(m_rtcMembers.end());
00210 while (it != it_end)
00211 {
00212 Member& member(*it);
00213 removePort(member, m_expPorts);
00214 removeParticipantFromEC(member);
00215 removeOrganizationFromTarget(member);
00216 startOwnedEC(member);
00217 ::SDOPackage::Organization_impl::remove_member(member.profile_->instance_name);
00218 ++it;
00219 }
00220 m_rtcMembers.clear();
00221 m_expPorts.clear();
00222 }
00223
00231 bool
00232 PeriodicECOrganization::sdoToDFC(const SDO_ptr sdo,
00233 ::OpenRTM::DataFlowComponent_ptr& dfc)
00234 {
00235 if (::CORBA::is_nil(sdo)) return false;
00236
00237
00238 dfc = ::OpenRTM::DataFlowComponent::_narrow(sdo);
00239 if (::CORBA::is_nil(dfc)) return false;
00240 return true;
00241 }
00242
00250 void PeriodicECOrganization::stopOwnedEC(Member& member)
00251 {
00252
00253 ::RTC::ExecutionContextList_var ecs(member.eclist_);
00254 for (::CORBA::ULong i(0), len(ecs->length()); i < len; ++i)
00255 {
00256 ecs[i]->stop();
00257 }
00258 return;
00259 }
00260
00268 void PeriodicECOrganization::startOwnedEC(Member& member)
00269 {
00270
00271 ::RTC::ExecutionContextList_var ecs(member.eclist_);
00272 for (::CORBA::ULong i(0), len(ecs->length()); i < len; ++i)
00273 {
00274 ecs[i]->start();
00275 }
00276 return;
00277 }
00278
00286 void PeriodicECOrganization::addOrganizationToTarget(Member& member)
00287 {
00288
00289
00290 Configuration_var conf(member.config_);
00291 if (::CORBA::is_nil(conf)) return;
00292
00293
00294 conf->add_organization(m_objref);
00295 }
00296
00304 void PeriodicECOrganization::removeOrganizationFromTarget(Member& member)
00305 {
00306
00307 if (::CORBA::is_nil(member.config_)) { return; }
00308
00309
00310 member.config_->remove_organization(m_pId.c_str());
00311 }
00312
00320 void PeriodicECOrganization::addParticipantToEC(Member& member)
00321 {
00322 if (::CORBA::is_nil(m_ec))
00323 {
00324 ::RTC::ExecutionContextList_var ecs(m_rtobj->get_owned_contexts());
00325 if (ecs->length() > 0)
00326 {
00327 m_ec = ecs[0];
00328 }
00329 else
00330 {
00331 return;
00332 }
00333 }
00334
00335 m_ec->add_component(member.rtobj_.in());
00336
00337 OrganizationList_var orglist = member.rtobj_->get_organizations();
00338 for (CORBA::ULong i(0); i < orglist->length(); ++i)
00339 {
00340 SDOList_var sdos = orglist[i]->get_members();
00341 for (CORBA::ULong j(0); j < sdos->length(); ++j)
00342 {
00343 #ifndef ORB_IS_RTORB
00344 ::OpenRTM::DataFlowComponent_var dfc;
00345 if (!sdoToDFC(sdos[j].in(), dfc.out())) { continue; }
00346 #else // ORB_IS_RTORB
00347 ::OpenRTM::DataFlowComponent_var dfc;
00348 ::OpenRTM::DataFlowComponent_ptr dfc_ptr(dfc);
00349 if (!sdoToDFC(sdos[j].in(), dfc_ptr)) { continue; }
00350 #endif // ORB_IS_RTORB
00351 m_ec->add_component(dfc.in());
00352 }
00353 }
00354
00355
00356 }
00357
00365 void PeriodicECOrganization::removeParticipantFromEC(Member& member)
00366 {
00367 if (::CORBA::is_nil(m_ec))
00368 {
00369 ::RTC::ExecutionContextList_var ecs(m_rtobj->get_owned_contexts());
00370 if (ecs->length() == 0)
00371 {
00372 RTC_FATAL(("no owned EC"));
00373 return;
00374 }
00375 m_ec = ecs[0];
00376 }
00377 m_ec->remove_component(member.rtobj_.in());
00378
00379 OrganizationList_var orglist = member.rtobj_->get_organizations();
00380 for (CORBA::ULong i(0); i < orglist->length(); ++i)
00381 {
00382 SDOList_var sdos = orglist[i]->get_members();
00383 for (CORBA::ULong j(0); j < sdos->length(); ++j)
00384 {
00385 #ifndef ORB_IS_RTORB
00386 ::OpenRTM::DataFlowComponent_var dfc;
00387 if (!sdoToDFC(sdos[j].in(), dfc.out())) { continue; }
00388 #else // ORB_IS_RTORB
00389 ::OpenRTM::DataFlowComponent_var dfc;
00390 ::OpenRTM::DataFlowComponent_ptr dfc_ptr(dfc);
00391 if (!sdoToDFC(sdos[j].in(), dfc_ptr)) { continue; }
00392 #endif // ORB_IS_RTORB
00393 m_ec->remove_component(dfc.in());
00394 }
00395 }
00396 }
00397
00405 void
00406 PeriodicECOrganization::addPort(Member& member,
00407 PortList& portlist)
00408 {
00409 RTC_TRACE(("addPort(%s)", ::coil::flatten(portlist).c_str()));
00410 if (portlist.size() == 0) { return; }
00411
00412 std::string comp_name(member.profile_->instance_name);
00413 #ifndef ORB_IS_RTORB
00414 ::RTC::PortProfileList& plist(member.profile_->port_profiles);
00415 #else // ORB_IS_RTORB
00416 ::RTC::PortProfileList plist(member.profile_->port_profiles);
00417 #endif // ORB_IS_RTORB
00418
00419
00420 for (::CORBA::ULong i(0), len(plist.length()); i < len; ++i)
00421 {
00422 std::string port_name(plist[i].name);
00423
00424 RTC_DEBUG(("port_name: %s is in %s?",
00425 port_name.c_str(),
00426 ::coil::flatten(portlist).c_str()));
00427
00428 std::vector<std::string>::iterator pos =
00429 std::find(portlist.begin(), portlist.end(), port_name);
00430 if (pos == portlist.end())
00431 {
00432 RTC_DEBUG(("Not found: %s is in %s?",
00433 port_name.c_str(),
00434 ::coil::flatten(portlist).c_str()));
00435 continue;
00436 }
00437
00438 RTC_DEBUG(("Found: %s is in %s",
00439 port_name.c_str(),
00440 ::coil::flatten(portlist).c_str()));
00441
00442 m_rtobj->addPort(plist[i].port_ref);
00443
00444 RTC_DEBUG(("Port %s was delegated.", port_name.c_str()));
00445
00446 }
00447 }
00448
00456 void PeriodicECOrganization::removePort(Member& member,
00457 PortList& portlist)
00458 {
00459 RTC_TRACE(("removePort(%s)", coil::flatten(portlist).c_str()));
00460 if (portlist.size() == 0) { return; }
00461
00462 std::string comp_name(member.profile_->instance_name);
00463 #ifndef ORB_IS_RTORB
00464 ::RTC::PortProfileList& plist(member.profile_->port_profiles);
00465 #else // ORB_IS_RTORB
00466 ::RTC::PortProfileList plist(member.profile_->port_profiles);
00467 #endif // ORB_IS_RTORB
00468
00469
00470 for (::CORBA::ULong i(0), len(plist.length()); i < len; ++i)
00471 {
00472
00473 std::string port_name(plist[i].name);
00474
00475 RTC_DEBUG(("port_name: %s is in %s?",
00476 port_name.c_str(),
00477 ::coil::flatten(portlist).c_str()));
00478
00479 std::vector<std::string>::iterator pos =
00480 std::find(portlist.begin(), portlist.end(), port_name);
00481 if (pos == portlist.end())
00482 {
00483 RTC_DEBUG(("Not found: %s is in %s?",
00484 port_name.c_str(),
00485 ::coil::flatten(portlist).c_str()));
00486 continue;
00487 }
00488
00489 RTC_DEBUG(("Found: %s is in %s",
00490 port_name.c_str(),
00491 ::coil::flatten(portlist).c_str()));
00492
00493 m_rtobj->removePort(plist[i].port_ref);
00494 portlist.erase(pos);
00495
00496 RTC_DEBUG(("Port %s was deleted.", port_name.c_str()));
00497 }
00498 }
00499
00507 void PeriodicECOrganization::updateExportedPortsList()
00508 {
00509 std::string plist(m_rtobj->getProperties()["conf.default.exported_ports"]);
00510 m_expPorts = ::coil::split(plist, ",");
00511 }
00512
00520 void PeriodicECOrganization::updateDelegatedPorts()
00521 {
00522 std::vector<std::string>& oldPorts(m_expPorts);
00523 std::sort(oldPorts.begin(),oldPorts.end());
00524 std::vector<std::string>
00525 newPorts(coil::split(m_rtobj->getProperties()["conf.default.exported_ports"], ","));
00526 std::sort(newPorts.begin(),newPorts.end());
00527
00528 std::vector<std::string> removedPorts;
00529 std::vector<std::string> createdPorts;
00530
00531 set_difference(oldPorts.begin(), oldPorts.end(),
00532 newPorts.begin(), newPorts.end(),
00533 std::back_inserter(removedPorts));
00534 set_difference(newPorts.begin(), newPorts.end(),
00535 oldPorts.begin(), oldPorts.end(),
00536 std::back_inserter(createdPorts));
00537
00538 RTC_VERBOSE(("old ports: %s", ::coil::flatten(oldPorts).c_str()));
00539 RTC_VERBOSE(("new ports: %s", ::coil::flatten(newPorts).c_str()));
00540 RTC_VERBOSE(("remove ports: %s", ::coil::flatten(removedPorts).c_str()));
00541 RTC_VERBOSE(("add ports: %s", ::coil::flatten(createdPorts).c_str()));
00542
00543 for (int i(0), len(m_rtcMembers.size()); i < len; ++i)
00544 {
00545 removePort(m_rtcMembers[i], removedPorts);
00546 addPort(m_rtcMembers[i], createdPorts);
00547 }
00548
00549 m_expPorts = newPorts;
00550 }
00551
00552 };
00553
00554
00555
00556 bool stringToStrVec(std::vector<std::string>& v, const char* is)
00557 {
00558 std::string s(is);
00559 v = coil::split(s ,",");
00560 return true;
00561 }
00562
00563 namespace RTC
00564 {
00565 class setCallback
00566 : public OnSetConfigurationSetCallback
00567 {
00568 public:
00569 setCallback(::SDOPackage::PeriodicECOrganization* org) : m_org(org) {}
00570 virtual ~setCallback(){};
00571 virtual void operator()(const coil::Properties& config_set)
00572 {
00573 m_org->updateDelegatedPorts();
00574 }
00575 private:
00576 ::SDOPackage::PeriodicECOrganization* m_org;
00577 };
00578
00579
00580 class addCallback
00581 : public OnAddConfigurationAddCallback
00582 {
00583 public:
00584 addCallback(::SDOPackage::PeriodicECOrganization* org) : m_org(org) {}
00585 virtual ~addCallback(){};
00586 virtual void operator()(const coil::Properties& config_set)
00587 {
00588 m_org->updateDelegatedPorts();
00589 }
00590 private:
00591 ::SDOPackage::PeriodicECOrganization* m_org;
00592 };
00593
00601 PeriodicECSharedComposite::PeriodicECSharedComposite(Manager* manager)
00602 : RTObject_impl(manager)
00603 {
00604 m_ref = this->_this();
00605 m_objref = RTC::RTObject::_duplicate(m_ref);
00606 m_org = new SDOPackage::PeriodicECOrganization(this);
00607 ::CORBA_SeqUtil::push_back(m_sdoOwnedOrganizations,
00608 ::SDOPackage::Organization::_duplicate(m_org->getObjRef()));
00609 bindParameter("members", m_members, "", stringToStrVec);
00610
00611 m_configsets.setOnSetConfigurationSet(new setCallback(m_org));
00612 m_configsets.setOnAddConfigurationSet(new addCallback(m_org));
00613
00614 }
00615
00616
00624 PeriodicECSharedComposite::~PeriodicECSharedComposite()
00625 {
00626 RTC_TRACE(("~PeriodicECSharedComposite()"));
00627 }
00628
00629
00637 ReturnCode_t PeriodicECSharedComposite::onInitialize()
00638 {
00639 RTC_TRACE(("onInitialize()"));
00640
00641 std::string active_set;
00642 active_set = m_properties.getProperty("configuration.active_config",
00643 "default");
00644 if (m_configsets.haveConfig(active_set.c_str()))
00645 {
00646 m_configsets.update(active_set.c_str());
00647 }
00648 else
00649 {
00650 m_configsets.update("default");
00651 }
00652
00653 ::RTC::Manager& mgr(::RTC::Manager::instance());
00654
00655 std::vector<RTObject_impl*> comps = mgr.getComponents();
00656
00657 ::SDOPackage::SDOList sdos;
00658 for (int i(0), len(m_members.size()); i < len; ++i)
00659 {
00660 RTObject_impl* rtc = mgr.getComponent(m_members[i].c_str());
00661 if (rtc == NULL) {
00662 continue;
00663 }
00664
00665 ::SDOPackage::SDO_var sdo;
00666 #ifndef ORB_IS_RTORB
00667 sdo = ::SDOPackage::SDO::_duplicate(rtc->getObjRef());
00668 if (::CORBA::is_nil(sdo)) continue;
00669
00670 ::CORBA_SeqUtil::push_back(sdos, sdo);
00671 #else // ORB_IS_RTORB
00672 sdo = ::SDOPackage::SDO::_duplicate((rtc->getObjRef()).in());
00673 if (::CORBA::is_nil(sdo)) continue;
00674
00675 ::CORBA_SeqUtil::push_back(sdos, ::SDOPackage::SDO_ptr(sdo));
00676 #endif // ORB_IS_RTORB
00677 }
00678
00679 try
00680 {
00681 m_org->set_members(sdos);
00682 }
00683 catch (...)
00684 {
00685 }
00686 return ::RTC::RTC_OK;
00687 }
00688
00696 ReturnCode_t PeriodicECSharedComposite::onActivated(RTC::UniqueId exec_handle)
00697 {
00698 RTC_TRACE(("onActivated(%d)", exec_handle));
00699 ::RTC::ExecutionContextList_var ecs(get_owned_contexts());
00700 ::SDOPackage::SDOList_var sdos(m_org->get_members());
00701
00702 for (::CORBA::ULong i(0), len(sdos->length()); i < len; ++i)
00703 {
00704 ::RTC::RTObject_var rtc(::RTC::RTObject::_narrow(sdos[i]));
00705 ecs[0]->activate_component(rtc.in());
00706 }
00707 RTC_DEBUG(("%d member RTC%s activated.", sdos->length(),
00708 sdos->length() == 1 ? " was" : "s were"));
00709 return ::RTC::RTC_OK;
00710 }
00711
00719 ReturnCode_t PeriodicECSharedComposite::onDeactivated(RTC::UniqueId exec_handle)
00720 {
00721 RTC_TRACE(("onDeactivated(%d)", exec_handle));
00722 ::RTC::ExecutionContextList_var ecs(get_owned_contexts());
00723 ::SDOPackage::SDOList_var sdos(m_org->get_members());
00724
00725 for (::CORBA::ULong i(0), len(sdos->length()); i < len; ++i)
00726 {
00727 ::RTC::RTObject_var rtc(::RTC::RTObject::_narrow(sdos[i]));
00728 ecs[0]->deactivate_component(rtc.in());
00729 }
00730 return ::RTC::RTC_OK;
00731 }
00732
00740 ReturnCode_t PeriodicECSharedComposite::onReset(RTC::UniqueId exec_handle)
00741 {
00742 RTC_TRACE(("onReset(%d)", exec_handle));
00743 ::RTC::ExecutionContextList_var ecs(get_owned_contexts());
00744 ::SDOPackage::SDOList_var sdos(m_org->get_members());
00745
00746 for (::CORBA::ULong i(0), len(sdos->length()); i < len; ++i)
00747 {
00748 ::RTC::RTObject_var rtc(::RTC::RTObject::_narrow(sdos[i]));
00749 ecs[0]->reset_component(rtc.in());
00750 }
00751 return ::RTC::RTC_OK;
00752 }
00753
00761 ReturnCode_t PeriodicECSharedComposite::onFinalize()
00762 {
00763 RTC_TRACE(("onFinalize()"));
00764 m_org->removeAllMembers();
00765 RTC_PARANOID(("onFinalize() done"));
00766 return RTC::RTC_OK;
00767 }
00768
00769 };
00770
00771 extern "C"
00772 {
00773 void PeriodicECSharedCompositeInit(RTC::Manager* manager)
00774 {
00775 coil::Properties profile(periodicecsharedcomposite_spec);
00776 manager->registerFactory(profile,
00777 RTC::Create<RTC::PeriodicECSharedComposite>,
00778 RTC::Delete<RTC::PeriodicECSharedComposite>);
00779 }
00780 };