task-call.hpp
Go to the documentation of this file.
1 
5 #include <qi/jsoncodec.hpp>
6 
7 #include <qicore/task.hpp>
8 
9 
10 #ifndef QICORE_TASK_CALL_H_
11 # define QICORE_TASK_CALL_H_
12 
13 namespace qi
14 {
17  template<typename T>
18  class TaskCall: public Task
19  {
20  public:
21  TaskCall(AnyFunction f)
22  : result(typeOf<T>())
23  , _f(f)
24  {
25  }
26  virtual bool interrupt() { return false;}
27  virtual void start(const AnyVarArguments& args)
28  {
29  running.set(true);
30  try
31  {
32  std::vector<AnyReference> nargs;
33  nargs.reserve(args.args().size());
34  for (unsigned i=0; i<args.args().size(); ++i)
35  nargs.push_back(AnyReference(args.args()[i].type(), args.args()[i].rawValue()));
36  T res = _f.call(nargs);
37  result.setValue(AnyReference(res));
38  }
39  catch(const std::exception& e)
40  {
41  error.set(e.what());
42  }
43  catch(...)
44  {
45  error.set("Unknown exception");
46  }
47  running.set(false);
48  }
49  GenericProperty result;
50  AnyFunction _f;
51  };
52 
53  template<typename T>
54  class TaskCall<Future<T> >: public Task
55  {
56  public:
58  : result(typeOf<T>()) {}
59  // Accept an explicit type that overrides
60  TaskCall(AnyFunction f, TypeInterface* eff = 0)
61  : result(eff?eff:typeOf<T>())
62  , _f(f)
63  , _live(new bool(true))
64  {
65  if (eff && qi::typeOf<T>()->info() != qi::typeOf<qi::AnyValue>()->info())
66  qiLogWarning("TaskCall") << "Overriding TaskCall type for a template different from GenericValue";
67  qiLogDebug("TaskCall") << "TaskCall " << this;
68  }
70  {
71  qiLogDebug("TaskCall") << "~TaskCall " << this;
72  *_live = false;
73  }
74  virtual void start(const AnyVarArguments& args)
75  {
76  qiLogDebug("TaskCall") << "start " << this;
77  running.set(true);
78  try
79  {
80  std::vector<AnyReference> nargs;
81  nargs.reserve(args.args().size());
82  for (unsigned i=0; i<args.args().size(); ++i)
83  nargs.push_back(AnyReference(args.args()[i].type(), args.args()[i].rawValue()));
84  AnyReference v = _f.call(nargs);
85  _fut = *v.ptr<Future<T> >();
86  v.destroy();
87  _fut.connect(boost::bind(&TaskCall<Future<T> >::onResult, this, _1, _live));
88  }
89  catch(const std::exception& e)
90  {
91  error.set(e.what());
92  }
93  catch(...)
94  {
95  error.set("Unknown exception");
96  }
97  }
98  void onResult(Future<T> fut, boost::shared_ptr<bool> live)
99  {
100  qiLogDebug("TaskCall") << "onResult " << this;
101  if (!*_live) // shouldn't you be threadsafe or something?
102  return;
103  switch(fut.wait(0))
104  {
105  case FutureState_Canceled:
106  error.set("interrupted");
107  break;
108  case FutureState_FinishedWithError:
109  error.set(fut.error());
110  break;
111  case FutureState_FinishedWithValue:
112  qiLogDebug("TaskCall") << "setResult " << encodeJSON(AnyReference::from(fut.value()));
113  result.setValue(fut.value());
114  break;
115  case FutureState_None:
116  case FutureState_Running:
117  error.set("Inconsistent state");
118  break;
119  }
120  running.set(false);
121  }
122  virtual bool interrupt()
123  {
124  try
125  {
126  _fut.cancel();
127  return true;
128  }
129  catch(...)
130  {
131  return false;
132  }
133  return true; // for distracted compilers
134  }
135  GenericProperty result;
136  AnyFunction _f;
137  Future<T> _fut;
138  boost::shared_ptr<bool> _live;
139  };
140 }
141 QI_TEMPLATE_OBJECT(qi::TaskCall, start, interrupt, running, error, result);
142 #endif
QI_TEMPLATE_OBJECT
QI_TEMPLATE_OBJECT(qi::TaskCall, start, interrupt, running, error, result)
task.hpp
qi::TaskCall::start
virtual void start(const AnyVarArguments &args)
Definition: task-call.hpp:27
qi::TaskCall
Definition: task-call.hpp:18
qi::TaskCall< Future< T > >::TaskCall
TaskCall(AnyFunction f, TypeInterface *eff=0)
Definition: task-call.hpp:60
qi::Task::running
Property< bool > running
RO, Indicates if the task is currently running.
Definition: task.hpp:29
qi::TaskCall< Future< T > >::~TaskCall
~TaskCall()
Definition: task-call.hpp:69
qi::TaskCall< Future< T > >::interrupt
virtual bool interrupt()
Definition: task-call.hpp:122
qi::Task
Definition: task.hpp:15
qi::TaskCall::TaskCall
TaskCall(AnyFunction f)
Definition: task-call.hpp:21
qi::TaskCall::result
GenericProperty result
Definition: task-call.hpp:49
qi::Task::error
Property< std::string > error
Definition: task.hpp:35
qi::TaskCall< Future< T > >::_live
boost::shared_ptr< bool > _live
Definition: task-call.hpp:138
qi::TaskCall< Future< T > >::_f
AnyFunction _f
Definition: task-call.hpp:136
qi::TaskCall< Future< T > >::_fut
Future< T > _fut
Definition: task-call.hpp:137
qi
Definition: file.hpp:21
qi::TaskCall::_f
AnyFunction _f
Definition: task-call.hpp:50
qi::TaskCall< Future< T > >::onResult
void onResult(Future< T > fut, boost::shared_ptr< bool > live)
Definition: task-call.hpp:98
qi::TaskCall::interrupt
virtual bool interrupt()
Definition: task-call.hpp:26
qi::TaskCall< Future< T > >::TaskCall
TaskCall()
Definition: task-call.hpp:57
qi::TaskCall< Future< T > >::result
GenericProperty result
Definition: task-call.hpp:135
qi::TaskCall< Future< T > >::start
virtual void start(const AnyVarArguments &args)
Definition: task-call.hpp:74


naoqi_libqicore
Author(s): Aldebaran
autogenerated on Wed Sep 14 2022 02:22:41