remoteprocedure.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011 by Tommi Maekitalo
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * As a special exception, you may use this file as part of a free
10  * software library without restriction. Specifically, if other files
11  * instantiate templates or use macros or inline functions from this
12  * file, or you compile this file and link it with other files to
13  * produce an executable, this file does not by itself cause the
14  * resulting executable to be covered by the GNU General Public
15  * License. This exception does not however invalidate any other
16  * reasons why the executable file might be covered by the GNU Library
17  * General Public License.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27  */
28 
29 #ifndef CXXTOOLS_REMOTEPROCEDURE_H
30 #define CXXTOOLS_REMOTEPROCEDURE_H
31 
32 #include <cxxtools/remoteclient.h>
33 #include <cxxtools/remoteresult.h>
34 #include <cxxtools/composer.h>
35 #include <cxxtools/decomposer.h>
36 #include <cxxtools/signal.h>
37 #include <cxxtools/string.h>
38 #include <string>
39 
40 namespace cxxtools
41 {
42 
44 {
45  public:
47  : _client(&client)
48  , _name(name)
49  { }
50 
52  { cancel(); }
53 
55  { return *_client; }
56 
58  { _client = &client; }
59 
60  const String& name() const
61  { return _name; }
62 
63  virtual void setFault(int rc, const std::string& msg) = 0;
64 
65  virtual bool failed() const = 0;
66 
67  void cancel()
68  {
69  if (_client && _client->activeProcedure() == this)
70  _client->cancel();
71  }
72 
73  virtual void onFinished() = 0;
74 
75  private:
76  RemoteClient* _client;
77  String _name;
78 };
79 
80 
81 template <typename R>
83 {
84  public:
86  : IRemoteProcedure(client, name),
87  _result(client)
88  { }
89 
90  void setFault(int rc, const std::string& msg)
91  {
92  _result.setFault(rc, msg);
93  }
94 
95  const R& result()
96  {
97  return _result.get();
98  }
99 
100  virtual bool failed() const
101  {
102  return _result.failed();
103  }
104 
105  Signal< const RemoteResult<R> & > finished;
106 
107  const R& end(std::size_t msecs = RemoteClient::WaitInfinite)
108  {
109  _result.client().wait(msecs);
110  return _result.get();
111  }
112 
113  protected:
114  void onFinished()
115  { finished.send(_result); }
116 
119 };
120 
121 
122 template <typename R,
123  typename A1 = cxxtools::Void,
124  typename A2 = cxxtools::Void,
125  typename A3 = cxxtools::Void,
126  typename A4 = cxxtools::Void,
127  typename A5 = cxxtools::Void,
128  typename A6 = cxxtools::Void,
129  typename A7 = cxxtools::Void,
130  typename A8 = cxxtools::Void,
131  typename A9 = cxxtools::Void,
132  typename A10 = cxxtools::Void>
134 {
135  public:
137  : RemoteProcedureBase<R>(client, name)
138  { }
139 
141  : RemoteProcedureBase<R>(client, String(name))
142  { }
143 
144  void begin(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10)
145  {
146  this->_result.clearFault();
147 
148  _a1.begin(a1);
149  _a2.begin(a2);
150  _a3.begin(a3);
151  _a4.begin(a4);
152  _a5.begin(a5);
153  _a6.begin(a6);
154  _a7.begin(a7);
155  _a8.begin(a8);
156  _a9.begin(a9);
157  _a10.begin(a10);
158 
159  this->_r.begin(this->_result.value());
160 
161  IDecomposer* argv[10] = { &_a1, &_a2, &_a3, &_a4, &_a5, &_a6, &_a7, &_a8, &_a9, &_a10 };
162  this->client().beginCall(this->_r, *this, argv, 10);
163  }
164 
165  const R& call(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10)
166  {
167  this->_result.clearFault();
168 
169  _a1.begin(a1);
170  _a2.begin(a2);
171  _a3.begin(a3);
172  _a4.begin(a4);
173  _a5.begin(a5);
174  _a6.begin(a6);
175  _a7.begin(a7);
176  _a8.begin(a8);
177  _a9.begin(a9);
178  _a10.begin(a10);
179  this->_r.begin(this->_result.value());
180 
181  IDecomposer* argv[10] = { &_a1, &_a2, &_a3, &_a4, &_a5, &_a6, &_a7, &_a8, &_a9, &_a10 };
182  this->client().call(this->_r, *this, argv, 10);
183  return this->_result.get();
184  }
185 
186  const R& operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10)
187  {
188  return this->call(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
189  }
190 
191  private:
192  Decomposer<A1> _a1;
193  Decomposer<A2> _a2;
194  Decomposer<A3> _a3;
195  Decomposer<A4> _a4;
196  Decomposer<A5> _a5;
197  Decomposer<A6> _a6;
198  Decomposer<A7> _a7;
199  Decomposer<A8> _a8;
200  Decomposer<A9> _a9;
201  Decomposer<A10> _a10;
202 };
203 
204 
205 template <typename R,
206  typename A1,
207  typename A2,
208  typename A3,
209  typename A4,
210  typename A5,
211  typename A6,
212  typename A7,
213  typename A8,
214  typename A9>
215 class RemoteProcedure<R, A1, A2, A3, A4, A5, A6, A7, A8, A9,
216  cxxtools::Void> : public RemoteProcedureBase<R>
217 {
218  public:
220  : RemoteProcedureBase<R>(client, name)
221  { }
222 
224  : RemoteProcedureBase<R>(client, String(name))
225  { }
226 
227  void begin(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9)
228  {
229  this->_result.clearFault();
230 
231  _a1.begin(a1);
232  _a2.begin(a2);
233  _a3.begin(a3);
234  _a4.begin(a4);
235  _a5.begin(a5);
236  _a6.begin(a6);
237  _a7.begin(a7);
238  _a8.begin(a8);
239  _a9.begin(a9);
240 
241  this->_r.begin(this->_result.value());
242 
243  IDecomposer* argv[9] = { &_a1, &_a2, &_a3, &_a4, &_a5, &_a6, &_a7, &_a8, &_a9 };
244  this->client().beginCall(this->_r, *this, argv, 9);
245  }
246 
247  const R& call(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9)
248  {
249  this->_result.clearFault();
250 
251  _a1.begin(a1);
252  _a2.begin(a2);
253  _a3.begin(a3);
254  _a4.begin(a4);
255  _a5.begin(a5);
256  _a6.begin(a6);
257  _a7.begin(a7);
258  _a8.begin(a8);
259  _a9.begin(a9);
260  this->_r.begin(this->_result.value());
261 
262  IDecomposer* argv[9] = { &_a1, &_a2, &_a3, &_a4, &_a5, &_a6, &_a7, &_a8, &_a9 };
263  this->client().call(this->_r, *this, argv, 9);
264  return this->_result.get();
265  }
266 
267  const R& operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9)
268  {
269  return this->call(a1, a2, a3, a4, a5, a6, a7, a8, a9);
270  }
271 
272  private:
273  Decomposer<A1> _a1;
274  Decomposer<A2> _a2;
275  Decomposer<A3> _a3;
276  Decomposer<A4> _a4;
277  Decomposer<A5> _a5;
278  Decomposer<A6> _a6;
279  Decomposer<A7> _a7;
280  Decomposer<A8> _a8;
281  Decomposer<A9> _a9;
282 };
283 
284 
285 template <typename R,
286  typename A1,
287  typename A2,
288  typename A3,
289  typename A4,
290  typename A5,
291  typename A6,
292  typename A7,
293  typename A8>
294 class RemoteProcedure<R, A1, A2, A3, A4, A5, A6, A7, A8,
295  cxxtools::Void,
297 {
298  public:
300  : RemoteProcedureBase<R>(client, name)
301  { }
302 
304  : RemoteProcedureBase<R>(client, String(name))
305  { }
306 
307  void begin(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8)
308  {
309  this->_result.clearFault();
310 
311  _a1.begin(a1);
312  _a2.begin(a2);
313  _a3.begin(a3);
314  _a4.begin(a4);
315  _a5.begin(a5);
316  _a6.begin(a6);
317  _a7.begin(a7);
318  _a8.begin(a8);
319 
320  this->_r.begin(this->_result.value());
321 
322  IDecomposer* argv[8] = { &_a1, &_a2, &_a3, &_a4, &_a5, &_a6, &_a7, &_a8 };
323  this->client().beginCall(this->_r, *this, argv, 8);
324  }
325 
326  const R& call(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8)
327  {
328  this->_result.clearFault();
329 
330  _a1.begin(a1);
331  _a2.begin(a2);
332  _a3.begin(a3);
333  _a4.begin(a4);
334  _a5.begin(a5);
335  _a6.begin(a6);
336  _a7.begin(a7);
337  _a8.begin(a8);
338  this->_r.begin(this->_result.value());
339 
340  IDecomposer* argv[8] = { &_a1, &_a2, &_a3, &_a4, &_a5, &_a6, &_a7, &_a8 };
341  this->client().call(this->_r, *this, argv, 8);
342  return this->_result.get();
343  }
344 
345  const R& operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8)
346  {
347  return this->call(a1, a2, a3, a4, a5, a6, a7, a8);
348  }
349 
350  private:
351  Decomposer<A1> _a1;
352  Decomposer<A2> _a2;
353  Decomposer<A3> _a3;
354  Decomposer<A4> _a4;
355  Decomposer<A5> _a5;
356  Decomposer<A6> _a6;
357  Decomposer<A7> _a7;
358  Decomposer<A8> _a8;
359 };
360 
361 
362 template <typename R,
363  typename A1,
364  typename A2,
365  typename A3,
366  typename A4,
367  typename A5,
368  typename A6,
369  typename A7>
370 class RemoteProcedure<R, A1, A2, A3, A4, A5, A6, A7,
371  cxxtools::Void,
374 {
375  public:
377  : RemoteProcedureBase<R>(client, name)
378  { }
379 
381  : RemoteProcedureBase<R>(client, String(name))
382  { }
383 
384  void begin(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7)
385  {
386  this->_result.clearFault();
387 
388  _a1.begin(a1);
389  _a2.begin(a2);
390  _a3.begin(a3);
391  _a4.begin(a4);
392  _a5.begin(a5);
393  _a6.begin(a6);
394  _a7.begin(a7);
395 
396  this->_r.begin(this->_result.value());
397 
398  IDecomposer* argv[7] = { &_a1, &_a2, &_a3, &_a4, &_a5, &_a6, &_a7 };
399  this->client().beginCall(this->_r, *this, argv, 7);
400  }
401 
402  const R& call(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7)
403  {
404  this->_result.clearFault();
405 
406  _a1.begin(a1);
407  _a2.begin(a2);
408  _a3.begin(a3);
409  _a4.begin(a4);
410  _a5.begin(a5);
411  _a6.begin(a6);
412  _a7.begin(a7);
413  this->_r.begin(this->_result.value());
414 
415  IDecomposer* argv[7] = { &_a1, &_a2, &_a3, &_a4, &_a5, &_a6, &_a7 };
416  this->client().call(this->_r, *this, argv, 7);
417  return this->_result.get();
418  }
419 
420  const R& operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7)
421  {
422  return this->call(a1, a2, a3, a4, a5, a6, a7);
423  }
424 
425  private:
426  Decomposer<A1> _a1;
427  Decomposer<A2> _a2;
428  Decomposer<A3> _a3;
429  Decomposer<A4> _a4;
430  Decomposer<A5> _a5;
431  Decomposer<A6> _a6;
432  Decomposer<A7> _a7;
433 };
434 
435 
436 template <typename R,
437  typename A1,
438  typename A2,
439  typename A3,
440  typename A4,
441  typename A5,
442  typename A6>
443 class RemoteProcedure<R, A1, A2, A3, A4, A5, A6,
444  cxxtools::Void,
448 {
449  public:
451  : RemoteProcedureBase<R>(client, name)
452  { }
453 
455  : RemoteProcedureBase<R>(client, String(name))
456  { }
457 
458  void begin(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6)
459  {
460  this->_result.clearFault();
461 
462  _a1.begin(a1);
463  _a2.begin(a2);
464  _a3.begin(a3);
465  _a4.begin(a4);
466  _a5.begin(a5);
467  _a6.begin(a6);
468 
469  this->_r.begin(this->_result.value());
470 
471  IDecomposer* argv[6] = { &_a1, &_a2, &_a3, &_a4, &_a5, &_a6 };
472  this->client().beginCall(this->_r, *this, argv, 6);
473  }
474 
475  const R& call(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6)
476  {
477  this->_result.clearFault();
478 
479  _a1.begin(a1);
480  _a2.begin(a2);
481  _a3.begin(a3);
482  _a4.begin(a4);
483  _a5.begin(a5);
484  _a6.begin(a6);
485  this->_r.begin(this->_result.value());
486 
487  IDecomposer* argv[6] = { &_a1, &_a2, &_a3, &_a4, &_a5, &_a6 };
488  this->client().call(this->_r, *this, argv, 6);
489  return this->_result.get();
490  }
491 
492  const R& operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6)
493  {
494  return this->call(a1, a2, a3, a4, a5, a6);
495  }
496 
497  private:
498  Decomposer<A1> _a1;
499  Decomposer<A2> _a2;
500  Decomposer<A3> _a3;
501  Decomposer<A4> _a4;
502  Decomposer<A5> _a5;
503  Decomposer<A6> _a6;
504 };
505 
506 
507 template <typename R,
508  typename A1,
509  typename A2,
510  typename A3,
511  typename A4,
512  typename A5>
513 class RemoteProcedure<R, A1, A2, A3, A4, A5,
514  cxxtools::Void,
519 {
520  public:
522  : RemoteProcedureBase<R>(client, name)
523  { }
524 
526  : RemoteProcedureBase<R>(client, String(name))
527  { }
528 
529  void begin(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
530  {
531  this->_result.clearFault();
532 
533  _a1.begin(a1);
534  _a2.begin(a2);
535  _a3.begin(a3);
536  _a4.begin(a4);
537  _a5.begin(a5);
538 
539  this->_r.begin(this->_result.value());
540 
541  IDecomposer* argv[5] = { &_a1, &_a2, &_a3, &_a4, &_a5 };
542  this->client().beginCall(this->_r, *this, argv, 5);
543  }
544 
545  const R& call(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
546  {
547  this->_result.clearFault();
548 
549  _a1.begin(a1);
550  _a2.begin(a2);
551  _a3.begin(a3);
552  _a4.begin(a4);
553  _a5.begin(a5);
554  this->_r.begin(this->_result.value());
555 
556  IDecomposer* argv[5] = { &_a1, &_a2, &_a3, &_a4, &_a5 };
557  this->client().call(this->_r, *this, argv, 5);
558  return this->_result.get();
559  }
560 
561  const R& operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
562  {
563  return this->call(a1, a2, a3, a4, a5);
564  }
565 
566  private:
567  Decomposer<A1> _a1;
568  Decomposer<A2> _a2;
569  Decomposer<A3> _a3;
570  Decomposer<A4> _a4;
571  Decomposer<A5> _a5;
572 };
573 
574 
575 template <typename R,
576  typename A1,
577  typename A2,
578  typename A3,
579  typename A4>
580 class RemoteProcedure<R, A1, A2, A3, A4,
581  cxxtools::Void,
587 {
588  public:
590  : RemoteProcedureBase<R>(client, name)
591  { }
592 
594  : RemoteProcedureBase<R>(client, String(name))
595  { }
596 
597  void begin(const A1& a1, const A2& a2, const A3& a3, const A4& a4)
598  {
599  this->_result.clearFault();
600 
601  _a1.begin(a1);
602  _a2.begin(a2);
603  _a3.begin(a3);
604  _a4.begin(a4);
605 
606  this->_r.begin(this->_result.value());
607 
608  IDecomposer* argv[4] = { &_a1, &_a2, &_a3, &_a4 };
609  this->client().beginCall(this->_r, *this, argv, 4);
610  }
611 
612  const R& call(const A1& a1, const A2& a2, const A3& a3, const A4& a4)
613  {
614  this->_result.clearFault();
615 
616  _a1.begin(a1);
617  _a2.begin(a2);
618  _a3.begin(a3);
619  _a4.begin(a4);
620  this->_r.begin(this->_result.value());
621 
622  IDecomposer* argv[4] = { &_a1, &_a2, &_a3, &_a4 };
623  this->client().call(this->_r, *this, argv, 4);
624  return this->_result.get();
625  }
626 
627  const R& operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4)
628  {
629  return this->call(a1, a2, a3, a4);
630  }
631 
632  private:
633  Decomposer<A1> _a1;
634  Decomposer<A2> _a2;
635  Decomposer<A3> _a3;
636  Decomposer<A4> _a4;
637 };
638 
639 
640 template <typename R,
641  typename A1,
642  typename A2,
643  typename A3>
644 class RemoteProcedure<R, A1, A2, A3,
645  cxxtools::Void,
652 {
653  public:
655  : RemoteProcedureBase<R>(client, name)
656  { }
657 
659  : RemoteProcedureBase<R>(client, String(name))
660  { }
661 
662  void begin(const A1& a1, const A2& a2, const A3& a3)
663  {
664  this->_result.clearFault();
665 
666  _a1.begin(a1);
667  _a2.begin(a2);
668  _a3.begin(a3);
669 
670  this->_r.begin(this->_result.value());
671 
672  IDecomposer* argv[3] = { &_a1, &_a2, &_a3 };
673  this->client().beginCall(this->_r, *this, argv, 3);
674  }
675 
676  const R& call(const A1& a1, const A2& a2, const A3& a3)
677  {
678  this->_result.clearFault();
679 
680  _a1.begin(a1);
681  _a2.begin(a2);
682  _a3.begin(a3);
683  this->_r.begin(this->_result.value());
684 
685  IDecomposer* argv[3] = { &_a1, &_a2, &_a3 };
686  this->client().call(this->_r, *this, argv, 3);
687  return this->_result.get();
688  }
689 
690  const R& operator()(const A1& a1, const A2& a2, const A3& a3)
691  {
692  return this->call(a1, a2, a3);
693  }
694 
695  private:
696  Decomposer<A1> _a1;
697  Decomposer<A2> _a2;
698  Decomposer<A3> _a3;
699 };
700 
701 
702 template <typename R,
703  typename A1,
704  typename A2>
705 class RemoteProcedure<R, A1, A2,
706  cxxtools::Void,
714 {
715  public:
717  : RemoteProcedureBase<R>(client, name)
718  { }
719 
721  : RemoteProcedureBase<R>(client, String(name))
722  { }
723 
724  void begin(const A1& a1, const A2& a2)
725  {
726  this->_result.clearFault();
727 
728  _a1.begin(a1);
729  _a2.begin(a2);
730 
731  this->_r.begin(this->_result.value());
732 
733  IDecomposer* argv[2] = { &_a1, &_a2 };
734  this->client().beginCall(this->_r, *this, argv, 2);
735  }
736 
737  const R& call(const A1& a1, const A2& a2)
738  {
739  this->_result.clearFault();
740 
741  _a1.begin(a1);
742  _a2.begin(a2);
743  this->_r.begin(this->_result.value());
744 
745  IDecomposer* argv[2] = { &_a1, &_a2 };
746  this->client().call(this->_r, *this, argv, 2);
747  return this->_result.get();
748  }
749 
750  const R& operator()(const A1& a1, const A2& a2)
751  {
752  return this->call(a1, a2);
753  }
754 
755  private:
756  Decomposer<A1> _a1;
757  Decomposer<A2> _a2;
758 };
759 
760 
761 template <typename R,
762  typename A1>
763 class RemoteProcedure<R, A1,
764  cxxtools::Void,
773 {
774  public:
776  : RemoteProcedureBase<R>(client, name)
777  { }
778 
780  : RemoteProcedureBase<R>(client, String(name))
781  { }
782 
783  void begin(const A1& a1)
784  {
785  this->_result.clearFault();
786 
787  _a1.begin(a1);
788 
789  this->_r.begin(this->_result.value());
790 
791  IDecomposer* argv[1] = { &_a1 };
792  this->client().beginCall(this->_r, *this, argv, 1);
793  }
794 
795  const R& call(const A1& a1)
796  {
797  this->_result.clearFault();
798 
799  _a1.begin(a1);
800  this->_r.begin(this->_result.value());
801 
802  IDecomposer* argv[1] = { &_a1 };
803  this->client().call(this->_r, *this, argv, 1);
804  return this->_result.get();
805  }
806 
807  const R& operator()(const A1& a1)
808  {
809  return this->call(a1);
810  }
811 
812  private:
813  Decomposer<A1> _a1;
814 };
815 
816 
817 template <typename R>
819  cxxtools::Void,
829 {
830  public:
832  : RemoteProcedureBase<R>(client, name)
833  { }
834 
836  : RemoteProcedureBase<R>(client, String(name))
837  { }
838 
839  void begin()
840  {
841  this->_result.clearFault();
842 
843  this->_r.begin(this->_result.value());
844 
845  IDecomposer* argv[1] = { 0 };
846  this->client().beginCall(this->_r, *this, argv, 0);
847  }
848 
849  const R& call()
850  {
851  this->_result.clearFault();
852 
853  this->_r.begin(this->_result.value());
854 
855  IDecomposer* argv[1] = { 0 };
856  this->client().call(this->_r, *this, argv, 0);
857  return this->_result.get();
858  }
859 
860  const R& operator()()
861  {
862  return this->call();
863  }
864 };
865 
866 
867 }
868 
869 #endif // CXXTOOLS_REMOTEPROCEDURE_H