26 #include <ArmarXCore/interface/core/Profiler.h>
32 #include <ArmarXCore/interface/core/ManagedIceObjectDefinitions.h>
33 #include <ArmarXCore/interface/core/ManagedIceObjectDependencyBase.h>
45 #include <Ice/BuiltinSequences.h>
46 #include <Ice/Identity.h>
47 #include <Ice/LocalException.h>
48 #include <Ice/ObjectAdapter.h>
49 #include <IceStorm/IceStorm.h>
50 #include <IceUtil/Shared.h>
51 #include <IceUtil/UUID.h>
61 class NotRegisteredException;
62 class ObjectAdapterDeactivatedException;
80 impl->objectState = eManagedIceObjectCreated;
82 impl->enableProfilerFunction = &ManagedIceObject::Noop;
88 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;
109 if (impl->name.empty())
119 return superObjectName +
"." + subObjectName;
130 for (
const auto& [name, task] : impl->periodicTasks)
137 impl->periodicTasks.clear();
142 return impl->objectAdapter;
156 throw LocalException(
"proxyName must not be empty.");
159 std::unique_lock lock(impl->connectivityMutex);
162 if (impl->connectivity.dependencies.find(name) != impl->connectivity.dependencies.end())
169 impl->connectivity.dependencies.insert(std::make_pair(name, proxyDependency));
178 throw LocalException(
"The proxy name must not be empty.");
181 if (
getState() < eManagedIceObjectStarting)
183 throw LocalException(
"Calling getProxy before component has been started");
186 if (addToDependencies)
198 std::vector<std::string> dependencies;
200 for (
auto& dependencie : con.dependencies)
202 ManagedIceObjectDependencyBasePtr& dep = dependencie.second;
204 if (!dep->getResolved())
206 dependencies.push_back(dep->getName());
217 case eManagedIceObjectCreated:
220 case eManagedIceObjectInitializing:
221 return "Initializing";
223 case eManagedIceObjectInitialized:
224 return "Initialized";
225 case eManagedIceObjectInitializationFailed:
226 return "InitializationFailed";
228 case eManagedIceObjectStarting:
231 case eManagedIceObjectStartingFailed:
232 return "StartingFailed";
234 case eManagedIceObjectStarted:
237 case eManagedIceObjectExiting:
240 case eManagedIceObjectExited:
251 std::unique_lock lock(impl->connectivityMutex);
254 if (std::find(impl->connectivity.usedTopics.begin(), impl->connectivity.usedTopics.end(), name) != impl->connectivity.usedTopics.end())
260 impl->connectivity.usedTopics.push_back(name);
261 impl->orderedTopicPublishing[name] = orderedPublishing;
265 if (
getState() >= eManagedIceObjectStarting)
267 getIceManager()->subscribeTopic(impl->proxy, name, orderedPublishing);
274 std::unique_lock lock(impl->connectivityMutex);
279 auto it = std::find(impl->connectivity.usedTopics.begin(), impl->connectivity.usedTopics.end(), name);
280 if (it != impl->connectivity.usedTopics.end())
282 impl->connectivity.usedTopics.erase(it);
293 std::unique_lock lock(impl->connectivityMutex);
296 if (std::find(impl->connectivity.offeredTopics.begin(), impl->connectivity.offeredTopics.end(), topicName) != impl->connectivity.offeredTopics.end())
302 impl->connectivity.offeredTopics.push_back(topicName);
303 ARMARX_INFO <<
"Offering topic with name: '" << topicName <<
"'";
306 if (
getState() >= eManagedIceObjectStarting)
314 if (
getState() < eManagedIceObjectStarting)
316 throw LocalException(
"Calling getTopic before component has been started");
329 std::unique_lock lock(impl->connectivityMutex);
332 DependencyMap::iterator it = impl->connectivity.dependencies.find(name);
334 if (it == impl->connectivity.dependencies.end())
339 ARMARX_VERBOSE <<
"Removing proxy '" << name <<
"' from dependency list.";
340 impl->connectivity.dependencies.erase(it);
350 return impl->armarXManager;
355 return impl->iceManager;
361 return impl->profiler;
369 impl->enableProfilerFunction = &ManagedIceObject::Noop;
373 impl->profiler->setLoggingStrategy(strategy);
383 ManagedIceObject::EnableProfilerOn(
this);
388 impl->enableProfilerFunction = &ManagedIceObject::EnableProfilerOn;
398 if (waitForScheduler)
400 while (!oSched && ((
TimeUtil::GetTime(
true) - startTime).toMilliSecondsDouble() < timeoutMs || timeoutMs < 0))
408 oSched->waitForObjectStateMinimum(eManagedIceObjectStarting, timeoutMs);
412 ARMARX_WARNING_S <<
"called on an object without a object scheduler. To fix this add the object to an ArmarXManager prior to calling this function.";
422 impl->stateCondition.notify_all();
423 impl->objectScheduler->terminate();
428 this->impl->name = name;
443 setObjectState(eManagedIceObjectInitializing);
446 this->impl->iceManager = iceManager;
449 impl->enableProfilerFunction(
this);
452 ARMARX_DEBUG <<
"call preOnInitComponent for all plugins...";
453 foreach_plugin([&](
const auto & typeidx,
const auto & name,
const auto & plugin)
458 <<
") preOnInitComponent...";
459 plugin->preOnInitComponent();
462 <<
") preOnInitComponent...done!";
463 }, __LINE__, __FILE__, BOOST_CURRENT_FUNCTION);
464 ARMARX_DEBUG <<
"call preOnInitComponent for all plugins...done!";
479 ARMARX_DEBUG <<
"call postOnInitComponent for all plugins...";
480 foreach_plugin([&](
const auto & typeidx,
const auto & name,
const auto & plugin)
485 <<
") postOnInitComponent...";
486 plugin->postOnInitComponent();
489 <<
") postOnInitComponent...done!";
490 }, __LINE__, __FILE__, BOOST_CURRENT_FUNCTION);
491 ARMARX_DEBUG <<
"call postOnInitComponent for all plugins...done!";
494 setObjectState(eManagedIceObjectInitialized);
501 this->impl->proxy = proxy;
502 this->impl->objectAdapter = objectAdapter;
505 setObjectState(eManagedIceObjectStarting);
508 ARMARX_DEBUG <<
"call preOnConnectComponent for all plugins...";
509 foreach_plugin([&](
const auto & typeidx,
const auto & name,
const auto & plugin)
514 <<
") preOnConnectComponent...";
515 plugin->preOnConnectComponent();
518 <<
") preOnConnectComponent...done!";
519 }, __LINE__, __FILE__, BOOST_CURRENT_FUNCTION);
520 ARMARX_DEBUG <<
"call preOnConnectComponent for all plugins...done!";
536 ARMARX_DEBUG <<
"call postOnConnectComponent for all plugins...";
537 foreach_plugin([&](
const auto & typeidx,
const auto & name,
const auto & plugin)
542 <<
") postOnConnectComponent...";
543 plugin->postOnConnectComponent();
546 <<
") postOnConnectComponent...done!";
547 }, __LINE__, __FILE__, BOOST_CURRENT_FUNCTION);
548 ARMARX_DEBUG <<
"call postOnConnectComponent for all plugins...done!";
551 setObjectState(eManagedIceObjectStarted);
554 void ManagedIceObject::disconnect()
562 ARMARX_DEBUG <<
"call preOnDisconnectComponent for all plugins...";
563 foreach_plugin([&](
const auto & typeidx,
const auto & name,
const auto & plugin)
568 <<
") preOnDisconnectComponent...";
569 plugin->preOnDisconnectComponent();
572 <<
") preOnDisconnectComponent...done!";
573 }, __LINE__, __FILE__, BOOST_CURRENT_FUNCTION);
574 ARMARX_DEBUG <<
"call preOnDisconnectComponent for all plugins...done!";
579 ARMARX_DEBUG <<
"call preOnDisconnectComponent...done!";
587 ARMARX_DEBUG <<
"call postOnDisconnectComponent...done!";
589 ARMARX_DEBUG <<
"call postOnDisconnectComponent for all plugins...";
590 foreach_plugin([&](
const auto & typeidx,
const auto & name,
const auto & plugin)
595 <<
") postOnDisconnectComponent...";
596 plugin->postOnDisconnectComponent();
599 <<
") postOnDisconnectComponent...done!";
600 }, __LINE__, __FILE__, BOOST_CURRENT_FUNCTION);
601 ARMARX_DEBUG <<
"call postOnDisconnectComponent for all plugins...done!";
608 setObjectState(eManagedIceObjectInitialized);
612 void ManagedIceObject::exit()
616 setObjectState(eManagedIceObjectExiting);
630 catch (Ice::ObjectAdapterDeactivatedException&)
633 catch (Ice::NotRegisteredException&)
640 ARMARX_DEBUG <<
"call preOnExitComponent for all plugins...";
641 foreach_plugin([&](
const auto & typeidx,
const auto & name,
const auto & plugin)
646 <<
") preOnExitComponent...";
647 plugin->preOnExitComponent();
650 <<
") preOnExitComponent...done!";
651 }, __LINE__, __FILE__, BOOST_CURRENT_FUNCTION);
652 ARMARX_DEBUG <<
"call preOnExitComponent for all plugins...done!";
667 ARMARX_DEBUG <<
"call postOnExitComponent for all plugins...";
668 foreach_plugin([&](
const auto & typeidx,
const auto & name,
const auto & plugin)
673 <<
") postOnExitComponent...";
674 plugin->postOnExitComponent();
677 <<
") postOnExitComponent...done!";
678 }, __LINE__, __FILE__, BOOST_CURRENT_FUNCTION);
679 ARMARX_DEBUG <<
"call postOnExitComponent for all plugins...done!";
686 setObjectState(eManagedIceObjectExited);
687 impl->armarXManager =
nullptr;
688 impl->iceManager =
nullptr;
689 impl->objectScheduler =
nullptr;
690 impl->objectAdapter =
nullptr;
691 impl->proxy =
nullptr;
695 void ManagedIceObject::setObjectState(
int newState)
698 std::unique_lock lock(impl->objectStateMutex);
699 ARMARX_DEBUG <<
"setObjectState: " << impl->objectState <<
" -> " << newState;
701 if (newState == impl->objectState)
706 impl->objectState = (ManagedIceObjectState)newState;
707 impl->stateCondition.notify_all();
710 void ManagedIceObject::Noop(ManagedIceObject*)
715 void ManagedIceObject::EnableProfilerOn(ManagedIceObject*
object)
718 object->offeringTopic(armarx::Profiler::PROFILER_TOPIC_NAME);
719 ProfilerListenerPrx profilerTopic =
object->getIceManager()->getTopic<ProfilerListenerPrx>(armarx::Profiler::PROFILER_TOPIC_NAME);
721 object->impl->profiler->setLoggingStrategy(strategy);
722 ARMARX_INFO_S <<
"Profiler enabled for " <<
object->getName();
727 std::unique_lock lock(impl->objectStateMutex);
728 return impl->objectState;
733 return impl->objectScheduler;
739 std::unique_lock lock(impl->connectivityMutex);
740 return impl->connectivity;
746 getObjectScheduler()->waitForDependencies();
751 std::unique_lock lock(impl->metaInfoMapMutex);
752 impl->metaInfoMap[id] =
value;
757 std::unique_lock lock(impl->metaInfoMapMutex);
758 return impl->metaInfoMap[id];
763 std::unique_lock lock(impl->metaInfoMapMutex);
764 return impl->metaInfoMap;
768 std::function<
void(
void)> f,
770 bool assureMeanInterval,
771 bool forceSystemTime)
775 <<
"The name '" << uniqueName <<
"' is not unique!";
777 f, periodMs, assureMeanInterval, uniqueName, forceSystemTime);
782 if (!impl->periodicTasks.count(name))
786 const auto task = impl->periodicTasks.at(name);
789 impl->periodicTasks.erase(name);
795 if (impl->periodicTasks.count(name))
797 return impl->periodicTasks.at(name);
803 void armarx::ManagedIceObject::foreach_plugin(
805 int line,
const char* file,
const char*
function)
809 << file <<
':' << line
810 <<
" in function '" <<
function <<
"'";
811 std::set<ManagedIceObjectPlugin*> processed;
812 std::map<ManagedIceObjectPlugin*, std::tuple<std::type_index, std::string>> toProcess;
813 for (
const auto& [key, plugin] : _plugins)
815 const auto& [typeidx, name] = key;
818 <<
", @" << plugin.get() <<
") to process list";
820 toProcess.emplace(plugin.get(), key);
823 while (processed.size() < toProcess.size())
826 const std::size_t oldNumProcessed = processed.size();
827 ARMARX_DEBUG <<
"foreach_plugin: strill processing " << toProcess.size() - oldNumProcessed <<
" plugins";
828 for (
const auto& [plugin, key] : toProcess)
830 if (processed.count(plugin))
834 const auto& [typeidx, name] = key;
837 <<
", @" << plugin <<
"): checking";
838 bool blocked =
false;
839 for (
const auto dep : plugin->_dependsOn)
841 if (!processed.count(dep))
851 <<
", @" << plugin <<
"): skipping for now";
857 <<
", @" << plugin <<
"): run functor";
858 f(typeidx, name, plugin);
859 processed.emplace(plugin);
861 if (processed.size() == oldNumProcessed)
863 std::stringstream
str;
864 str <<
"plugin graph is no DAG!\n";
865 for (
const auto& [plugin, key] : toProcess)
867 const auto& [typeidx, name] = key;
868 str <<
" plugin '" << name
870 <<
", @" << plugin <<
")\n";
871 if (plugin->_dependsOn.empty())
873 str <<
" has no dependencies\n";
877 for (
const auto dep : plugin->_dependsOn)
879 str <<
" depends on " << dep <<
'\n';