00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "FunctionGraph.hpp"
00040 #include "GraphCopier.hpp"
00041 #include "AttributeBase.hpp"
00042 #include "scripting/ProgramTask.hpp"
00043 #include "ProgramProcessor.hpp"
00044 #include "TaskObject.hpp"
00045
00046 #include "CommandNOP.hpp"
00047 #include "ConditionFalse.hpp"
00048 #include "ConditionTrue.hpp"
00049 #include <boost/graph/copy.hpp>
00050 #include <utility>
00051
00052 namespace RTT
00053 {
00054 using namespace boost;
00055 using namespace std;
00056
00057
00058
00059 FunctionGraph::FunctionGraph(const std::string& _name)
00060 : myName(_name), pausing(false), mstep(false), context(0)
00061 {
00062
00063 startv = add_vertex( program );
00064 put(vertex_exec, program, startv, VertexNode::normal_node );
00065 exitv = add_vertex( program );
00066 put(vertex_exec, program, exitv, VertexNode::normal_node);
00067 }
00068
00069 FunctionGraph::FunctionGraph( const FunctionGraph& orig )
00070 : program( orig.getGraph() ), myName( orig.getName() )
00071 {
00072
00073 graph_traits<Graph>::vertex_iterator v1,v2, it;
00074 tie(v1,v2) = vertices(program);
00075 for ( it=v1; it != v2; ++it)
00076 if ( get( vertex_exec, program, *it) == VertexNode::func_start_node )
00077 break;
00078 startv = *v1;
00079 for ( it=v1; it != v2; ++it)
00080 if ( get( vertex_exec, program, *it) == VertexNode::func_exit_node )
00081 break;
00082 exitv = *v1;
00083
00084
00085 std::vector<AttributeBase*> argsvect = orig.getArguments();
00086 std::vector<AttributeBase*>::iterator ita = argsvect.begin();
00087 for ( ; ita != argsvect.end(); ++ita)
00088 this->args.push_back( (*ita)->clone() );
00089 this->finish();
00090 }
00091
00092 void FunctionGraph::finish()
00093 {
00094 put(vertex_exec, program, startv, VertexNode::func_start_node );
00095 put(vertex_exec, program, exitv, VertexNode::func_exit_node);
00096
00097
00098
00099
00100 property_map<Graph, vertex_index_t>::type
00101 index = get(vertex_index, program);
00102
00103
00104
00105 graph_traits<Graph>::vertex_iterator vi, vend;
00106 graph_traits<Graph>::vertices_size_type cnt = 0;
00107 for(tie(vi,vend) = vertices(program); vi != vend; ++vi)
00108 put(index, *vi, cnt++);
00109 this->reset();
00110 }
00111
00112 FunctionGraph::~FunctionGraph()
00113 {
00114 std::vector<AttributeBase*>::iterator it = args.begin();
00115 for ( ; it != args.end(); ++it)
00116 delete *it;
00117 pStatus = Status::unloaded;
00118 this->handleUnload();
00119 }
00120
00121 void FunctionGraph::setProgramTask(TaskObject* mytask)
00122 {
00123 context = mytask;
00124 }
00125
00126 void FunctionGraph::handleUnload()
00127 {
00128 if (context == 0)
00129 return;
00130
00131 if (context->getParent() ) {
00132 context->getParent()->removeObject(context->getName());
00133 } else {
00134
00135 delete context;
00136 }
00137
00138 context = 0;
00139 }
00140
00141
00142 bool FunctionGraph::start()
00143 {
00144 if ( !pp || !pp->getActivity() || !pp->getActivity()->isActive() )
00145 return false;
00146 if ( pStatus == Status::stopped || pStatus == Status::paused) {
00147 pStatus = Status::running;
00148 return true;
00149 }
00150 return false;
00151 }
00152
00153 bool FunctionGraph::pause()
00154 {
00155 if ( pp ) {
00156 pausing = true;
00157 return true;
00158 }
00159 return false;
00160 }
00161
00162 bool FunctionGraph::step()
00163 {
00164 if ( pp && (pStatus == Status::paused) && mstep == false) {
00165 mstep = true;
00166 return true;
00167 }
00168 return false;
00169 }
00170
00171 bool FunctionGraph::stepDone() const
00172 {
00173 return mstep == false;
00174 }
00175
00176 bool FunctionGraph::execute()
00177 {
00178 if (pausing) {
00179 pStatus = Status::paused;
00180 pausing = false;
00181 return true;
00182 }
00183 switch (pStatus) {
00184 case Status::running:
00185 return this->executeUntil();
00186 break;
00187 case Status::paused:
00188 if (mstep) {
00189 mstep = false;
00190 return this->executeStep();
00191 } else
00192 return true;
00193 break;
00194 case Status::error:
00195 case Status::unloaded:
00196 return false;
00197 break;
00198 case Status::stopped:
00199 return true;
00200 break;
00201 }
00202 return false;
00203 }
00204
00205
00206 bool FunctionGraph::executeUntil()
00207 {
00208 graph_traits<Graph>::out_edge_iterator ei, ei_end;
00209
00210 boost::property_map<Graph, vertex_command_t>::type
00211 cmap = get(vertex_command, program);
00212 boost::property_map<Graph, edge_condition_t>::type
00213 emap = get(edge_condition, program);
00214
00215 do {
00216
00217
00218
00219
00220 if ( previous != current )
00221 {
00222 for ( tie(ei, ei_end) = boost::out_edges( current, program ); ei != ei_end; ++ei)
00223 emap[*ei].reset();
00224 cmap[current].startExecution();
00225 }
00226
00227
00228 previous = current;
00229
00230 if ( !cmap[current].execute() ) {
00231 pStatus = Status::error;
00232 return false;
00233 }
00234
00235
00236 if ( cmap[current].isValid() ) {
00237 for ( tie(ei, ei_end) = boost::out_edges( current, program ); ei != ei_end; ++ei) {
00238 if ( emap[*ei].evaluate() ) {
00239 current = boost::target(*ei, program);
00240
00241
00242 break;
00243 }
00244 }
00245 }
00246 } while ( previous != current && pStatus == Status::running && !pausing);
00247
00248
00249 if (current == exitv)
00250 this->stop();
00251 return true;
00252 }
00253
00254 bool FunctionGraph::executeStep()
00255 {
00256 graph_traits<Graph>::out_edge_iterator ei, ei_end;
00257
00258 boost::property_map<Graph, vertex_command_t>::type
00259 cmap = get(vertex_command, program);
00260 boost::property_map<Graph, edge_condition_t>::type
00261 emap = get(edge_condition, program);
00262
00263
00264 if ( previous != current )
00265 {
00266 for ( tie(ei, ei_end) = boost::out_edges( current, program ); ei != ei_end; ++ei)
00267 emap[*ei].reset();
00268 cmap[current].startExecution();
00269 previous = current;
00270 }
00271
00272
00273 if ( !cmap[current].execute() ) {
00274 pStatus = Status::error;
00275 return false;
00276 }
00277
00278
00279 if ( cmap[current].isValid() ) {
00280 for ( tie(ei, ei_end) = boost::out_edges( current, program ); ei != ei_end; ++ei) {
00281 if ( emap[*ei].evaluate() ) {
00282 current = boost::target(*ei, program);
00283 if (current == exitv)
00284 this->stop();
00285
00286
00287 return true;
00288 }
00289 }
00290 }
00291
00292 if (current == exitv)
00293 this->stop();
00294 return true;
00295 }
00296
00297 void FunctionGraph::reset() {
00298 this->stop();
00299 }
00300
00301 bool FunctionGraph::stop()
00302 {
00303
00304 current = startv;
00305 previous = exitv;
00306 pStatus = Status::stopped;
00307 return true;
00308 }
00309
00310 const std::string& FunctionGraph::getName() const
00311 {
00312 return myName;
00313 }
00314
00315 void FunctionGraph::setName(const std::string& name)
00316 {
00317 myName = name;
00318 }
00319
00320 std::string FunctionGraph::getText() const
00321 {
00322 return _text;
00323 }
00324
00325 void FunctionGraph::setText(const std::string& text)
00326 {
00327 _text = text;
00328 }
00329
00330 int FunctionGraph::getLineNumber() const
00331 {
00332 return get(vertex_command, program)[current].getLineNumber();
00333 }
00334
00335 FunctionGraph* FunctionGraph::copy( std::map<const DataSourceBase*, DataSourceBase*>& replacementdss ) const
00336 {
00337 typedef boost::property_map<Graph, vertex_index_t>::const_type indexmap_t;
00338 typedef boost::graph_traits<Graph>::vertex_descriptor vd_t;
00339 typedef std::vector<vd_t> o2cvect_t;
00340 typedef boost::iterator_property_map<o2cvect_t::iterator, indexmap_t, vd_t, vd_t&> o2cmap_t;
00341 FunctionGraph* ret = new FunctionGraph( getName() );
00342
00343
00344 remove_vertex( ret->startv, ret->program );
00345 remove_vertex( ret->exitv, ret->program );
00346
00347 indexmap_t indexmap = get( vertex_index, program );
00348
00349 o2cvect_t o2cvect( num_vertices( program ) );
00350 o2cmap_t o2cmap( o2cvect.begin(), indexmap );
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 for (unsigned int i=0; i < args.size(); ++i)
00361 ret->addArgument( args[i]->copy( replacementdss, false ) );
00362
00363 boost::copy_graph( program, ret->program,
00364 boost::vertex_copy( GraphVertexCopier( program, ret->program, replacementdss ) ).
00365 edge_copy( GraphEdgeCopier( program, ret->program, replacementdss ) ).
00366 orig_to_copy( o2cmap ) );
00367
00368 ret->startv = o2cmap[startv];
00369 ret->exitv = o2cmap[exitv];
00370 ret->current = o2cmap[current];
00371 ret->previous = o2cmap[previous];
00372
00373
00374 ret->finish();
00375
00376
00377 if (this->pp)
00378 ret->setProgramProcessor(pp);
00379
00380
00381
00382 return ret;
00383 }
00384
00385 FunctionGraph* FunctionGraph::clone() const
00386 {
00387 return new FunctionGraph(*this);
00388 }
00389
00390 void FunctionGraph::debugPrintout() const {
00391 #if 0
00392 graph_traits<Graph>::vertex_iterator v,vend;
00393 tie(v,vend) = vertices(program);
00394 boost::property_map<Graph, vertex_command_t>::const_type
00395 cmap = get(vertex_command, program);
00396 boost::property_map<Graph, vertex_index_t>::const_type
00397 imap = get(vertex_index, program);
00398 std::cerr << "program " << getName() << std::endl;
00399 std::cerr << " number of vertices: " << boost::num_vertices(program) << std::endl;
00400 for ( ; v != vend; ++v )
00401 {
00402 int index = get( imap, *v );
00403 CommandInterface* cmd = get( cmap, *v ).getCommand();
00404 if ( cmd )
00405 std::cerr << " " << index << " " << typeid( *cmd ).name() << std::endl;
00406 else
00407 std::cerr << " " << index << " (null)" << std::endl;
00408 }
00409 #endif
00410 }
00411
00412 void FunctionGraph::clearArguments() {
00413 for (std::vector<AttributeBase*>::iterator it = args.begin(); it != args.end(); ++it)
00414 delete *it;
00415 args.clear();
00416 }
00417
00418 }
00419