hpp-corbaserver  4.9.0
Corba server for Humanoid Path Planner applications
servant-base.hh
Go to the documentation of this file.
1 // Copyright (C) 2019 by Joseph Mirabel, LAAS-CNRS.
2 //
3 // This file is part of the hpp-corbaserver.
4 //
5 // This software is provided "as is" without warranty of any kind,
6 // either expressed or implied, including but not limited to the
7 // implied warranties of fitness for a particular purpose.
8 //
9 // See the COPYING file for more information.
10 
11 #ifndef HPP_CORBASERVER_SERVANT_BASE_HH
12 # define HPP_CORBASERVER_SERVANT_BASE_HH
13 
14 # include <boost/type.hpp>
15 
16 # include <hpp/common-idl.hh>
17 # include <hpp/corbaserver/server.hh>
18 
19 namespace hpp
20 {
21  namespace corbaServer
22  {
53 
54 #define SERVANT_BASE_TYPEDEFS(idlObj, hppObj) \
55  protected: \
56  using AbstractServantBase<hppObj>::server_; \
57  public: \
58  typedef _Base Base; \
59  typedef _Storage Storage; \
60  typedef idlObj Object; \
61  typedef idlObj ## _ptr Object_ptr; \
62  typedef idlObj ## _var Object_var; \
63  typedef ServantBase<hppObj, _Storage> _ServantBase; \
64  using _ServantBase::get; \
65  using _ServantBase::getT; \
66  using _ServantBase::getS
67 
70  {
71  public:
72  virtual Server::ServantKey getServantKey () const = 0;
73  };
74 
79  template <typename T> class AbstractServantBase : AbstractServantKey
80  {
81  public:
82  virtual ~AbstractServantBase () {}
83 
84  typedef boost::shared_ptr<T> TShPtr_t;
85  typedef boost::weak_ptr <T> TWkPtr_t;
86 
87  virtual TShPtr_t get() const = 0;
88 
90  {
91  return get().get();
92  }
93 
94  protected:
95  AbstractServantBase (Server* server) : server_ (server) {}
96 
98  };
99 
100  template <typename T, typename _Storage> class ServantBase : public AbstractServantBase<T>
101  {
102  public:
103  typedef _Storage Storage;
104  using typename AbstractServantBase<T>::TShPtr_t;
105  using typename AbstractServantBase<T>::TWkPtr_t;
106  typedef boost:: weak_ptr<typename Storage::element_type> StorageElementWkPtr_t;
107  typedef boost::shared_ptr<typename Storage::element_type> StorageElementShPtr_t;
108 
109  virtual ~ServantBase () {}
110 
111  virtual TShPtr_t get () const
112  {
113  TWkPtr_t wk ((StorageElementWkPtr_t) s);
114  if (wk.expired()) {
115  // Object expired. Remove the servant and throw.
116  objectExpired();
117  }
118  return wk.lock();
119  }
120 
121  StorageElementShPtr_t getT () const
122  {
123  StorageElementWkPtr_t wk ((StorageElementWkPtr_t) s);
124  if (wk.expired()) {
125  // Object expired. Remove the servant and throw.
126  objectExpired();
127  }
128  return wk.lock();
129  }
130 
131  const Storage& getS () const
132  {
133  return s;
134  }
135 
137  void persistantStorage (bool persistant)
138  {
139  if (persistant) p_ = get();
140  else p_.reset();
141  }
142 
144  bool persistantStorage () const
145  {
146  return p_;
147  }
148 
149  void deleteThis ()
150  {
151  persistantStorage(false);
152 
153  // Object expired. Try to remove the server.
154  PortableServer::Servant servant = dynamic_cast<PortableServer::Servant>(this);
155  if (servant == NULL)
156  throw Error ("The object was deleted. I could not delete the servant.");
157  this->server_->removeServant (servant);
158  // Deactivate object
159  PortableServer::ObjectId_var objectId
160  = this->server_->poa()->servant_to_id(servant);
161  this->server_->poa()->deactivate_object(objectId.in());
162  }
163 
164  protected:
165  ServantBase (Server* server, const Storage& _s)
166  : AbstractServantBase<T> (server), s(_s)
167  {
168  persistantStorage (true);
169  }
170 
171  Storage s;
172 
173  private:
174  void objectExpired () const
175  {
176  // Object expired. Try to remove the server.
177  PortableServer::Servant servant = dynamic_cast<PortableServer::Servant>(const_cast<ServantBase*>(this));
178  if (servant == NULL)
179  throw Error ("The object was deleted. I could not delete the servant.");
180  this->server_->removeServant (servant);
181  // Deactivate object
182  PortableServer::ObjectId_var objectId
183  = this->server_->poa()->servant_to_id(servant);
184  this->server_->poa()->deactivate_object(objectId.in());
185  throw Error ("The object has been deleted. I delete the servant.");
186  }
187 
188  TShPtr_t p_;
189  };
190 
206  template <typename T, typename Base> class AbstractStorage
207  {
208  public:
209  typedef boost::weak_ptr<T> ptr_t;
210 
211  ptr_t element;
212 
213  AbstractStorage (const ptr_t& _element) : element(_element) {}
214  operator boost::shared_ptr<T > () const { return element.lock(); }
215  operator boost::weak_ptr <T > () const { return element; }
216  long use_count() const { return element.use_count(); }
217 
218  // Mimic boost::shared_ptr<D> interface:
219  typedef T element_type;
220  operator bool () const { return use_count()>0; }
221  };
222 
223  typedef PortableServer::Servant_var<PortableServer::ServantBase> ServantBase_var;
224 
225  template <typename S, typename P> PortableServer::Servant_var<S> reference_to_servant (Server* server, const P& p)
226  {
227  PortableServer::Servant s = server->poa()->reference_to_servant(p);
228  if (s == NULL) throw Error ("The servant is not located here");
229  return dynamic_cast<S*> (s);
230  }
231 
232  template <typename T, typename P> AbstractServantBase<T>* reference_to_servant_base (Server* server, const P& p)
233  {
234  ServantBase_var s = server->poa()->reference_to_servant(p);
235  if (s.in() == NULL) throw Error ("The servant is not located here");
236  return dynamic_cast<AbstractServantBase<T>*> (s.in());
237  }
238 
247  template <typename P, typename S> P makeServant (Server* server, S* s)
248  {
249  Server::ServantKey servantKey = s->getServantKey();
250  S* servant = dynamic_cast<S*> (server->getServant (servantKey));
251  if (servant != NULL) {
252  delete s;
253  return servant->_this();
254  }
255 
256  PortableServer::Servant_var<S> d (s);
257  // ObjectId_var object is here to delete the servantId.
258  PortableServer::ObjectId_var servantId = server->poa()->activate_object(d);
259  (void) servantId;
260 
261  server->addServantKeyAndServant (servantKey, d.in());
262  return d->_this();
263  }
264 
266  namespace details
267  {
269  template <typename U, typename V, template<typename> class StorageTpl>
270  struct storage_cast_impl {
271  static StorageTpl<U> run (const StorageTpl<V>& o) {
272  return o.template cast<U>();
273  }
274  };
275 
277  template <typename U, typename V>
278  struct storage_cast_impl<U, V, boost::shared_ptr> {
279  static boost::shared_ptr<U> run (const boost::shared_ptr<V>& o) {
280  return boost::dynamic_pointer_cast<U>(o);
281  }
282  };
283 
285  template <typename U, typename V>
286  struct storage_cast_impl<U, V, boost::weak_ptr> {
287  static boost::weak_ptr<U> run (const boost::weak_ptr<V>& o) {
288  return boost::dynamic_pointer_cast<U>(o.lock());
289  }
290  };
291  }
293 
295  template <typename U, typename V, template<typename> class StorageTpl>
296  static StorageTpl<U> storage_cast(const StorageTpl<V>& o)
297  {
298  return details::storage_cast_impl<U, V, StorageTpl>::run (o);
299  }
300 
304  template <typename ServantBaseType>
306  {
307  public:
308  typedef typename ServantBaseType::Storage Storage;
309  typedef typename ServantBaseType::Object_var Object_var;
310 
311  ServantFactoryBase (const size_type& depth) : depth_ (depth) {}
312 
313  virtual Object_var servant (Server* server, const Storage& obj) = 0;
314 
318  size_type depth () const
319  {
320  return depth_;
321  }
322  private:
323  size_type depth_;
324  };
325 
326  template <typename ServantBaseType, typename ServantType>
327  struct ServantFactory : ServantFactoryBase<ServantBaseType>
328  {
329  typedef typename ServantBaseType::Object_var Object_var;
330  typedef typename ServantBaseType::Storage StorageBase;
331 
333  ServantFactoryBase<ServantBaseType> (depth) {}
334 
335  virtual Object_var servant (Server* s, const StorageBase& o)
336  {
337  typedef typename ServantType::Storage Storage;
338  Storage u = storage_cast<typename Storage::element_type>(o);
339  Object_var ret;
340  if (u.use_count()>0) ret = makeServant <Object_var> (s, new ServantType (s, u));
341  return ret;
342  }
343  };
344 
345  template <typename ServantBaseType>
346  std::vector< ServantFactoryBase<ServantBaseType>* >& objectDowncasts ();
347 
348  template <typename ServantBaseType>
350  {
351  typedef std::vector< ServantFactoryBase<ServantBaseType>* > vector_t;
352  typedef typename vector_t::iterator iterator;
353 
354  vector_t& vec = objectDowncasts<ServantBaseType>();
355  size_type d = object->depth();
356  for (iterator _obj = vec.begin(); _obj != vec.end(); ++_obj) {
357  if (d >= (*_obj)->depth()) {
358  vec.insert(_obj, object);
359  return;
360  }
361  }
362  vec.push_back(object);
363  }
364 
367  template <typename ServantBaseType, typename ReturnType>
368  typename ReturnType::Object_var makeServantDownCast (Server* server, const typename ServantBaseType::Storage& t)
369  {
370  typedef typename ServantBaseType::Object_var BaseObject_var;
371  typedef typename ReturnType::Object_var Object_var;
372  BaseObject_var servant;
373  assert (CORBA::Object_Helper::is_nil(servant.in()));
374 
375  typedef std::vector< ServantFactoryBase<ServantBaseType>* > vector_t;
376  typedef typename vector_t::iterator iterator;
377 
378  vector_t& vec = objectDowncasts<ServantBaseType>();
379  for (iterator _obj = vec.begin(); _obj != vec.end(); ++_obj) {
380  servant = (*_obj)->servant(server, t);
381  if (!CORBA::Object_Helper::is_nil(servant.in())) {
382  // Cast to child type.
383  return Object_var (ReturnType::Object::_narrow (servant._retn()));
384  }
385  }
386  return Object_var();
387  }
388 
389  template <typename ServantBaseType>
390  typename ServantBaseType::Object_var makeServantDownCast (Server* server, const typename ServantBaseType::Storage& t)
391  {
392  //TODO
393  //return makeServantDownCast <ServantBaseType, ServantBaseType> (server, t);
394  typedef typename ServantBaseType::Object_var Object_var;
395  Object_var servant;
396  assert (CORBA::Object_Helper::is_nil(servant.in()));
397 
398  typedef std::vector< ServantFactoryBase<ServantBaseType>* > vector_t;
399  typedef typename vector_t::iterator iterator;
400 
401  vector_t& vec = objectDowncasts<ServantBaseType>();
402  for (iterator _obj = vec.begin(); _obj != vec.end(); ++_obj) {
403  servant = (*_obj)->servant(server, t);
404  if (!CORBA::Object_Helper::is_nil(servant.in())) break;
405  }
406 
407  return servant;
408  }
409 
410  template <typename OutType, typename InnerBaseType, typename InnerType = InnerBaseType>
412  {
414 
415  vectorToSeqServant (Server* _s) : s (_s) {}
416 
417  template <typename InContainer>
418  inline OutType* operator() (const InContainer& input)
419  {
420  std::size_t len = std::distance (input.begin(), input.end());
421  OutType* seq = new OutType ();
422  seq->length ((CORBA::ULong) len);
423 
424  std::size_t i = 0;
425  typename InContainer::const_iterator it = input.begin();
426  while (it != input.end()) {
427  (*seq)[i] = makeServantDownCast<InnerBaseType, InnerType> (s, *it)._retn();
428  ++it;
429  ++i;
430  }
431  return seq;
432  }
433  };
434 
436  } // end of namespace corbaServer.
437 } // end of namespace hpp.
438 
447 #define HPP_CORBASERVER_ADD_DOWNCAST_OBJECT(ServantType, BaseServantType, depth) \
448  struct HPP_CORE_DLLAPI __InitializerClass_##ServantType { \
449  __InitializerClass_##ServantType () { \
450  ::hpp::corbaServer::addDowncastObjects<BaseServantType> \
451  ( new ::hpp::corbaServer::ServantFactory<BaseServantType, ServantType> (depth)); \
452  } \
453  }; \
454  HPP_CORBASERVER_DLLLOCAL __InitializerClass_##ServantType __instance_##ServantType;
455 
456 #endif // HPP_CORBASERVER_SERVANT_BASE_HH
Definition: servant-base.hh:100
PortableServer::Servant_var< PortableServer::ServantBase > ServantBase_var
Definition: servant-base.hh:223
boost::shared_ptr< T > TShPtr_t
Definition: servant-base.hh:84
std::vector< ServantFactoryBase< ServantBaseType > *> & objectDowncasts()
ServantFactory(const size_type &depth)
Definition: servant-base.hh:332
boost::shared_ptr< typename Storage::element_type > StorageElementShPtr_t
Definition: servant-base.hh:107
Definition: servant-base.hh:327
ServantBaseType::Object_var Object_var
Definition: servant-base.hh:309
Implement CORBA interface ``Obstacle&#39;&#39;.
AbstractServantBase(Server *server)
Definition: servant-base.hh:95
AbstractServantBase< T > * reference_to_servant_base(Server *server, const P &p)
Definition: servant-base.hh:232
unsigned long long size_t
Definition: paths.idl:18
boost::weak_ptr< T > ptr_t
Definition: servant-base.hh:209
T element_type
Definition: servant-base.hh:219
ptr_t element
Definition: servant-base.hh:211
size_type depth() const
Definition: servant-base.hh:318
Abstract class used to avoid duplication of the servants.
Definition: servant-base.hh:69
PortableServer::Servant_var< S > reference_to_servant(Server *server, const P &p)
Definition: servant-base.hh:225
void addServantKeyAndServant(ServantKey servantKey, PortableServer::Servant servant)
FCL_REAL depth() const
boost::weak_ptr< typename Storage::element_type > StorageElementWkPtr_t
Definition: servant-base.hh:106
Server * server_
Definition: servant-base.hh:97
Corba exception travelling through the Corba channel.
Definition: common.idl:24
Definition: servant-base.hh:206
bool persistantStorage() const
See persistantStorage(bool)
Definition: servant-base.hh:144
Definition: servant-base.hh:305
void addDowncastObjects(ServantFactoryBase< ServantBaseType > *const object)
Definition: servant-base.hh:349
virtual Server::ServantKey getServantKey() const =0
pinocchio::vector_t vector_t
Definition: fwd.hh:83
const Storage & getS() const
Definition: servant-base.hh:131
ReturnType::Object_var makeServantDownCast(Server *server, const typename ServantBaseType::Storage &t)
Definition: servant-base.hh:368
assert(d.lhs()._blocks()==d.rhs()._blocks())
PortableServer::POA_var poa()
Definition: server.hh:88
ServantBase(Server *server, const Storage &_s)
Definition: servant-base.hh:165
P makeServant(Server *server, S *s)
Definition: servant-base.hh:247
Storage s
Definition: servant-base.hh:171
AbstractStorage(const ptr_t &_element)
Definition: servant-base.hh:213
ServantBaseType::Object_var Object_var
Definition: servant-base.hh:329
virtual ~ServantBase()
Definition: servant-base.hh:109
vectorToSeqServant(Server *_s)
Definition: servant-base.hh:415
FCL_REAL d
Definition: servant-base.hh:411
virtual Object_var servant(Server *s, const StorageBase &o)
Definition: servant-base.hh:335
ServantBaseType::Storage StorageBase
Definition: servant-base.hh:330
Implementation of Hpp module Corba server.
Definition: server.hh:54
virtual Server::ServantKey getServantKey() const
Definition: servant-base.hh:89
PortableServer::Servant getServant(ServantKey servantKey) const
Definition: servant-base.hh:79
void persistantStorage(bool persistant)
Set to true if the servant should take ownership of this object.
Definition: servant-base.hh:137
Transform3f t
void * ServantKey
Definition: server.hh:146
boost::weak_ptr< T > TWkPtr_t
Definition: servant-base.hh:85
_Storage Storage
Definition: servant-base.hh:103
Server * s
Definition: servant-base.hh:413
StorageElementShPtr_t getT() const
Definition: servant-base.hh:121
void deleteThis()
Definition: servant-base.hh:149
ServantBaseType::Storage Storage
Definition: servant-base.hh:308
long use_count() const
Definition: servant-base.hh:216
Vec3f o
pinocchio::size_type size_type
Definition: fwd.hh:86
FCL_REAL distance(const KDOP< N > &other, Vec3f *P=NULL, Vec3f *Q=NULL) const
virtual ~AbstractServantBase()
Definition: servant-base.hh:82
ServantFactoryBase(const size_type &depth)
Definition: servant-base.hh:311