ChannelRef.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 ArmarX::Core
19* @author Kai Welke (welke@kit.edu)
20* @date 2012 Kai Welke
21* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22* GNU General Public License
23*/
24
25#include <algorithm>
26
27#include <Ice/ObjectAdapter.h>
28#include <Ice/ValueFactory.h>
29
37
38template class ::IceInternal::Handle<::armarx::ChannelRef>;
39
40namespace armarx
41{
42 using namespace armarx::exceptions::local;
43
44 // *******************************************************
45 // Construction / destruction
46 // *******************************************************
47 ChannelRef::ChannelRef(Observer* observer, std::string channelName) :
48 validationTimeout(4000), waitIntervallMs(10)
49 {
50 if (!observer)
51 {
52 ARMARX_FATAL_S << "observer must not be NULL";
53 throw exceptions::local::eNullPointerException("observer must not be NULL");
54 }
55
56 this->observerProxy = ObserverInterfacePrx::uncheckedCast(observer->getProxy());
57 this->communicator = observerProxy->ice_getCommunicator();
58 this->observerName = observer->getName();
59 this->channelName = channelName;
60
61 // initialize data fields and initialized state
62 initializeDataFields(observer);
63 }
64
65 ChannelRef::ChannelRef(ObserverInterfacePrx observerPrx, std::string channelName) :
66 validationTimeout(4000), waitIntervallMs(10)
67 {
68 if (!observerPrx)
69 {
70 throw exceptions::local::eNullPointerException("observerPrx must not be NULL");
71 }
72
73 this->observerProxy = observerPrx;
74 this->observerName = observerPrx->ice_getIdentity().name;
75 this->channelName = channelName;
76 this->communicator = observerProxy->ice_getCommunicator();
77
78 // initialize data fields and initialized state
79 initializeDataFields();
80 }
81
82 // *******************************************************
83 // Datafield access
84 // *******************************************************
86 ChannelRef::getDataFieldIdentifier(const std::string& datafieldName)
87 {
88 if (!assureProxy())
89 {
90 throw ProxyNotInitializedException(observerName);
91 }
92
93 if (std::find(datafieldNames.begin(), datafieldNames.end(), datafieldName) ==
94 datafieldNames.end())
95 {
97
98 if (std::find(datafieldNames.begin(), datafieldNames.end(), datafieldName) ==
99 datafieldNames.end())
100 {
101 throw exceptions::user::InvalidDataFieldException(channelName, datafieldName);
102 }
103 }
104
105 return new DataFieldIdentifier(observerName, channelName, datafieldName);
106 }
107
109 ChannelRef::getDataField(const std::string& datafieldName)
110 {
111 if (!assureProxy())
112 {
113 throw ProxyNotInitializedException(observerName);
114 }
115 TimedVariantPtr result;
116 try
117 {
118 result = TimedVariantPtr::dynamicCast(
119 observerProxy->getDatafieldByName(getChannelName(), datafieldName));
120 }
121 catch (...)
122 {
123 if (communicator)
124 {
125 observerProxy =
126 ObserverInterfacePrx::uncheckedCast(communicator->stringToProxy(observerName));
127 result = TimedVariantPtr::dynamicCast(
128 observerProxy->getDatafieldByName(getChannelName(), datafieldName));
129 }
130 else
131 {
132 throw;
133 }
134 }
135 return result;
136 }
137
138 // *******************************************************
139 // Properties
140 // *******************************************************
141 const ObserverInterfacePrx&
143 {
144 if (!assureProxy())
145 {
146 throw ProxyNotInitializedException(observerName);
147 }
148
149 return observerProxy;
150 }
151
152 const std::string&
154 {
155 return observerName;
156 }
157
158 const std::string&
160 {
161 return channelName;
162 }
163
164 const Ice::StringSeq&
166 {
167 return datafieldNames;
168 }
169
170 bool
171 ChannelRef::hasDatafield(const std::string& datafieldName) const
172 {
173 for (unsigned int i = 0; i < datafieldNames.size(); ++i)
174 {
175 if (datafieldName == datafieldNames.at(i))
176 {
177 return true;
178 }
179 }
180
181 return false;
182 }
183
184 bool
186 {
187 // once all datafields are initialized -> channel initialized
188 if (initialized)
189 {
190 return true;
191 }
192
193 // if proxy not there -> not initialized
194 if (!assureProxy())
195 {
196 return false;
197 }
198
199 ARMARX_INFO_S << "ChannelRef:" << getObserverName() << "." << getChannelName()
200 << ": Initialized as retrieved from proxy : " << initialized;
201
202 return initialized;
203 }
204
205 void
207 {
208 initializeDataFields();
209 }
210
211 // *******************************************************
212 // Inherited from VariantDataClass
213 // *******************************************************
214 VariantDataClassPtr
215 ChannelRef::clone(const Ice::Current& c) const
216 {
217 ChannelRefPtr cln = new ChannelRef(*this);
218
219 cln->initialized = this->initialized;
220
221 cln->observerName = this->observerName;
222 cln->channelName = this->channelName;
223 cln->datafieldNames = this->datafieldNames;
224
225 cln->observerProxy = this->observerProxy;
226
227 return cln;
228 }
229
230 std::string
231 ChannelRef::output(const Ice::Current& c) const
232 {
233 std::stringstream s;
234 s << "Reference to channel " << channelName << " on observer " << observerName;
235
236 return s.str();
237 }
238
240 ChannelRef::getType(const Ice::Current& c) const
241 {
243 }
244
245 bool
246 ChannelRef::validate(const Ice::Current& c)
247 {
248 int validateWaitIntervallMs = waitIntervallMs;
249 IceUtil::Time waitStartTime = IceUtil::Time::now();
250
251 IceUtil::Time timeout = IceUtil::Time::milliSeconds(validationTimeout);
252
253 IceUtil::Time lastOutput = IceUtil::Time::milliSeconds(0);
254
255 while (IceUtil::Time(waitStartTime + timeout - IceUtil::Time::now()).toMilliSeconds() > 0)
256 {
257 if (getInitialized())
258 {
259 return true;
260 }
261
262 if (IceUtil::Time(IceUtil::Time::now() - lastOutput).toSeconds() >=
263 1) // output only every second
264 {
265 ARMARX_VERBOSE_S << "Waiting for ChannelRef: " << getObserverName() << "."
266 << getChannelName() << flush;
267 lastOutput = IceUtil::Time::now();
268 }
269
270 usleep(validateWaitIntervallMs * 1000);
271
272 if (validateWaitIntervallMs <
273 validationTimeout * 0.5f) // increase wait time for lower cpu usage
274 {
275 validateWaitIntervallMs *= 2;
276 }
277 }
278
279 ARMARX_WARNING_S << "Could not validate ChannelRef: " << getObserverName() << "."
280 << getChannelName() << flush;
281 return false;
282 }
283
284 // private
285 bool
286 ChannelRef::assureProxy()
287 {
288 if (!observerProxy)
289 {
290 try
291 {
292 observerProxy =
293 ObserverInterfacePrx::checkedCast(communicator->stringToProxy(observerName));
294 }
295 catch (...)
296 {
297 }
298 }
299
300 if (observerProxy && !initialized)
301 {
302 initializeDataFields();
303 }
304
305 return (observerProxy != 0);
306 }
307
308 void
309 ChannelRef::initializeDataFields(Observer* obs)
310 {
311 ChannelRegistryEntry channel =
312 obs ? obs->getChannel(getChannelName()) : observerProxy->getChannel(getChannelName());
313
314 DataFieldRegistry::const_iterator iterData = channel.dataFields.begin();
315 datafieldNames.clear();
316
317 while (iterData != channel.dataFields.end())
318 {
319 datafieldNames.push_back(iterData->second.identifier->datafieldName);
320 iterData++;
321 }
322
323 initialized = channel.initialized;
324 }
325
326 void
328 {
329 if (observerProxy)
330 {
331 communicator = observerProxy->ice_getCommunicator();
332 }
333 }
334
335 void
336 ChannelRef::serialize(const ObjectSerializerBasePtr& serializer, const ::Ice::Current&) const
337 {
338 AbstractObjectSerializerPtr obj = AbstractObjectSerializerPtr::dynamicCast(serializer);
339
340 obj->setString("observerName", observerName);
341 obj->setString("channelName", channelName);
342 }
343
344 void
345 ChannelRef::deserialize(const ObjectSerializerBasePtr& serializer, const ::Ice::Current& c)
346 {
347 AbstractObjectSerializerPtr obj = AbstractObjectSerializerPtr::dynamicCast(serializer);
348
349 observerName = obj->getString("observerName");
350 channelName = obj->getString("channelName");
351
352 if (!c.adapter)
353 {
354 throw LocalException(
355 "The adapter in the Ice::current object must be set to load a ChannelRef from XML");
356 }
357
358 communicator = c.adapter->getCommunicator();
359 }
360} // namespace armarx
constexpr T c
VariantTypeId getType(const Ice::Current &c=Ice::emptyCurrent) const override
void ice_postUnmarshal() override
std::string output(const Ice::Current &c=Ice::emptyCurrent) const override
VariantDataClassPtr clone(const Ice::Current &c=Ice::emptyCurrent) const override
bool hasDatafield(const std::string &datafieldName) const
DataFieldIdentifierPtr getDataFieldIdentifier(const std::string &datafieldName)
bool validate(const Ice::Current &c=Ice::emptyCurrent) override
void deserialize(const ObjectSerializerBasePtr &serializer, const ::Ice::Current &=Ice::emptyCurrent) override
const ObserverInterfacePrx & getObserverProxy()
const std::string & getObserverName() const
const Ice::StringSeq & getDataFieldNames() const
void serialize(const ObjectSerializerBasePtr &serializer, const ::Ice::Current &=Ice::emptyCurrent) const override
TimedVariantPtr getDataField(const std::string &datafieldName)
const std::string & getChannelName() const
DataFieldIdentifier provide the basis to identify data field within a distributed ArmarX scenario.
std::string getName() const
Retrieve name of object.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
Baseclass for all ArmarX Observers.
Definition Observer.h:87
ChannelRegistryEntry getChannel(const std::string &channelName) const
Retrieve information on all sensory data channels available from the observer.
This exception is thrown when accessing an uninitialized proxy.
#define ARMARX_FATAL_S
The logging level for unexpected behaviour, that will lead to a seriously malfunctioning program and ...
Definition Logging.h:219
#define ARMARX_INFO_S
Definition Logging.h:202
#define ARMARX_VERBOSE_S
Definition Logging.h:207
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:213
const VariantTypeId ChannelRef
Definition ChannelRef.h:169
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< TimedVariant > TimedVariantPtr
IceInternal::Handle< ChannelRef > ChannelRefPtr
Definition ChannelRef.h:40
IceInternal::Handle< AbstractObjectSerializer > AbstractObjectSerializerPtr
Ice::Int VariantTypeId
Definition Variant.h:43
const LogSender::manipulator flush
Definition LogSender.h:251
IceInternal::Handle< DataFieldIdentifier > DataFieldIdentifierPtr
Typedef of DataFieldIdentifierPtr as IceInternal::Handle<DataFieldIdentifier> for convenience.