34 #include <Ice/BuiltinSequences.h>  
   35 #include <Ice/Identity.h>  
   36 #include <Ice/LocalException.h> 
   37 #include <Ice/ObjectAdapter.h>  
   38 #include <IceStorm/IceStorm.h>  
   39 #include <IceUtil/Shared.h>  
   40 #include <IceUtil/UUID.h>  
   48 #include <ArmarXCore/interface/core/ManagedIceObjectDefinitions.h> 
   49 #include <ArmarXCore/interface/core/ManagedIceObjectDependencyBase.h> 
   50 #include <ArmarXCore/interface/core/Profiler.h> 
   63     class NotRegisteredException;
 
   64     class ObjectAdapterDeactivatedException;
 
   80         impl->objectState = eManagedIceObjectCreated;
 
   82         impl->enableProfilerFunction = &ManagedIceObject::Noop;
 
   85     std::unique_ptr<ManagedIceObjectPlugin>&
 
   89         return _plugins[{type, prefix}];
 
   95         impl->name = other.impl->name;
 
   96         impl->armarXManager = other.impl->armarXManager;
 
   97         impl->iceManager = 
nullptr;
 
   98         impl->objectScheduler = 
nullptr;
 
   99         impl->objectState = eManagedIceObjectCreated;
 
  100         impl->proxy = 
nullptr;
 
  101         impl->objectAdapter = 
nullptr;
 
  102         impl->connectivity = other.impl->connectivity;
 
  103         impl->profiler = other.impl->profiler;
 
  104         impl->enableProfilerFunction = &ManagedIceObject::Noop;
 
  110         if (impl->name.empty())
 
  120                                             const std::string& subObjectName)
 
  122         return superObjectName + 
"." + subObjectName;
 
  133         for (
const auto& [name, task] : impl->periodicTasks)
 
  140         impl->periodicTasks.clear();
 
  146         return impl->objectAdapter;
 
  159             throw LocalException(
"proxyName must not be empty.");
 
  162         std::unique_lock lock(impl->connectivityMutex);
 
  165         if (impl->connectivity.dependencies.find(name) != impl->connectivity.dependencies.end())
 
  172         impl->connectivity.dependencies.insert(std::make_pair(name, proxyDependency));
 
  182             throw LocalException(
"The proxy name must not be empty.");
 
  185         if (
getState() < eManagedIceObjectStarting)
 
  187             throw LocalException(
"Calling getProxy before component has been started");
 
  190         if (addToDependencies)
 
  198     std::vector<std::string>
 
  203         std::vector<std::string> dependencies;
 
  205         for (
auto& dependencie : con.dependencies)
 
  207             ManagedIceObjectDependencyBasePtr& dep = dependencie.second;
 
  209             if (!dep->getResolved())
 
  211                 dependencies.push_back(dep->getName());
 
  223             case eManagedIceObjectCreated:
 
  226             case eManagedIceObjectInitializing:
 
  227                 return "Initializing";
 
  229             case eManagedIceObjectInitialized:
 
  230                 return "Initialized";
 
  231             case eManagedIceObjectInitializationFailed:
 
  232                 return "InitializationFailed";
 
  234             case eManagedIceObjectStarting:
 
  237             case eManagedIceObjectStartingFailed:
 
  238                 return "StartingFailed";
 
  240             case eManagedIceObjectStarted:
 
  243             case eManagedIceObjectExiting:
 
  246             case eManagedIceObjectExited:
 
  257         std::unique_lock lock(impl->connectivityMutex);
 
  260         if (
std::find(impl->connectivity.usedTopics.begin(),
 
  261                       impl->connectivity.usedTopics.end(),
 
  262                       name) != impl->connectivity.usedTopics.end())
 
  268         impl->connectivity.usedTopics.push_back(name);
 
  269         impl->orderedTopicPublishing[name] = orderedPublishing;
 
  273         if (
getState() >= eManagedIceObjectStarting)
 
  275             getIceManager()->subscribeTopic(impl->proxy, name, orderedPublishing);
 
  283         std::unique_lock lock(impl->connectivityMutex);
 
  289             impl->connectivity.usedTopics.begin(), impl->connectivity.usedTopics.end(), name);
 
  290         if (it != impl->connectivity.usedTopics.end())
 
  292             impl->connectivity.usedTopics.erase(it);
 
  303         std::unique_lock lock(impl->connectivityMutex);
 
  306         if (
std::find(impl->connectivity.offeredTopics.begin(),
 
  307                       impl->connectivity.offeredTopics.end(),
 
  308                       topicName) != impl->connectivity.offeredTopics.end())
 
  314         impl->connectivity.offeredTopics.push_back(topicName);
 
  315         ARMARX_INFO << 
"Offering topic with name: '" << topicName << 
"'";
 
  318         if (
getState() >= eManagedIceObjectStarting)
 
  327         if (
getState() < eManagedIceObjectStarting)
 
  329             throw LocalException(
"Calling getTopic before component has been started");
 
  340         std::unique_lock lock(impl->connectivityMutex);
 
  343         DependencyMap::iterator it = impl->connectivity.dependencies.find(name);
 
  345         if (it == impl->connectivity.dependencies.end())
 
  350         ARMARX_VERBOSE << 
"Removing proxy '" << name << 
"' from dependency list.";
 
  351         impl->connectivity.dependencies.erase(it);
 
  362         return impl->armarXManager;
 
  368         return impl->iceManager;
 
  374         return impl->profiler;
 
  383         impl->enableProfilerFunction = &ManagedIceObject::Noop;
 
  387             impl->profiler->setLoggingStrategy(strategy);
 
  397             ManagedIceObject::EnableProfilerOn(
this);
 
  402             impl->enableProfilerFunction = &ManagedIceObject::EnableProfilerOn;
 
  412         if (waitForScheduler)
 
  424             oSched->waitForObjectStateMinimum(eManagedIceObjectStarting, timeoutMs);
 
  428             ARMARX_WARNING_S << 
"called on an object without a object scheduler. To fix this add " 
  429                                 "the object to an ArmarXManager prior to calling this function.";
 
  440         impl->stateCondition.notify_all();
 
  441         impl->objectScheduler->terminate();
 
  447         this->impl->name = name;
 
  464         setObjectState(eManagedIceObjectInitializing);
 
  467         this->impl->iceManager = iceManager;
 
  470         impl->enableProfilerFunction(
this);
 
  473         ARMARX_DEBUG << 
"call preOnInitComponent for all plugins...";
 
  475             [&](
const auto& typeidx, 
const auto& name, 
const auto& plugin)
 
  479                              << 
") preOnInitComponent...";
 
  480                 plugin->preOnInitComponent();
 
  482                              << 
") preOnInitComponent...done!";
 
  486             BOOST_CURRENT_FUNCTION);
 
  487         ARMARX_DEBUG << 
"call preOnInitComponent for all plugins...done!";
 
  502         ARMARX_DEBUG << 
"call postOnInitComponent for all plugins...";
 
  504             [&](
const auto& typeidx, 
const auto& name, 
const auto& plugin)
 
  508                              << 
") postOnInitComponent...";
 
  509                 plugin->postOnInitComponent();
 
  511                              << 
") postOnInitComponent...done!";
 
  515             BOOST_CURRENT_FUNCTION);
 
  516         ARMARX_DEBUG << 
"call postOnInitComponent for all plugins...done!";
 
  519         setObjectState(eManagedIceObjectInitialized);
 
  527         this->impl->proxy = proxy;
 
  528         this->impl->objectAdapter = objectAdapter;
 
  531         setObjectState(eManagedIceObjectStarting);
 
  534         ARMARX_DEBUG << 
"call preOnConnectComponent for all plugins...";
 
  536             [&](
const auto& typeidx, 
const auto& name, 
const auto& plugin)
 
  540                              << 
") preOnConnectComponent...";
 
  541                 plugin->preOnConnectComponent();
 
  543                              << 
") preOnConnectComponent...done!";
 
  547             BOOST_CURRENT_FUNCTION);
 
  548         ARMARX_DEBUG << 
"call preOnConnectComponent for all plugins...done!";
 
  564         ARMARX_DEBUG << 
"call postOnConnectComponent for all plugins...";
 
  566             [&](
const auto& typeidx, 
const auto& name, 
const auto& plugin)
 
  570                              << 
") postOnConnectComponent...";
 
  571                 plugin->postOnConnectComponent();
 
  573                              << 
") postOnConnectComponent...done!";
 
  577             BOOST_CURRENT_FUNCTION);
 
  578         ARMARX_DEBUG << 
"call postOnConnectComponent for all plugins...done!";
 
  581         setObjectState(eManagedIceObjectStarted);
 
  585     ManagedIceObject::disconnect()
 
  593             ARMARX_DEBUG << 
"call preOnDisconnectComponent for all plugins...";
 
  595                 [&](
const auto& typeidx, 
const auto& name, 
const auto& plugin)
 
  599                                  << 
") preOnDisconnectComponent...";
 
  600                     plugin->preOnDisconnectComponent();
 
  602                                  << 
") preOnDisconnectComponent...done!";
 
  606                 BOOST_CURRENT_FUNCTION);
 
  607             ARMARX_DEBUG << 
"call preOnDisconnectComponent for all plugins...done!";
 
  612             ARMARX_DEBUG << 
"call preOnDisconnectComponent...done!";
 
  620             ARMARX_DEBUG << 
"call postOnDisconnectComponent...done!";
 
  622             ARMARX_DEBUG << 
"call postOnDisconnectComponent for all plugins...";
 
  624                 [&](
const auto& typeidx, 
const auto& name, 
const auto& plugin)
 
  628                                  << 
") postOnDisconnectComponent...";
 
  629                     plugin->postOnDisconnectComponent();
 
  631                                  << 
") postOnDisconnectComponent...done!";
 
  635                 BOOST_CURRENT_FUNCTION);
 
  636             ARMARX_DEBUG << 
"call postOnDisconnectComponent for all plugins...done!";
 
  643         setObjectState(eManagedIceObjectInitialized);
 
  647     ManagedIceObject::exit()
 
  651         setObjectState(eManagedIceObjectExiting);
 
  665         catch (Ice::ObjectAdapterDeactivatedException&)
 
  668         catch (Ice::NotRegisteredException&)
 
  675             ARMARX_DEBUG << 
"call preOnExitComponent for all plugins...";
 
  677                 [&](
const auto& typeidx, 
const auto& name, 
const auto& plugin)
 
  681                                  << 
") preOnExitComponent...";
 
  682                     plugin->preOnExitComponent();
 
  684                                  << 
") preOnExitComponent...done!";
 
  688                 BOOST_CURRENT_FUNCTION);
 
  689             ARMARX_DEBUG << 
"call preOnExitComponent for all plugins...done!";
 
  704             ARMARX_DEBUG << 
"call postOnExitComponent for all plugins...";
 
  706                 [&](
const auto& typeidx, 
const auto& name, 
const auto& plugin)
 
  710                                  << 
") postOnExitComponent...";
 
  711                     plugin->postOnExitComponent();
 
  713                                  << 
") postOnExitComponent...done!";
 
  717                 BOOST_CURRENT_FUNCTION);
 
  718             ARMARX_DEBUG << 
"call postOnExitComponent for all plugins...done!";
 
  725         setObjectState(eManagedIceObjectExited);
 
  726         impl->armarXManager = 
nullptr;
 
  727         impl->iceManager = 
nullptr;
 
  728         impl->objectScheduler = 
nullptr;
 
  729         impl->objectAdapter = 
nullptr;
 
  730         impl->proxy = 
nullptr;
 
  735     ManagedIceObject::setObjectState(
int newState)
 
  738         std::unique_lock lock(impl->objectStateMutex);
 
  739         ARMARX_DEBUG << 
"setObjectState: " << impl->objectState << 
" -> " << newState;
 
  741         if (newState == impl->objectState)
 
  746         impl->objectState = (ManagedIceObjectState)newState;
 
  747         impl->stateCondition.notify_all();
 
  751     ManagedIceObject::Noop(ManagedIceObject*)
 
  757     ManagedIceObject::EnableProfilerOn(ManagedIceObject* 
object)
 
  760         object->offeringTopic(armarx::Profiler::PROFILER_TOPIC_NAME);
 
  761         ProfilerListenerPrx profilerTopic = 
object->getIceManager()->getTopic<ProfilerListenerPrx>(
 
  762             armarx::Profiler::PROFILER_TOPIC_NAME);
 
  764         object->impl->profiler->setLoggingStrategy(strategy);
 
  765         ARMARX_INFO_S << 
"Profiler enabled for " << 
object->getName();
 
  771         std::unique_lock lock(impl->objectStateMutex);
 
  772         return impl->objectState;
 
  778         return impl->objectScheduler;
 
  781     ManagedIceObjectConnectivity
 
  784         std::unique_lock lock(impl->connectivityMutex);
 
  785         return impl->connectivity;
 
  791         getObjectScheduler()->waitForDependencies();
 
  797         std::unique_lock lock(impl->metaInfoMapMutex);
 
  798         impl->metaInfoMap[id] = 
value;
 
  804         std::unique_lock lock(impl->metaInfoMapMutex);
 
  805         return impl->metaInfoMap[id];
 
  811         std::unique_lock lock(impl->metaInfoMapMutex);
 
  812         return impl->metaInfoMap;
 
  817                                         std::function<
void(
void)> f,
 
  819                                         bool assureMeanInterval,
 
  820                                         bool forceSystemTime)
 
  824             << 
"The name '" << uniqueName << 
"' is not unique!";
 
  825         impl->periodicTasks[uniqueName] =
 
  833         if (!impl->periodicTasks.count(name))
 
  837         const auto task = impl->periodicTasks.at(name);
 
  840         impl->periodicTasks.erase(name);
 
  848         if (impl->periodicTasks.count(name))
 
  850             return impl->periodicTasks.at(name);
 
  856     armarx::ManagedIceObject::foreach_plugin(
 
  860         const char* 
function)
 
  863         ARMARX_DEBUG << 
"foreach_plugin called from " << file << 
':' << line << 
" in function '" 
  865         std::set<ManagedIceObjectPlugin*> processed;
 
  866         std::map<ManagedIceObjectPlugin*, std::tuple<std::type_index, std::string>> toProcess;
 
  867         for (
const auto& [key, plugin] : _plugins)
 
  869             const auto& [typeidx, name] = key;
 
  871                          << plugin.get() << 
") to process list";
 
  873             toProcess.emplace(plugin.get(), key);
 
  876         while (processed.size() < toProcess.size())
 
  879             const std::size_t oldNumProcessed = processed.size();
 
  881                          << toProcess.size() - oldNumProcessed << 
" plugins";
 
  882             for (
const auto& [plugin, key] : toProcess)
 
  884                 if (processed.count(plugin))
 
  888                 const auto& [typeidx, name] = key;
 
  890                              << 
", @" << plugin << 
"): checking";
 
  891                 bool blocked = 
false;
 
  892                 for (
const auto dep : plugin->_dependsOn)
 
  894                     if (!processed.count(dep))
 
  903                                  << 
", @" << plugin << 
"): skipping for now";
 
  908                              << 
", @" << plugin << 
"): run functor";
 
  909                 f(typeidx, name, plugin);
 
  910                 processed.emplace(plugin);
 
  912             if (processed.size() == oldNumProcessed)
 
  914                 std::stringstream 
str;
 
  915                 str << 
"plugin graph is no DAG!\n";
 
  916                 for (
const auto& [plugin, key] : toProcess)
 
  918                     const auto& [typeidx, name] = key;
 
  921                     if (plugin->_dependsOn.empty())
 
  923                         str << 
"        has no dependencies\n";
 
  927                         for (
const auto dep : plugin->_dependsOn)
 
  929                             str << 
"        depends on " << dep << 
'\n';