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 <ArmarXCore/interface/core/Profiler.h>
27 #include <ArmarXCore/core/ArmarXFwd.h> // for ArmarXObjectSchedulerPtr, etc
29 #include <ArmarXCore/core/logging/LogSender.h> // for LogSender
30 #include <ArmarXCore/core/logging/Logging.h> // for ARMARX_VERBOSE, etc
31 #include <ArmarXCore/core/services/profiler/Profiler.h> // for Profiler, etc
32 #include <ArmarXCore/interface/core/ManagedIceObjectDefinitions.h>
33 #include <ArmarXCore/interface/core/ManagedIceObjectDependencyBase.h>
35 #include "ArmarXManager.h" // for ArmarXObjectSchedulerPtr, etc
36 #include "ArmarXObjectScheduler.h" // for ArmarXObjectScheduler
37 #include "IceManager.h" // for IceManager, IceManagerPtr
38 #include "ManagedIceObject.h"
39 #include "ManagedIceObjectImpl.h"
42 #include "services/profiler/LoggingStrategy.h" // for LoggingStrategy, etc
44 
45 #include <Ice/BuiltinSequences.h> // for StringSeq
46 #include <Ice/Identity.h> // for Identity
47 #include <Ice/LocalException.h>
48 #include <Ice/ObjectAdapter.h> // for ObjectAdapterPtr, etc
49 #include <IceStorm/IceStorm.h> // for TopicPrx
50 #include <IceUtil/Shared.h> // for Shared
51 #include <IceUtil/UUID.h> // for generateUUID
52 
53 #include <algorithm> // for find
54 #include <map> // for _Rb_tree_iterator, etc
55 #include <ostream> // for operator<<, basic_ostream, etc
56 #include <utility> // for pair, make_pair
57 #include <sstream>
58 
59 namespace Ice
60 {
61  class NotRegisteredException;
62  class ObjectAdapterDeactivatedException;
63 } // namespace Ice
64 
65 
66 namespace armarx
67 {
68  // *******************************************************
69  // static data
70  // *******************************************************
72 
73  // *******************************************************
74  // construction
75  // *******************************************************
77  : impl(new Impl)
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>& ManagedIceObject::getPluginPointer(std::type_info const& type, std::string const& prefix)
86  {
87  ARMARX_CHECK_EXPRESSION(getState() == ManagedIceObjectState::eManagedIceObjectCreated);
88  return _plugins[ {type, prefix}];
89  }
90 
92  : IceUtil::Shared()
93  , 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 ManagedIceObject::getName() const
108  {
109  if (impl->name.empty())
110  {
111  return getDefaultName();
112  }
113 
114  return impl->name;
115  }
116 
117  std::string ManagedIceObject::generateSubObjectName(const std::string& superObjectName, const std::string& subObjectName)
118  {
119  return superObjectName + "." + subObjectName;
120  }
121 
122  std::string ManagedIceObject::generateSubObjectName(const std::string& subObjectName)
123  {
124  return generateSubObjectName(getName(), subObjectName);
125  }
126 
127 
129  {
130  for (const auto& [name, task] : impl->periodicTasks)
131  {
132  if (task)
133  {
134  task->stop();
135  }
136  }
137  impl->periodicTasks.clear();
138  }
139 
141  {
142  return impl->objectAdapter;
143  }
144 
145 
146 
147  // *******************************************************
148  // establish dependencies
149  // *******************************************************
150 
151  bool ManagedIceObject::usingProxy(const std::string& name, const std::string&)
152  {
153  ARMARX_TRACE;
154  if (name.empty())
155  {
156  throw LocalException("proxyName must not be empty.");
157  }
158 
159  std::unique_lock lock(impl->connectivityMutex);
160 
161  // check if proxy already exists
162  if (impl->connectivity.dependencies.find(name) != impl->connectivity.dependencies.end())
163  {
164  return false;
165  }
166 
167  // add dependency
168  ManagedIceObjectDependencyPtr proxyDependency = new ProxyDependency(getIceManager(), name);
169  impl->connectivity.dependencies.insert(std::make_pair(name, proxyDependency));
170 
171  return true;
172  }
173 
174  void ManagedIceObject::waitForProxy(const std::string& name, bool addToDependencies)
175  {
176  if (name.empty())
177  {
178  throw LocalException("The proxy name must not be empty.");
179  }
180 
181  if (getState() < eManagedIceObjectStarting)
182  {
183  throw LocalException("Calling getProxy before component has been started");
184  }
185 
186  if (addToDependencies)
187  {
188  usingProxy(name);
189 
191  }
192  }
193 
194  std::vector<std::string> ManagedIceObject::getUnresolvedDependencies() const
195  {
196  ARMARX_TRACE;
197  ManagedIceObjectConnectivity con = getConnectivity();
198  std::vector<std::string> dependencies;
199 
200  for (auto& dependencie : con.dependencies)
201  {
202  ManagedIceObjectDependencyBasePtr& dep = dependencie.second;
203 
204  if (!dep->getResolved())
205  {
206  dependencies.push_back(dep->getName());
207  }
208  }
209 
210  return dependencies;
211  }
212 
214  {
215  switch (state)
216  {
217  case eManagedIceObjectCreated:
218  return "Created";
219 
220  case eManagedIceObjectInitializing:
221  return "Initializing";
222 
223  case eManagedIceObjectInitialized:
224  return "Initialized";
225  case eManagedIceObjectInitializationFailed:
226  return "InitializationFailed";
227 
228  case eManagedIceObjectStarting:
229  return "Starting";
230 
231  case eManagedIceObjectStartingFailed:
232  return "StartingFailed";
233 
234  case eManagedIceObjectStarted:
235  return "Started";
236 
237  case eManagedIceObjectExiting:
238  return "Exiting";
239 
240  case eManagedIceObjectExited:
241  return "Exited";
242  }
243 
244  return "Unknown";
245  }
246 
247 
248  void ManagedIceObject::usingTopic(const std::string& name, bool orderedPublishing)
249  {
250  ARMARX_TRACE;
251  std::unique_lock lock(impl->connectivityMutex);
252 
253  // check if topic is already used
254  if (std::find(impl->connectivity.usedTopics.begin(), impl->connectivity.usedTopics.end(), name) != impl->connectivity.usedTopics.end())
255  {
256  return;
257  }
258 
259  // add dependency
260  impl->connectivity.usedTopics.push_back(name);
261  impl->orderedTopicPublishing[name] = orderedPublishing;
262  ARMARX_VERBOSE << "Using topic with name: '" << name << "'";
263 
264  // only subscribe direcly if component has been initialized. Otherwise the dependency resolution will take care
265  if (getState() >= eManagedIceObjectStarting)
266  {
267  getIceManager()->subscribeTopic(impl->proxy, name, orderedPublishing);
268  }
269  }
270 
271  bool ManagedIceObject::unsubscribeFromTopic(const std::string& name)
272  {
273  ARMARX_TRACE;
274  std::unique_lock lock(impl->connectivityMutex);
275 
276  ARMARX_CHECK_EXPRESSION(impl->proxy);
277  getIceManager()->unsubscribeTopic(impl->proxy, name);
278  // check if topic is already used
279  auto it = std::find(impl->connectivity.usedTopics.begin(), impl->connectivity.usedTopics.end(), name);
280  if (it != impl->connectivity.usedTopics.end())
281  {
282  impl->connectivity.usedTopics.erase(it);
283  ARMARX_VERBOSE << "Removing " << name << " from used topic list";
284  return true;
285  }
286  return false;
287  }
288 
289 
290  void ManagedIceObject::offeringTopic(const std::string& name)
291  {
292  ARMARX_TRACE;
293  std::unique_lock lock(impl->connectivityMutex);
294  auto topicName = name + getIceManager()->getTopicSuffix();
295  // check if topic is already used
296  if (std::find(impl->connectivity.offeredTopics.begin(), impl->connectivity.offeredTopics.end(), topicName) != impl->connectivity.offeredTopics.end())
297  {
298  return;
299  }
300 
301  // add dependency
302  impl->connectivity.offeredTopics.push_back(topicName);
303  ARMARX_INFO << "Offering topic with name: '" << topicName << "'";
304 
305  // only retrieve topic direcly if component has been initialized. Otherwise the dependency resolution will take care
306  if (getState() >= eManagedIceObjectStarting)
307  {
308  getIceManager()->getTopic<IceStorm::TopicPrx>(name);
309  }
310  }
311 
312  void ManagedIceObject::preambleGetTopic(const std::string& name)
313  {
314  if (getState() < eManagedIceObjectStarting)
315  {
316  throw LocalException("Calling getTopic before component has been started");
317  }
318 
319  // make sure proxy is on the dependency list
320  offeringTopic(name);
321  }
322 
323 
324 
325 
326  bool ManagedIceObject::removeProxyDependency(const std::string& name)
327  {
328  ARMARX_TRACE;
329  std::unique_lock lock(impl->connectivityMutex);
330 
331  // check if proxy already exists
332  DependencyMap::iterator it = impl->connectivity.dependencies.find(name);
333 
334  if (it == impl->connectivity.dependencies.end())
335  {
336  return false;
337  }
338 
339  ARMARX_VERBOSE << "Removing proxy '" << name << "' from dependency list.";
340  impl->connectivity.dependencies.erase(it);
341  getObjectScheduler()->wakeupDependencyCheck();
342  return true;
343  }
344 
345  // *******************************************************
346  // getters
347  // *******************************************************
349  {
350  return impl->armarXManager;
351  }
352 
354  {
355  return impl->iceManager;
356  }
357 
358 
360  {
361  return impl->profiler;
362  }
363 
365  {
366  ARMARX_TRACE;
368  // set to empty log strategy if enable == false
369  impl->enableProfilerFunction = &ManagedIceObject::Noop;
370 
371  if (!enable)
372  {
373  impl->profiler->setLoggingStrategy(strategy);
374  return;
375  }
376 
377  // enable the IceLoggingStrategy if IceManager is available
378  // otherwise defer the creation until ManagedIceObject::init() is called
379  if (getIceManager())
380  {
381  // create the IceLoggingStrategy immediately if Ice is available
382  //enableProfilerFunction(this);
383  ManagedIceObject::EnableProfilerOn(this);
384  }
385  else
386  {
387  // if Ice is not yet available, the creation of IceLoggingStrategy is delayed via the enableProfilerFunction
388  impl->enableProfilerFunction = &ManagedIceObject::EnableProfilerOn;
389  }
390  }
391 
392 
393  Ice::ObjectPrx ManagedIceObject::getProxy(long timeoutMs, bool waitForScheduler) const
394  {
395  ARMARX_TRACE;
397  IceUtil::Time startTime = TimeUtil::GetTime(true);
398  if (waitForScheduler)
399  {
400  while (!oSched && ((TimeUtil::GetTime(true) - startTime).toMilliSecondsDouble() < timeoutMs || timeoutMs < 0))
401  {
402  oSched = getObjectScheduler();
403  TimeUtil::USleep(10000);
404  }
405  }
406  if (oSched)
407  {
408  oSched->waitForObjectStateMinimum(eManagedIceObjectStarting, timeoutMs);
409  }
410  else
411  {
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.";
413  }
414  return impl->proxy;
415  }
416 
417  // *******************************************************
418  // termination
419  // *******************************************************
421  {
422  impl->stateCondition.notify_all();
423  impl->objectScheduler->terminate();
424  }
425 
426  void ManagedIceObject::setName(std::string name)
427  {
428  this->impl->name = name;
429  }
430 
432  {
433  return getIceManager()->getCommunicator();
434  }
435 
436  // *******************************************************
437  // phase handling
438  // *******************************************************
439  void ManagedIceObject::init(IceManagerPtr iceManager)
440  {
441  ARMARX_TRACE;
442  // set state
443  setObjectState(eManagedIceObjectInitializing);
444 
445  // set ice manager
446  this->impl->iceManager = iceManager;
447 
448  // evaluate function created by enableProfiling();
449  impl->enableProfilerFunction(this);
450 
451  // call framwork hook
452  ARMARX_DEBUG << "call preOnInitComponent for all plugins...";
453  foreach_plugin([&](const auto & typeidx, const auto & name, const auto & plugin)
454  {
455  ARMARX_TRACE;
456  ARMARX_DEBUG << "plugin '" << name
457  << "' (" << GetTypeString(typeidx)
458  << ") preOnInitComponent...";
459  plugin->preOnInitComponent();
460  ARMARX_DEBUG << "plugin '" << name
461  << "' (" << GetTypeString(typeidx)
462  << ") preOnInitComponent...done!";
463  }, __LINE__, __FILE__, BOOST_CURRENT_FUNCTION);
464  ARMARX_DEBUG << "call preOnInitComponent for all plugins...done!";
465  ARMARX_TRACE;
466 
467  ARMARX_DEBUG << "call preOnInitComponent...";
469  ARMARX_DEBUG << "call preOnInitComponent...done!";
470 
471  ARMARX_DEBUG << "call onInitComponent...";
472  onInitComponent();
473  ARMARX_DEBUG << "call onInitComponent...done!";
474 
475  ARMARX_DEBUG << "call postOnInitComponent...";
477  ARMARX_DEBUG << "call postOnInitComponent...done!";
478 
479  ARMARX_DEBUG << "call postOnInitComponent for all plugins...";
480  foreach_plugin([&](const auto & typeidx, const auto & name, const auto & plugin)
481  {
482  ARMARX_TRACE;
483  ARMARX_DEBUG << "plugin '" << name
484  << "' (" << GetTypeString(typeidx)
485  << ") postOnInitComponent...";
486  plugin->postOnInitComponent();
487  ARMARX_DEBUG << "plugin '" << name
488  << "' (" << GetTypeString(typeidx)
489  << ") postOnInitComponent...done!";
490  }, __LINE__, __FILE__, BOOST_CURRENT_FUNCTION);
491  ARMARX_DEBUG << "call postOnInitComponent for all plugins...done!";
492 
493  // set state
494  setObjectState(eManagedIceObjectInitialized);
495  }
496 
497  void ManagedIceObject::start(Ice::ObjectPrx& proxy, const Ice::ObjectAdapterPtr& objectAdapter)
498  {
499  ARMARX_TRACE;
500  // set members
501  this->impl->proxy = proxy;
502  this->impl->objectAdapter = objectAdapter;
503 
504  // set state
505  setObjectState(eManagedIceObjectStarting);
506 
507  // call framwork hook
508  ARMARX_DEBUG << "call preOnConnectComponent for all plugins...";
509  foreach_plugin([&](const auto & typeidx, const auto & name, const auto & plugin)
510  {
511  ARMARX_TRACE;
512  ARMARX_DEBUG << "plugin '" << name
513  << "' (" << GetTypeString(typeidx)
514  << ") preOnConnectComponent...";
515  plugin->preOnConnectComponent();
516  ARMARX_DEBUG << "plugin '" << name
517  << "' (" << GetTypeString(typeidx)
518  << ") preOnConnectComponent...done!";
519  }, __LINE__, __FILE__, BOOST_CURRENT_FUNCTION);
520  ARMARX_DEBUG << "call preOnConnectComponent for all plugins...done!";
521  ARMARX_TRACE;
522 
523  ARMARX_DEBUG << "call preOnConnectComponent...";
525  ARMARX_DEBUG << "call preOnConnectComponent...done!";
526 
527  ARMARX_DEBUG << "call onConnectComponent...";
529  ARMARX_DEBUG << "call onConnectComponent...done!";
530 
531  ARMARX_DEBUG << "call postOnConnectComponent...";
533  ARMARX_DEBUG << "call postOnConnectComponent...done!";
534 
535 
536  ARMARX_DEBUG << "call postOnConnectComponent for all plugins...";
537  foreach_plugin([&](const auto & typeidx, const auto & name, const auto & plugin)
538  {
539  ARMARX_TRACE;
540  ARMARX_DEBUG << "plugin '" << name
541  << "' (" << GetTypeString(typeidx)
542  << ") postOnConnectComponent...";
543  plugin->postOnConnectComponent();
544  ARMARX_DEBUG << "plugin '" << name
545  << "' (" << GetTypeString(typeidx)
546  << ") postOnConnectComponent...done!";
547  }, __LINE__, __FILE__, BOOST_CURRENT_FUNCTION);
548  ARMARX_DEBUG << "call postOnConnectComponent for all plugins...done!";
549 
550  // set state
551  setObjectState(eManagedIceObjectStarted);
552  }
553 
554  void ManagedIceObject::disconnect()
555  {
556  ARMARX_TRACE;
557  // set state
558 
559  try
560  {
561  // call framwork hook
562  ARMARX_DEBUG << "call preOnDisconnectComponent for all plugins...";
563  foreach_plugin([&](const auto & typeidx, const auto & name, const auto & plugin)
564  {
565  ARMARX_TRACE;
566  ARMARX_DEBUG << "plugin '" << name
567  << "' (" << GetTypeString(typeidx)
568  << ") preOnDisconnectComponent...";
569  plugin->preOnDisconnectComponent();
570  ARMARX_DEBUG << "plugin '" << name
571  << "' (" << GetTypeString(typeidx)
572  << ") preOnDisconnectComponent...done!";
573  }, __LINE__, __FILE__, BOOST_CURRENT_FUNCTION);
574  ARMARX_DEBUG << "call preOnDisconnectComponent for all plugins...done!";
575  ARMARX_TRACE;
576 
577  ARMARX_DEBUG << "call preOnDisconnectComponent...";
579  ARMARX_DEBUG << "call preOnDisconnectComponent...done!";
580 
581  ARMARX_DEBUG << "call onDisconnectComponent...";
583  ARMARX_DEBUG << "call onDisconnectComponent...done!";
584 
585  ARMARX_DEBUG << "call postOnDisconnectComponent...";
587  ARMARX_DEBUG << "call postOnDisconnectComponent...done!";
588 
589  ARMARX_DEBUG << "call postOnDisconnectComponent for all plugins...";
590  foreach_plugin([&](const auto & typeidx, const auto & name, const auto & plugin)
591  {
592  ARMARX_TRACE;
593  ARMARX_DEBUG << "plugin '" << name
594  << "' (" << GetTypeString(typeidx)
595  << ") postOnDisconnectComponent...";
596  plugin->postOnDisconnectComponent();
597  ARMARX_DEBUG << "plugin '" << name
598  << "' (" << GetTypeString(typeidx)
599  << ") postOnDisconnectComponent...done!";
600  }, __LINE__, __FILE__, BOOST_CURRENT_FUNCTION);
601  ARMARX_DEBUG << "call postOnDisconnectComponent for all plugins...done!";
602  // set state
603  }
604  catch (...) // dispatch and handle exception
605  {
607  }
608  setObjectState(eManagedIceObjectInitialized);
609 
610  }
611 
612  void ManagedIceObject::exit()
613  {
614  ARMARX_TRACE;
615  // set state
616  setObjectState(eManagedIceObjectExiting);
617 
618  Ice::Identity id;
619  id.name = getName();
620 
621  // remove self so no new calls are coming in
622  try
623  {
624  ARMARX_TRACE;
625  if (getObjectAdapter())
626  {
627  getObjectAdapter()->remove(id);
628  }
629  }
630  catch (Ice::ObjectAdapterDeactivatedException&)
631  {
632  }
633  catch (Ice::NotRegisteredException&)
634  {
635  }
636 
637  try
638  {
639  // call framwork hook
640  ARMARX_DEBUG << "call preOnExitComponent for all plugins...";
641  foreach_plugin([&](const auto & typeidx, const auto & name, const auto & plugin)
642  {
643  ARMARX_TRACE;
644  ARMARX_DEBUG << "plugin '" << name
645  << "' (" << GetTypeString(typeidx)
646  << ") preOnExitComponent...";
647  plugin->preOnExitComponent();
648  ARMARX_DEBUG << "plugin '" << name
649  << "' (" << GetTypeString(typeidx)
650  << ") preOnExitComponent...done!";
651  }, __LINE__, __FILE__, BOOST_CURRENT_FUNCTION);
652  ARMARX_DEBUG << "call preOnExitComponent for all plugins...done!";
653  ARMARX_TRACE;
654 
655  ARMARX_DEBUG << "call preOnExitComponent...";
657  ARMARX_DEBUG << "call preOnExitComponent...done!";
658 
659  ARMARX_DEBUG << "call onExitComponent...";
660  onExitComponent();
661  ARMARX_DEBUG << "call onExitComponent...done!";
662 
663  ARMARX_DEBUG << "call postOnExitComponent...";
665  ARMARX_DEBUG << "call postOnExitComponent...done!";
666 
667  ARMARX_DEBUG << "call postOnExitComponent for all plugins...";
668  foreach_plugin([&](const auto & typeidx, const auto & name, const auto & plugin)
669  {
670  ARMARX_TRACE;
671  ARMARX_DEBUG << "plugin '" << name
672  << "' (" << GetTypeString(typeidx)
673  << ") postOnExitComponent...";
674  plugin->postOnExitComponent();
675  ARMARX_DEBUG << "plugin '" << name
676  << "' (" << GetTypeString(typeidx)
677  << ") postOnExitComponent...done!";
678  }, __LINE__, __FILE__, BOOST_CURRENT_FUNCTION);
679  ARMARX_DEBUG << "call postOnExitComponent for all plugins...done!";
680  }
681  catch (...) // dispatch and handle exception
682  {
684  }
685  // set state
686  setObjectState(eManagedIceObjectExited);
687  impl->armarXManager = nullptr;
688  impl->iceManager = nullptr;
689  impl->objectScheduler = nullptr;
690  impl->objectAdapter = nullptr;
691  impl->proxy = nullptr;
692  ARMARX_VERBOSE << "Object '" << this->getName() << "' is finished";
693  }
694 
695  void ManagedIceObject::setObjectState(int newState)
696  {
697  ARMARX_TRACE;
698  std::unique_lock lock(impl->objectStateMutex);
699  ARMARX_DEBUG << "setObjectState: " << impl->objectState << " -> " << newState;
700 
701  if (newState == impl->objectState)
702  {
703  return;
704  }
705 
706  impl->objectState = (ManagedIceObjectState)newState;
707  impl->stateCondition.notify_all();
708  }
709 
710  void ManagedIceObject::Noop(ManagedIceObject*)
711  {
712  // NOOP
713  }
714 
715  void ManagedIceObject::EnableProfilerOn(ManagedIceObject* object)
716  {
717  ARMARX_TRACE;
718  object->offeringTopic(armarx::Profiler::PROFILER_TOPIC_NAME);
719  ProfilerListenerPrx profilerTopic = object->getIceManager()->getTopic<ProfilerListenerPrx>(armarx::Profiler::PROFILER_TOPIC_NAME);
720  Profiler::LoggingStrategyPtr strategy(new Profiler::IceLoggingStrategy(profilerTopic));
721  object->impl->profiler->setLoggingStrategy(strategy);
722  ARMARX_INFO_S << "Profiler enabled for " << object->getName();
723  }
724 
726  {
727  std::unique_lock lock(impl->objectStateMutex);
728  return impl->objectState;
729  }
730 
732  {
733  return impl->objectScheduler;
734  }
735 
736 
737  ManagedIceObjectConnectivity ManagedIceObject::getConnectivity() const
738  {
739  std::unique_lock lock(impl->connectivityMutex);
740  return impl->connectivity;
741  }
742 
743 
745  {
746  getObjectScheduler()->waitForDependencies();
747  }
748 
749  void ManagedIceObject::setMetaInfo(const std::string& id, const VariantBasePtr& value)
750  {
751  std::unique_lock lock(impl->metaInfoMapMutex);
752  impl->metaInfoMap[id] = value;
753  }
754 
756  {
757  std::unique_lock lock(impl->metaInfoMapMutex);
758  return impl->metaInfoMap[id];
759  }
760 
762  {
763  std::unique_lock lock(impl->metaInfoMapMutex);
764  return impl->metaInfoMap;
765  }
766 
767  void ManagedIceObject::startPeriodicTask(const std::string& uniqueName,
768  std::function<void(void)> f,
769  int periodMs,
770  bool assureMeanInterval,
771  bool forceSystemTime)
772  {
773  ARMARX_TRACE;
774  ARMARX_CHECK_EXPRESSION(!impl->periodicTasks.count(uniqueName))
775  << "The name '" << uniqueName << "' is not unique!";
776  impl->periodicTasks[uniqueName] = new SimplePeriodicTask(
777  f, periodMs, assureMeanInterval, uniqueName, forceSystemTime);
778  }
779  bool ManagedIceObject::stopPeriodicTask(const std::string& name)
780  {
781  ARMARX_TRACE;
782  if (!impl->periodicTasks.count(name))
783  {
784  return false;
785  }
786  const auto task = impl->periodicTasks.at(name);
787  ARMARX_CHECK_NOT_NULL(task);
788  task->stop();
789  impl->periodicTasks.erase(name);
790  return true;
791  }
793  {
794  ARMARX_TRACE;
795  if (impl->periodicTasks.count(name))
796  {
797  return impl->periodicTasks.at(name);
798  }
799  return nullptr;
800  }
801 
802 
803  void armarx::ManagedIceObject::foreach_plugin(
804  const std::function<void (std::type_index, const std::string&, ManagedIceObjectPlugin*)>& f,
805  int line, const char* file, const char* function)
806  {
807  ARMARX_TRACE;
808  ARMARX_DEBUG << "foreach_plugin called from "
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)
814  {
815  const auto& [typeidx, name] = key;
816  ARMARX_DEBUG << "adding plugin '" << name
817  << "' (" << GetTypeString(typeidx)
818  << ", @" << plugin.get() << ") to process list";
819 
820  toProcess.emplace(plugin.get(), key);
821  }
822 
823  while (processed.size() < toProcess.size())
824  {
825  ARMARX_TRACE;
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)
829  {
830  if (processed.count(plugin))
831  {
832  continue;
833  }
834  const auto& [typeidx, name] = key;
835  ARMARX_DEBUG << "processing plugin '" << name
836  << "' (" << GetTypeString(typeidx)
837  << ", @" << plugin << "): checking";
838  bool blocked = false;
839  for (const auto dep : plugin->_dependsOn)
840  {
841  if (!processed.count(dep))
842  {
843  blocked = true;
844  break;
845  }
846  }
847  if (blocked)
848  {
849  ARMARX_DEBUG << "processing plugin '" << name
850  << "' (" << GetTypeString(typeidx)
851  << ", @" << plugin << "): skipping for now";
852  continue;
853  }
854 
855  ARMARX_DEBUG << "processing plugin '" << name
856  << "' (" << GetTypeString(typeidx)
857  << ", @" << plugin << "): run functor";
858  f(typeidx, name, plugin);
859  processed.emplace(plugin);
860  }
861  if (processed.size() == oldNumProcessed)
862  {
863  std::stringstream str;
864  str << "plugin graph is no DAG!\n";
865  for (const auto& [plugin, key] : toProcess)
866  {
867  const auto& [typeidx, name] = key;
868  str << " plugin '" << name
869  << "' (" << GetTypeString(typeidx)
870  << ", @" << plugin << ")\n";
871  if (plugin->_dependsOn.empty())
872  {
873  str << " has no dependencies\n";
874  }
875  else
876  {
877  for (const auto dep : plugin->_dependsOn)
878  {
879  str << " depends on " << dep << '\n';
880  }
881  }
882  }
883  ARMARX_CHECK_EXPRESSION(false) << str.str();
884  }
885  }
886  }
887 
888 }
armarx::ManagedIceObject::setName
void setName(std::string name)
Override name of well-known object.
Definition: ManagedIceObject.cpp:426
armarx::ManagedIceObject::waitForProxy
void waitForProxy(std::string const &name, bool addToDependencies)
Definition: ManagedIceObject.cpp:174
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::ManagedIceObject::getConnectivity
ManagedIceObjectConnectivity getConnectivity() const
Retrieve connectivity of the object (topcis as well as proxies)
Definition: ManagedIceObject.cpp:737
armarx::ManagedIceObject::getIceManager
IceManagerPtr getIceManager() const
Returns the IceManager.
Definition: ManagedIceObject.cpp:353
str
std::string str(const T &t)
Definition: UserAssistedSegmenterGuiWidgetController.cpp:42
armarx::ManagedIceObject::setMetaInfo
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.
Definition: ManagedIceObject.cpp:749
armarx::StringVariantBaseMap
std::map< std::string, VariantBasePtr > StringVariantBaseMap
Definition: ManagedIceObject.h:111
armarx::ManagedIceObject::postOnExitComponent
virtual void postOnExitComponent()
Definition: ManagedIceObject.h:572
armarx::ManagedIceObject::postOnDisconnectComponent
virtual void postOnDisconnectComponent()
Definition: ManagedIceObject.h:565
GetTypeString.h
armarx::ManagedIceObject::getObjectAdapter
Ice::ObjectAdapterPtr getObjectAdapter() const
Returns object's Ice adapter.
Definition: ManagedIceObject.cpp:140
ArmarXManager.h
armarx::ManagedIceObject::waitForObjectScheduler
void waitForObjectScheduler()
Waits until the ObjectScheduler could resolve all dependencies.
Definition: ManagedIceObject.cpp:744
armarx::ManagedIceObject::NullPtr
static const ManagedIceObjectPtr NullPtr
A nullptr to be used when a const ref to a nullptr is required.
Definition: ManagedIceObject.h:222
ARMARX_CHECK_NOT_NULL
#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...
Definition: ExpressionException.h:206
armarx::ManagedIceObject::getArmarXManager
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
Definition: ManagedIceObject.cpp:348
armarx::ManagedIceObject::getMetaInfo
VariantBasePtr getMetaInfo(const std::string &id)
Definition: ManagedIceObject.cpp:755
armarx::ManagedIceObject::getState
int getState() const
Retrieve current state of the ManagedIceObject.
Definition: ManagedIceObject.cpp:725
armarx::ManagedIceObject::postOnInitComponent
virtual void postOnInitComponent()
Definition: ManagedIceObject.h:542
armarx::ManagedIceObject::removeProxyDependency
bool removeProxyDependency(const std::string &name)
This function removes the dependency of this object on the in parameter name specified object.
Definition: ManagedIceObject.cpp:326
armarx::ManagedIceObject::startPeriodicTask
void startPeriodicTask(const std::string &uniqueName, std::function< void(void)> f, int periodMs, bool assureMeanInterval=false, bool forceSystemTime=true)
Definition: ManagedIceObject.cpp:767
armarx::Profiler::LoggingStrategy
A brief description.
Definition: LoggingStrategy.h:50
armarx::ManagedIceObject::ManagedIceObject
ManagedIceObject()
Protected default constructor.
Definition: ManagedIceObject.cpp:76
armarx::ManagedIceObject::stopPeriodicTask
bool stopPeriodicTask(const std::string &name)
Definition: ManagedIceObject.cpp:779
armarx::ManagedIceObject::onExitComponent
virtual void onExitComponent()
Hook for subclass.
Definition: ManagedIceObject.h:570
armarx::ManagedIceObject::GetObjectStateAsString
static std::string GetObjectStateAsString(int state)
Definition: ManagedIceObject.cpp:213
armarx::ManagedIceObject::onInitComponent
virtual void onInitComponent()=0
Pure virtual hook for the subclass.
armarx::ManagedIceObject::getProfiler
Profiler::ProfilerPtr getProfiler() const
getProfiler returns an instance of armarx::Profiler
Definition: ManagedIceObject.cpp:359
IceUtil
Definition: Instance.h:21
armarx::ManagedIceObject::getMetaInfoMap
StringVariantBaseMap getMetaInfoMap() const
Definition: ManagedIceObject.cpp:761
armarx::Profiler::LoggingStrategyPtr
std::shared_ptr< LoggingStrategy > LoggingStrategyPtr
Definition: LoggingStrategy.h:42
armarx::ManagedIceObject::onDisconnectComponent
virtual void onDisconnectComponent()
Hook for subclass.
Definition: ManagedIceObject.h:563
armarx::ManagedIceObject::preOnExitComponent
virtual void preOnExitComponent()
Definition: ManagedIceObject.h:571
IceLoggingStrategy.h
armarx::ManagedIceObject::getPluginPointer
std::unique_ptr< ManagedIceObjectPlugin > & getPluginPointer(std::type_info const &type, std::string const &prefix)
Definition: ManagedIceObject.cpp:85
IceInternal::Handle< ::Ice::ObjectAdapter >
ARMARX_TRACE
#define ARMARX_TRACE
Definition: trace.h:69
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:523
armarx::ManagedIceObject::postOnConnectComponent
virtual void postOnConnectComponent()
Definition: ManagedIceObject.h:554
armarx::ManagedIceObject::preambleGetTopic
void preambleGetTopic(std::string const &name)
Definition: ManagedIceObject.cpp:312
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::TimeUtil::USleep
static int USleep(long usec)
like timed_wait on boost condition_variables, but with timeserver support
Definition: TimeUtil.cpp:148
ManagedIceObject.h
armarx::ManagedIceObject::preOnDisconnectComponent
virtual void preOnDisconnectComponent()
Definition: ManagedIceObject.h:564
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
armarx::ManagedIceObject::preOnInitComponent
virtual void preOnInitComponent()
Definition: ManagedIceObject.h:541
armarx::ManagedIceObject::Impl
Definition: ManagedIceObjectImpl.h:11
armarx::Profiler::Profiler
The armarx::Profiler::Profiler class can be used for timing executions within the ArmarX framework.
Definition: Profiler.h:88
armarx::ProxyDependency
The ProxyDependency class is part of the ManagedIceObjectConnectivity.
Definition: ManagedIceObjectDependency.h:170
armarx::ManagedIceObjectPtr
IceInternal::Handle< ManagedIceObject > ManagedIceObjectPtr
Definition: ArmarXFwd.h:42
armarx::ManagedIceObject::generateSubObjectName
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.
Definition: ManagedIceObject.cpp:117
armarx::ManagedIceObject::terminate
void terminate()
Initiates termination of this IceManagedObject.
Definition: ManagedIceObject.cpp:420
IceManager.h
ArmarXObjectScheduler.h
armarx::ManagedIceObject::preOnConnectComponent
virtual void preOnConnectComponent()
Definition: ManagedIceObject.h:553
TaskUtil.h
armarx::ManagedIceObject::unsubscribeFromTopic
bool unsubscribeFromTopic(const std::string &name)
Unsubscribe from a topic.
Definition: ManagedIceObject.cpp:271
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:206
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::GetTypeString
std::string GetTypeString(const std::type_info &tinf, bool withoutNamespaceSpecifier=false)
Definition: GetTypeString.h:36
ManagedIceObjectDependency.h
armarx::ManagedIceObject::getDefaultName
virtual std::string getDefaultName() const =0
Retrieve default name of component.
LoggingStrategy.h
armarx::TimeUtil::GetTime
static IceUtil::Time GetTime(TimeMode timeMode=TimeMode::VirtualTime)
Get the current time.
Definition: TimeUtil.cpp:42
armarx::ManagedIceObject::getPeriodicTask
PeriodicTaskPtr getPeriodicTask(const std::string &name)
Definition: ManagedIceObject.cpp:792
ExpressionException.h
armarx::SimplePeriodicTask
SimplePeriodicTask(Ts...) -> SimplePeriodicTask< std::function< void(void)>>
armarx::ManagedIceObject::usingTopic
void usingTopic(const std::string &name, bool orderedPublishing=false)
Registers a proxy for subscription after initialization.
Definition: ManagedIceObject.cpp:248
ArmarXFwd.h
Ice
Definition: DBTypes.cpp:64
armarx::ManagedIceObject
The ManagedIceObject is the base class for all ArmarX objects.
Definition: ManagedIceObject.h:163
Profiler.h
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::ManagedIceObject::offeringTopic
void offeringTopic(const std::string &name)
Registers a topic for retrival after initialization.
Definition: ManagedIceObject.cpp:290
IceUtil::Handle
Definition: forward_declarations.h:29
LogSender.h
IceInternal::ProxyHandle< ::IceProxy::IceStorm::Topic >
armarx::Profiler::ProfilerPtr
std::shared_ptr< Profiler > ProfilerPtr
Definition: ManagedIceObject.h:75
armarx::ManagedIceObject::enableProfiler
void enableProfiler(bool enable)
setProfiler allows setting ManagedIceObject::profiler to a new instance (if the new instance is actua...
Definition: ManagedIceObject.cpp:364
armarx::ManagedIceObject::getName
std::string getName() const
Retrieve name of object.
Definition: ManagedIceObject.cpp:107
armarx::ManagedIceObjectPlugin
Definition: ManagedIceObjectPlugin.h:50
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:195
Logging.h
ManagedIceObjectImpl.h
armarx::handleExceptions
void handleExceptions()
Definition: Exception.cpp:141
armarx::ManagedIceObject::~ManagedIceObject
~ManagedIceObject() override
Definition: ManagedIceObject.cpp:128
armarx::ManagedIceObject::getProxy
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
Definition: ManagedIceObject.cpp:393
armarx::ManagedIceObject::getCommunicator
Ice::CommunicatorPtr getCommunicator() const
Definition: ManagedIceObject.cpp:431
armarx::ManagedIceObject::onConnectComponent
virtual void onConnectComponent()=0
Pure virtual hook for the subclass.
armarx::ManagedIceObject::getUnresolvedDependencies
std::vector< std::string > getUnresolvedDependencies() const
returns the names of all unresolved dependencies
Definition: ManagedIceObject.cpp:194
armarx::ManagedIceObject::usingProxy
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
Definition: ManagedIceObject.cpp:151
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::ManagedIceObject::getObjectScheduler
ArmarXObjectSchedulerPtr getObjectScheduler() const
Definition: ManagedIceObject.cpp:731