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';