ManagedIceObject.h
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#pragma once
27
28#include <memory> // for unique_ptr
29#include <string> // for string
30#include <type_traits>
31#include <typeindex>
32#include <vector> // for vector
33
34#include <Ice/Handle.h> // for Handle
35#include <Ice/Object.h> // for Object
36#include <Ice/ProxyF.h> // for ObjectPrx
37#include <IceUtil/Handle.h> // for HandleBase
38
39#include <ArmarXCore/core/ArmarXFwd.h> // for ArmarXManagerPtr, etc
40#include <ArmarXCore/core/IceManager.h> // for IceManagerPtr
42#include <ArmarXCore/core/exceptions/LocalException.h> // for LocalException
43#include <ArmarXCore/core/exceptions/local/ExpressionException.h> // for ARMARX_CHECK_EXPRESSION
44#include <ArmarXCore/core/logging/Logging.h> // for Logging
45#include <ArmarXCore/core/system/ImportExport.h> // for ARMARXCORE_IMPORT_EXPORT
46
47// Forward declarations
49{
50 inline namespace fundamentals_v2
51 {
52 template <typename T>
54
55 template <typename _Tp>
56 observer_ptr<_Tp> make_observer(_Tp* __p) noexcept;
57 } // namespace fundamentals_v2
58} // namespace std::experimental
59
60namespace Ice
61{
62
63 class Communicator;
65
66 class ObjectAdapter;
68
69} // namespace Ice
70
72{
73 class Profiler;
74 using ProfilerPtr = std::shared_ptr<Profiler>;
75} // namespace armarx::Profiler
76
77namespace armarx
78{
79 template <class>
81#define TYPEDEF_PTRS_SHARED(T) \
82 class T; \
83 using T##Ptr = ::std::shared_ptr<T>; \
84 using Const##T##Ptr = ::std::shared_ptr<const T>
85
86#define TYPEDEF_PTRS_HANDLE(T) \
87 class T; \
88 using T##Ptr = IceUtil::Handle<T>
89
90 template <class T, class... Args>
91 auto
92 make_shared(Args&&... args)
93 {
94 if constexpr (std::is_base_of_v<IceUtil::Shared, T> ||
95 std::is_base_of_v<IceUtil::SimpleShared, T>)
96 {
97 return IceUtil::Handle<T>(new T(std::forward<Args>(args)...));
98 }
99 else
100 {
101 return std::make_shared<T>(std::forward<Args>(args)...);
102 }
103 }
104} // namespace armarx
105
106namespace armarx
107{
108 class VariantBase;
109 typedef ::IceInternal::Handle<::armarx::VariantBase> VariantBasePtr;
110 using StringVariantBaseMap = std::map<std::string, VariantBasePtr>;
111
112 /**
113 * ManagedIceObject shared pointer for convenience
114 */
115 class ManagedIceObject;
116
117 struct ManagedIceObjectConnectivity;
118
119
121
123
124 /**
125 * @class ManagedIceObject
126 * @ingroup DistributedProcessingGrp
127 * @brief The ManagedIceObject is the base class for all ArmarX objects.
128 *
129 * ManagedIceObject are the ArmarX equivalent to well-known Ice objects.
130 * A defined lifecycle is guaranteed which and state dependent interface
131 * is provided by the following framework hooks:
132 * @li ManagedIceObjects::onInitComponent()
133 * @li ManagedIceObjects::onConnectComponent()
134 * @li ManagedIceObjects::onExitComponent()
135 *
136 * @image html Lifecycle-UML.svg Lifecyle of a ManagedIceObject managed by the ArmarXObjectScheduler
137 * Every subclass of ManagedIceObject can specify dependent proxies and topics
138 * as well as offered topics in ManagedIceObjects::onInitComponent().
139 * These connectivity parameters are specified through the following methods:
140 * @li MangedIceObject::usingProxy()
141 * @li MangedIceObject::usingTopic()
142 * @li MangedIceObject::offeringTopic()
143 *
144 * These dependencies are resolved at runtime and can be visualized.
145 * Additionally it is possible to handle the case of crashed dependencies.
146 \code
147 MyManagedIceObject::onInitComponent()
148 {
149 // component depends on proxy "MyDataProvider"
150 usingProxy("MyDataProvider");
151
152 // component wants to subscribe to topic "News"
153 usingTopic("News");
154
155 // component will offer topic "FilteredNews"
156 offeringTopic("FilteredNews");
157 }
158 \endcode
159
160 @see ArmarXObjectScheduler
161 */
163 virtual public Ice::Object,
164 virtual public Logging
165
166 {
167 private:
168 friend class Component;
170 std::map<std::pair<std::type_index, std::string>, std::unique_ptr<ManagedIceObjectPlugin>>
171 _plugins;
172
173 void foreach_plugin(
174 std::function<void(std::type_index, std::string const&, ManagedIceObjectPlugin*)> const&
175 f,
176 int line,
177 const char* file,
178 const char* function);
179
180 protected:
181 std::unique_ptr<ManagedIceObjectPlugin>& getPluginPointer(std::type_info const& type,
182 std::string const& prefix);
183
184 template <class PluginT, class... ParamsT>
185 PluginT*
186 addPlugin(const std::string prefix = "", ParamsT&&... params)
187 {
188 static_assert(std::is_base_of_v<ManagedIceObjectPlugin, PluginT>);
189 auto& ptr = getPluginPointer(typeid(PluginT), prefix);
190 if (ptr)
191 {
192 auto tptr = dynamic_cast<PluginT*>(ptr.get());
194 << "Plugin is of wrong type. This should be impossible!";
195 return tptr;
196 }
197 PluginT* tptr = new PluginT(*this, prefix, std::forward<ParamsT>(params)...);
198 ptr.reset(tptr);
199 return tptr;
200 }
201
202 template <class PluginT, class... ParamsT>
203 void
204 addPlugin(PluginT*& targ, const std::string prefix = "", ParamsT&&... params)
205 {
206 ARMARX_CHECK_NULL(targ) << "This is an out parameter";
207 targ = addPlugin<PluginT>(prefix, std::forward<ParamsT>(params)...);
208 }
209
210 template <class PluginT, class... ParamsT>
211 void
213 const std::string prefix = "",
214 ParamsT&&... params)
215 {
216 ARMARX_CHECK_NULL(targ) << "This is an out parameter";
218 addPlugin<PluginT>(prefix, std::forward<ParamsT>(params)...));
219 }
220
221
222 private:
224 friend class ArmarXManager;
225
226 public:
227 using PeriodicTaskPtr = IceUtil::Handle<SimplePeriodicTask<std::function<void(void)>>>;
228
229 /**
230 * @brief A nullptr to be used when a const ref to a nullptr is required.
231 */
233
235
236
237 /**
238 * Retrieve name of object. Corresponds to well-known object name.
239 *
240 * @return name
241 */
242 std::string getName() const;
243
244 /**
245 * @brief Generates a unique name for a sub object from a general name and unique name.
246 * @param superObjectName The name of the super object (has to be unique)
247 * @param subObjectName The sub object's name (has to be unique among the sub objects)
248 * @return
249 */
250 static std::string generateSubObjectName(const std::string& superObjectName,
251 const std::string& subObjectName);
252
253 /**
254 * @brief Generates a unique name for a sub object from a general name.(given the current object name is unique)
255 * @param subObjectName The sub object's name (has to be unique among the sub objects)
256 * @return The unique sub object name
257 *
258 * Generates a unique name for a sub object from a general name.
259 * E.g.:
260 * Two objects A (object name "A") and B (object name "B") have a DebugDrawer as sub object.
261 * A and B can generate different object names for the debug drawer by calling this function with the same name "DebugDrawer".
262 * Additionally the created name contains the super object's name.
263 */
264 std::string generateSubObjectName(const std::string& subObjectName);
265
266 /**
267 * @brief Returns the proxy of this object (optionally it waits for the proxy)
268 * @param timeoutMs Timeout in miliseconds until this function stops waiting for the proxy.
269 * Set to -1 for infinite waiting.
270 * @return object's proxy (will be null if the time runs out/no object scheduler was set (e.g. by calling addObject on an ArmarXManager))
271 */
272 Ice::ObjectPrx getProxy(long timeoutMs = 0, bool waitForScheduler = true) const;
273
274 template <class Prx>
275 Prx
276 getProxy(long timeoutMs = 0, bool waitForScheduler = true) const
277 {
278 return Prx::checkedCast(getProxy(timeoutMs, waitForScheduler));
279 }
280
281 template <class Prx>
282 void
283 getProxy(Prx& prx, long timeoutMs = 0, bool waitForScheduler = true) const
284 {
285 prx = Prx::checkedCast(getProxy(timeoutMs, waitForScheduler));
286 }
287
288 /**
289 * Retrieve current state of the ManagedIceObject
290 *
291 * @return state of the ManagedIceObject
292 */
293 int getState() const;
294
295
296 ArmarXObjectSchedulerPtr getObjectScheduler() const;
297
298 /**
299 * Retrieve connectivity of the object (topcis as well as proxies)
300 *
301 * @return connectivity
302 */
303 ManagedIceObjectConnectivity getConnectivity() const;
304
305 /**
306 * Returns the ArmarX manager used to add and remove components
307 *
308 * @retrun pointer to the armarXManager
309 */
310 ArmarXManagerPtr getArmarXManager() const;
311
312 /**
313 * Returns the IceManager
314 *
315 * @return pointer to IceManager
316 */
317 IceManagerPtr getIceManager() const;
318
319 /**
320 * Registers a proxy for retrieval after initialization and adds it to the dependency list.
321 * This ManagedIceObject won't start (onConnectComponent()) until this proxy is avaiable.
322 *
323 * @param name Proxy name
324 * @param endpoints Specific endpoints, e.g. tcp ‑p 10002
325 * @return returns true if new dependency, else false
326 */
327 bool usingProxy(const std::string& name, const std::string& endpoints = "");
328
329 void waitForProxy(std::string const& name, bool addToDependencies);
330
331 /**
332 * Retrieves a proxy object.
333 *
334 * @param name Proxy name, e.g. Log
335 * @param addToDependencies If true, this proxy is added to the dependency list and this function won't return until the proxy becomes available.
336 * @param endpoints The endpoints, e.g. tcp ‑p 10002
337 * @param throwOnProxyError If true, throws Exception on any proxy error. If false, just returns zero pointer.
338 * @throw LocalException Throws if proxy is not available, this object is not yet starting or the proxyName is empty.
339 * @return A proxy of the remote instance.
340 */
341 template <class ProxyType>
343 getProxy(const std::string& name,
344 bool addToDependencies = false,
345 const std::string& endpoints = "",
346 bool throwOnProxyError = true)
347 {
348 waitForProxy(name, addToDependencies);
349
350 // return proxy
351 try
352 {
353 return getIceManager()->getProxy<ProxyType>(name, endpoints);
354 }
355 catch (...)
356 {
357 if (throwOnProxyError)
358 {
359 throw;
360 }
361 else
362 {
363 return nullptr;
364 }
365 }
366 }
367
368 /**
369 * @brief Assigns a proxy to `proxy`.
370 * This method can be called without explicit template argument, as
371 * the proxy type can be inferred from the arguments.
372 * @see getProxy<>()
373 */
374 template <class ProxyTarg, class... Args>
375 void
377 const std::string& name,
378 Args&&... args)
379 {
381 proxy = getProxy<ProxyType>(name, std::forward<Args>(args)...);
382 }
383
384 template <class ProxyTarg, class... Args>
385 void
386 getProxy(const std::string& name,
388 Args&&... args)
389 {
391 proxy = getProxy<ProxyType>(name, std::forward<Args>(args)...);
392 }
393
394 template <class ProxyTarg, class... Args>
395 void
396 getProxy(IceInternal::ProxyHandle<ProxyTarg>& proxy, const char* name, Args&&... args)
397 {
399 proxy = getProxy<ProxyType>(name, std::forward<Args>(args)...);
400 }
401
402 template <class ProxyTarg, class... Args>
403 void
404 getProxy(const char* name, IceInternal::ProxyHandle<ProxyTarg>& proxy, Args&&... args)
405 {
407 proxy = getProxy<ProxyType>(name, std::forward<Args>(args)...);
408 }
409
410 /// Overload to allow using string literals as name (solve ambiguous overload).
411 template <class ProxyType>
412 inline void
414 const char* name,
415 bool addToDependencies = false,
416 const std::string& endpoints = "",
417 bool throwOnProxyError = true)
418 {
420 proxy, std::string(name), addToDependencies, endpoints, throwOnProxyError);
421 }
422
423 /**
424 * @brief returns the names of all unresolved dependencies
425 */
426 std::vector<std::string> getUnresolvedDependencies() const;
427
428 static std::string GetObjectStateAsString(int state);
429
430 /**
431 * @brief getProfiler returns an instance of armarx::Profiler
432 */
433 Profiler::ProfilerPtr getProfiler() const;
434
435 /**
436 * @brief setProfiler allows setting ManagedIceObject::profiler to a new instance (if the new instance is actually not a null pointer)
437 */
438 void enableProfiler(bool enable);
439
440 /**
441 * Returns object's Ice adapter
442 *
443 * @return object's adapter
444 */
445 Ice::ObjectAdapterPtr getObjectAdapter() const;
446
447 /**
448 * Registers a proxy for subscription after initialization
449 *
450 * @param name Topic name
451 * @see unsubscribeFromTopic()
452 */
453 void usingTopic(const std::string& name, bool orderedPublishing = false);
454
455 /**
456 * @brief Unsubscribe from a topic
457 * @param name Name of the topic
458 * @return True if the ManagedIceObject was subscribed before, false otherwise.
459 */
460 bool unsubscribeFromTopic(const std::string& name);
461
462 /**
463 * Registers a topic for retrival after initialization
464 *
465 * @param name Topic name
466 */
467 void offeringTopic(const std::string& name);
468
469 void preambleGetTopic(std::string const& name);
470
471 /**
472 * Returns a proxy of the specified topic.
473 *
474 * @param name Topic name
475 *
476 * @return Topic proxy of the type \e TopicProxyType
477 */
478 template <class TopicProxyType>
479 TopicProxyType
480 getTopic(const std::string& name)
481 {
482 preambleGetTopic(name);
483
484 // retrieve topic
485 return getIceManager()->getTopic<TopicProxyType>(name);
486 }
487
488 /**
489 * @brief Assigns a proxy of the specified topic to `topicProxy`.
490 * This method can be called without explicit template argument, as
491 * the topic proxy type can be inferred from the arguments.
492 *
493 * @param topicProxy The topic proxy to be assigned.
494 * @param name Topic name
495 *
496 * @see getTopic<>()
497 */
498 template <class TopicProxyType>
499 void
500 getTopic(TopicProxyType& topicProxy, const std::string& name)
501 {
502 topicProxy = getTopic<TopicProxyType>(name);
503 }
504
505 /**
506 * @brief Waits until the ObjectScheduler could resolve all dependencies.
507 */
508 void waitForObjectScheduler();
509
510 /**
511 * Retrieve default name of component
512 *
513 * Implement this method in each IceManagedObject. The default name of a
514 * is used if no name is specified in the factory method.
515 *
516 * @return default name of the component (e.g. "KinematicUnit")
517 */
518 virtual std::string getDefaultName() const = 0;
519
520 /**
521 * @brief Allows to set meta information that can be queried live via Ice interface
522 * on the ArmarXManager.
523 * @param id Id and description of the meta information.
524 * @param value Value to be stored. Should only be basic types and strings.
525 */
526 void setMetaInfo(const std::string& id, const VariantBasePtr& value);
527 VariantBasePtr getMetaInfo(const std::string& id);
529
530 void startPeriodicTask(const std::string& uniqueName,
531 std::function<void(void)> f,
532 int periodMs,
533 bool assureMeanInterval = false,
534 bool forceSystemTime = true);
535 bool stopPeriodicTask(const std::string& name);
536 PeriodicTaskPtr getPeriodicTask(const std::string& name);
537
538 protected:
539 /**
540 * Protected default constructor. Used for virtual inheritance. Use createManagedIceObject() instead.
541 */
543 ~ManagedIceObject() override;
544
545 /**
546 * @brief This function removes the dependency of this object
547 * on the in parameter name specified object.
548 * @param name name of the depedency proxy
549 * @return returns true if depedency was found and removed
550 * false if dependency does not exist
551 */
552 bool removeProxyDependency(const std::string& name);
553
554
555 /**
556 * Initiates termination of this IceManagedObject. Returns immediately.
557 */
558 void terminate();
559
560 /**
561 * Override name of well-known object
562 */
563 void setName(std::string name);
564
565 /**
566 * Pure virtual hook for the subclass. Is called once initialization of the ManagedIceObject is done.
567 * This hook is called in the implenting class once and never again during the lifecyle of the object. This function is called
568 * as soon as the ManagedIceObject was added to the ArmarXManager. Called in an own thread and not the thread it was created in.
569 *
570 */
571 virtual void onInitComponent() = 0;
572
573 virtual void
575 {
576 }
577
578 virtual void
580 {
581 }
582
583 /**
584 * Pure virtual hook for the subclass. Is called once all dependencies of the object have been resolved and Ice connection is established.
585 * This hook is called whenever the dependencies are found. That means if the a depedency crashes or shuts down, the ManagedIceObject goes
586 * into disconnected state. When the dependencies are found again, this hook is called again.
587 *
588 *
589 * @see onDisconnectComponent()
590 */
591 virtual void onConnectComponent() = 0;
592
593 virtual void
597
598 virtual void
602
603 /**
604 * Hook for subclass. Is called if a dependency of the object got lost (crash, network error, stopped, ...).
605 * This hook should be the inverse to onConnectComponent(). So that onDisconnectComponent() and onConnectComponent() can be called alternatingly
606 * and the ManagedIceObject remains in valid states. *
607 *
608 * @see onConnectComponent
609 */
610 virtual void
614
615 virtual void
619
620 virtual void
624
625 /**
626 * Hook for subclass. Is called once the component terminates. Use for cleanup. Only called once.
627 */
628 virtual void
630 {
631 }
632
633 virtual void
635 {
636 }
637
638 virtual void
640 {
641 }
642
643 Ice::CommunicatorPtr getCommunicator() const;
644
645 private:
646 // init sets members and calls onInitComponent hook
647 void init(IceManagerPtr iceManager);
648 // start sets members and calls onConnectComponent hook
649 void start(Ice::ObjectPrx& proxy, const Ice::ObjectAdapterPtr& objectAdapter);
650 void disconnect();
651 // exit sets members and calls onExitComponent hook
652 void exit();
653
654 void setObjectState(int newState);
655
656 private:
657 struct Impl;
658 std::unique_ptr<Impl> impl;
659
660 /**
661 * @brief Noop function which does nothing (Only to be used as default value for enableProfilerFunction function pointer)
662 * @param object
663 */
664 static void Noop(ManagedIceObject* object);
665
666 /**
667 * @brief EnableProfilerOn creates an instance of armarx::IceLoggingStrategy and sets it on object->profiler
668 * @param object
669 */
670 static void EnableProfilerOn(ManagedIceObject* object);
671 };
672
673} // namespace armarx
#define ARMARX_CHECK_NULL(ptr)
#define ARMARXCORE_IMPORT_EXPORT
The ManagedIceObject is the base class for all ArmarX objects.
VariantBasePtr getMetaInfo(const std::string &id)
virtual void preOnInitComponent()
void addPlugin(PluginT *&targ, const std::string prefix="", ParamsT &&... params)
TopicProxyType getTopic(const std::string &name)
Returns a proxy of the specified topic.
ProxyType getProxy(const std::string &name, bool addToDependencies=false, const std::string &endpoints="", bool throwOnProxyError=true)
Retrieves a proxy object.
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.
virtual void postOnExitComponent()
void getProxy(IceInternal::ProxyHandle< ProxyTarg > &proxy, const std::string &name, Args &&... args)
Assigns a proxy to proxy.
virtual void postOnInitComponent()
virtual void onDisconnectComponent()
Hook for subclass.
PluginT * addPlugin(const std::string prefix="", ParamsT &&... params)
ManagedIceObject(ManagedIceObject const &other)
virtual std::string getDefaultName() const =0
Retrieve default name of component.
void getProxy(const std::string &name, IceInternal::ProxyHandle< ProxyTarg > &proxy, Args &&... args)
virtual void postOnDisconnectComponent()
void terminate()
Initiates termination of this IceManagedObject.
void waitForProxy(std::string const &name, bool addToDependencies)
std::unique_ptr< ManagedIceObjectPlugin > & getPluginPointer(std::type_info const &type, std::string const &prefix)
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.
void getProxy(IceInternal::ProxyHandle< ProxyTarg > &proxy, const char *name, Args &&... args)
void getTopic(TopicProxyType &topicProxy, const std::string &name)
Assigns a proxy of the specified topic to topicProxy.
void getProxy(const char *name, IceInternal::ProxyHandle< ProxyTarg > &proxy, Args &&... args)
void getProxy(Prx &prx, long timeoutMs=0, bool waitForScheduler=true) 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()
virtual void onInitComponent()=0
Pure virtual hook for the subclass.
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.
void preambleGetTopic(std::string const &name)
void setName(std::string name)
Override name of well-known object.
virtual void preOnExitComponent()
virtual void postOnConnectComponent()
void getProxy(ProxyType &proxy, const char *name, bool addToDependencies=false, const std::string &endpoints="", bool throwOnProxyError=true)
Overload to allow using string literals as name (solve ambiguous overload).
void addPlugin(std::experimental::observer_ptr< PluginT > &targ, const std::string prefix="", ParamsT &&... params)
Prx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
The armarx::Profiler::Profiler class can be used for timing executions within the ArmarX framework.
Definition Profiler.h:89
#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...
::IceInternal::Handle<::Ice::Communicator > CommunicatorPtr
Definition IceManager.h:49
::IceInternal::Handle<::Ice::ObjectAdapter > ObjectAdapterPtr
Definition IceManager.h:52
std::shared_ptr< Profiler > ProfilerPtr
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< ArmarXManager > ArmarXManagerPtr
std::map< std::string, VariantBasePtr > StringVariantBaseMap
auto make_shared(Args &&... args)
IceUtil::Handle< ArmarXObjectScheduler > ArmarXObjectSchedulerPtr
Definition ArmarXFwd.h:33
IceUtil::Handle< IceManager > IceManagerPtr
IceManager smart pointer.
Definition ArmarXFwd.h:39
::IceInternal::Handle<::armarx::VariantBase > VariantBasePtr
IceInternal::Handle< ManagedIceObject > ManagedIceObjectPtr
Definition ArmarXFwd.h:42
observer_ptr< _Tp > make_observer(_Tp *__p) noexcept