signal-time-dependent.h 4.47 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
40
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
41
42
43
44
45
46
47
48
49
50
51
  virtual ~SignalTimeDependent() {}

  inline const T& operator()(const Time& t1) { return access(t1); }
  const T& access(const Time& t1);

  virtual void addDependency(const SignalBase<Time>& signal);
  virtual void removeDependency(const SignalBase<Time>& signal);
  virtual void clearDependencies();

  std::ostream& writeGraph(std::ostream& os) const { return os; }

52
53
54
55
56
57
58
  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
59
60
61
62
63
64
65
66
67

  virtual bool needUpdate(const Time& t) const;
  virtual void setPeriodTime(const Time& p);
  virtual Time getPeriodTime() const;
};

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

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

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

template <class T, class Time>
78
79
80
81
82
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
83
84
85
86
  this->setFunction(t);
}

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

  /*       std::cout << "Time before: "<< signalTime << " -- "   */
93
94
95
96
97
98
99
100
101
102
103
104
  /*            << t1<< "  -> Up: "<<up <<std::endl ;   */
  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
105
106
107
}

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

template <class T, class Time>
115
116
117
void SignalTimeDependent<T, Time>::
removeDependency(const SignalBase<Time>& signal)
{
Bergé's avatar
Bergé committed
118
119
120
121
  TimeDependency<Time>::removeDependency(signal);
}

template <class T, class Time>
122
123
124
void SignalTimeDependent<T, Time>::
clearDependencies()
{
Bergé's avatar
Bergé committed
125
126
127
128
  TimeDependency<Time>::clearDependency();
}

template <class T, class Time>
129
130
131
bool SignalTimeDependent<T, Time>::
needUpdate(const Time& t) const
{
Bergé's avatar
Bergé committed
132
133
134
135
  return TimeDependency<Time>::needUpdate(t);
}

template <class T, class Time>
136
137
138
void SignalTimeDependent<T, Time>::
setPeriodTime(const Time& p)
{
Bergé's avatar
Bergé committed
139
140
141
  TimeDependency<Time>::setPeriodTime(p);
}
template <class T, class Time>
142
143
144
Time SignalTimeDependent<T, Time>::
getPeriodTime() const
{
Bergé's avatar
Bergé committed
145
146
147
148
149
150
  return TimeDependency<Time>::getPeriodTime();
}

}  // end of namespace dynamicgraph

#endif  //! DYNAMIC_GRAPH_SIGNAL_TIME_DEPENDENT_H