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
57 #include "ManagedIceObjectImpl.h"
59 #include "services/profiler/LoggingStrategy.h" // for LoggingStrategy, etc
60 
61 namespace Ice
62 {
63  class NotRegisteredException;
64  class ObjectAdapterDeactivatedException;
65 } // namespace Ice
66 
67 namespace 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  {
156  ARMARX_TRACE;
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  {
201  ARMARX_TRACE;
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  {
256  ARMARX_TRACE;
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
280  ManagedIceObject::unsubscribeFromTopic(const std::string& name)
281  {
282  ARMARX_TRACE;
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  {
302  ARMARX_TRACE;
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  {
339  ARMARX_TRACE;
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  {
380  ARMARX_TRACE;
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  {
409  ARMARX_TRACE;
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
445  ManagedIceObject::setName(std::string name)
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  {
462  ARMARX_TRACE;
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  {
477  ARMARX_TRACE;
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!";
488  ARMARX_TRACE;
489 
490  ARMARX_DEBUG << "call preOnInitComponent...";
492  ARMARX_DEBUG << "call preOnInitComponent...done!";
493 
494  ARMARX_DEBUG << "call onInitComponent...";
495  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  {
506  ARMARX_TRACE;
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  {
525  ARMARX_TRACE;
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  {
538  ARMARX_TRACE;
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!";
549  ARMARX_TRACE;
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  {
568  ARMARX_TRACE;
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  {
587  ARMARX_TRACE;
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  {
597  ARMARX_TRACE;
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!";
608  ARMARX_TRACE;
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  {
626  ARMARX_TRACE;
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  {
649  ARMARX_TRACE;
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  {
659  ARMARX_TRACE;
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  {
679  ARMARX_TRACE;
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!";
690  ARMARX_TRACE;
691 
692  ARMARX_DEBUG << "call preOnExitComponent...";
694  ARMARX_DEBUG << "call preOnExitComponent...done!";
695 
696  ARMARX_DEBUG << "call onExitComponent...";
697  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  {
708  ARMARX_TRACE;
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  {
737  ARMARX_TRACE;
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  {
759  ARMARX_TRACE;
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  {
822  ARMARX_TRACE;
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  {
832  ARMARX_TRACE;
833  if (!impl->periodicTasks.count(name))
834  {
835  return false;
836  }
837  const auto task = impl->periodicTasks.at(name);
838  ARMARX_CHECK_NOT_NULL(task);
839  task->stop();
840  impl->periodicTasks.erase(name);
841  return true;
842  }
843 
845  ManagedIceObject::getPeriodicTask(const std::string& name)
846  {
847  ARMARX_TRACE;
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  {
862  ARMARX_TRACE;
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  {
878  ARMARX_TRACE;
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
armarx::ManagedIceObject::setName
void setName(std::string name)
Override name of well-known object.
Definition: ManagedIceObject.cpp:445
armarx::ManagedIceObject::waitForProxy
void waitForProxy(std::string const &name, bool addToDependencies)
Definition: ManagedIceObject.cpp:178
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:187
armarx::ManagedIceObject::getConnectivity
ManagedIceObjectConnectivity getConnectivity() const
Retrieve connectivity of the object (topcis as well as proxies)
Definition: ManagedIceObject.cpp:782
armarx::ManagedIceObject::getIceManager
IceManagerPtr getIceManager() const
Returns the IceManager.
Definition: ManagedIceObject.cpp:366
str
std::string str(const T &t)
Definition: UserAssistedSegmenterGuiWidgetController.cpp:43
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:795
armarx::StringVariantBaseMap
std::map< std::string, VariantBasePtr > StringVariantBaseMap
Definition: ManagedIceObject.h:110
armarx::ManagedIceObject::postOnExitComponent
virtual void postOnExitComponent()
Definition: ManagedIceObject.h:639
armarx::ManagedIceObject::postOnDisconnectComponent
virtual void postOnDisconnectComponent()
Definition: ManagedIceObject.h:621
GetTypeString.h
armarx::ManagedIceObject::getObjectAdapter
Ice::ObjectAdapterPtr getObjectAdapter() const
Returns object's Ice adapter.
Definition: ManagedIceObject.cpp:144
ArmarXManager.h
armarx::ManagedIceObject::waitForObjectScheduler
void waitForObjectScheduler()
Waits until the ObjectScheduler could resolve all dependencies.
Definition: ManagedIceObject.cpp:789
armarx::ManagedIceObject::NullPtr
static const ManagedIceObjectPtr NullPtr
A nullptr to be used when a const ref to a nullptr is required.
Definition: ManagedIceObject.h:232
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:360
armarx::ManagedIceObject::getMetaInfo
VariantBasePtr getMetaInfo(const std::string &id)
Definition: ManagedIceObject.cpp:802
armarx::ManagedIceObject::getState
int getState() const
Retrieve current state of the ManagedIceObject.
Definition: ManagedIceObject.cpp:769
armarx::ManagedIceObject::postOnInitComponent
virtual void postOnInitComponent()
Definition: ManagedIceObject.h:579
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:337
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:816
armarx::Profiler::LoggingStrategy
A brief description.
Definition: LoggingStrategy.h:51
armarx::ManagedIceObject::ManagedIceObject
ManagedIceObject()
Protected default constructor.
Definition: ManagedIceObject.cpp:77
armarx::ManagedIceObject::stopPeriodicTask
bool stopPeriodicTask(const std::string &name)
Definition: ManagedIceObject.cpp:830
armarx::ManagedIceObject::onExitComponent
virtual void onExitComponent()
Hook for subclass.
Definition: ManagedIceObject.h:629
armarx::ManagedIceObject::GetObjectStateAsString
static std::string GetObjectStateAsString(int state)
Definition: ManagedIceObject.cpp:219
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:372
IceUtil
Definition: Instance.h:21
armarx::ManagedIceObject::getMetaInfoMap
StringVariantBaseMap getMetaInfoMap() const
Definition: ManagedIceObject.cpp:809
armarx::Profiler::LoggingStrategyPtr
std::shared_ptr< LoggingStrategy > LoggingStrategyPtr
Definition: LoggingStrategy.h:42
armarx::ManagedIceObject::onDisconnectComponent
virtual void onDisconnectComponent()
Hook for subclass.
Definition: ManagedIceObject.h:611
armarx::ManagedIceObject::preOnExitComponent
virtual void preOnExitComponent()
Definition: ManagedIceObject.h:634
IceLoggingStrategy.h
armarx::ManagedIceObject::getPluginPointer
std::unique_ptr< ManagedIceObjectPlugin > & getPluginPointer(std::type_info const &type, std::string const &prefix)
Definition: ManagedIceObject.cpp:86
IceInternal::Handle
Definition: forward_declarations.h:8
ARMARX_TRACE
#define ARMARX_TRACE
Definition: trace.h:77
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:570
armarx::ManagedIceObject::postOnConnectComponent
virtual void postOnConnectComponent()
Definition: ManagedIceObject.h:599
armarx::ManagedIceObject::preambleGetTopic
void preambleGetTopic(std::string const &name)
Definition: ManagedIceObject.cpp:325
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:855
armarx::TimeUtil::USleep
static int USleep(long usec)
like timed_wait on boost condition_variables, but with timeserver support
Definition: TimeUtil.cpp:159
ManagedIceObject.h
armarx::ManagedIceObject::preOnDisconnectComponent
virtual void preOnDisconnectComponent()
Definition: ManagedIceObject.h:616
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:184
armarx::ManagedIceObject::preOnInitComponent
virtual void preOnInitComponent()
Definition: ManagedIceObject.h:574
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:177
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:119
armarx::ManagedIceObject::terminate
void terminate()
Initiates termination of this IceManagedObject.
Definition: ManagedIceObject.cpp:438
IceManager.h
ArmarXObjectScheduler.h
armarx::ManagedIceObject::preOnConnectComponent
virtual void preOnConnectComponent()
Definition: ManagedIceObject.h:594
TaskUtil.h
armarx::ManagedIceObject::unsubscribeFromTopic
bool unsubscribeFromTopic(const std::string &name)
Unsubscribe from a topic.
Definition: ManagedIceObject.cpp:280
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:213
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:38
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:845
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:254
ArmarXFwd.h
Ice
Definition: DBTypes.cpp:63
armarx::ManagedIceObject
The ManagedIceObject is the base class for all ArmarX objects.
Definition: ManagedIceObject.h:162
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:181
armarx::ManagedIceObject::offeringTopic
void offeringTopic(const std::string &name)
Registers a topic for retrival after initialization.
Definition: ManagedIceObject.cpp:300
IceUtil::Handle
Definition: forward_declarations.h:30
LogSender.h
IceInternal::ProxyHandle<::IceProxy::IceStorm::Topic >
armarx::Profiler::ProfilerPtr
std::shared_ptr< Profiler > ProfilerPtr
Definition: ManagedIceObject.h:74
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:378
armarx::ManagedIceObject::getName
std::string getName() const
Retrieve name of object.
Definition: ManagedIceObject.cpp:108
armarx::ManagedIceObjectPlugin
Definition: ManagedIceObjectPlugin.h:49
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:202
Logging.h
ManagedIceObjectImpl.h
armarx::handleExceptions
void handleExceptions()
Definition: Exception.cpp:157
armarx::ManagedIceObject::~ManagedIceObject
~ManagedIceObject() override
Definition: ManagedIceObject.cpp:131
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:407
armarx::ManagedIceObject::getCommunicator
Ice::CommunicatorPtr getCommunicator() const
Definition: ManagedIceObject.cpp:451
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:199
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:154
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::ManagedIceObject::getObjectScheduler
ArmarXObjectSchedulerPtr getObjectScheduler() const
Definition: ManagedIceObject.cpp:776