GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/** |
||
2 |
* @file periodic-call.cpp |
||
3 |
* @author Maximilien Naveau (maximilien.naveau@gmail.com) |
||
4 |
* @license License BSD-3-Clause |
||
5 |
* @copyright Copyright (c) 2019, New York University and Max Planck Gesellschaft. |
||
6 |
* @date 2019-05-22 |
||
7 |
*/ |
||
8 |
|||
9 |
#include <algorithm> |
||
10 |
#include <dynamic-graph/pool.h> |
||
11 |
#include <dynamic-graph/python/interpreter.hh> |
||
12 |
#include <dynamic-graph/all-commands.h> |
||
13 |
#include <dynamic-graph/exception-factory.h> |
||
14 |
#include <dynamic-graph/debug.h> |
||
15 |
|||
16 |
#include <dynamic_graph_manager/exception/exception-tools.hh> |
||
17 |
#include <dynamic_graph_manager/periodic-call.hh> |
||
18 |
|||
19 |
using namespace std; |
||
20 |
using namespace dynamic_graph; |
||
21 |
namespace dg = dynamicgraph; |
||
22 |
|||
23 |
40 |
PeriodicCall::PeriodicCall( void ): |
|
24 |
signal_map_(), |
||
25 |
cmd_list_(), |
||
26 |
inner_time_( 0 ), |
||
27 |
40 |
py_interpreter_( nullptr ) |
|
28 |
{ |
||
29 |
40 |
} |
|
30 |
|||
31 |
9 |
void PeriodicCall::addSignal( const std::string &name, |
|
32 |
dg::SignalBase<int>& sig ) |
||
33 |
{ |
||
34 |
9 |
signal_map_[ name ] = SignalToCall(&sig); |
|
35 |
9 |
return ; |
|
36 |
} |
||
37 |
|||
38 |
9 |
void PeriodicCall::addSignal( const std::string& sigpath ) |
|
39 |
{ |
||
40 |
✓✗ | 18 |
std::istringstream sig_iss( sigpath ); |
41 |
dg::SignalBase<int>& signal = |
||
42 |
✓✗✓✗ |
9 |
::dg::PoolStorage::getInstance()->getSignal( sig_iss ); |
43 |
✓✗ | 9 |
addSignal( sigpath,signal ); |
44 |
18 |
return ; |
|
45 |
} |
||
46 |
|||
47 |
2 |
void PeriodicCall::addDownsampledSignal( |
|
48 |
const std::string &name, |
||
49 |
dg::SignalBase<int>& sig, |
||
50 |
const unsigned int& downsamplingFactor ) |
||
51 |
{ |
||
52 |
2 |
signal_map_[ name ] = SignalToCall(&sig,downsamplingFactor); |
|
53 |
2 |
return ; |
|
54 |
} |
||
55 |
|||
56 |
2 |
void PeriodicCall::addDownsampledSignal( |
|
57 |
const std::string& sigpath, |
||
58 |
const unsigned int& downsamplingFactor ) |
||
59 |
{ |
||
60 |
✓✗ | 4 |
std::istringstream sig_iss( sigpath ); |
61 |
dg::SignalBase<int>& signal = |
||
62 |
✓✗✓✗ |
2 |
::dg::PoolStorage::getInstance()->getSignal( sig_iss ); |
63 |
✓✗ | 2 |
addDownsampledSignal( sigpath,signal,downsamplingFactor ); |
64 |
4 |
return ; |
|
65 |
} |
||
66 |
|||
67 |
void PeriodicCall:: |
||
68 |
rmSignal( const std::string &name ) |
||
69 |
{ |
||
70 |
signal_map_.erase( name ); |
||
71 |
return ; |
||
72 |
} |
||
73 |
|||
74 |
void PeriodicCall:: |
||
75 |
addCmd( const std::string& cmdLine ) |
||
76 |
{ |
||
77 |
cmd_list_.push_back( cmdLine ); |
||
78 |
return ; |
||
79 |
} |
||
80 |
|||
81 |
void PeriodicCall:: |
||
82 |
rmCmd( const std::string& args ) |
||
83 |
{ |
||
84 |
CmdListType::iterator iter = std::find( cmd_list_.begin(),cmd_list_.end(),args); |
||
85 |
if( cmd_list_.end()!=iter ) { |
||
86 |
cmd_list_.erase( iter ); |
||
87 |
} |
||
88 |
} |
||
89 |
|||
90 |
4 |
void PeriodicCall:: |
|
91 |
runSignals( const int& t ) |
||
92 |
{ |
||
93 |
✓✓ | 18 |
for( SignalMapType::iterator iter = signal_map_.begin(); |
94 |
12 |
signal_map_.end()!=iter; ++iter ) |
|
95 |
{ |
||
96 |
✓✗ | 2 |
if( static_cast<unsigned int>(t) % iter->second.down_sampling_factor_ == 0) |
97 |
{ |
||
98 |
✓✗ | 2 |
(*iter).second.signal_->recompute( t ); |
99 |
} |
||
100 |
} |
||
101 |
4 |
return ; |
|
102 |
} |
||
103 |
|||
104 |
4 |
void PeriodicCall:: |
|
105 |
runCmds( void ) |
||
106 |
{ |
||
107 |
✓✗ | 4 |
if( nullptr == py_interpreter_ ) |
108 |
{ |
||
109 |
ExceptionTools( ExceptionTools::PY_SHELL_PTR, |
||
110 |
✓✗✓✗ |
4 |
"Python interpreter not set." ); |
111 |
} |
||
112 |
|||
113 |
8 |
std::string result, out, err; |
|
114 |
|||
115 |
✗✓ | 12 |
for( CmdListType::const_iterator iter = cmd_list_.begin(); |
116 |
8 |
cmd_list_.end()!=iter; ++iter ) |
|
117 |
{ |
||
118 |
py_interpreter_->python( *iter, result, out, err ); |
||
119 |
} |
||
120 |
8 |
return ; |
|
121 |
} |
||
122 |
|||
123 |
4 |
void PeriodicCall:: |
|
124 |
run( const int & t ) |
||
125 |
{ |
||
126 |
4 |
runSignals( t ); runCmds(); |
|
127 |
4 |
return ; |
|
128 |
} |
||
129 |
|||
130 |
/* --------------------------------------------------------------------- */ |
||
131 |
/* --------------------------------------------------------------------- */ |
||
132 |
/* --------------------------------------------------------------------- */ |
||
133 |
|||
134 |
|||
135 |
void PeriodicCall:: |
||
136 |
display( std::ostream& os ) const |
||
137 |
{ |
||
138 |
os <<" (t=" << inner_time_ << ")" <<endl; |
||
139 |
|||
140 |
os<<" -> SIGNALS:"<<endl; |
||
141 |
for( SignalMapType::const_iterator iter = signal_map_.begin(); |
||
142 |
signal_map_.end()!=iter; ++iter ) |
||
143 |
{ |
||
144 |
os << " - " << (*iter).first << endl; |
||
145 |
} |
||
146 |
|||
147 |
os<<" -> CMDS:"<<endl; |
||
148 |
for( CmdListType::const_iterator iter = cmd_list_.begin(); |
||
149 |
cmd_list_.end()!=iter; ++iter ) |
||
150 |
{ |
||
151 |
os << " - " << (*iter) << endl; |
||
152 |
} |
||
153 |
|||
154 |
} |
||
155 |
|||
156 |
static std::string readLineStr( istringstream& args ) |
||
157 |
{ |
||
158 |
stringbuf* pbuf=args.rdbuf(); |
||
159 |
const std::streamsize size = pbuf->in_avail(); |
||
160 |
char * buffer = new char[ size+1 ]; |
||
161 |
pbuf->sgetn( buffer,size ); |
||
162 |
|||
163 |
buffer[size]='\0'; |
||
164 |
std::string res( buffer ); |
||
165 |
delete [] buffer; |
||
166 |
return res; |
||
167 |
} |
||
168 |
|||
169 |
bool PeriodicCall:: |
||
170 |
commandLine( const std::string& cmdLine, |
||
171 |
std::istringstream& cmdArgs, |
||
172 |
std::ostream& os ) |
||
173 |
{ |
||
174 |
if( cmdLine == "help" ) |
||
175 |
{ |
||
176 |
os << "PeriodicCall:"<<endl |
||
177 |
<<" - addSignal/rmSignal <int> " <<endl |
||
178 |
<<" - addCmd/rmCmd " <<endl |
||
179 |
<<" - runSignal/runCmd " <<endl |
||
180 |
<<" - run" <<endl; |
||
181 |
} |
||
182 |
else if( cmdLine == "addSignal" ) |
||
183 |
{ |
||
184 |
std::string sigpath; cmdArgs >> std::skipws >> sigpath; |
||
185 |
addSignal( sigpath ); |
||
186 |
} |
||
187 |
else if( cmdLine == "rmSignal" ) |
||
188 |
{ |
||
189 |
std::string sigpath; cmdArgs >> std::skipws >> sigpath; |
||
190 |
rmSignal( sigpath ); |
||
191 |
} |
||
192 |
else if( cmdLine == "runSignals" ) |
||
193 |
{ runSignals( inner_time_++ ); } |
||
194 |
|||
195 |
else if( cmdLine == "addCmd" ) |
||
196 |
{ addCmd( readLineStr(cmdArgs) ); } |
||
197 |
else if( cmdLine == "rmCmd" ) |
||
198 |
{ rmCmd( readLineStr(cmdArgs) ); } |
||
199 |
else if( cmdLine == "runCmds" ) |
||
200 |
{ runCmds(); } |
||
201 |
|||
202 |
else if( cmdLine == "run" ) |
||
203 |
{ run( inner_time_++ ); } |
||
204 |
else if( cmdLine == "clear" ) |
||
205 |
{ clear(); } |
||
206 |
else if( cmdLine == "print" ) |
||
207 |
{ display(os) ; } |
||
208 |
else { return false; } |
||
209 |
return true; |
||
210 |
} |
||
211 |
|||
212 |
#define ADD_COMMAND( name,def ) \ |
||
213 |
if (commandMap.count(prefix+name) != 0) { \ |
||
214 |
DG_THROW dg::ExceptionFactory(dg::ExceptionFactory::OBJECT_CONFLICT, \ |
||
215 |
"Command " + prefix+name + \ |
||
216 |
" already registered in Entity."); \ |
||
217 |
} \ |
||
218 |
commandMap.insert( std::make_pair( prefix+name,def ) ) |
||
219 |
|||
220 |
|||
221 |
40 |
void PeriodicCall::addSpecificCommands(dg::Entity& ent, |
|
222 |
dg::Entity::CommandMap_t& commandMap, |
||
223 |
const std::string& prefix ) |
||
224 |
{ |
||
225 |
using namespace dg::command; |
||
226 |
|||
227 |
/* Explicit typage to help the compiler. */ |
||
228 |
boost::function< void( const std::string& ) > |
||
229 |
✓✗✓✗ |
80 |
addSignal = boost::bind( &PeriodicCall::addSignal, this,_1 ), |
230 |
✓✗✓✗ |
80 |
rmSignal = boost::bind( &PeriodicCall::rmSignal, this,_1 ); |
231 |
boost::function< void( const std::string&, const unsigned int& ) > |
||
232 |
✓✗✓✗ |
80 |
addDownsampledSignal = boost::bind( &PeriodicCall::addDownsampledSignal, this,_1,_2); |
233 |
boost::function< void( void ) > |
||
234 |
✓✗✓✗ |
80 |
clear = boost::bind( &PeriodicCall::clear, this ); |
235 |
boost::function< void( std::ostream& ) > |
||
236 |
✓✗✓✗ |
80 |
disp = boost::bind( &PeriodicCall::display, this,_1 ); |
237 |
|||
238 |
✓✗✓✗ ✗✓✗✗ ✗✗✗✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
80 |
ADD_COMMAND("addSignal", |
239 |
makeCommandVoid1(ent,addSignal, |
||
240 |
docCommandVoid1("Add the signal to the refresh list", |
||
241 |
✓✗ | 40 |
"string (sig name)"))); |
242 |
✓✗✓✗ ✗✓✗✗ ✗✗✗✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
80 |
ADD_COMMAND("addDownsampledSignal", |
243 |
makeCommandVoid2(ent,addDownsampledSignal, |
||
244 |
docCommandVoid2("Add the signal to the refresh list", |
||
245 |
"string (sig name)", |
||
246 |
✓✗ | 40 |
"unsigned int (downsampling factor, 1 means every time, 2 means every other time, etc..."))); |
247 |
✓✗✓✗ ✗✓✗✗ ✗✗✗✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
80 |
ADD_COMMAND("rmSignal", |
248 |
makeCommandVoid1(ent,rmSignal, |
||
249 |
docCommandVoid1("Remove the signal to the refresh list", |
||
250 |
✓✗ | 40 |
"string (sig name)"))); |
251 |
✓✗✓✗ ✗✓✗✗ ✗✗✗✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ |
80 |
ADD_COMMAND("clear", |
252 |
makeCommandVoid0(ent,clear, |
||
253 |
✓✗ | 40 |
docCommandVoid0("Clear all signals and commands from the refresh list."))); |
254 |
|||
255 |
✓✗✓✗ ✗✓✗✗ ✗✗✗✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ |
80 |
ADD_COMMAND("disp", |
256 |
makeCommandVerbose(ent,disp, |
||
257 |
✓✗ | 40 |
docCommandVerbose("Print the list of to-refresh signals and commands."))); |
258 |
|||
259 |
✓✗✓✗ |
52 |
} |
260 |
|||
261 |
|||
262 |
/* |
||
263 |
* Local variables: |
||
264 |
* c-basic-offset: 2 |
||
265 |
* End: |
||
266 |
*/ |
||
267 |
Generated by: GCOVR (Version 4.2) |