GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: include/dynamic-graph/signal.t.cpp Lines: 95 115 82.6 %
Date: 2023-03-15 12:04:10 Branches: 22 58 37.9 %

Line Branch Exec Source
1
// -*- mode: c++ -*-
2
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
3
// JRL, CNRS/AIST.
4
//
5
6
#ifndef DYNAMIC_GRAPH_SIGNAL_T_CPP
7
#define DYNAMIC_GRAPH_SIGNAL_T_CPP
8
#include <dynamic-graph/signal-caster.h>
9
#include <dynamic-graph/signal.h>
10
11
#undef VP_TEMPLATE_DEBUG_MODE
12
#define VP_TEMPLATE_DEBUG_MODE 0
13
#include <dynamic-graph/debug.h>
14
15
#define __SIGNAL_INIT(name, Tcpy, Tref, TrefNC, mutex)                   \
16
  SignalBase<Time>(name), signalType(SIGNAL_TYPE_DEFAULT), Tcopy1(Tcpy), \
17
      Tcopy2(Tcpy), Tcopy(&Tcopy1), Treference(Tref),                    \
18
      TreferenceNonConst(TrefNC), Tfunction(),                           \
19
      keepReference(KEEP_REFERENCE_DEFAULT), providerMutex(mutex)
20
21
namespace dynamicgraph {
22
23
template <class T, class Time>
24
69
Signal<T, Time>::Signal(std::string name)
25

69
    : __SIGNAL_INIT(name, T(), NULL, NULL, NULL) {
26
69
  return;
27
}
28
29
/* ------------------------------------------------------------------------ */
30
31
template <class T, class Time>
32
62
void Signal<T, Time>::set(std::istringstream &stringValue) {
33
62
  (*this) = signal_io<T>::cast(stringValue);
34
}
35
36
template <class T, class Time>
37
34
void Signal<T, Time>::get(std::ostream &os) const {
38
34
  signal_io<T>::disp(this->accessCopy(), os);
39
}
40
41
template <class T, class Time>
42
5009
void Signal<T, Time>::trace(std::ostream &os) const {
43
  try {
44

5009
    signal_io<T>::trace(this->accessCopy(), os);
45
  } catch DG_RETHROW catch (...) {
46
    DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE,
47
                             "TRACE operation not possible with this signal. ",
48
                             "(bad cast while getting value from %s).",
49
                             SignalBase<Time>::getName().c_str());
50
  }
51
5009
}
52
53
/* ------------------------------------------------------------------------ */
54
55
template <class T, class Time>
56
47
const T &Signal<T, Time>::setTcopy(const T &t) {
57
47
  if (Tcopy == &Tcopy1) {
58
31
    Tcopy2 = t;
59
31
    copyInit = true;
60
31
    Tcopy = &Tcopy2;
61
31
    return Tcopy2;
62
  } else {
63
16
    Tcopy1 = t;
64
16
    copyInit = true;
65
16
    Tcopy = &Tcopy1;
66
16
    return Tcopy1;
67
  }
68
}
69
70
template <class T, class Time>
71
4040
T &Signal<T, Time>::getTwork() {
72
4040
  if (Tcopy == &Tcopy1)
73
2026
    return Tcopy2;
74
  else
75
2014
    return Tcopy1;
76
}
77
78
template <class T, class Time>
79
const T &Signal<T, Time>::getTwork() const {
80
  if (Tcopy == &Tcopy1)
81
    return Tcopy2;
82
  else
83
    return Tcopy1;
84
}
85
86
template <class T, class Time>
87
4040
const T &Signal<T, Time>::switchTcopy() {
88
4040
  if (Tcopy == &Tcopy1) {
89
2026
    Tcopy = &Tcopy2;
90
2026
    return Tcopy2;
91
  } else {
92
2014
    Tcopy = &Tcopy1;
93
2014
    return Tcopy1;
94
  }
95
}
96
97
template <class T, class Time>
98
43
void Signal<T, Time>::setConstant(const T &t) {
99
43
  signalType = CONSTANT;
100
43
  setTcopy(t);
101
43
  setReady();
102
43
}
103
104
template <class T, class Time>
105
2
void Signal<T, Time>::setReference(const T *t, Mutex *mutexref) {
106
2
  signalType = REFERENCE;
107
2
  Treference = t;
108
2
  providerMutex = mutexref;
109
2
  copyInit = false;
110
2
  setReady();
111
}
112
113
template <class T, class Time>
114
2
void Signal<T, Time>::setReferenceNonConstant(T *t, Mutex *mutexref) {
115
2
  signalType = REFERENCE_NON_CONST;
116
2
  Treference = t;
117
2
  TreferenceNonConst = t;
118
2
  providerMutex = mutexref;
119
2
  copyInit = false;
120
2
  setReady();
121
}
122
123
template <class T, class Time>
124
27
void Signal<T, Time>::setFunction(boost::function2<T &, T &, Time> t,
125
                                  Mutex *mutexref) {
126
27
  signalType = FUNCTION;
127
27
  Tfunction = t;
128
27
  providerMutex = mutexref;
129
27
  copyInit = false;
130
27
  setReady();
131
27
}
132
133
template <class T, class Time>
134
11083
const T &Signal<T, Time>::accessCopy() const {
135
11083
  return *Tcopy;
136
}
137
138
template <class T, class Time>
139
10052
const T &Signal<T, Time>::access(const Time &t) {
140
10052
  switch (signalType) {
141
4
    case REFERENCE:
142
    case REFERENCE_NON_CONST: {
143
4
      if (NULL == providerMutex) {
144
4
        copyInit = true;
145
4
        signalTime = t;
146
4
        return setTcopy(*Treference);
147
      } else {
148
        try {
149
#ifdef HAVE_LIBBOOST_THREAD
150
          boost::try_mutex::scoped_try_lock lock(*providerMutex);
151
#endif
152
          copyInit = true;
153
          signalTime = t;
154
          return setTcopy(*Treference);
155
        } catch (const MutexError &) {
156
          return accessCopy();
157
        }
158
      }
159
160
      break;
161
    }
162
163
4040
    case FUNCTION: {
164
4040
      if (NULL == providerMutex) {
165
4040
        signalTime = t;
166
4040
        Tfunction(getTwork(), t);
167
4040
        copyInit = true;
168
4040
        return switchTcopy();
169
      } else {
170
        try {
171
#ifdef HAVE_LIBBOOST_THREAD
172
          boost::try_mutex::scoped_try_lock lock(*providerMutex);
173
#endif
174
          signalTime = t;
175
          Tfunction(getTwork(), t);
176
          copyInit = true;
177
          return switchTcopy();
178
        } catch (const MutexError &) {
179
          return accessCopy();
180
        }
181
      }
182
      break;
183
    }
184
6008
    case CONSTANT:
185
    default:
186
6008
      if (this->getReady()) {
187
9
        setReady(false);
188
9
        this->setTime(t);
189
      }
190
6008
      return accessCopy();
191
  };
192
}
193
194
template <class T, class Time>
195
24
Signal<T, Time> &Signal<T, Time>::operator=(const T &t) {
196

24
  if (keepReference && (REFERENCE_NON_CONST == signalType) &&
197
      (NULL != TreferenceNonConst)) {
198
    if (NULL == providerMutex) {
199
      setTcopy(t);
200
      (*TreferenceNonConst) = t;
201
    } else {
202
      try {
203
#ifdef HAVE_LIBBOOST_THREAD
204
        boost::try_mutex::scoped_try_lock lock(*providerMutex);
205
#endif
206
        setTcopy(t);
207
        (*TreferenceNonConst) = t;
208
      } catch (const MutexError &) { /* TODO ERROR */
209
      }
210
    }
211
  } else {
212
24
    setConstant(t);
213
  }
214
24
  return *this;
215
}
216
217
template <class T, class Time>
218
89
std::ostream &Signal<T, Time>::display(std::ostream &os) const {
219
89
  os << "Sig:" << this->name << " (Type ";
220

89
  switch (this->signalType) {
221
6
    case Signal<T, Time>::CONSTANT:
222
6
      os << "Cst";
223
6
      break;
224
1
    case Signal<T, Time>::REFERENCE:
225
1
      os << "Ref";
226
1
      break;
227
1
    case Signal<T, Time>::REFERENCE_NON_CONST:
228
1
      os << "RefNonCst";
229
1
      break;
230
81
    case Signal<T, Time>::FUNCTION:
231
81
      os << "Fun";
232
81
      break;
233
  }
234
89
  return os << ")";
235
}
236
237
}  // end of namespace dynamicgraph.
238
239
#undef __SIGNAL_INIT
240
#endif  //! DYNAMIC_GRAPH_SIGNAL_T_CPP