1 |
|
|
/* |
2 |
|
|
* Copyright 2010, |
3 |
|
|
* François Bleibel, |
4 |
|
|
* Olivier Stasse, |
5 |
|
|
* |
6 |
|
|
* CNRS/AIST |
7 |
|
|
* |
8 |
|
|
*/ |
9 |
|
|
|
10 |
|
|
#ifndef __SIGNAL_HH |
11 |
|
|
#define __SIGNAL_HH |
12 |
|
|
|
13 |
|
|
#include <dynamic-graph/exception-signal.h> |
14 |
|
|
#include <dynamic-graph/signal-base.h> |
15 |
|
|
|
16 |
|
|
#include <boost/bind.hpp> |
17 |
|
|
#include <boost/function.hpp> |
18 |
|
|
#include <string> |
19 |
|
|
|
20 |
|
|
#ifdef HAVE_LIBBOOST_THREAD |
21 |
|
|
#include <boost/thread.hpp> |
22 |
|
|
#endif |
23 |
|
|
|
24 |
|
|
namespace dynamicgraph { |
25 |
|
|
|
26 |
|
|
/*! \ingroup dgraph |
27 |
|
|
\brief Signals link I/O ports of entities. They can be |
28 |
|
|
constant-valued signals, or copy the value of a heap variable, |
29 |
|
|
or evaluated as a function. |
30 |
|
|
See SignalPtr and SignalTimeDependent for other types of signals, |
31 |
|
|
and SignalArray for a way of grouping them. |
32 |
|
|
|
33 |
|
|
There are several ways to specify the value output by a signal: |
34 |
|
|
\li using the function setConstant(T) to set the value of the signal to T; |
35 |
|
|
\li using the function setReference(mutex, T*) to set the value |
36 |
|
|
from a pointer, whose access is restricted by a mutex; |
37 |
|
|
\li using the function setFunction(boost::function2) that will be called |
38 |
|
|
when the signal's value is accessed. |
39 |
|
|
*/ |
40 |
|
|
template <class T, class Time> |
41 |
|
|
class Signal : public SignalBase<Time> { |
42 |
|
|
protected: |
43 |
|
|
enum SignalType { CONSTANT, REFERENCE, REFERENCE_NON_CONST, FUNCTION }; |
44 |
|
|
static const SignalType SIGNAL_TYPE_DEFAULT = CONSTANT; |
45 |
|
|
|
46 |
|
|
SignalType signalType; |
47 |
|
|
T Tcopy1, Tcopy2; |
48 |
|
|
T *Tcopy; |
49 |
|
|
bool copyInit; |
50 |
|
|
|
51 |
|
|
const T *Treference; |
52 |
|
|
T *TreferenceNonConst; |
53 |
|
|
boost::function2<T &, T &, Time> Tfunction; |
54 |
|
|
|
55 |
|
|
bool keepReference; |
56 |
|
|
const static bool KEEP_REFERENCE_DEFAULT = false; |
57 |
|
|
|
58 |
|
|
public: |
59 |
|
|
#ifdef HAVE_LIBBOOST_THREAD |
60 |
|
|
typedef boost::try_mutex Mutex; |
61 |
|
|
typedef boost::lock_error MutexError; |
62 |
|
|
#else |
63 |
|
|
typedef int *Mutex; |
64 |
|
|
typedef int *MutexError; |
65 |
|
|
#endif |
66 |
|
|
|
67 |
|
|
protected: |
68 |
|
|
Mutex *providerMutex; |
69 |
|
|
using SignalBase<Time>::signalTime; |
70 |
|
|
|
71 |
|
|
public: |
72 |
|
|
using SignalBase<Time>::setReady; |
73 |
|
|
|
74 |
|
|
public: |
75 |
|
|
/* --- Constructor/destrusctor --- */ |
76 |
|
|
Signal(std::string name); |
77 |
|
54 |
virtual ~Signal() {} |
78 |
|
|
|
79 |
|
|
/* --- Generic In/Out function --- */ |
80 |
|
|
virtual void get(std::ostream &value) const; |
81 |
|
|
virtual void set(std::istringstream &value); |
82 |
|
|
virtual void trace(std::ostream &os) const; |
83 |
|
|
|
84 |
|
|
/* --- Generic Set function --- */ |
85 |
|
|
virtual void setConstant(const T &t); |
86 |
|
|
virtual void setReference(const T *t, Mutex *mutexref = NULL); |
87 |
|
|
virtual void setReferenceNonConstant(T *t, Mutex *mutexref = NULL); |
88 |
|
|
virtual void setFunction(boost::function2<T &, T &, Time> t, |
89 |
|
|
Mutex *mutexref = NULL); |
90 |
|
|
|
91 |
|
|
inline bool getKeepReference() { return keepReference; } |
92 |
|
|
inline void setKeepReference(const bool &b) { keepReference = b; } |
93 |
|
|
|
94 |
|
|
/* --- Signal computation --- */ |
95 |
|
|
virtual const T &access(const Time &t); |
96 |
|
4008 |
virtual inline void recompute(const Time &t) { access(t); } |
97 |
|
|
virtual const T &accessCopy() const; |
98 |
|
|
|
99 |
|
|
virtual std::ostream &display(std::ostream &os) const; |
100 |
|
|
|
101 |
|
|
/* --- Operators --- */ |
102 |
|
4000 |
virtual inline const T &operator()(const Time &t) { return access(t); } |
103 |
|
|
virtual Signal<T, Time> &operator=(const T &t); |
104 |
|
|
inline operator const T &() const { return accessCopy(); } |
105 |
|
4 |
virtual void getClassName(std::string &aClassName) const { |
106 |
|
4 |
aClassName = typeid(this).name(); |
107 |
|
|
} |
108 |
|
|
|
109 |
|
|
public: |
110 |
|
|
/// checkCompatibility is used to get the object contained in the |
111 |
|
|
/// signal. This used to verify if a dynamic cast is possible or not. |
112 |
|
8 |
virtual void checkCompatibility() { throw Tcopy; } |
113 |
|
|
|
114 |
|
|
private: |
115 |
|
|
const T &setTcopy(const T &t); |
116 |
|
|
T &getTwork(); |
117 |
|
|
const T &getTwork() const; |
118 |
|
|
const T &switchTcopy(); |
119 |
|
|
}; |
120 |
|
|
|
121 |
|
|
} // end of namespace dynamicgraph |
122 |
|
|
|
123 |
|
|
#include <dynamic-graph/signal.t.cpp> |
124 |
|
|
|
125 |
|
|
#endif // #ifndef __SIGNAL_HH |
126 |
|
|
|
127 |
|
|
/* |
128 |
|
|
* Local variables: |
129 |
|
|
* c-basic-offset: 4 |
130 |
|
|
* End: |
131 |
|
|
*/ |