RSB  0.17.0
LocalServer.h
Go to the documentation of this file.
1 /* ============================================================
2  *
3  * This file is a part of RSB project
4  *
5  * Copyright (C) 2010 by Johannes Wienke <jwienke at techfak dot uni-bielefeld dot de>
6  * Copyright (C) 2011, 2012, 2013, 2014, 2015 Jan Moringen <jmoringe@techfak.uni-bielefeld.de>
7  *
8  * This file may be licensed under the terms of the
9  * GNU Lesser General Public License Version 3 (the ``LGPL''),
10  * or (at your option) any later version.
11  *
12  * Software distributed under the License is distributed
13  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
14  * express or implied. See the LGPL for the specific language
15  * governing rights and limitations.
16  *
17  * You should have received a copy of the LGPL along with this
18  * program. If not, go to http://www.gnu.org/licenses/lgpl.html
19  * or write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  * The development of this software was supported by:
23  * CoR-Lab, Research Institute for Cognition and Robotics
24  * Bielefeld University
25  *
26  * ============================================================ */
27 
28 #pragma once
29 
30 #include <string>
31 #include <map>
32 
33 #include <boost/shared_ptr.hpp>
34 #include <boost/enable_shared_from_this.hpp>
35 
36 #include <rsc/runtime/TypeStringTools.h>
37 #include <rsc/logging/Logger.h>
38 
39 #include "../Handler.h"
40 
41 #include "Server.h"
42 
43 #include "rsb/rsbexports.h"
44 
45 namespace rsb {
46 namespace patterns {
47 
54 class RSB_EXPORT LocalServer: public Participant,
55  public boost::enable_shared_from_this<LocalServer> {
56 public:
57 
63  class RSB_EXPORT IntlCallback {
64  public:
65  virtual ~IntlCallback();
66 
67  virtual EventPtr intlCall(const std::string& methodName,
68  EventPtr request) = 0;
69  };
70 
71  typedef boost::shared_ptr<IntlCallback> CallbackPtr;
72 
78  class RSB_EXPORT EventCallback : public IntlCallback {
79  public:
80  virtual EventPtr call(const std::string& methodName, EventPtr request) = 0;
81  private:
82  EventPtr intlCall(const std::string& methodName, EventPtr request);
83  };
84 
90  class RSB_EXPORT CallbackBase : public IntlCallback {
91  public:
92  virtual const std::string& getRequestType() const;
93  virtual const std::string& getReplyType() const;
94  protected:
95  CallbackBase(const std::string& requestType,
96  const std::string& replyType);
97 
98  std::string requestType;
99  std::string replyType;
100  };
101 
109  template<class RequestType>
110  class RSB_EXPORT AnyReplyTypeCallback : public CallbackBase {
111  public:
112  // typeid is due to msvc strangeness
113  AnyReplyTypeCallback(const std::string& requestType
114  = rsc::runtime::typeName(typeid(RequestType))) :
115  CallbackBase(requestType, "") {
116  }
117 
128  virtual AnnotatedData call(const std::string& methodName,
129  boost::shared_ptr<RequestType> input) = 0;
130  private:
131  EventPtr intlCall(const std::string& methodName, EventPtr request) {
132  boost::shared_ptr<RequestType> argument
133  = boost::static_pointer_cast<RequestType>(request->getData());
134  AnnotatedData result = call(methodName, argument);
135  EventPtr reply(new Event());
136  reply->setType(result.first);
137  reply->setData(result.second);
138  return reply;
139  }
140 
141  };
142 
151  template<class RequestType, class ReplyType>
152  class Callback: public CallbackBase {
153  public:
154  // typeid is due to msvc strangeness
155  Callback(const std::string& requestType
156  = rsc::runtime::typeName(typeid(RequestType)),
157  const std::string& replyType
158  = rsc::runtime::typeName(typeid(ReplyType))) :
159  CallbackBase(requestType, replyType) {
160  }
161 
172  virtual boost::shared_ptr<ReplyType> call(const std::string& methodName,
173  boost::shared_ptr<RequestType> input) = 0;
174  private:
175  EventPtr intlCall(const std::string& methodName, EventPtr request) {
176  boost::shared_ptr<RequestType> argument
177  = boost::static_pointer_cast<RequestType>(request->getData());
178  boost::shared_ptr<ReplyType> result = call(methodName, argument);
179  EventPtr reply(new Event());
180  reply->setType(getReplyType());
181  reply->setData(result);
182  return reply;
183  }
184  };
185 
186  template<class RequestType>
187  class Callback<RequestType, void>: public CallbackBase {
188  public:
189  // typeid is due to msvc strangeness
190  Callback(const std::string& requestType
191  = rsc::runtime::typeName(typeid(RequestType)),
192  const std::string& replyType
193  = rsc::runtime::typeName(typeid(void))) :
194  CallbackBase(requestType, replyType) {
195  }
196 
206  virtual void call(const std::string& methodName,
207  boost::shared_ptr<RequestType> input) = 0;
208  private:
209  EventPtr intlCall(const std::string& methodName, EventPtr request) {
210  boost::shared_ptr<RequestType> argument
211  = boost::static_pointer_cast<RequestType>(request->getData());
212  call(methodName, argument);
213  EventPtr reply(new Event());
214  reply->setType(getReplyType());
215  reply->setData(boost::shared_ptr<void>());
216  return reply;
217  }
218 
219  };
220 
221  template<class ReplyType>
222  class Callback<void, ReplyType>: public CallbackBase {
223  public:
224  // typeid is due to msvc strangeness
225  Callback(const std::string& requestType
226  = rsc::runtime::typeName(typeid(void)),
227  const std::string& replyType
228  = rsc::runtime::typeName(typeid(ReplyType))) :
229  CallbackBase(requestType, replyType) {
230  }
231 
241  virtual boost::shared_ptr<ReplyType> call(
242  const std::string& methodName) = 0;
243  private:
244  EventPtr intlCall(const std::string& methodName, EventPtr /*request*/) {
245  EventPtr reply(new Event());
246  reply->setType(getReplyType());
247  reply->setData(call(methodName));
248  return reply;
249  }
250 
251  };
252 
260  template<class RequestType, class ReplyType>
262  public:
266  typedef boost::function<
267  typename boost::shared_ptr<ReplyType>(
268  typename boost::shared_ptr<RequestType>)> FunctionType;
269 
270  explicit FunctionCallback(FunctionType function,
271  const std::string& requestType = rsc::runtime::typeName(
272  typeid(RequestType)), const std::string& replyType =
273  rsc::runtime::typeName(typeid(ReplyType))) :
274  CallbackBase(requestType, replyType), function(function) {
275  }
276 
277  private:
278  EventPtr intlCall(const std::string& /*methodName*/, EventPtr request) {
279  boost::shared_ptr<RequestType> argument
280  = boost::static_pointer_cast<RequestType>(request->getData());
281  boost::shared_ptr<ReplyType> result = function(argument);
282  EventPtr reply(new Event());
283  reply->setType(getReplyType());
284  reply->setData(result);
285  return reply;
286  }
287 
288  FunctionType function;
289  };
290 
296  template<class RequestType>
297  class FunctionCallback<RequestType, void>: public CallbackBase {
298  public:
302  typedef boost::function<void(typename boost::shared_ptr<RequestType>)> FunctionType;
303 
304  explicit FunctionCallback(FunctionType function,
305  const std::string& requestType = rsc::runtime::typeName(
306  typeid(RequestType)), const std::string& replyType =
307  rsc::runtime::typeName(typeid(void))) :
308  CallbackBase(requestType, replyType), function(function) {
309  }
310 
311  private:
312  EventPtr intlCall(const std::string& /*methodName*/, EventPtr request) {
313  boost::shared_ptr<RequestType> argument =
314  boost::static_pointer_cast<RequestType>(request->getData());
315  function(argument);
316  EventPtr reply(new Event());
317  reply->setType(getReplyType());
318  reply->setData(boost::shared_ptr<void>());
319  return reply;
320  }
321 
322  FunctionType function;
323  };
324 
330  template<class ReplyType>
331  class FunctionCallback<void, ReplyType>: public CallbackBase {
332  public:
336  typedef boost::function<
337  typename boost::shared_ptr<ReplyType>(void)> FunctionType;
338 
339  explicit FunctionCallback(FunctionType function,
340  const std::string& requestType = rsc::runtime::typeName(
341  typeid(void)), const std::string& replyType =
342  rsc::runtime::typeName(typeid(ReplyType))) :
343  CallbackBase(requestType, replyType), function(function) {
344  }
345 
346  private:
347  EventPtr intlCall(const std::string& /*methodName*/,
348  EventPtr /*request*/) {
349  boost::shared_ptr<ReplyType> result = function();
350  EventPtr reply(new Event());
351  reply->setType(getReplyType());
352  reply->setData(result);
353  return reply;
354  }
355 
356  FunctionType function;
357  };
358 
366  class LocalMethod: public Method {
367  public:
368  LocalMethod(const Scope& scope,
369  const std::string& name,
370  const ParticipantConfig& listenerConfig,
371  const ParticipantConfig& informerConfig,
372  CallbackPtr callback);
373  virtual ~LocalMethod();
374 
375  // Overrides method in Participant.
376  virtual std::string getKind() const;
377  private:
378  rsc::logging::LoggerPtr logger;
379 
380  CallbackPtr callback;
381 
382  ListenerPtr makeListener();
383 
384  void handle(EventPtr event);
385  };
386 
387  typedef boost::shared_ptr<LocalMethod> LocalMethodPtr;
388 
389  LocalServer(const Scope& scope,
390  const ParticipantConfig &listenerConfig,
391  const ParticipantConfig &informerConfig);
392  virtual ~LocalServer();
393 
394  // Overrides method in Participant.
395  virtual std::string getKind() const;
396 
397  // Overrides method in Participant.
398  virtual const std::set<std::string> getTransportURLs() const;
399 
407  void registerMethod(const std::string& name, CallbackPtr callback);
408 
409 private:
412 
413  std::map<std::string, LocalMethodPtr> methods;
414 };
415 
416 // Since these are complete specializations, they
417 // cannot be declared inline in Server like the partial
418 // specializations (see C++03, ยง14.7.3/2:).
419 
426 template<>
427 class RSB_EXPORT LocalServer::Callback<void, void>: public LocalServer::CallbackBase {
428 public:
429  // typeid is due to msvc strangeness
431  LocalServer::CallbackBase(rsc::runtime::typeName(typeid(void)),
432  rsc::runtime::typeName(typeid(void))) {
433  }
434 
443  virtual void call(const std::string& methodName) = 0;
444 private:
445  EventPtr intlCall(const std::string& methodName, EventPtr /*request*/) {
446  call(methodName);
447  EventPtr reply(new Event());
448  reply->setType(getReplyType());
449  reply->setData(boost::shared_ptr<void>());
450  return reply;
451  }
452 
453 };
454 
461 template<>
462 class RSB_EXPORT LocalServer::FunctionCallback<void, void>: public LocalServer::CallbackBase {
463 public:
467  typedef boost::function<void(void)> FunctionType;
468 
469  explicit FunctionCallback(FunctionType function,
470  const std::string& requestType = rsc::runtime::typeName(
471  typeid(void)), const std::string& replyType =
472  rsc::runtime::typeName(typeid(void))) :
473  LocalServer::CallbackBase(requestType, replyType), function(
474  function) {
475  }
476 
477 private:
478  EventPtr intlCall(const std::string& /*methodName*/, EventPtr /*request*/) {
479  function();
480  EventPtr reply(new Event());
481  reply->setType(getReplyType());
482  reply->setData(boost::shared_ptr<void>());
483  return reply;
484  }
485 
486  FunctionType function;
487 };
488 
489 typedef boost::shared_ptr<LocalServer> LocalServerPtr;
490 
491 }
492 }
EventPtr intlCall(const std::string &, EventPtr request)
Definition: LocalServer.h:312
std::pair< std::string, boost::shared_ptr< void > > AnnotatedData
A combination of data type and the actual data.
Definition: Event.h:269
EventPtr intlCall(const std::string &, EventPtr request)
Definition: LocalServer.h:278
boost::function< typename boost::shared_ptr< ReplyType >void)> FunctionType
Type of functions that can be accepted.
Definition: LocalServer.h:337
FunctionCallback(FunctionType function, const std::string &requestType=rsc::runtime::typeName(typeid(RequestType)), const std::string &replyType=rsc::runtime::typeName(typeid(ReplyType)))
Definition: LocalServer.h:270
boost::shared_ptr< LocalServer > LocalServerPtr
Definition: LocalServer.h:489
boost::shared_ptr< LocalMethod > LocalMethodPtr
Definition: LocalServer.h:387
Basic message that is exchanged between informers and listeners.
Definition: Event.h:60
Callback object used to register one method for a server.
Definition: LocalServer.h:152
Objects of this class participate in the exchange of notifications on one channel of the bus...
Definition: Participant.h:65
FunctionCallback(FunctionType function, const std::string &requestType=rsc::runtime::typeName(typeid(void)), const std::string &replyType=rsc::runtime::typeName(typeid(void)))
Definition: LocalServer.h:469
EventPtr intlCall(const std::string &methodName, EventPtr request)
Definition: LocalServer.h:209
boost::function< void(typename boost::shared_ptr< RequestType >)> FunctionType
Type of functions that can be accepted.
Definition: LocalServer.h:302
EventPtr intlCall(const std::string &methodName, EventPtr)
Definition: LocalServer.h:244
Base class for callback classes.
Definition: LocalServer.h:90
EventPtr intlCall(const std::string &methodName, EventPtr request)
Definition: LocalServer.h:131
A callback which allows any kind of reply type but is restricted to a single request type...
Definition: LocalServer.h:110
Callback class with receives and returns events.
Definition: LocalServer.h:78
AnyReplyTypeCallback(const std::string &requestType=rsc::runtime::typeName(typeid(RequestType)))
Definition: LocalServer.h:113
Callback(const std::string &requestType=rsc::runtime::typeName(typeid(void)), const std::string &replyType=rsc::runtime::typeName(typeid(ReplyType)))
Definition: LocalServer.h:225
An adapter to use boost functions for callbacks.
Definition: LocalServer.h:261
boost::shared_ptr< Listener > ListenerPtr
Definition: Listener.h:155
std::map< std::string, LocalMethodPtr > methods
Definition: LocalServer.h:413
FunctionCallback(FunctionType function, const std::string &requestType=rsc::runtime::typeName(typeid(void)), const std::string &replyType=rsc::runtime::typeName(typeid(ReplyType)))
Definition: LocalServer.h:339
boost::function< typename boost::shared_ptr< ReplyType > typename boost::shared_ptr< RequestType >)> FunctionType
Type of functions that can be accepted.
Definition: LocalServer.h:268
A derived Method class which can be called from the remote side and implements its behavior by invoki...
Definition: LocalServer.h:366
Callback(const std::string &requestType=rsc::runtime::typeName(typeid(RequestType)), const std::string &replyType=rsc::runtime::typeName(typeid(ReplyType)))
Definition: LocalServer.h:155
boost::shared_ptr< IntlCallback > CallbackPtr
Definition: LocalServer.h:71
Callback object interface to implement for registering callable methods.
Definition: LocalServer.h:63
The server side of a request-reply-based communication channel.
Definition: LocalServer.h:54
EventPtr intlCall(const std::string &, EventPtr)
Definition: LocalServer.h:347
Base class for method classes.
Definition: Server.h:55
boost::function< void(void)> FunctionType
Type of functions that can be accepted.
Definition: LocalServer.h:467
EventPtr intlCall(const std::string &methodName, EventPtr)
Definition: LocalServer.h:445
Callback(const std::string &requestType=rsc::runtime::typeName(typeid(RequestType)), const std::string &replyType=rsc::runtime::typeName(typeid(void)))
Definition: LocalServer.h:190
A class describing the configuration of Participant instances.
FunctionCallback(FunctionType function, const std::string &requestType=rsc::runtime::typeName(typeid(RequestType)), const std::string &replyType=rsc::runtime::typeName(typeid(void)))
Definition: LocalServer.h:304
EventPtr intlCall(const std::string &, EventPtr)
Definition: LocalServer.h:478
ParticipantConfig listenerConfig
Definition: LocalServer.h:410
boost::shared_ptr< Event > EventPtr
Definition: Event.h:264
Scope is a descriptor for a hierarchical channel of the unified bus.
Definition: Scope.h:46
ParticipantConfig informerConfig
Definition: LocalServer.h:411
EventPtr intlCall(const std::string &methodName, EventPtr request)
Definition: LocalServer.h:175