PeriodicECSharedComposite.cpp
Go to the documentation of this file.
00001 // -*- C++ -*-
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     // narrowing: SDO -> RTC (DataFlowComponent)
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     // stop target RTC's ExecutionContext
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     // start target RTC's ExecutionContext
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     // get given RTC's configuration object
00289     //    Configuration_var conf(member.config_.in());
00290     Configuration_var conf(member.config_);
00291     if (::CORBA::is_nil(conf)) return;
00292     
00293     // set organization to target RTC's conf
00294     conf->add_organization(m_objref);
00295   }
00296 
00304   void PeriodicECOrganization::removeOrganizationFromTarget(Member& member)
00305   {
00306     // get given RTC's configuration object
00307     if (::CORBA::is_nil(member.config_)) { return; }
00308     
00309     // set organization to target RTC's conf
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     // set ec to target RTC
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     // port delegation
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     // port delegation
00470     for (::CORBA::ULong i(0), len(plist.length()); i < len; ++i)
00471       {
00472         // port name -> comp_name.port_name
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; // oldPorts - interPorts
00529     std::vector<std::string> createdPorts;   // newPorts - interPorts
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 }; // namespace RTC
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 };


openrtm_aist
Author(s): Noriaki Ando
autogenerated on Thu Aug 27 2015 14:16:38