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 
27 
33 
34 #include <Ice/ObjectAdapter.h>
35 #include <Ice/ValueFactory.h>
36 
37 #include <algorithm>
38 
39 template class ::IceInternal::Handle<::armarx::ChannelRef>;
40 
41 namespace armarx
42 {
43  using namespace armarx::exceptions::local;
44 
45  // *******************************************************
46  // Construction / destruction
47  // *******************************************************
48  ChannelRef::ChannelRef(Observer* observer, std::string channelName) :
49  validationTimeout(4000),
50  waitIntervallMs(10)
51  {
52  if (!observer)
53  {
54  ARMARX_FATAL_S << "observer must not be NULL";
55  throw exceptions::local::eNullPointerException("observer must not be NULL");
56  }
57 
58  this->observerProxy = ObserverInterfacePrx::uncheckedCast(observer->getProxy());
59  this->communicator = observerProxy->ice_getCommunicator();
60  this->observerName = observer->getName();
61  this->channelName = channelName;
62 
63  // initialize data fields and initialized state
64  initializeDataFields(observer);
65  }
66 
67  ChannelRef::ChannelRef(ObserverInterfacePrx observerPrx, std::string channelName) :
68  validationTimeout(4000),
69  waitIntervallMs(10)
70  {
71  if (!observerPrx)
72  {
73  throw exceptions::local::eNullPointerException("observerPrx must not be NULL");
74  }
75 
76  this->observerProxy = observerPrx;
77  this->observerName = observerPrx->ice_getIdentity().name;
78  this->channelName = channelName;
79  this->communicator = observerProxy->ice_getCommunicator();
80 
81  // initialize data fields and initialized state
82  initializeDataFields();
83  }
84 
85  // *******************************************************
86  // Datafield access
87  // *******************************************************
89  {
90  if (!assureProxy())
91  {
92  throw ProxyNotInitializedException(observerName);
93  }
94 
95  if (std::find(datafieldNames.begin(), datafieldNames.end(), datafieldName) == datafieldNames.end())
96  {
98 
99  if (std::find(datafieldNames.begin(), datafieldNames.end(), datafieldName) == datafieldNames.end())
100  {
101  throw exceptions::user::InvalidDataFieldException(channelName, datafieldName);
102  }
103  }
104 
105  return new DataFieldIdentifier(observerName, channelName, datafieldName);
106  }
107 
108  TimedVariantPtr ChannelRef::getDataField(const std::string& datafieldName)
109  {
110  if (!assureProxy())
111  {
112  throw ProxyNotInitializedException(observerName);
113  }
114  TimedVariantPtr result;
115  try
116  {
117  result = TimedVariantPtr::dynamicCast(observerProxy->getDatafieldByName(getChannelName(), datafieldName));
118  }
119  catch (...)
120  {
121  if (communicator)
122  {
123  observerProxy = ObserverInterfacePrx::uncheckedCast(communicator->stringToProxy(observerName));
124  result = TimedVariantPtr::dynamicCast(observerProxy->getDatafieldByName(getChannelName(), datafieldName));
125  }
126  else
127  {
128  throw;
129  }
130  }
131  return result;
132  }
133 
134  // *******************************************************
135  // Properties
136  // *******************************************************
137  const ObserverInterfacePrx& ChannelRef::getObserverProxy()
138  {
139  if (!assureProxy())
140  {
141  throw ProxyNotInitializedException(observerName);
142  }
143 
144  return observerProxy;
145  }
146 
147  const std::string& ChannelRef::getObserverName() const
148  {
149  return observerName;
150  }
151 
152  const std::string& ChannelRef::getChannelName() const
153  {
154  return channelName;
155  }
156 
157  const Ice::StringSeq& ChannelRef::getDataFieldNames() const
158  {
159  return datafieldNames;
160  }
161 
162  bool ChannelRef::hasDatafield(const std::string& datafieldName) const
163  {
164  for (unsigned int i = 0; i < datafieldNames.size(); ++i)
165  {
166  if (datafieldName == datafieldNames.at(i))
167  {
168  return true;
169  }
170  }
171 
172  return false;
173  }
174 
176  {
177  // once all datafields are initialized -> channel initialized
178  if (initialized)
179  {
180  return true;
181  }
182 
183  // if proxy not there -> not initialized
184  if (!assureProxy())
185  {
186  return false;
187  }
188 
189  ARMARX_INFO_S << "ChannelRef:" << getObserverName() << "." << getChannelName() << ": Initialized as retrieved from proxy : " << initialized;
190 
191  return initialized;
192  }
193 
195  {
196  initializeDataFields();
197  }
198 
199 
200  // *******************************************************
201  // Inherited from VariantDataClass
202  // *******************************************************
203  VariantDataClassPtr ChannelRef::clone(const Ice::Current& c) const
204  {
205  ChannelRefPtr cln = new ChannelRef(*this);
206 
207  cln->initialized = this->initialized;
208 
209  cln->observerName = this->observerName;
210  cln->channelName = this->channelName;
211  cln->datafieldNames = this->datafieldNames;
212 
213  cln->observerProxy = this->observerProxy;
214 
215  return cln;
216  }
217 
218  std::string ChannelRef::output(const Ice::Current& c) const
219  {
220  std::stringstream s;
221  s << "Reference to channel " << channelName << " on observer " << observerName;
222 
223  return s.str();
224  }
225 
226  VariantTypeId ChannelRef::getType(const Ice::Current& c) const
227  {
229  }
230 
231  bool ChannelRef::validate(const Ice::Current& c)
232  {
233  int validateWaitIntervallMs = waitIntervallMs;
234  IceUtil::Time waitStartTime = IceUtil::Time::now();
235 
236  IceUtil::Time timeout = IceUtil::Time::milliSeconds(validationTimeout);
237 
238  IceUtil::Time lastOutput = IceUtil::Time::milliSeconds(0);
239 
240  while (IceUtil::Time(waitStartTime + timeout - IceUtil::Time::now()).toMilliSeconds() > 0)
241  {
242  if (getInitialized())
243  {
244  return true;
245  }
246 
247  if (IceUtil::Time(IceUtil::Time::now() - lastOutput).toSeconds() >= 1) // output only every second
248  {
249  ARMARX_VERBOSE_S << "Waiting for ChannelRef: " << getObserverName() << "." << getChannelName() << flush;
250  lastOutput = IceUtil::Time::now();
251  }
252 
253  usleep(validateWaitIntervallMs * 1000);
254 
255  if (validateWaitIntervallMs < validationTimeout * 0.5f) // increase wait time for lower cpu usage
256  {
257  validateWaitIntervallMs *= 2;
258  }
259  }
260 
261  ARMARX_WARNING_S << "Could not validate ChannelRef: " << getObserverName() << "." << getChannelName() << flush;
262  return false;
263 
264  }
265 
266  // private
267  bool ChannelRef::assureProxy()
268  {
269  if (!observerProxy)
270  {
271  try
272  {
273  observerProxy = ObserverInterfacePrx::checkedCast(communicator->stringToProxy(observerName));
274  }
275  catch (...)
276  {
277  }
278  }
279 
280  if (observerProxy && !initialized)
281  {
282  initializeDataFields();
283  }
284 
285  return (observerProxy != 0);
286  }
287 
288  void ChannelRef::initializeDataFields(Observer* obs)
289  {
290  ChannelRegistryEntry channel = obs ?
291  obs->getChannel(getChannelName()) :
292  observerProxy->getChannel(getChannelName());
293 
294  DataFieldRegistry::const_iterator iterData = channel.dataFields.begin();
295  datafieldNames.clear();
296 
297  while (iterData != channel.dataFields.end())
298  {
299  datafieldNames.push_back(iterData->second.identifier->datafieldName);
300  iterData++;
301  }
302 
303  initialized = channel.initialized;
304  }
305 
307  {
308  if (observerProxy)
309  {
310  communicator = observerProxy->ice_getCommunicator();
311  }
312  }
313 
314  void ChannelRef::serialize(const ObjectSerializerBasePtr& serializer, const ::Ice::Current&) const
315  {
316  AbstractObjectSerializerPtr obj = AbstractObjectSerializerPtr::dynamicCast(serializer);
317 
318  obj->setString("observerName", observerName);
319  obj->setString("channelName", channelName);
320  }
321 
322  void ChannelRef::deserialize(const ObjectSerializerBasePtr& serializer, const ::Ice::Current& c)
323  {
324  AbstractObjectSerializerPtr obj = AbstractObjectSerializerPtr::dynamicCast(serializer);
325 
326  observerName = obj->getString("observerName");
327  channelName = obj->getString("channelName");
328 
329  if (!c.adapter)
330  {
331  throw LocalException("The adapter in the Ice::current object must be set to load a ChannelRef from XML");
332  }
333 
334  communicator = c.adapter->getCommunicator();
335  }
336 }
armarx::ChannelRef::getDataFieldIdentifier
DataFieldIdentifierPtr getDataFieldIdentifier(const std::string &datafieldName)
Definition: ChannelRef.cpp:88
armarx::Observer
Baseclass for all ArmarX Observers.
Definition: Observer.h:80
armarx::ChannelRef::hasDatafield
bool hasDatafield(const std::string &datafieldName) const
Definition: ChannelRef.cpp:162
armarx::ChannelRef::getDataFieldNames
const Ice::StringSeq & getDataFieldNames() const
Definition: ChannelRef.cpp:157
AbstractObjectSerializer.h
armarx::ChannelRef::ChannelRef
ChannelRef()
Definition: ChannelRef.h:57
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
armarx::ChannelRef::getType
VariantTypeId getType(const Ice::Current &c=Ice::emptyCurrent) const override
Definition: ChannelRef.cpp:226
armarx::exceptions::local::eNullPointerException
Definition: Exception.h:42
Observer.h
IceInternal::Handle< DataFieldIdentifier >
armarx::ChannelRef::getChannelName
const std::string & getChannelName() const
Definition: ChannelRef.cpp:152
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:203
armarx::VariantType::ChannelRef
const VariantTypeId ChannelRef
Definition: ChannelRef.h:162
armarx::ChannelRef::validate
bool validate(const Ice::Current &c=Ice::emptyCurrent) override
Definition: ChannelRef.cpp:231
InvalidDatafieldException.h
armarx::ChannelRef::getObserverName
const std::string & getObserverName() const
Definition: ChannelRef.cpp:147
ProxyNotInitializedException.h
armarx::VariantTypeId
Ice::Int VariantTypeId
Definition: Variant.h:44
armarx::ChannelRef::getInitialized
bool getInitialized()
Definition: ChannelRef.cpp:175
armarx::ChannelRef::output
std::string output(const Ice::Current &c=Ice::emptyCurrent) const override
Definition: ChannelRef.cpp:218
armarx::ChannelRef::getObserverProxy
const ObserverInterfacePrx & getObserverProxy()
Definition: ChannelRef.cpp:137
InvalidDataFieldException.h
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::ChannelRef::refetchChannel
void refetchChannel()
Definition: ChannelRef.cpp:194
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:212
armarx::ChannelRef::getDataField
TimedVariantPtr getDataField(const std::string &datafieldName)
Definition: ChannelRef.cpp:108
ARMARX_VERBOSE_S
#define ARMARX_VERBOSE_S
Definition: Logging.h:200
armarx::ManagedIceObject::getName
std::string getName() const
Retrieve name of object.
Definition: ManagedIceObject.cpp:107
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:195
armarx::ChannelRef::ice_postUnmarshal
void ice_postUnmarshal() override
Definition: ChannelRef.cpp:306
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:393
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:28
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:322
armarx::ChannelRef::serialize
void serialize(const ObjectSerializerBasePtr &serializer, const ::Ice::Current &=Ice::emptyCurrent) const override
Definition: ChannelRef.cpp:314