1
2
3
4
5
6
7
8
9
10
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177 | /**
* @file ModuleCreator.h
* @author <a href="mailto:mellmann@informatik.hu-berlin.de">Heinrich Mellmann</a>
*/
#ifndef _ModuleCreator_h_
#define _ModuleCreator_h_
#include "Module.h"
#include <Tools/DataStructures/Printable.h>
#include <Representations/Debug/Stopwatch.h>
#include <Eigen/Eigen>
/**
* AbstractModuleCreator is an interface.
* It is used to create lists of modules.
* Additionally it provides functionality to enable/disable the module
*/
class AbstractModuleCreator: public Printable
{
public:
virtual std::string moduleClassName() const = 0;
virtual std::string modulePath() const = 0;
virtual void setEnabled(bool value) = 0;
virtual bool isEnabled() const = 0;
virtual void execute() = 0;
virtual Module* getModule() const = 0;
virtual const Stopwatch& getStopwatch() const = 0;
virtual ~AbstractModuleCreator() {}
virtual const RegistrationInterfaceMap& staticProvided() const = 0;
virtual const RegistrationInterfaceMap& staticRequired() const = 0;
};
/**
* ModuleInstance is needed to instantiate the
* BlackBoardInterface of the class V (if it has one)
* with a blackboard.
* We assume, that the class V already inherites from BlackBoardInterface.
* Thereby 'virtual' inheritence is esential (!).
*
* (in fact, what we are doing is to extend the default constructor of the class V
* by providing a pointer to a blackboard instance, i.e., we call another
* constructor of the BlackBoardInterface)
*/
template<class V>
class ModuleInstance: virtual public BlackBoardInterface, virtual public V
{
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
ModuleInstance(BlackBoard& theBlackBoard)<--- Class 'ModuleInstance' has a constructor with 1 argument that is not explicit. [+]Class 'ModuleInstance' has a constructor with 1 argument that is not explicit. Such constructors should in general be explicit for type safety reasons. Using the explicit keyword in the constructor means some mistakes when using the class can be avoided.
: BlackBoardInterface(&theBlackBoard)
{}
};
/**
* ModuleCreator implements the AbstractModuleCreator.
* A module is deleted if it is disabled and created new if it is enabled.
*/
template<class M>
class ModuleCreator : public AbstractModuleCreator
{
private:
BlackBoard& theBlackBoard;
M* theInstance;
// cannot be copied
//ModuleCreator& operator=( const ModuleCreator& ) {}
//
Stopwatch& stopwatch;
public:
ModuleCreator(BlackBoard& theBlackBoard, bool enabled = false)
: theBlackBoard(theBlackBoard),
theInstance(NULL),
//stopwatch(StopwatchManager::getInstance().getStopwatch(IF<M>::getName()))
stopwatch((*(theBlackBoard.template getRepresentation<DataHolder<StopwatchManager> >("StopwatchManager"))).getStopwatch(IF<M>::getName()))
{
setEnabled(enabled);
}
virtual ~ModuleCreator() {
delete theInstance;
}
bool isEnabled() const {
return theInstance != NULL;
}
void setEnabled(bool value)
{
if(value) {
if( theInstance == NULL ) {
theInstance = new ModuleInstance<M>(theBlackBoard);
}
} else {
delete theInstance;
theInstance = NULL;
}
}
void execute()
{
if( theInstance != NULL ) {
stopwatch.start();
theInstance->execute();
stopwatch.stop();
}
}
Module* getModule() const
{
ASSERT(isEnabled());
// ACHTUNG:
// we have to use the unsafe C-cast because some modules may be privatly
// derive from Module and make a type cast inaccesible
return (Module*)(theInstance);<--- C-style pointer casting [+]C-style pointer casting detected. C++ offers four different kinds of casts as replacements: static_cast, const_cast, dynamic_cast and reinterpret_cast. A C-style cast could evaluate to any of those automatically, thus it is considered safer if the programmer explicitly states which kind of cast is expected. See also: https://www.securecoding.cert.org/confluence/display/cplusplus/EXP05-CPP.+Do+not+use+C-style+casts.
}
M* getModuleT() const {
ASSERT(isEnabled());
return theInstance;
}
std::string moduleClassName() const {
return typeid(M).name();
}
virtual std::string modulePath() const {
return IF<M>::getModulePath();
}
const RegistrationInterfaceMap& staticProvided() const {
return IF<M>::getProvide();
}
const RegistrationInterfaceMap& staticRequired() const {
return IF<M>::getRequire();
}
void print(std::ostream& stream) const
{
if(isEnabled()) {
stream << *getModule();
return;
}
stream << "[ " << moduleClassName() << " ]" << std::endl;
RegistrationInterfaceMap::const_iterator i = staticRequired().begin();
for(;i != staticRequired().end(); ++i) {
stream << " > " << i->first << std::endl;
}
i = staticProvided().begin();
for(;i != staticProvided().end(); ++i) {
stream << " < " << i->first << std::endl;
}
}//end print
virtual const Stopwatch& getStopwatch() const
{
return stopwatch;
}
};
#endif //_ModuleCreator_h_
|