signal-time-dependent.h 4.56 KB
Newer Older
Thomas Moulard's avatar
Thomas Moulard committed
1
2
3
4
5
6
// -*- mode: c++ -*-
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
// JRL, CNRS/AIST.
//

#ifndef DYNAMIC_GRAPH_SIGNAL_TIME_DEPENDENT_H
Bergé's avatar
Bergé committed
7
8
9
10
#define DYNAMIC_GRAPH_SIGNAL_TIME_DEPENDENT_H
#include <dynamic-graph/signal.h>
#include <dynamic-graph/time-dependency.h>

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
namespace dynamicgraph {
/*!  \brief A type of signal that enforces a time dependency between other
  signals,
  making sure its inputs are up to date on access, using a incrementing time
  tick as reference.
  It works this way: for a given SignalTimeDependent S, the user manually
  adds dependent signals through the
  use of the addDependency function. On access (calling the signal S
  operator  () or access(Time) function),
  if the dependent signals are not up-to-date, i.e. if their [last update]
  time is less than the
  current time, their value will be access ()'ed to bring them up-to-date.
  Thus, the value of dependent
  signals can be accessed \b quickly and \b repeatedly through the
  accessCopy () function.
*/
template <class T, class Time>
class SignalTimeDependent : public virtual Signal<T, Time>,
                            public TimeDependency<Time> {
  // TimeDependency<Time> timeDependency;

public:
  SignalTimeDependent(std::string name = "");
  SignalTimeDependent(const SignalArray_const<Time> &arr,
                      std::string name = "");
  SignalTimeDependent(boost::function2<T &, T &, Time> t,
                      const SignalArray_const<Time> &sig,
                      std::string name = "");

Bergé's avatar
Bergé committed
40
41
  virtual ~SignalTimeDependent() {}

42
43
  inline const T &operator()(const Time &t1) { return access(t1); }
  const T &access(const Time &t1);
Bergé's avatar
Bergé committed
44

45
46
  virtual void addDependency(const SignalBase<Time> &signal);
  virtual void removeDependency(const SignalBase<Time> &signal);
Bergé's avatar
Bergé committed
47
48
  virtual void clearDependencies();

49
  std::ostream &writeGraph(std::ostream &os) const { return os; }
Bergé's avatar
Bergé committed
50

51
52
53
54
55
56
57
  std::ostream &displayDependencies(std::ostream &os, const int depth = -1,
                                    std::string space = "",
                                    std::string next1 = "",
                                    std::string next2 = "") const {
    return TimeDependency<Time>::displayDependencies(os, depth, space, next1,
                                                     next2);
  }
Bergé's avatar
Bergé committed
58

59
60
  virtual bool needUpdate(const Time &t) const;
  virtual void setPeriodTime(const Time &p);
Bergé's avatar
Bergé committed
61
62
63
64
65
66
  virtual Time getPeriodTime() const;
};

/* -------------------------------------------- */

template <class T, class Time>
67
SignalTimeDependent<T, Time>::SignalTimeDependent(std::string name)
Bergé's avatar
Bergé committed
68
69
70
    : Signal<T, Time>(name), TimeDependency<Time>(this) {}

template <class T, class Time>
71
72
SignalTimeDependent<T, Time>::SignalTimeDependent(
    const SignalArray_const<Time> &arr, std::string name)
Bergé's avatar
Bergé committed
73
74
75
    : Signal<T, Time>(name), TimeDependency<Time>(this, arr) {}

template <class T, class Time>
76
77
78
79
SignalTimeDependent<T, Time>::SignalTimeDependent(
    boost::function2<T &, T &, Time> t, const SignalArray_const<Time> &sig,
    std::string name)
    : Signal<T, Time>(name), TimeDependency<Time>(this, sig) {
Bergé's avatar
Bergé committed
80
81
82
83
  this->setFunction(t);
}

template <class T, class Time>
84
const T &SignalTimeDependent<T, Time>::access(const Time &t1) {
Bergé's avatar
Bergé committed
85
86
87
88
  const bool up = TimeDependency<Time>::needUpdate(t1);
  // SignalBase<Time>::setReady(false);

  /*       std::cout << "Time before: "<< signalTime << " -- "   */
89
  /*            << t1<< "  -> Up: "<<up <<std::endl ;   */
90
91
92
93
94
95
96
97
  if (up) {
    TimeDependency<Time>::lastAskForUpdate = false;
    const T &Tres = Signal<T, Time>::access(t1);
    SignalBase<Time>::setReady(false);
    return Tres;
  } else {
    return Signal<T, Time>::accessCopy();
  }
Bergé's avatar
Bergé committed
98
99
100
}

template <class T, class Time>
101
102
void SignalTimeDependent<T, Time>::addDependency(
    const SignalBase<Time> &signal) {
Bergé's avatar
Bergé committed
103
104
105
106
  TimeDependency<Time>::addDependency(signal);
}

template <class T, class Time>
107
108
void SignalTimeDependent<T, Time>::removeDependency(
    const SignalBase<Time> &signal) {
Bergé's avatar
Bergé committed
109
110
111
112
  TimeDependency<Time>::removeDependency(signal);
}

template <class T, class Time>
113
void SignalTimeDependent<T, Time>::clearDependencies() {
Bergé's avatar
Bergé committed
114
115
116
117
  TimeDependency<Time>::clearDependency();
}

template <class T, class Time>
118
bool SignalTimeDependent<T, Time>::needUpdate(const Time &t) const {
Bergé's avatar
Bergé committed
119
120
121
122
  return TimeDependency<Time>::needUpdate(t);
}

template <class T, class Time>
123
void SignalTimeDependent<T, Time>::setPeriodTime(const Time &p) {
Bergé's avatar
Bergé committed
124
125
126
  TimeDependency<Time>::setPeriodTime(p);
}
template <class T, class Time>
127
Time SignalTimeDependent<T, Time>::getPeriodTime() const {
Bergé's avatar
Bergé committed
128
129
130
  return TimeDependency<Time>::getPeriodTime();
}

131
} // end of namespace dynamicgraph
Bergé's avatar
Bergé committed
132

133
#endif //! DYNAMIC_GRAPH_SIGNAL_TIME_DEPENDENT_H