FusedFunctorDataSource.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: The SourceWorks Tue Sep 7 00:55:18 CEST 2010 FusedFunctorDataSource.hpp
3 
4  FusedFunctorDataSource.hpp - description
5  -------------------
6  begin : Tue September 07 2010
7  copyright : (C) 2010 The SourceWorks
8  email : peter@thesourceworks.com
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * Lesser General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 
39 #ifndef ORO_FUSEDFUNCTORDATASOURCE_HPP_
40 #define ORO_FUSEDFUNCTORDATASOURCE_HPP_
41 
42 #include "DataSource.hpp"
43 #include "CreateSequence.hpp"
44 #include "../SendStatus.hpp"
45 #include "BindStorage.hpp"
46 #include "../ExecutionEngine.hpp"
47 #include "../os/oro_allocator.hpp"
48 #include "UnMember.hpp"
49 #include <boost/bind.hpp>
50 #include <boost/type_traits.hpp>
51 #include <boost/function.hpp>
52 #include <boost/function_types/function_type.hpp>
53 #include <boost/fusion/include/invoke.hpp>
54 #include <boost/fusion/include/invoke_procedure.hpp>
55 #include <boost/mpl/bool.hpp>
56 #include <boost/make_shared.hpp>
57 
58 namespace RTT
59 {
60  namespace internal
61  {
62  namespace bf = boost::fusion;
63 
69  template<typename Signature, class Enable=void>
71  : public DataSource<
72  typename remove_cr<typename boost::function_traits<Signature>::result_type>::type >
73  {
74  //BOOST_STATIC_ASSERT( boost::mpl::false_::value );
75  typedef typename boost::function_traits<Signature>::result_type
79  typedef create_sequence<
80  typename boost::function_types::parameter_types<Signature>::type> SequenceFactory;
82  typedef boost::function<Signature> call_type;
84  boost::function<Signature> ff;
85  DataSourceSequence args;
87  public:
88  typedef boost::intrusive_ptr<FusedFunctorDataSource<Signature> >
90 
91  template<class Func>
93  const DataSourceSequence& s = DataSourceSequence() ) :
94  ff(g), args(s)
95  {
96  }
97 
98  void setArguments(const DataSourceSequence& a1)
99  {
100  args = a1;
101  }
102 
103  value_t value() const
104  {
105  return ret.result();
106  }
107 
108  const_reference_t rvalue() const
109  {
110  return ret.result();
111  }
112 
113  bool evaluate() const {
114  // forward invoke to ret object, which stores return value.
115  // this foo pointer dance is because older compilers don't handle using
116  // &bf::invoke<call_type,arg_type> directly.
117  typedef typename bf::result_of::invoke<call_type,arg_type>::type iret;
118  typedef iret(*IType)(call_type, arg_type const&);
119  IType foo = &bf::invoke<call_type,arg_type>;
120  ret.exec( boost::bind(foo, boost::ref(ff), SequenceFactory::data(args)));
122  return true;
123  }
124 
125  value_t get() const
126  {
128  return ret.result();
129  }
130 
132  {
134  }
136  std::map<
137  const base::DataSourceBase*,
138  base::DataSourceBase*>& alreadyCloned) const
139  {
140  return new FusedFunctorDataSource<Signature> (ff, SequenceFactory::copy(args, alreadyCloned));
141  }
142  };
143 
144  template<typename Signature>
145  struct FusedFunctorDataSource<Signature, typename boost::enable_if< is_pure_reference<typename boost::function_traits<Signature>::result_type> >::type >
146  : public AssignableDataSource<
147  typename remove_cr<typename boost::function_traits<Signature>::result_type>::type >
148  {
149  //BOOST_STATIC_ASSERT( boost::mpl::false_::value );
150  typedef typename boost::function_traits<Signature>::result_type
155  typedef create_sequence<
156  typename boost::function_types::parameter_types<Signature>::type> SequenceFactory;
158  typedef boost::function<Signature> call_type;
160  boost::function<Signature> ff;
161  DataSourceSequence args;
163  public:
164  typedef boost::intrusive_ptr<FusedFunctorDataSource<Signature> >
166 
167  template<class Func>
169  const DataSourceSequence& s = DataSourceSequence() ) :
170  ff(g), args(s)
171  {
172  }
173 
174  void setArguments(const DataSourceSequence& a1)
175  {
176  args = a1;
177  }
178 
179  value_t value() const
180  {
181  return ret.result();
182  }
183 
184  const_reference_t rvalue() const
185  {
186  return ret.result();
187  }
188 
189  bool evaluate() const {
190  // forward invoke to ret object, which stores return value.
191  // this foo pointer dance is because older compilers don't handle using
192  // &bf::invoke<call_type,arg_type> directly.
193  typedef typename bf::result_of::invoke<call_type,arg_type>::type iret;
194  typedef iret(*IType)(call_type, arg_type const&);
195  IType foo = &bf::invoke<call_type,arg_type>;
196  ret.exec( boost::bind(foo, boost::ref(ff), SequenceFactory::data(args)));
198  return true;
199  }
200  value_t get() const
201  {
203  return ret.result();
204  }
205 
206  void set( typename AssignableDataSource<value_t>::param_t arg) {
207  // we need to get the new reference before we set the arg.
208  get(); ret.result() = arg;
209  }
210 
211  reference_t set() {
212  get(); return ret.result();
213  }
214 
216  {
218  }
220  std::map<
221  const base::DataSourceBase*,
222  base::DataSourceBase*>& alreadyCloned) const
223  {
224  return new FusedFunctorDataSource<Signature> (ff, SequenceFactory::copy(args, alreadyCloned));
225  }
226  };
237  template<class Function>
238  base::DataSourceBase* newFunctorDataSource(Function f, const std::vector<base::DataSourceBase::shared_ptr>& args)
239  {
240  typedef typename boost::function_types::function_type<Function>::type Signature;
242  if ( args.size() != boost::function_traits<Signature>::arity )
243  throw wrong_number_of_args_exception(boost::function_traits<Signature>::arity, args.size() );
244  return new FusedFunctorDataSource<Signature>(f, SequenceFactory::sources(args.begin()));
245  }
246 
252  template<typename Signature>
254  : public DataSource<
255  typename remove_cr<typename boost::function_traits<Signature>::result_type>::type >
256  {
257  typedef typename boost::function_traits<Signature>::result_type
261  typedef create_sequence<
262  typename boost::function_types::parameter_types<Signature>::type> SequenceFactory;
265  DataSourceSequence args;
267  public:
268  typedef boost::intrusive_ptr<FusedMCallDataSource<Signature> >
270 
272  const DataSourceSequence& s = DataSourceSequence() ) :
273  ff(g), args(s)
274  {
275  }
276 
277  void setArguments(const DataSourceSequence& a1)
278  {
279  args = a1;
280  }
281 
282  value_t value() const
283  {
284  return ret.result();
285  }
286 
287  const_reference_t rvalue() const
288  {
289  return ret.result();
290  }
291 
292  bool evaluate() const {
293  // put the member's object as first since SequenceFactory does not know about the OperationCallerBase type.
294  typedef bf::cons<base::OperationCallerBase<Signature>*, typename SequenceFactory::data_type> arg_type;
296  // this foo pointer dance is because older compilers don't handle using
297  // &bf::invoke<call_type,arg_type> directly.
298  typedef typename bf::result_of::invoke<call_type,arg_type>::type iret;
299  typedef iret(*IType)(call_type, arg_type const&);
300  IType foo = &bf::invoke<call_type,arg_type>;
301  // we need to store the ret value ourselves.
302  ret.exec( boost::bind(foo, &base::OperationCallerBase<Signature>::call, arg_type(ff.get(), SequenceFactory::data(args))) );
303  if(ret.isError()) {
304  ff->reportError();
305  ret.checkError();
306  }
308  return true;
309  }
310 
311  value_t get() const
312  {
313  evaluate();
314  return ret.result();
315  }
316 
318  {
320  }
322  std::map<
323  const base::DataSourceBase*,
324  base::DataSourceBase*>& alreadyCloned) const
325  {
326  return new FusedMCallDataSource<Signature> (ff, SequenceFactory::copy(args, alreadyCloned));
327  }
328  };
329 
334  template<typename Signature>
336  : public AssignableDataSource<SendHandle<Signature> >
337  {
339  typedef result_type value_t;
343  typedef create_sequence<
344  typename boost::function_types::parameter_types<Signature>::type> SequenceFactory;
347  DataSourceSequence args;
348  mutable SendHandle<Signature> sh; // mutable because of get() const
349  mutable bool isqueued;
350  public:
351  typedef boost::intrusive_ptr<FusedMSendDataSource<Signature> >
353 
355  const DataSourceSequence& s = DataSourceSequence() ) :
356  ff(g), args(s), sh(), isqueued(false)
357  {
358  }
359 
360  void setArguments(const DataSourceSequence& a1)
361  {
362  args = a1;
363  }
364 
365  virtual void set( param_t t ) {
366  sh = t;
367  }
368 
369  reference_t set() {
370  return sh;
371  }
372 
373  value_t value() const
374  {
375  return sh;
376  }
377 
378  const_reference_t rvalue() const
379  {
380  return sh;
381  }
382 
383  value_t get() const
384  {
385  if (isqueued)
386  return sh;
387  // put the member's object as first since SequenceFactory does not know about the OperationCallerBase type.
389  if ( sh.ready() ) // only queued if sh contains a collectable operation
390  isqueued = true;
391  return sh;
392  }
393 
394  void reset() {
395  isqueued = false;
396  }
397 
399  {
401  }
402 
404  std::map<
405  const base::DataSourceBase*,
406  base::DataSourceBase*>& alreadyCloned) const
407  {
408  // we need copy semantics because FusedMCollectDataSource tracks us.
409  if ( alreadyCloned[this] != 0 ) {
410  assert( dynamic_cast<FusedMSendDataSource<Signature>*>( alreadyCloned[this] ) == static_cast<FusedMSendDataSource<Signature>*>( alreadyCloned[this] ) );
411  return static_cast<FusedMSendDataSource<Signature>*>( alreadyCloned[this] );
412  }
413  // Other pieces in the code rely on insertion in the map :
414  alreadyCloned[this] = new FusedMSendDataSource<Signature>(ff, SequenceFactory::copy(args, alreadyCloned));
415  // return copy
416  return static_cast<FusedMSendDataSource<Signature>*>( alreadyCloned[this] );
417  }
418  };
419 
426  template<typename Signature>
428  : public DataSource<SendStatus>
429  {
431  typedef result_type value_t;
433  // push the SendHandle pointer in front.
435  typedef typename boost::function_types::parameter_types<CollectSignature>::type arg_types;
436  typedef typename mpl::push_front<arg_types, SendHandle<Signature>& >::type handle_and_arg_types;
437  typedef create_sequence< handle_and_arg_types
440  DataSourceSequence args;
442  mutable SendStatus ss; // because of get() const
443  public:
444  typedef boost::intrusive_ptr<FusedMCollectDataSource<Signature> >
446 
448  const DataSourceSequence& s, DataSource<bool>::shared_ptr blocking ) :
449  args(s), isblocking(blocking), ss(SendFailure)
450  {
451  }
452 
453  void setArguments(const DataSourceSequence& a1)
454  {
455  args = a1;
456  }
457 
458  value_t value() const
459  {
460  return ss;
461  }
462 
463  const_reference_t rvalue() const
464  {
465  return ss;
466  }
467 
468  value_t get() const
469  {
470  // put the member's object as first since SequenceFactory does not know about the OperationCallerBase type.
471  if (isblocking->get())
473  else
476  return ss;
477  }
478 
480  {
481  return new FusedMCollectDataSource<Signature> ( args, isblocking);
482  }
483 
485  std::map<
486  const base::DataSourceBase*,
487  base::DataSourceBase*>& alreadyCloned) const
488  {
489  // we need copy semantics because CmdCollectCondition tracks us.
490  // WARNING: This is a tricky precedent... should all DataSources with state + multiple living references then implement this ? Should we assert on this ?
491  if ( alreadyCloned[this] != 0 ) {
492  assert ( dynamic_cast<FusedMCollectDataSource<Signature>*>( alreadyCloned[this] ) == static_cast<FusedMCollectDataSource<Signature>*>( alreadyCloned[this] ) );
493  return static_cast<FusedMCollectDataSource<Signature>*>( alreadyCloned[this] );
494  }
495  // Other pieces in the code rely on insertion in the map :
496  alreadyCloned[this] = new FusedMCollectDataSource<Signature>(SequenceFactory::copy(args, alreadyCloned), isblocking);
497  // return copy
498  return static_cast<FusedMCollectDataSource<Signature>*>( alreadyCloned[this] );
499  }
500  };
501 
510  template<typename Signature>
512  {
513  typedef typename boost::function_traits<Signature>::result_type
515  typedef result_type value_t;
516  typedef create_sequence<
517  typename boost::function_types::parameter_types<Signature>::type> SequenceFactory;
519  boost::shared_ptr<base::ActionInterface> mact;
520  // We need the arg_cache to store data similar to BindStorage,
521  // such that we can safely access it during execute().
523  DataSourceSequence args;
530  boost::shared_ptr<FusedMSignal<Signature> > self;
531  public:
532  typedef boost::shared_ptr<FusedMSignal<Signature> > shared_ptr;
533 
542  const DataSourceSequence& s,
543  ExecutionEngine* subscr ) :
544  mact(act), args(s), subscriber(subscr), self()
545  {
546  }
547 
549  }
550 
556  result_type invoke(const typename SequenceFactory::data_type& seq) const {
557  if ( subscriber ) {
558  // asynchronous
559  shared_ptr sg = this->cloneRT();
560  sg->arg_cache = SequenceFactory::store(seq);
561  sg->self = sg;
562  if ( subscriber->process( sg.get() ) ) {
563  // all ok
564  } else {
565  sg->dispose();
566  }
567  } else {
568  // synchronous
569  SequenceFactory::set( seq, args );
570  mact->execute();
571  }
572 
573  return NA<result_type>::na();
574  }
575 
577  SequenceFactory::load( this->arg_cache, this->args );
578  mact->execute();
579  dispose();
580  }
581 
586  void dispose() {
587  self.reset();
588  }
589 
590 
591  void setArguments(const DataSourceSequence& a1)
592  {
593  args = a1;
594  }
595 
597  {
598  // returns identical copy of this;
599  return boost::allocate_shared<FusedMSignal<Signature> >(os::rt_allocator<FusedMSignal<Signature> >(), *this);
600  }
601  };
602 
603  }
604 }
605 
606 #endif /* ORO_FUSEDFUNCTORDATASOURCE_HPP_ */
boost::function_traits< Signature >::result_type result_type
bf::cons< arg_store_type, arg_store_tail_type > data_store_type
boost::intrusive_ptr< FusedFunctorDataSource< Signature > > shared_ptr
boost::function_traits< Signature >::result_type result_type
virtual result_t get() const =0
create_sequence< typename boost::function_types::parameter_types< Signature >::type > SequenceFactory
FusedMSignal< Signature >::shared_ptr cloneRT() const
virtual FusedMCallDataSource< Signature > * clone() const
The base class for all internal data representations.
remove_cr< result_type >::type value_t
static T na()
Definition: NA.hpp:57
SequenceFactory::atype DataSourceSequence
SequenceFactory::data_store_type arg_cache
void setArguments(const DataSourceSequence &a1)
base::DataSourceBase * newFunctorDataSource(Function f, const std::vector< base::DataSourceBase::shared_ptr > &args)
FusedMSendDataSource(typename base::OperationCallerBase< Signature >::shared_ptr g, const DataSourceSequence &s=DataSourceSequence())
virtual FusedMSendDataSource< Signature > * copy(std::map< const base::DataSourceBase *, base::DataSourceBase * > &alreadyCloned) const
remove_cr< result_type >::type value_t
boost::intrusive_ptr< FusedMSendDataSource< Signature > > shared_ptr
DataSource< value_t >::const_reference_t const_reference_t
static void load(const data_store_type &in, const atype &seq)
boost::function_traits< Signature >::result_type result_type
virtual FusedFunctorDataSource< Signature > * copy(std::map< const base::DataSourceBase *, base::DataSourceBase * > &alreadyCloned) const
FusedFunctorDataSource(Func g, const DataSourceSequence &s=DataSourceSequence())
void setArguments(const DataSourceSequence &a1)
CollectType< Signature >::type CollectSignature
SendStatus
Definition: SendStatus.hpp:53
AssignableDataSource< value_t >::reference_t reference_t
DataSource< value_t >::const_reference_t const_reference_t
boost::shared_ptr< OperationCallerBase< F > > shared_ptr
boost::intrusive_ptr< FusedMCollectDataSource< Signature > > shared_ptr
void setArguments(const DataSourceSequence &a1)
The SendHandle is used to collect the result values of an asynchronous invocation. The template argument Signature must have the same type as the method being invoked.
Definition: rtt-fwd.hpp:79
create_sequence< typename boost::function_types::parameter_types< Signature >::type > SequenceFactory
FusedMCallDataSource(typename base::OperationCallerBase< Signature >::shared_ptr g, const DataSourceSequence &s=DataSourceSequence())
static type copy(const type &seq, std::map< const base::DataSourceBase *, base::DataSourceBase * > &alreadyCloned)
static type sources(std::vector< base::DataSourceBase::shared_ptr >::const_iterator args, int argnbr=1)
FusedMCollectDataSource(const DataSourceSequence &s, DataSource< bool >::shared_ptr blocking)
create_sequence< typename boost::function_types::parameter_types< Signature >::type > SequenceFactory
Based on the software pattern &#39;command&#39;, this interface allows execution of action objects...
base::OperationCallerBase< Signature >::shared_ptr ff
boost::intrusive_ptr< FusedMCallDataSource< Signature > > shared_ptr
result_type invoke(const typename SequenceFactory::data_type &seq) const
virtual FusedMCollectDataSource< Signature > * clone() const
An object that is executable and is freed after execution.
base::OperationCallerBase< Signature >::shared_ptr ff
AssignableDataSource< value_t >::const_reference_t const_reference_t
virtual FusedMSendDataSource< Signature > * clone() const
DataSource< SendStatus >::const_reference_t const_reference_t
AssignableDataSource< value_t >::param_t param_t
FusedMSignal(base::ActionInterface *act, const DataSourceSequence &s, ExecutionEngine *subscr)
boost::function_types::parameter_types< CollectSignature >::type arg_types
void setArguments(const DataSourceSequence &a1)
void setArguments(const DataSourceSequence &a1)
boost::remove_const< typename boost::remove_reference< T >::type >::type type
Definition: mystd.hpp:63
virtual FusedMCollectDataSource< Signature > * copy(std::map< const base::DataSourceBase *, base::DataSourceBase * > &alreadyCloned) const
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:53
static void set(const data_type &in, const atype &seq)
virtual bool process(base::DisposableInterface *c)
mpl::push_front< arg_types, SendHandle< Signature > & >::type handle_and_arg_types
virtual FusedFunctorDataSource< Signature > * clone() const
virtual FusedFunctorDataSource< Signature > * copy(std::map< const base::DataSourceBase *, base::DataSourceBase * > &alreadyCloned) const
details::GetConstRef< T >::type const_reference_t
Definition: DataSource.hpp:107
create_sequence< typename boost::function_types::parameter_types< Signature >::type > SequenceFactory
bool ready() const
Definition: SendHandle.hpp:117
create_sequence< handle_and_arg_types > SequenceFactory
boost::shared_ptr< base::ActionInterface > mact
virtual FusedMCallDataSource< Signature > * copy(std::map< const base::DataSourceBase *, base::DataSourceBase * > &alreadyCloned) const
boost::shared_ptr< FusedMSignal< Signature > > shared_ptr
void foo(double d)


rtt
Author(s): RTT Developers
autogenerated on Tue Jun 25 2019 19:33:24