libqi-api  2.8.7.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
autoservice.hxx
Go to the documentation of this file.
1 #include <stdexcept>
2 
3 namespace qi
4 {
5  template <typename T>
6  AutoService<T>::AutoService(const std::string& name, SessionPtr session)
7  : qi::Trackable<AutoService<T> > (this)
8  , _session(session)
9  , _name(name)
10  {
11  Future<qi::AnyObject> fut = session->service(name);
12  fut.connect(&AutoService::onServiceModified, this, fut);
13 
14  _session->serviceRegistered.connect(&AutoService::onServiceAdded, this, _2);
15  _session->serviceUnregistered.connect(&AutoService::onServiceRemoved, this, _2);
16  }
17 
18  template <typename T>
20  {
21  this->destroy();
22  }
23 
24  template <typename T>
25  void AutoService<T>::onServiceRemoved(const std::string& name)
26  {
27  if (name == _name)
28  {
29  {
30  boost::mutex::scoped_lock scoped_lock(_mutex);
31  _object = qi::Object<T>();
32  _promise = qi::Promise<void>();
33  }
34  serviceRemoved();
35  }
36  }
37 
38  template <typename T>
39  void AutoService<T>::onServiceModified(const qi::Future<qi::AnyObject>& future)
40  {
41  if (!future.hasError())
42  {
43  {
44  boost::mutex::scoped_lock scoped_lock(_mutex);
45  _object = qi::Object<T>(future.value());
46  if (!_promise.future().isFinished())
47  _promise.setValue(0);
48  }
49  serviceAdded();
50  }
51  else
52  { // A Service has been added, but it has been impossible to get it; so we delete it.
53  {
54  boost::mutex::scoped_lock scoped_lock(_mutex);
55  _object = qi::Object<T>();
56  _promise = qi::Promise<void>();
57  }
58  serviceRemoved();
59  }
60  }
61 
62  template <typename T>
63  void AutoService<T>::onServiceAdded(const std::string& name)
64  {
65  if (name == _name)
66  {
67  boost::mutex::scoped_lock scoped_lock(_mutex);
68  qi::Future<qi::AnyObject> future = _session->service(name);
69  future.connect(&AutoService::onServiceModified, this, future);
70  }
71  }
72 
79  template <typename T>
81  {
82  boost::mutex::scoped_lock scoped_lock(_mutex);
84  if (keeper._obj)
85  return keeper;
86  else
87  throw std::runtime_error("Service " + _name + " unavailable");
88  }
89 
90  template <typename T>
92  {
93  boost::mutex::scoped_lock scoped_lock(_mutex);
95  if (keeper._obj)
96  return keeper;
97  else
98  throw std::runtime_error("Service " + _name + " unavailable");
99  }
100 
101  template <typename T>
102  const T* AutoService<T>::get() const
103  {
104  boost::mutex::scoped_lock scoped_lock(_mutex);
105  if (_object)
106  return &(*_object);
107  else
108  throw std::runtime_error("Service " + _name + " unavailable");
109  }
110 
111  template <typename T>
113  {
114  boost::mutex::scoped_lock scoped_lock(_mutex);
115  if (_object)
116  return &(*_object);
117  else
118  throw std::runtime_error("Service " + _name + " unavailable");
119  }
120 
121  template <typename T>
123  {
124  return *get();
125  }
126 
127 
128  template <typename T>
130  {
131  return _promise.future();
132  }
133 
134  template <typename T>
136  {
137  boost::mutex::scoped_lock scoped_lock(_mutex);
138  if (_object)
139  return _object.asGenericObject();
140  else
141  throw std::runtime_error("Service " + _name + " unavailable");
142  }
143 
149  template <>
151  {
152  private:
153  virtual void forbiden() = 0;
154  };
155 
156 
157  namespace detail
158  {
159  template <typename T>
160  class Keeper
161  {
162  public:
164  : _obj(obj)
165  {
166  }
167 
169  {
170  return &(*_obj);
171  }
172 
174  };
175  }
176 }
qi::GenericObject * asGenericObject() const
boost::shared_ptr< Session > SessionPtr
Definition: session.hpp:34
void destroy()
Stop and flush the logging system.
void connect(const AF &fun, FutureCallbackType type=FutureCallbackType_Auto)
Definition: future_fwd.hpp:545
qi::detail::Keeper< T > operator->()
Definition: autoservice.hxx:80
qi::FutureSync< void > waitForReady()
qi::Object< T > _obj
AutoService(const std::string &name, qi::SessionPtr session)
Definition: autoservice.hxx:6
Keeper(qi::Object< T > &obj)
Object tracking by blocking destruction while shared pointers are present.
Definition: trackable.hpp:45
const ValueType & value(int msecs=FutureTimeout_Infinite) const
Return the value associated to a Future.
Definition: future_fwd.hpp:249
bool hasError(int msecs=FutureTimeout_Infinite) const
Definition: future_fwd.hpp:348