GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: include/dynamic-graph/signal-time-dependent.h Lines: 36 36 100.0 %
Date: 2023-03-15 12:04:10 Branches: 12 22 54.5 %

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_TIME_DEPENDENT_H
7
#define DYNAMIC_GRAPH_SIGNAL_TIME_DEPENDENT_H
8
#include <dynamic-graph/signal.h>
9
#include <dynamic-graph/time-dependency.h>
10
11
namespace dynamicgraph {
12
/*!  \brief A type of signal that enforces a time dependency between other
13
  signals,
14
  making sure its inputs are up to date on access, using a incrementing time
15
  tick as reference.
16
17
  It works this way. For a given SignalTimeDependent S,
18
  - the user manually adds dependent signals through the use of the
19
  SignalTimeDependent::addDependency function.
20
  - On access (calling the signal S SignalTimeDependent::operator()(const Time&)
21
  or SignalTimeDependent::access(const Time&) function), if the dependent
22
  signals are not up-to-date, i.e. if their [last update] time is less than the
23
  current time, their value will be SignalTimeDependent::access ()'ed to bring
24
  them up-to-date.
25
26
  Thus, the value of dependent signals can be accessed \b quickly and
27
  \b repeatedly through the Signal::accessCopy () function.
28
29
  An example:
30
  \code
31
  class MyEntity : public Entity {
32
  public:
33
  // Some signal dependencies
34
  SignalPtr<T,int> dep1, dep2;
35
  SignalTimeDependent<T,int> signal;
36
37
  MyEntity (const std::string& name)
38
    : Entity (name)
39
    , signal (
40
        // Set the function that computes the signal value
41
        boost::bind (&Entity::computeSignal, this, _1, _2),
42
        // Declare the dependencies
43
        dep1 << dep2,
44
        "signalname")
45
  {}
46
47
   T& computeSignal (T& res, int time)
48
   {
49
     // The accesses below update the signal if necessary.
50
     dep1(time);
51
     dep1.access(time);
52
     dep1.recompute(time);
53
     // If dep1 and dep2 are already up-to-date, for a faster access, use
54
     dep1.accessCopy();
55
     dep2.accessCopy();
56
57
     // Compute res
58
     return res;
59
   }
60
  \endcode
61
*/
62
template <class T, class Time>
63
class SignalTimeDependent : public virtual Signal<T, Time>,
64
                            public TimeDependency<Time> {
65
  // TimeDependency<Time> timeDependency;
66
67
 public:
68
  SignalTimeDependent(std::string name = "");
69
  SignalTimeDependent(const SignalArray_const<Time> &arr,
70
                      std::string name = "");
71
  SignalTimeDependent(boost::function2<T &, T &, Time> t,
72
                      const SignalArray_const<Time> &sig,
73
                      std::string name = "");
74
75
16
  virtual ~SignalTimeDependent() {}
76
77
2
  inline const T &operator()(const Time &t1) { return access(t1); }
78
  const T &access(const Time &t1);
79
80
  virtual void addDependency(const SignalBase<Time> &signal);
81
  virtual void removeDependency(const SignalBase<Time> &signal);
82
  virtual void clearDependencies();
83
84
3
  std::ostream &writeGraph(std::ostream &os) const { return os; }
85
86
160
  std::ostream &displayDependencies(std::ostream &os, const int depth = -1,
87
                                    std::string space = "",
88
                                    std::string next1 = "",
89
                                    std::string next2 = "") const {
90

320
    return TimeDependency<Time>::displayDependencies(os, depth, space, next1,
91
320
                                                     next2);
92
  }
93
94
  virtual bool needUpdate(const Time &t) const;
95
  virtual void setPeriodTime(const Time &p);
96
  virtual Time getPeriodTime() const;
97
};
98
99
/* -------------------------------------------- */
100
101
template <class T, class Time>
102
6
SignalTimeDependent<T, Time>::SignalTimeDependent(std::string name)
103
6
    : Signal<T, Time>(name), TimeDependency<Time>(this) {}
104
105
template <class T, class Time>
106
6
SignalTimeDependent<T, Time>::SignalTimeDependent(
107
    const SignalArray_const<Time> &arr, std::string name)
108

6
    : Signal<T, Time>(name), TimeDependency<Time>(this, arr) {}
109
110
template <class T, class Time>
111
14
SignalTimeDependent<T, Time>::SignalTimeDependent(
112
    boost::function2<T &, T &, Time> t, const SignalArray_const<Time> &sig,
113
    std::string name)
114

14
    : Signal<T, Time>(name), TimeDependency<Time>(this, sig) {
115

14
  this->setFunction(t);
116
14
}
117
118
template <class T, class Time>
119
4068
const T &SignalTimeDependent<T, Time>::access(const Time &t1) {
120
4068
  const bool up = TimeDependency<Time>::needUpdate(t1);
121
  // SignalBase<Time>::setReady(false);
122
123
  /*       std::cout << "Time before: "<< signalTime << " -- "   */
124
  /*            << t1<< "  -> Up: "<<up <<std::endl ;   */
125
4068
  if (up) {
126
4038
    TimeDependency<Time>::lastAskForUpdate = false;
127
4038
    const T &Tres = Signal<T, Time>::access(t1);
128
4038
    SignalBase<Time>::setReady(false);
129
4038
    return Tres;
130
  } else {
131
30
    return Signal<T, Time>::accessCopy();
132
  }
133
}
134
135
template <class T, class Time>
136
4
void SignalTimeDependent<T, Time>::addDependency(
137
    const SignalBase<Time> &signal) {
138
4
  TimeDependency<Time>::addDependency(signal);
139
4
}
140
141
template <class T, class Time>
142
2
void SignalTimeDependent<T, Time>::removeDependency(
143
    const SignalBase<Time> &signal) {
144
2
  TimeDependency<Time>::removeDependency(signal);
145
}
146
147
template <class T, class Time>
148
2
void SignalTimeDependent<T, Time>::clearDependencies() {
149
2
  TimeDependency<Time>::clearDependency();
150
2
}
151
152
template <class T, class Time>
153
26
bool SignalTimeDependent<T, Time>::needUpdate(const Time &t) const {
154
26
  return TimeDependency<Time>::needUpdate(t);
155
}
156
157
template <class T, class Time>
158
2
void SignalTimeDependent<T, Time>::setPeriodTime(const Time &p) {
159
2
  TimeDependency<Time>::setPeriodTime(p);
160
}
161
template <class T, class Time>
162
1
Time SignalTimeDependent<T, Time>::getPeriodTime() const {
163
1
  return TimeDependency<Time>::getPeriodTime();
164
}
165
166
}  // end of namespace dynamicgraph
167
168
#endif  //! DYNAMIC_GRAPH_SIGNAL_TIME_DEPENDENT_H