signal-ptr.cpp 7.87 KB
Newer Older
Nicolas Mansard's avatar
ivigit.  
Nicolas Mansard committed
1
2
3
4
5
// Copyright 2010 Thomas Moulard.
//

#include <string>

6
7
#include <boost/foreach.hpp>

Nicolas Mansard's avatar
ivigit.  
Nicolas Mansard committed
8
9
10
#include <dynamic-graph/debug.h>
#include <dynamic-graph/entity.h>
#include <dynamic-graph/factory.h>
11
12
#include <dynamic-graph/pool.h>
#include <dynamic-graph/signal-base.h>
Nicolas Mansard's avatar
ivigit.  
Nicolas Mansard committed
13
#include <dynamic-graph/signal-ptr.h>
14
#include <dynamic-graph/signal-time-dependent.h>
Nicolas Mansard's avatar
ivigit.  
Nicolas Mansard committed
15
16
17
#include <dynamic-graph/signal.h>
#include <iostream>

Bergé's avatar
   
Bergé committed
18
#include <boost/test/output_test_stream.hpp>
19
20
21
#include <boost/test/unit_test.hpp>
#include <boost/test/unit_test_suite.hpp>
#include <string>
22

23
24
25
26
27
using boost::test_tools::output_test_stream;

typedef dynamicgraph::SignalTimeDependent<double, int> sigDouble_t;
typedef dynamicgraph::SignalTimeDependent<std::string, int> sigString_t;

Bergé's avatar
   
Bergé committed
28
29
using namespace dynamicgraph;
using std::cout;
Nicolas Mansard's avatar
ivigit.  
Nicolas Mansard committed
30

31
32
33
34
35
36
template <class T> class DummyClass {
public:
  std::string proname;
  std::list<sigDouble_t *> inputsig;
  std::list<sigString_t *> inputsigV;

Olivier Stasse's avatar
Olivier Stasse committed
37
38
  explicit DummyClass(const std::string &n)
      : proname(n), res(), call(), timedata() {}
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

  T &fun(T &res, int t) {
    ++call;
    timedata = t;

    BOOST_FOREACH (sigDouble_t *ptr, inputsig)
      ptr->access(timedata);

    BOOST_FOREACH (sigString_t *ptr, inputsigV)
      ptr->access(timedata);

    res = (*this)();
    return res;
  }

  void add(sigDouble_t &sig) { inputsig.push_back(&sig); }
  void add(sigString_t &sig) { inputsigV.push_back(&sig); }

  T operator()();

  T res;
  int call;
  int timedata;
};

template <> double DummyClass<double>::operator()() {
  res = call * timedata;
  return res;
}
template <> std::string DummyClass<std::string>::operator()() {
  std::ostringstream oss;
  oss << call * timedata;
  return oss.str();
}

template <class T> T DummyClass<T>::operator()() { return this->res; }

BOOST_AUTO_TEST_CASE(normal_cst_test) {
Bergé's avatar
Bergé committed
77
  SignalPtr<double, int> sigNotPlug(NULL, "sigNotPlug");
78
  const SignalPtr<double, int> cstSigNotPlug(NULL, "sigNotPlug");
Bergé's avatar
   
Bergé committed
79
80

  try {
Bergé's avatar
Bergé committed
81
    sigNotPlug.getPtr();
Olivier Stasse's avatar
Olivier Stasse committed
82
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
83
    cout << "Error catch" << std::endl;
Bergé's avatar
   
Bergé committed
84
  }
Nicolas Mansard's avatar
ivigit.  
Nicolas Mansard committed
85

86
87
88
89
90
91
  // Test getPtr without plug
  /// This create a ExceptionSignal::NOT_INITIALIZED
  bool res = false;
  try {
    //    Signal<double, int> * r =
    sigNotPlug.getPtr();
92
93
  } catch (const ExceptionSignal &aea) {
    res = (aea.getCode() == ExceptionSignal::NOT_INITIALIZED);
94
95
96
97
98
99
  }
  BOOST_CHECK(res);

  /// Testing const getPtr() interface: no plug case
  try {
    cstSigNotPlug.getPtr();
100
101
  } catch (const ExceptionSignal &aea) {
    res = (aea.getCode() == ExceptionSignal::NOT_INITIALIZED);
102
103
104
105
  }
  BOOST_CHECK(res);

  /// Test needUpdate without plug
Olivier Stasse's avatar
Olivier Stasse committed
106
107
  res = (sigNotPlug.needUpdate(5) == false);
  BOOST_CHECK(res);
108
109
110
111
112
  sigNotPlug.getTime();
  output_test_stream output;
  sigNotPlug.display(output);
  cstSigNotPlug.display(output);

113
114
  /// Testing getAbsatractPtr() interface: no plug
  res = false;
115
116
  try {
    sigNotPlug.getAbstractPtr();
117
118
  } catch (const ExceptionSignal &aea) {
    res = (aea.getCode() == ExceptionSignal::NOT_INITIALIZED);
119
120
121
122
123
124
  }
  BOOST_CHECK(res);

  /// Testing const getAbstractPtr() interface: no plug case
  try {
    cstSigNotPlug.getAbstractPtr();
125
126
  } catch (const ExceptionSignal &aea) {
    res = (aea.getCode() == ExceptionSignal::NOT_INITIALIZED);
127
128
129
  }
  BOOST_CHECK(res);

130
131
132
133
  try {
    sigNotPlug.checkCompatibility();
  } catch (...) {
  }
134
135
136
137
138
  BOOST_CHECK(res);
}

BOOST_AUTO_TEST_CASE(normal_test) {
  Signal<double, int> sig("sig");
139
140
  Signal<int, int> sigint("sig");
  Signal<std::string, int> sigstr("sig_str");
141
142
143
144
  SignalPtr<double, int> sigPtrA(NULL, "sigPtrA"), sigPtrB(NULL, "sigPtrB");
  SignalPtr<double, int> sigPtrAbstract(NULL, "sigPtrAbstract");
  DummyClass<double> pro3("pro3");

Bergé's avatar
Bergé committed
145
  sig.setConstant(1.56);
Bergé's avatar
   
Bergé committed
146
147
148
149
150
  sig.recompute(2);
  std::string name = "sig";
  sig.getClassName(name);
  std::string test = "test";
  try {
Bergé's avatar
Bergé committed
151
    sig.getClassName(test);
Olivier Stasse's avatar
Olivier Stasse committed
152
  } catch (ExceptionSignal &e) {
Bergé's avatar
Bergé committed
153
    e.getExceptionName();
Bergé's avatar
   
Bergé committed
154
  }
155
  BOOST_CHECK(true);
156
157

  sigPtrA.setFunction(boost::bind(&DummyClass<double>::fun, &pro3, _1, _2));
158
  sigPtrA.recompute(3);
159

160
  /// Plugging signal.
161
  SignalBase<int> &sigRef = sig, sigBase("sigBase");
162
163
  SignalBase<int> &sigPtrARef = sigPtrA, &sigPtrBRef = sigPtrB,
                  &sigPtrAbstractRef = sigPtrAbstract;
164
  sigPtrARef.plug(0);
Bergé's avatar
Bergé committed
165
166
  sigPtrARef.plug(&sigRef);
  sigPtrBRef.plug(&sigPtrARef);
167
168
169
170
171
172
173
174
175
  /// Try to plug an incompatible signal.
  /// leave
  bool res = false;
  try {
    sigPtrARef.plug(&sigstr);
  } catch (const ExceptionSignal &aes) {
    res = (aes.getCode() == ExceptionSignal::PLUG_IMPOSSIBLE);
  }
  BOOST_CHECK(res);
Bergé's avatar
   
Bergé committed
176

177
  /// Plug the signal.
Bergé's avatar
Bergé committed
178
  sigPtrAbstractRef.plug(&sigRef);
Bergé's avatar
   
Bergé committed
179
  sigPtrA.getPtr();
180
  BOOST_CHECK(true);
181
182
183
184
185
186
187
188
189
190
191
  try {
    sigPtrARef.checkCompatibility();
  } catch (const ExceptionSignal &aes) {
    /// Should be NOT_INITIALIZED becase the last plug
    /// on sigstr failed.
    res = (aes.getCode() == ExceptionSignal::NOT_INITIALIZED);
  } catch (const std::exception &e) {
    std::cout << "Standard Exception:" << e.what() << std::endl;
  } catch (...) {
    std::cout << "Anything else: " << std::endl;
  }
192
  sigPtrA.needUpdate(5);
193
194
  BOOST_CHECK(true);

195
  int ltime = sigPtrA.getTime();
Bergé's avatar
   
Bergé committed
196
  sigPtrA.getPluged();
197
  sigPtrA(ltime);
198
  BOOST_CHECK(true);
199

Bergé's avatar
   
Bergé committed
200
  sigPtrB.getPtr();
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
  /// Test sigPtrAbstract with a normal plug.
  res = false;
  try {
    sigPtrAbstract.getAbstractPtr();
  } catch (ExceptionSignal &aes) {
    /// Should be NOT_INITIALIZED becase the last plug
    /// on sigstr failed.
    std::cout << "Code: " << aes.getCode() << std::endl;
    res = (aes.getCode() == ExceptionSignal::NOT_INITIALIZED);
  } catch (...) {
    std::cout << "Anything else with sigPtrAbstract.getAbstractPtr()"
              << std::endl;
  }
  BOOST_CHECK(true);

  /// Test the case where the plug ref is zero.
  sigPtrAbstractRef.plug(0);
  BOOST_CHECK(true);
Bergé's avatar
   
Bergé committed
219

Bergé's avatar
Bergé committed
220
  assert(sigRef.isPlugged() != true);
Bergé's avatar
   
Bergé committed
221
  SignalBase<int> *t = sigRef.getPluged();
Bergé's avatar
Bergé committed
222
  // assert(sigPtrA.get()=false);
Bergé's avatar
   
Bergé committed
223

Bergé's avatar
Bergé committed
224
  // TODO Can't check if the constant change
Bergé's avatar
   
Bergé committed
225
  sigPtrA.setConstantDefault(1.2);
Bergé's avatar
Bergé committed
226
  // getconstant
Bergé's avatar
   
Bergé committed
227
  sigPtrA.setConstantDefault();
Bergé's avatar
Bergé committed
228
  // getconstant
Bergé's avatar
   
Bergé committed
229
  sigPtrA.setConstant(3.4);
Bergé's avatar
Bergé committed
230
  // getconstant
Bergé's avatar
   
Bergé committed
231
232
233
  double tab_D[2];
  tab_D[0] = 1.2;
  tab_D[1] = 3.4;
Bergé's avatar
Bergé committed
234
  sigPtrA.setReference(tab_D, NULL);
235
236
237
238
239
240
  sigPtrA.access(5);
  output_test_stream output;
  sigPtrA.display(output);
  sigPtrA.setReferenceNonConstant(tab_D, NULL);
  sigPtrA.access(5);
  sigPtrA.display(output);
241

Bergé's avatar
Bergé committed
242
  // getreference
Bergé's avatar
   
Bergé committed
243
  sigPtrA.operator=(1.2);
Bergé's avatar
Bergé committed
244
  // getconstant
245
  sigPtrA.displayDependencies(output);
246

Bergé's avatar
Bergé committed
247
248
249
250
251
252
253
254
255
256
  cout << t << std::endl;
  cout << "Sig = ";
  sigRef.get(cout);
  cout << std::endl;
  cout << "SigPtrA = ";
  sigPtrARef.get(cout);
  cout << std::endl;
  cout << "SigPtrB = ";
  sigPtrBRef.get(cout);
  cout << std::endl;
257
258

  sigPtrA.unplug();
Nicolas Mansard's avatar
ivigit.  
Nicolas Mansard committed
259
}
260

Olivier Stasse's avatar
Olivier Stasse committed
261
BOOST_AUTO_TEST_CASE(plug_signal_string) {
262
  Signal<std::string, int> outSig("output");
Olivier Stasse's avatar
Olivier Stasse committed
263
  SignalPtr<std::string, int> inSig(NULL, "input");
264

265
266
267
  Signal<dynamicgraph::Vector, int> outSigVec("outputVec");
  SignalPtr<dynamicgraph::Vector, int> inSigVec(NULL, "inputVec");

Olivier Stasse's avatar
Olivier Stasse committed
268
  std::string str("two words");
269
  outSig.setConstant(str);
Olivier Stasse's avatar
Olivier Stasse committed
270
  inSig.plug(&outSig);
271
  inSig.recompute(1);
272
  std::ostringstream os1;
Olivier Stasse's avatar
Olivier Stasse committed
273
274
275
  inSig.get(os1);
  std::string res(os1.str());
  BOOST_CHECK(res == str);
276

277
278
279
280
281
282
283
284
285
286
287
288
  dynamicgraph::Vector aVec;
  aVec.resize(5);
  aVec(0) = 1.0;
  aVec(1) = 2.0;
  aVec(2) = 3.0;
  aVec(3) = 4.0;
  aVec(4) = 5.0;
  outSigVec.setConstant(aVec);
  inSigVec.plug(&outSigVec);
  inSigVec.recompute(1);
  output_test_stream output;
  inSigVec.get(output);
Joseph Mirabel's avatar
Joseph Mirabel committed
289
  BOOST_CHECK(output.is_equal("1 2 3 4 5"));
290

Olivier Stasse's avatar
Olivier Stasse committed
291
  Signal<std::string, int> s("signal");
292
  std::ostringstream os2;
Olivier Stasse's avatar
Olivier Stasse committed
293
294
295
296
  s.setConstant(str);
  os2.clear();
  s.get(os2);
  res = os2.str();
297
  std::cout << "res=" << res << std::endl;
Olivier Stasse's avatar
Olivier Stasse committed
298
  BOOST_CHECK(res == str);
299
}
300
301
302
303
304
305
306
307
308

BOOST_AUTO_TEST_CASE(set_signal_string) {
  Signal<std::string, int> s("signal");
  std::string str("");
  std::ostringstream os;
  os << str;
  std::istringstream value(os.str());
  try {
    s.set(value);
Olivier Stasse's avatar
Olivier Stasse committed
309
  } catch (const std::exception &exc) {
310
311
312
313
    std::cout << exc.what() << std::endl;
    BOOST_CHECK(!"Tentative to set signal to empty string");
  }
}