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 
38 template class ::IceInternal::Handle<::armarx::ChannelRef>;
39 
40 namespace 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
armarx::ChannelRef::getDataFieldIdentifier
DataFieldIdentifierPtr getDataFieldIdentifier(const std::string &datafieldName)
Definition: ChannelRef.cpp:86
armarx::Observer
Baseclass for all ArmarX Observers.
Definition: Observer.h:84
armarx::ChannelRef::hasDatafield
bool hasDatafield(const std::string &datafieldName) const
Definition: ChannelRef.cpp:171
armarx::ChannelRef::getDataFieldNames
const Ice::StringSeq & getDataFieldNames() const
Definition: ChannelRef.cpp:165
AbstractObjectSerializer.h
armarx::ChannelRef::ChannelRef
ChannelRef()
Definition: ChannelRef.h:56
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
armarx::ChannelRef::getType
VariantTypeId getType(const Ice::Current &c=Ice::emptyCurrent) const override
Definition: ChannelRef.cpp:240
armarx::exceptions::local::eNullPointerException
Definition: Exception.h:49
Observer.h
IceInternal::Handle< DataFieldIdentifier >
armarx::ChannelRef::getChannelName
const std::string & getChannelName() const
Definition: ChannelRef.cpp:159
armarx::exceptions::local
Definition: DynamicLibraryException.h:31
armarx::flush
const LogSender::manipulator flush
Definition: LogSender.h:251
armarx::ChannelRef::clone
VariantDataClassPtr clone(const Ice::Current &c=Ice::emptyCurrent) const override
Definition: ChannelRef.cpp:215
armarx::VariantType::ChannelRef
const VariantTypeId ChannelRef
Definition: ChannelRef.h:169
armarx::ChannelRef::validate
bool validate(const Ice::Current &c=Ice::emptyCurrent) override
Definition: ChannelRef.cpp:246
InvalidDatafieldException.h
armarx::ChannelRef::getObserverName
const std::string & getObserverName() const
Definition: ChannelRef.cpp:153
ProxyNotInitializedException.h
armarx::VariantTypeId
Ice::Int VariantTypeId
Definition: Variant.h:43
armarx::ChannelRef::getInitialized
bool getInitialized()
Definition: ChannelRef.cpp:185
armarx::ChannelRef::output
std::string output(const Ice::Current &c=Ice::emptyCurrent) const override
Definition: ChannelRef.cpp:231
armarx::ChannelRef::getObserverProxy
const ObserverInterfacePrx & getObserverProxy()
Definition: ChannelRef.cpp:142
InvalidDataFieldException.h
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::ChannelRef::refetchChannel
void refetchChannel()
Definition: ChannelRef.cpp:206
armarx::exceptions::local::ProxyNotInitializedException
This exception is thrown when accessing an uninitialized proxy.
Definition: ProxyNotInitializedException.h:38
armarx::exceptions::user::InvalidDataFieldException
Definition: InvalidDatafieldException.h:30
ARMARX_FATAL_S
#define ARMARX_FATAL_S
Definition: Logging.h:219
armarx::ChannelRef::getDataField
TimedVariantPtr getDataField(const std::string &datafieldName)
Definition: ChannelRef.cpp:109
ARMARX_VERBOSE_S
#define ARMARX_VERBOSE_S
Definition: Logging.h:207
armarx::ManagedIceObject::getName
std::string getName() const
Retrieve name of object.
Definition: ManagedIceObject.cpp:108
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:202
armarx::ChannelRef::ice_postUnmarshal
void ice_postUnmarshal() override
Definition: ChannelRef.cpp:327
Exception.h
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::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::DataFieldIdentifier
DataFieldIdentifier provide the basis to identify data field within a distributed ArmarX scenario.
Definition: DataFieldIdentifier.h:48
ChannelRef.h
armarx::ChannelRef::deserialize
void deserialize(const ObjectSerializerBasePtr &serializer, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: ChannelRef.cpp:345
armarx::ChannelRef::serialize
void serialize(const ObjectSerializerBasePtr &serializer, const ::Ice::Current &=Ice::emptyCurrent) const override
Definition: ChannelRef.cpp:336