ManagedIceObject.cpp
Go to the documentation of this file.
1/*
2* This file is part of ArmarX.
3*
4* Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5*
6* ArmarX is free software; you can redistribute it and/or modify
7* it under the terms of the GNU General Public License version 2 as
8* published by the Free Software Foundation.
9*
10* ArmarX is distributed in the hope that it will be useful, but
11* WITHOUT ANY WARRANTY; without even the implied warranty of
12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13* GNU General Public License for more details.
14*
15* You should have received a copy of the GNU General Public License
16* along with this program. If not, see <http://www.gnu.org/licenses/>.
17*
18* @package ArmarXCore::core
19* @author Kai Welke (welke at kit dot edu)
20* @author Jan Issac (jan dot issac at gmx dot de)
21* @date 2011
22* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
23* GNU General Public License
24*/
25
26#include "ManagedIceObject.h"
27
28#include <algorithm> // for find
29#include <map> // for _Rb_tree_iterator, etc
30#include <ostream> // for operator<<, basic_ostream, etc
31#include <sstream>
32#include <utility> // for pair, make_pair
33
34#include <Ice/BuiltinSequences.h> // for StringSeq
35#include <Ice/Identity.h> // for Identity
36#include <Ice/LocalException.h>
37#include <Ice/ObjectAdapter.h> // for ObjectAdapterPtr, etc
38#include <IceStorm/IceStorm.h> // for TopicPrx
39#include <IceUtil/Shared.h> // for Shared
40#include <IceUtil/UUID.h> // for generateUUID
41
42#include <ArmarXCore/core/ArmarXFwd.h> // for ArmarXObjectSchedulerPtr, etc
44#include <ArmarXCore/core/logging/LogSender.h> // for LogSender
45#include <ArmarXCore/core/logging/Logging.h> // for ARMARX_VERBOSE, etc
46#include <ArmarXCore/core/services/profiler/Profiler.h> // for Profiler, etc
48#include <ArmarXCore/interface/core/ManagedIceObjectDefinitions.h>
49#include <ArmarXCore/interface/core/ManagedIceObjectDependencyBase.h>
50#include <ArmarXCore/interface/core/Profiler.h>
52
53#include "ArmarXManager.h" // for ArmarXObjectSchedulerPtr, etc
54#include "ArmarXObjectScheduler.h" // for ArmarXObjectScheduler
55#include "IceManager.h" // for IceManager, IceManagerPtr
59#include "services/profiler/LoggingStrategy.h" // for LoggingStrategy, etc
60
61namespace Ice
62{
63 class NotRegisteredException;
64 class ObjectAdapterDeactivatedException;
65} // namespace Ice
66
67namespace armarx
68{
69 // *******************************************************
70 // static data
71 // *******************************************************
73
74 // *******************************************************
75 // construction
76 // *******************************************************
78 {
79 impl->name = "";
80 impl->objectState = eManagedIceObjectCreated;
81 impl->profiler.reset(new Profiler::Profiler());
82 impl->enableProfilerFunction = &ManagedIceObject::Noop;
83 }
84
85 std::unique_ptr<ManagedIceObjectPlugin>&
86 ManagedIceObject::getPluginPointer(std::type_info const& type, std::string const& prefix)
87 {
88 ARMARX_CHECK_EXPRESSION(getState() == ManagedIceObjectState::eManagedIceObjectCreated);
89 return _plugins[{type, prefix}];
90 }
91
93 IceUtil::Shared(), impl(new Impl)
94 {
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;
105 }
106
107 std::string
109 {
110 if (impl->name.empty())
111 {
112 return getDefaultName();
113 }
114
115 return impl->name;
116 }
117
118 std::string
119 ManagedIceObject::generateSubObjectName(const std::string& superObjectName,
120 const std::string& subObjectName)
121 {
122 return superObjectName + "." + subObjectName;
123 }
124
125 std::string
126 ManagedIceObject::generateSubObjectName(const std::string& subObjectName)
127 {
128 return generateSubObjectName(getName(), subObjectName);
129 }
130
132 {
133 for (const auto& [name, task] : impl->periodicTasks)
134 {
135 if (task)
136 {
137 task->stop();
138 }
139 }
140 impl->periodicTasks.clear();
141 }
142
145 {
146 return impl->objectAdapter;
147 }
148
149 // *******************************************************
150 // establish dependencies
151 // *******************************************************
152
153 bool
154 ManagedIceObject::usingProxy(const std::string& name, const std::string&)
155 {
157 if (name.empty())
158 {
159 throw LocalException("proxyName must not be empty.");
160 }
161
162 std::unique_lock lock(impl->connectivityMutex);
163
164 // check if proxy already exists
165 if (impl->connectivity.dependencies.find(name) != impl->connectivity.dependencies.end())
166 {
167 return false;
168 }
169
170 // add dependency
171 ManagedIceObjectDependencyPtr proxyDependency = new ProxyDependency(getIceManager(), name);
172 impl->connectivity.dependencies.insert(std::make_pair(name, proxyDependency));
173
174 return true;
175 }
176
177 void
178 ManagedIceObject::waitForProxy(const std::string& name, bool addToDependencies)
179 {
180 if (name.empty())
181 {
182 throw LocalException("The proxy name must not be empty.");
183 }
184
185 if (getState() < eManagedIceObjectStarting)
186 {
187 throw LocalException("Calling getProxy before component has been started");
188 }
189
190 if (addToDependencies)
191 {
192 usingProxy(name);
193
195 }
196 }
197
198 std::vector<std::string>
200 {
202 ManagedIceObjectConnectivity con = getConnectivity();
203 std::vector<std::string> dependencies;
204
205 for (auto& dependencie : con.dependencies)
206 {
207 ManagedIceObjectDependencyBasePtr& dep = dependencie.second;
208
209 if (!dep->getResolved())
210 {
211 dependencies.push_back(dep->getName());
212 }
213 }
214
215 return dependencies;
216 }
217
218 std::string
220 {
221 switch (state)
222 {
223 case eManagedIceObjectCreated:
224 return "Created";
225
226 case eManagedIceObjectInitializing:
227 return "Initializing";
228
229 case eManagedIceObjectInitialized:
230 return "Initialized";
231 case eManagedIceObjectInitializationFailed:
232 return "InitializationFailed";
233
234 case eManagedIceObjectStarting:
235 return "Starting";
236
237 case eManagedIceObjectStartingFailed:
238 return "StartingFailed";
239
240 case eManagedIceObjectStarted:
241 return "Started";
242
243 case eManagedIceObjectExiting:
244 return "Exiting";
245
246 case eManagedIceObjectExited:
247 return "Exited";
248 }
249
250 return "Unknown";
251 }
252
253 void
254 ManagedIceObject::usingTopic(const std::string& name, bool orderedPublishing)
255 {
257 std::unique_lock lock(impl->connectivityMutex);
258
259 // check if topic is already used
260 if (std::find(impl->connectivity.usedTopics.begin(),
261 impl->connectivity.usedTopics.end(),
262 name) != impl->connectivity.usedTopics.end())
263 {
264 return;
265 }
266
267 // add dependency
268 impl->connectivity.usedTopics.push_back(name);
269 impl->orderedTopicPublishing[name] = orderedPublishing;
270 ARMARX_VERBOSE << "Using topic with name: '" << name << "'";
271
272 // only subscribe direcly if component has been initialized. Otherwise the dependency resolution will take care
273 if (getState() >= eManagedIceObjectStarting)
274 {
275 getIceManager()->subscribeTopic(impl->proxy, name, orderedPublishing);
276 }
277 }
278
279 bool
281 {
283 std::unique_lock lock(impl->connectivityMutex);
284
285 ARMARX_CHECK_EXPRESSION(impl->proxy);
286 getIceManager()->unsubscribeTopic(impl->proxy, name);
287 // check if topic is already used
288 auto it = std::find(
289 impl->connectivity.usedTopics.begin(), impl->connectivity.usedTopics.end(), name);
290 if (it != impl->connectivity.usedTopics.end())
291 {
292 impl->connectivity.usedTopics.erase(it);
293 ARMARX_VERBOSE << "Removing " << name << " from used topic list";
294 return true;
295 }
296 return false;
297 }
298
299 void
300 ManagedIceObject::offeringTopic(const std::string& name)
301 {
303 std::unique_lock lock(impl->connectivityMutex);
304 auto topicName = name + getIceManager()->getTopicSuffix();
305 // check if topic is already used
306 if (std::find(impl->connectivity.offeredTopics.begin(),
307 impl->connectivity.offeredTopics.end(),
308 topicName) != impl->connectivity.offeredTopics.end())
309 {
310 return;
311 }
312
313 // add dependency
314 impl->connectivity.offeredTopics.push_back(topicName);
315 ARMARX_INFO << "Offering topic with name: '" << topicName << "'";
316
317 // only retrieve topic direcly if component has been initialized. Otherwise the dependency resolution will take care
318 if (getState() >= eManagedIceObjectStarting)
319 {
320 getIceManager()->getTopic<IceStorm::TopicPrx>(name);
321 }
322 }
323
324 void
325 ManagedIceObject::preambleGetTopic(const std::string& name)
326 {
327 if (getState() < eManagedIceObjectStarting)
328 {
329 throw LocalException("Calling getTopic before component has been started");
330 }
331
332 // make sure proxy is on the dependency list
333 offeringTopic(name);
334 }
335
336 bool
338 {
340 std::unique_lock lock(impl->connectivityMutex);
341
342 // check if proxy already exists
343 DependencyMap::iterator it = impl->connectivity.dependencies.find(name);
344
345 if (it == impl->connectivity.dependencies.end())
346 {
347 return false;
348 }
349
350 ARMARX_VERBOSE << "Removing proxy '" << name << "' from dependency list.";
351 impl->connectivity.dependencies.erase(it);
352 getObjectScheduler()->wakeupDependencyCheck();
353 return true;
354 }
355
356 // *******************************************************
357 // getters
358 // *******************************************************
361 {
362 return impl->armarXManager;
363 }
364
367 {
368 return impl->iceManager;
369 }
370
373 {
374 return impl->profiler;
375 }
376
377 void
379 {
382 // set to empty log strategy if enable == false
383 impl->enableProfilerFunction = &ManagedIceObject::Noop;
384
385 if (!enable)
386 {
387 impl->profiler->setLoggingStrategy(strategy);
388 return;
389 }
390
391 // enable the IceLoggingStrategy if IceManager is available
392 // otherwise defer the creation until ManagedIceObject::init() is called
393 if (getIceManager())
394 {
395 // create the IceLoggingStrategy immediately if Ice is available
396 //enableProfilerFunction(this);
397 ManagedIceObject::EnableProfilerOn(this);
398 }
399 else
400 {
401 // if Ice is not yet available, the creation of IceLoggingStrategy is delayed via the enableProfilerFunction
402 impl->enableProfilerFunction = &ManagedIceObject::EnableProfilerOn;
403 }
404 }
405
406 Ice::ObjectPrx
407 ManagedIceObject::getProxy(long timeoutMs, bool waitForScheduler) const
408 {
411 IceUtil::Time startTime = TimeUtil::GetTime(true);
412 if (waitForScheduler)
413 {
414 while (!oSched &&
415 ((TimeUtil::GetTime(true) - startTime).toMilliSecondsDouble() < timeoutMs ||
416 timeoutMs < 0))
417 {
418 oSched = getObjectScheduler();
419 TimeUtil::USleep(10000);
420 }
421 }
422 if (oSched)
423 {
424 oSched->waitForObjectStateMinimum(eManagedIceObjectStarting, timeoutMs);
425 }
426 else
427 {
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.";
430 }
431 return impl->proxy;
432 }
433
434 // *******************************************************
435 // termination
436 // *******************************************************
437 void
439 {
440 impl->stateCondition.notify_all();
441 impl->objectScheduler->terminate();
442 }
443
444 void
446 {
447 this->impl->name = name;
448 }
449
452 {
453 return getIceManager()->getCommunicator();
454 }
455
456 // *******************************************************
457 // phase handling
458 // *******************************************************
459 void
460 ManagedIceObject::init(IceManagerPtr iceManager)
461 {
463 // set state
464 setObjectState(eManagedIceObjectInitializing);
465
466 // set ice manager
467 this->impl->iceManager = iceManager;
468
469 // evaluate function created by enableProfiling();
470 impl->enableProfilerFunction(this);
471
472 // call framwork hook
473 ARMARX_DEBUG << "call preOnInitComponent for all plugins...";
474 foreach_plugin(
475 [&](const auto& typeidx, const auto& name, const auto& plugin)
476 {
478 ARMARX_DEBUG << "plugin '" << name << "' (" << GetTypeString(typeidx)
479 << ") preOnInitComponent...";
480 plugin->preOnInitComponent();
481 ARMARX_DEBUG << "plugin '" << name << "' (" << GetTypeString(typeidx)
482 << ") preOnInitComponent...done!";
483 },
484 __LINE__,
485 __FILE__,
486 BOOST_CURRENT_FUNCTION);
487 ARMARX_DEBUG << "call preOnInitComponent for all plugins...done!";
489
490 ARMARX_DEBUG << "call preOnInitComponent...";
492 ARMARX_DEBUG << "call preOnInitComponent...done!";
493
494 ARMARX_DEBUG << "call onInitComponent...";
496 ARMARX_DEBUG << "call onInitComponent...done!";
497
498 ARMARX_DEBUG << "call postOnInitComponent...";
500 ARMARX_DEBUG << "call postOnInitComponent...done!";
501
502 ARMARX_DEBUG << "call postOnInitComponent for all plugins...";
503 foreach_plugin(
504 [&](const auto& typeidx, const auto& name, const auto& plugin)
505 {
507 ARMARX_DEBUG << "plugin '" << name << "' (" << GetTypeString(typeidx)
508 << ") postOnInitComponent...";
509 plugin->postOnInitComponent();
510 ARMARX_DEBUG << "plugin '" << name << "' (" << GetTypeString(typeidx)
511 << ") postOnInitComponent...done!";
512 },
513 __LINE__,
514 __FILE__,
515 BOOST_CURRENT_FUNCTION);
516 ARMARX_DEBUG << "call postOnInitComponent for all plugins...done!";
517
518 // set state
519 setObjectState(eManagedIceObjectInitialized);
520 }
521
522 void
523 ManagedIceObject::start(Ice::ObjectPrx& proxy, const Ice::ObjectAdapterPtr& objectAdapter)
524 {
526 // set members
527 this->impl->proxy = proxy;
528 this->impl->objectAdapter = objectAdapter;
529
530 // set state
531 setObjectState(eManagedIceObjectStarting);
532
533 // call framwork hook
534 ARMARX_DEBUG << "call preOnConnectComponent for all plugins...";
535 foreach_plugin(
536 [&](const auto& typeidx, const auto& name, const auto& plugin)
537 {
539 ARMARX_DEBUG << "plugin '" << name << "' (" << GetTypeString(typeidx)
540 << ") preOnConnectComponent...";
541 plugin->preOnConnectComponent();
542 ARMARX_DEBUG << "plugin '" << name << "' (" << GetTypeString(typeidx)
543 << ") preOnConnectComponent...done!";
544 },
545 __LINE__,
546 __FILE__,
547 BOOST_CURRENT_FUNCTION);
548 ARMARX_DEBUG << "call preOnConnectComponent for all plugins...done!";
550
551 ARMARX_DEBUG << "call preOnConnectComponent...";
553 ARMARX_DEBUG << "call preOnConnectComponent...done!";
554
555 ARMARX_DEBUG << "call onConnectComponent...";
557 ARMARX_DEBUG << "call onConnectComponent...done!";
558
559 ARMARX_DEBUG << "call postOnConnectComponent...";
561 ARMARX_DEBUG << "call postOnConnectComponent...done!";
562
563
564 ARMARX_DEBUG << "call postOnConnectComponent for all plugins...";
565 foreach_plugin(
566 [&](const auto& typeidx, const auto& name, const auto& plugin)
567 {
569 ARMARX_DEBUG << "plugin '" << name << "' (" << GetTypeString(typeidx)
570 << ") postOnConnectComponent...";
571 plugin->postOnConnectComponent();
572 ARMARX_DEBUG << "plugin '" << name << "' (" << GetTypeString(typeidx)
573 << ") postOnConnectComponent...done!";
574 },
575 __LINE__,
576 __FILE__,
577 BOOST_CURRENT_FUNCTION);
578 ARMARX_DEBUG << "call postOnConnectComponent for all plugins...done!";
579
580 // set state
581 setObjectState(eManagedIceObjectStarted);
582 }
583
584 void
585 ManagedIceObject::disconnect()
586 {
588 // set state
589
590 try
591 {
592 // call framwork hook
593 ARMARX_DEBUG << "call preOnDisconnectComponent for all plugins...";
594 foreach_plugin(
595 [&](const auto& typeidx, const auto& name, const auto& plugin)
596 {
598 ARMARX_DEBUG << "plugin '" << name << "' (" << GetTypeString(typeidx)
599 << ") preOnDisconnectComponent...";
600 plugin->preOnDisconnectComponent();
601 ARMARX_DEBUG << "plugin '" << name << "' (" << GetTypeString(typeidx)
602 << ") preOnDisconnectComponent...done!";
603 },
604 __LINE__,
605 __FILE__,
606 BOOST_CURRENT_FUNCTION);
607 ARMARX_DEBUG << "call preOnDisconnectComponent for all plugins...done!";
609
610 ARMARX_DEBUG << "call preOnDisconnectComponent...";
612 ARMARX_DEBUG << "call preOnDisconnectComponent...done!";
613
614 ARMARX_DEBUG << "call onDisconnectComponent...";
616 ARMARX_DEBUG << "call onDisconnectComponent...done!";
617
618 ARMARX_DEBUG << "call postOnDisconnectComponent...";
620 ARMARX_DEBUG << "call postOnDisconnectComponent...done!";
621
622 ARMARX_DEBUG << "call postOnDisconnectComponent for all plugins...";
623 foreach_plugin(
624 [&](const auto& typeidx, const auto& name, const auto& plugin)
625 {
627 ARMARX_DEBUG << "plugin '" << name << "' (" << GetTypeString(typeidx)
628 << ") postOnDisconnectComponent...";
629 plugin->postOnDisconnectComponent();
630 ARMARX_DEBUG << "plugin '" << name << "' (" << GetTypeString(typeidx)
631 << ") postOnDisconnectComponent...done!";
632 },
633 __LINE__,
634 __FILE__,
635 BOOST_CURRENT_FUNCTION);
636 ARMARX_DEBUG << "call postOnDisconnectComponent for all plugins...done!";
637 // set state
638 }
639 catch (...) // dispatch and handle exception
640 {
642 }
643 setObjectState(eManagedIceObjectInitialized);
644 }
645
646 void
647 ManagedIceObject::exit()
648 {
650 // set state
651 setObjectState(eManagedIceObjectExiting);
652
653 Ice::Identity id;
654 id.name = getName();
655
656 // remove self so no new calls are coming in
657 try
658 {
660 if (getObjectAdapter())
661 {
662 getObjectAdapter()->remove(id);
663 }
664 }
665 catch (Ice::ObjectAdapterDeactivatedException&)
666 {
667 }
668 catch (Ice::NotRegisteredException&)
669 {
670 }
671
672 try
673 {
674 // call framwork hook
675 ARMARX_DEBUG << "call preOnExitComponent for all plugins...";
676 foreach_plugin(
677 [&](const auto& typeidx, const auto& name, const auto& plugin)
678 {
680 ARMARX_DEBUG << "plugin '" << name << "' (" << GetTypeString(typeidx)
681 << ") preOnExitComponent...";
682 plugin->preOnExitComponent();
683 ARMARX_DEBUG << "plugin '" << name << "' (" << GetTypeString(typeidx)
684 << ") preOnExitComponent...done!";
685 },
686 __LINE__,
687 __FILE__,
688 BOOST_CURRENT_FUNCTION);
689 ARMARX_DEBUG << "call preOnExitComponent for all plugins...done!";
691
692 ARMARX_DEBUG << "call preOnExitComponent...";
694 ARMARX_DEBUG << "call preOnExitComponent...done!";
695
696 ARMARX_DEBUG << "call onExitComponent...";
698 ARMARX_DEBUG << "call onExitComponent...done!";
699
700 ARMARX_DEBUG << "call postOnExitComponent...";
702 ARMARX_DEBUG << "call postOnExitComponent...done!";
703
704 ARMARX_DEBUG << "call postOnExitComponent for all plugins...";
705 foreach_plugin(
706 [&](const auto& typeidx, const auto& name, const auto& plugin)
707 {
709 ARMARX_DEBUG << "plugin '" << name << "' (" << GetTypeString(typeidx)
710 << ") postOnExitComponent...";
711 plugin->postOnExitComponent();
712 ARMARX_DEBUG << "plugin '" << name << "' (" << GetTypeString(typeidx)
713 << ") postOnExitComponent...done!";
714 },
715 __LINE__,
716 __FILE__,
717 BOOST_CURRENT_FUNCTION);
718 ARMARX_DEBUG << "call postOnExitComponent for all plugins...done!";
719 }
720 catch (...) // dispatch and handle exception
721 {
723 }
724 // set state
725 setObjectState(eManagedIceObjectExited);
726 impl->armarXManager = nullptr;
727 impl->iceManager = nullptr;
728 impl->objectScheduler = nullptr;
729 impl->objectAdapter = nullptr;
730 impl->proxy = nullptr;
731 ARMARX_VERBOSE << "Object '" << this->getName() << "' is finished";
732 }
733
734 void
735 ManagedIceObject::setObjectState(int newState)
736 {
738 std::unique_lock lock(impl->objectStateMutex);
739 ARMARX_DEBUG << "setObjectState: " << impl->objectState << " -> " << newState;
740
741 if (newState == impl->objectState)
742 {
743 return;
744 }
745
746 impl->objectState = (ManagedIceObjectState)newState;
747 impl->stateCondition.notify_all();
748 }
749
750 void
751 ManagedIceObject::Noop(ManagedIceObject*)
752 {
753 // NOOP
754 }
755
756 void
757 ManagedIceObject::EnableProfilerOn(ManagedIceObject* object)
758 {
760 object->offeringTopic(armarx::Profiler::PROFILER_TOPIC_NAME);
761 ProfilerListenerPrx profilerTopic = object->getIceManager()->getTopic<ProfilerListenerPrx>(
762 armarx::Profiler::PROFILER_TOPIC_NAME);
763 Profiler::LoggingStrategyPtr strategy(new Profiler::IceLoggingStrategy(profilerTopic));
764 object->impl->profiler->setLoggingStrategy(strategy);
765 ARMARX_INFO_S << "Profiler enabled for " << object->getName();
766 }
767
768 int
770 {
771 std::unique_lock lock(impl->objectStateMutex);
772 return impl->objectState;
773 }
774
777 {
778 return impl->objectScheduler;
779 }
780
781 ManagedIceObjectConnectivity
783 {
784 std::unique_lock lock(impl->connectivityMutex);
785 return impl->connectivity;
786 }
787
788 void
790 {
791 getObjectScheduler()->waitForDependencies();
792 }
793
794 void
795 ManagedIceObject::setMetaInfo(const std::string& id, const VariantBasePtr& value)
796 {
797 std::unique_lock lock(impl->metaInfoMapMutex);
798 impl->metaInfoMap[id] = value;
799 }
800
802 ManagedIceObject::getMetaInfo(const std::string& id)
803 {
804 std::unique_lock lock(impl->metaInfoMapMutex);
805 return impl->metaInfoMap[id];
806 }
807
810 {
811 std::unique_lock lock(impl->metaInfoMapMutex);
812 return impl->metaInfoMap;
813 }
814
815 void
816 ManagedIceObject::startPeriodicTask(const std::string& uniqueName,
817 std::function<void(void)> f,
818 int periodMs,
819 bool assureMeanInterval,
820 bool forceSystemTime)
821 {
823 ARMARX_CHECK_EXPRESSION(!impl->periodicTasks.count(uniqueName))
824 << "The name '" << uniqueName << "' is not unique!";
825 impl->periodicTasks[uniqueName] =
826 new SimplePeriodicTask(f, periodMs, assureMeanInterval, uniqueName, forceSystemTime);
827 }
828
829 bool
830 ManagedIceObject::stopPeriodicTask(const std::string& name)
831 {
833 if (!impl->periodicTasks.count(name))
834 {
835 return false;
836 }
837 const auto task = impl->periodicTasks.at(name);
839 task->stop();
840 impl->periodicTasks.erase(name);
841 return true;
842 }
843
845 ManagedIceObject::getPeriodicTask(const std::string& name)
846 {
848 if (impl->periodicTasks.count(name))
849 {
850 return impl->periodicTasks.at(name);
851 }
852 return nullptr;
853 }
854
855 void
856 armarx::ManagedIceObject::foreach_plugin(
857 const std::function<void(std::type_index, const std::string&, ManagedIceObjectPlugin*)>& f,
858 int line,
859 const char* file,
860 const char* function)
861 {
863 ARMARX_DEBUG << "foreach_plugin called from " << file << ':' << line << " in function '"
864 << 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)
868 {
869 const auto& [typeidx, name] = key;
870 ARMARX_DEBUG << "adding plugin '" << name << "' (" << GetTypeString(typeidx) << ", @"
871 << plugin.get() << ") to process list";
872
873 toProcess.emplace(plugin.get(), key);
874 }
875
876 while (processed.size() < toProcess.size())
877 {
879 const std::size_t oldNumProcessed = processed.size();
880 ARMARX_DEBUG << "foreach_plugin: strill processing "
881 << toProcess.size() - oldNumProcessed << " plugins";
882 for (const auto& [plugin, key] : toProcess)
883 {
884 if (processed.count(plugin))
885 {
886 continue;
887 }
888 const auto& [typeidx, name] = key;
889 ARMARX_DEBUG << "processing plugin '" << name << "' (" << GetTypeString(typeidx)
890 << ", @" << plugin << "): checking";
891 bool blocked = false;
892 for (const auto dep : plugin->_dependsOn)
893 {
894 if (!processed.count(dep))
895 {
896 blocked = true;
897 break;
898 }
899 }
900 if (blocked)
901 {
902 ARMARX_DEBUG << "processing plugin '" << name << "' (" << GetTypeString(typeidx)
903 << ", @" << plugin << "): skipping for now";
904 continue;
905 }
906
907 ARMARX_DEBUG << "processing plugin '" << name << "' (" << GetTypeString(typeidx)
908 << ", @" << plugin << "): run functor";
909 f(typeidx, name, plugin);
910 processed.emplace(plugin);
911 }
912 if (processed.size() == oldNumProcessed)
913 {
914 std::stringstream str;
915 str << "plugin graph is no DAG!\n";
916 for (const auto& [plugin, key] : toProcess)
917 {
918 const auto& [typeidx, name] = key;
919 str << " plugin '" << name << "' (" << GetTypeString(typeidx) << ", @"
920 << plugin << ")\n";
921 if (plugin->_dependsOn.empty())
922 {
923 str << " has no dependencies\n";
924 }
925 else
926 {
927 for (const auto dep : plugin->_dependsOn)
928 {
929 str << " depends on " << dep << '\n';
930 }
931 }
932 }
933 ARMARX_CHECK_EXPRESSION(false) << str.str();
934 }
935 }
936 }
937
938} // namespace armarx
std::string str(const T &t)
The ManagedIceObject is the base class for all ArmarX objects.
ManagedIceObjectConnectivity getConnectivity() const
Retrieve connectivity of the object (topcis as well as proxies)
void offeringTopic(const std::string &name)
Registers a topic for retrival after initialization.
VariantBasePtr getMetaInfo(const std::string &id)
virtual void preOnInitComponent()
Profiler::ProfilerPtr getProfiler() const
getProfiler returns an instance of armarx::Profiler
bool unsubscribeFromTopic(const std::string &name)
Unsubscribe from a topic.
bool stopPeriodicTask(const std::string &name)
IceUtil::Handle< SimplePeriodicTask< std::function< void(void)> > > PeriodicTaskPtr
virtual void onExitComponent()
Hook for subclass.
StringVariantBaseMap getMetaInfoMap() const
static const ManagedIceObjectPtr NullPtr
A nullptr to be used when a const ref to a nullptr is required.
static std::string generateSubObjectName(const std::string &superObjectName, const std::string &subObjectName)
Generates a unique name for a sub object from a general name and unique name.
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
void waitForObjectScheduler()
Waits until the ObjectScheduler could resolve all dependencies.
ArmarXObjectSchedulerPtr getObjectScheduler() const
virtual void postOnExitComponent()
Ice::ObjectAdapterPtr getObjectAdapter() const
Returns object's Ice adapter.
virtual void postOnInitComponent()
virtual void onDisconnectComponent()
Hook for subclass.
ManagedIceObject(ManagedIceObject const &other)
virtual std::string getDefaultName() const =0
Retrieve default name of component.
virtual void postOnDisconnectComponent()
void terminate()
Initiates termination of this IceManagedObject.
void usingTopic(const std::string &name, bool orderedPublishing=false)
Registers a proxy for subscription after initialization.
void waitForProxy(std::string const &name, bool addToDependencies)
std::unique_ptr< ManagedIceObjectPlugin > & getPluginPointer(std::type_info const &type, std::string const &prefix)
ManagedIceObject()
Protected default constructor.
virtual void onConnectComponent()=0
Pure virtual hook for the subclass.
std::string getName() const
Retrieve name of object.
IceManagerPtr getIceManager() const
Returns the IceManager.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
bool removeProxyDependency(const std::string &name)
This function removes the dependency of this object on the in parameter name specified object.
Ice::CommunicatorPtr getCommunicator() const
void startPeriodicTask(const std::string &uniqueName, std::function< void(void)> f, int periodMs, bool assureMeanInterval=false, bool forceSystemTime=true)
virtual void preOnConnectComponent()
virtual void preOnDisconnectComponent()
static std::string GetObjectStateAsString(int state)
virtual void onInitComponent()=0
Pure virtual hook for the subclass.
int getState() const
Retrieve current state of the ManagedIceObject.
PeriodicTaskPtr getPeriodicTask(const std::string &name)
void setMetaInfo(const std::string &id, const VariantBasePtr &value)
Allows to set meta information that can be queried live via Ice interface on the ArmarXManager.
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
void preambleGetTopic(std::string const &name)
void setName(std::string name)
Override name of well-known object.
virtual void preOnExitComponent()
virtual void postOnConnectComponent()
std::vector< std::string > getUnresolvedDependencies() const
returns the names of all unresolved dependencies
void enableProfiler(bool enable)
setProfiler allows setting ManagedIceObject::profiler to a new instance (if the new instance is actua...
The armarx::Profiler::Profiler class can be used for timing executions within the ArmarX framework.
Definition Profiler.h:89
The ProxyDependency class is part of the ManagedIceObjectConnectivity.
static IceUtil::Time GetTime(TimeMode timeMode=TimeMode::VirtualTime)
Get the current time.
Definition TimeUtil.cpp:42
static int USleep(long usec)
like timed_wait on boost condition_variables, but with timeserver support
Definition TimeUtil.cpp:159
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_INFO_S
Definition Logging.h:202
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:213
::IceInternal::ProxyHandle<::IceProxy::IceStorm::Topic > TopicPrx
Definition IceManager.h:70
::IceInternal::Handle<::Ice::Communicator > CommunicatorPtr
Definition IceManager.h:49
::IceInternal::Handle<::Ice::ObjectAdapter > ObjectAdapterPtr
Definition IceManager.h:52
std::shared_ptr< LoggingStrategy > LoggingStrategyPtr
std::shared_ptr< Profiler > ProfilerPtr
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< ManagedIceObjectDependency > ManagedIceObjectDependencyPtr
IceUtil::Handle< ArmarXManager > ArmarXManagerPtr
std::map< std::string, VariantBasePtr > StringVariantBaseMap
IceUtil::Handle< ArmarXObjectScheduler > ArmarXObjectSchedulerPtr
Definition ArmarXFwd.h:33
void handleExceptions()
std::string GetTypeString(const std::type_info &tinf, bool withoutNamespaceSpecifier=false)
IceUtil::Handle< IceManager > IceManagerPtr
IceManager smart pointer.
Definition ArmarXFwd.h:39
SimplePeriodicTask(Ts...) -> SimplePeriodicTask< std::function< void(void)> >
::IceInternal::Handle<::armarx::VariantBase > VariantBasePtr
IceInternal::Handle< ManagedIceObject > ManagedIceObjectPtr
Definition ArmarXFwd.h:42
#define ARMARX_TRACE
Definition trace.h:77