58 #include <rtt/Logger.hpp> 59 #include <rtt/extras/MultiVector.hpp> 60 #include <rtt/types/TypeStream.hpp> 61 #include <rtt/types/Types.hpp> 62 #include "TaskBrowser.hpp" 64 #include <rtt/scripting/TryCommand.hpp> 65 #include <rtt/TaskContext.hpp> 66 #include <rtt/plugin/PluginLoader.hpp> 67 #include <rtt/scripting/parser-debug.hpp> 68 #include <rtt/scripting/Parser.hpp> 69 #include <rtt/scripting/parse_exception.hpp> 70 #include <rtt/scripting/PeerParser.hpp> 71 #include <rtt/scripting/Scripting.hpp> 72 #include <rtt/plugin/PluginLoader.hpp> 73 #include <rtt/internal/GlobalService.hpp> 74 #include <rtt/types/GlobalsRepository.hpp> 75 #include <rtt/internal/GlobalEngine.hpp> 76 #include <boost/algorithm/string.hpp> 86 #if defined(HAS_READLINE) && !defined(NO_GPL) 89 #if defined(HAS_EDITLINE) 95 # if defined(_POSIX_VERSION) && defined(HAS_READLINE) && !defined(HAS_EDITLINE) 96 # define USE_SIGNALS 1 102 # include <editline/readline.h> 104 # include <readline/readline.h> 105 # include <readline/history.h> 108 #include <boost/bind.hpp> 109 #include <boost/lambda/lambda.hpp> 116 #if defined(USE_SIGNALS) && defined(OROCOS_TARGET_XENOMAI) && CONFIG_XENO_VERSION_MAJOR == 2 && CONFIG_XENO_VERSION_MINOR >= 5 118 int xeno_sigwinch_handler(
int sig, siginfo_t *si,
void *ctxt);
122 using namespace boost;
127 std::vector<std::string> TaskBrowser::candidates;
128 std::vector<std::string> TaskBrowser::completes;
129 std::vector<std::string>::iterator TaskBrowser::complete_iter;
130 std::string TaskBrowser::component;
131 std::string TaskBrowser::component_found;
132 std::string TaskBrowser::peerpath;
133 std::string TaskBrowser::text;
135 RTT::TaskContext* TaskBrowser::taskcontext = 0;
136 Service::shared_ptr TaskBrowser::taskobject;
137 RTT::TaskContext* TaskBrowser::peer = 0;
138 RTT::TaskContext* TaskBrowser::tb = 0;
139 RTT::TaskContext* TaskBrowser::context = 0;
148 std::deque<TaskContext*> taskHistory;
159 nl(std::ostream& __os)
160 {
return __os.put(__os.widen(
'\n')); }
163 #if defined(USE_READLINE) 166 int TaskBrowser::rl_received_signal;
167 #if defined(USE_SIGNALS) 168 void TaskBrowser::rl_sigwinch_handler(
int sig, siginfo_t *si,
void *ctxt) {
169 rl_received_signal = sig;
170 #if defined(OROCOS_TARGET_XENOMAI) && CONFIG_XENO_VERSION_MAJOR == 2 && CONFIG_XENO_VERSION_MINOR >= 5 171 if (xeno_sigwinch_handler(sig, si, ctxt) == 0)
173 rl_resize_terminal();
176 void TaskBrowser::rl_signal_handler(
int sig, siginfo_t *si,
void *ctxt) {
177 rl_received_signal = sig;
181 rl_free_line_state();
182 rl_echo_signal_char(sig);
183 rl_received_signal = 0;
187 #endif // USE_SIGNALS 189 int TaskBrowser::rl_getc(FILE *stream)
196 rl_received_signal = 0;
197 result = ::read(fileno(stream), &c,
sizeof(
unsigned char));
199 if (result ==
sizeof(
unsigned char))
208 if (errno == EINTR && (rl_received_signal == SIGINT || rl_received_signal == SIGTERM))
209 return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
215 return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
219 char *TaskBrowser::rl_gets ()
246 if ( !macrorecording ) {
253 if (rl_set_signals() != 0)
254 cerr <<
"Error setting signals !" <<endl;
257 line_read = readline ( p.c_str() );
260 if (rl_clear_signals() != 0)
261 cerr <<
"Error clearing signals !" <<endl;
266 if (line_read && *line_read) {
268 string s = line_read;
269 if (s !=
"quit" && ! ( history_get( where_history() ) && s ==
string(history_get( where_history() )->line) ) ) {
272 add_history (line_read);
278 char* TaskBrowser::dupstr(
const char *s )
282 rv = (
char*) malloc( strlen( s ) + 1 );
283 strncpy( rv, s, strlen(s) + 1 );
287 char *TaskBrowser::command_generator(
const char *_text,
int state )
297 complete_iter = completes.begin();
303 if ( complete_iter == completes.end() )
306 return dupstr( complete_iter->c_str() );
313 void TaskBrowser::find_completes() {
314 std::string::size_type pos;
315 std::string::size_type startpos;
316 std::string line( rl_line_buffer, rl_point );
319 if ( line.find(std::string(
"cd ")) == 0 || line.find(std::string(
"ls ")) == 0) {
322 pos = line.find(
" ");
323 startpos = line.find_last_of(
". ");
327 if ( pos+1 != line.length() )
328 peer = findPeer( line.substr(pos+1) );
333 RTT::TaskContext::PeerList v = peer->getPeerList();
334 for (RTT::TaskContext::PeerList::iterator i = v.begin(); i != v.end(); ++i) {
336 if ( !( pos+1 > startpos) )
337 path = line.substr(pos+1, startpos - pos);
339 if ( *i == line.substr(startpos+1) )
340 completes.push_back( path + *i +
".");
342 if ( startpos == std::string::npos || startpos+1 == line.length() || i->find( line.substr(startpos+1)) == 0 )
343 completes.push_back( *i );
346 if (line.find(std::string(
"cd ")) == 0)
349 v = peer->provides()->getProviderNames();
350 for (RTT::TaskContext::PeerList::iterator i = v.begin(); i != v.end(); ++i) {
352 if ( !( pos+1 > startpos) )
353 path = line.substr(pos+1, startpos - pos);
355 if ( *i == line.substr(startpos+1) )
356 completes.push_back( path + *i +
".");
358 if ( startpos == std::string::npos || startpos+1 == line.length() || i->find( line.substr(startpos+1)) == 0 )
359 completes.push_back( *i );
365 if ( line.find(std::string(
".")) == 0 ) {
367 std::vector<std::string> tbcoms;
368 tbcoms.push_back(
".loadProgram ");
369 tbcoms.push_back(
".unloadProgram ");
370 tbcoms.push_back(
".loadStateMachine ");
371 tbcoms.push_back(
".unloadStateMachine ");
372 tbcoms.push_back(
".light");
373 tbcoms.push_back(
".dark");
374 tbcoms.push_back(
".hex");
375 tbcoms.push_back(
".nohex");
376 tbcoms.push_back(
".nocolors");
377 tbcoms.push_back(
".connect");
378 tbcoms.push_back(
".record");
379 tbcoms.push_back(
".end");
380 tbcoms.push_back(
".cancel");
381 tbcoms.push_back(
".provide");
382 tbcoms.push_back(
".services");
383 tbcoms.push_back(
".typekits");
384 tbcoms.push_back(
".types");
387 for( std::vector<std::string>::iterator it = tbcoms.begin();
390 if ( it->find(line) == 0 )
391 completes.push_back( *it );
395 if ( line.find(std::string(
"list ")) == 0
396 || line.find(std::string(
"trace ")) == 0
397 || line.find(std::string(
"untrace ")) == 0) {
398 stringstream ss( line.c_str() );
402 std::vector<std::string> progs;
404 if ( context->provides()->hasService(
"scripting") ) {
406 progs = context->getProvider<Scripting>(
"scripting")->getProgramList();
408 for( std::vector<std::string>::iterator it = progs.begin();
411 string res = lcommand + *it;
412 if ( res.find(line) == 0 )
413 completes.push_back( *it );
415 progs = context->getProvider<Scripting>(
"scripting")->getStateMachineList();
416 for( std::vector<std::string>::iterator it = progs.begin();
419 string res = lcommand + *it;
420 if ( res.find(line) == 0 )
421 completes.push_back( *it );
427 startpos = text.find_last_of(
",( ");
428 if ( startpos == std::string::npos )
432 find_peers(startpos);
439 std::string comp = component;
449 if ( line.empty() ) {
450 completes.push_back(
"cd ");
451 completes.push_back(
"cd ..");
452 completes.push_back(
"ls");
453 completes.push_back(
"help");
454 completes.push_back(
"quit");
455 completes.push_back(
"list");
456 completes.push_back(
"trace");
457 completes.push_back(
"untrace");
458 if (taskcontext == context)
459 completes.push_back(
"leave");
461 completes.push_back(
"enter");
466 if ( !text.empty() ) {
467 if ( std::string(
"cd " ).find(text) == 0 )
468 completes.push_back(
"cd ");
469 if ( std::string(
"ls" ).find(text) == 0 )
470 completes.push_back(
"ls");
471 if ( std::string(
"cd .." ).find(text) == 0 )
472 completes.push_back(
"cd ..");
473 if ( std::string(
"help" ).find(text) == 0 )
474 completes.push_back(
"help");
475 if ( std::string(
"quit" ).find(text) == 0 )
476 completes.push_back(
"quit");
477 if ( std::string(
"list " ).find(text) == 0 )
478 completes.push_back(
"list ");
479 if ( std::string(
"trace " ).find(text) == 0 )
480 completes.push_back(
"trace ");
481 if ( std::string(
"untrace " ).find(text) == 0 )
482 completes.push_back(
"untrace ");
484 if (taskcontext == context &&
string(
"leave").find(text) == 0)
485 completes.push_back(
"leave");
487 if (context == tb &&
string(
"enter").find(text) == 0)
488 completes.push_back(
"enter");
492 void TaskBrowser::find_ops()
496 std::vector<std::string> attrs;
497 attrs = taskobject->getAttributeNames();
498 for (std::vector<std::string>::iterator i = attrs.begin(); i!= attrs.end(); ++i ) {
499 if ( i->find( component ) == 0 )
500 completes.push_back( peerpath + *i );
503 std::vector<std::string> props;
504 taskobject->properties()->list(props);
505 for (std::vector<std::string>::iterator i = props.begin(); i!= props.end(); ++i ) {
506 if ( i->find( component ) == 0 ) {
507 completes.push_back( peerpath + *i );
512 vector<string> comps = taskobject->getNames();
513 for (std::vector<std::string>::iterator i = comps.begin(); i!= comps.end(); ++i ) {
514 if ( i->find( component ) == 0 )
515 completes.push_back( peerpath + *i );
519 comps = Types()->getDottedTypes();
520 for (std::vector<std::string>::iterator i = comps.begin(); i!= comps.end(); ++i ) {
521 if ( peerpath.empty() && i->find( component ) == 0 )
522 completes.push_back( *i );
526 comps = GlobalsRepository::Instance()->getAttributeNames();
527 for (std::vector<std::string>::iterator i = comps.begin(); i!= comps.end(); ++i ) {
528 if ( peerpath.empty() && i->find( component ) == 0 )
529 completes.push_back( *i );
533 if ( taskobject == peer->provides() && peer == context) {
534 comps = GlobalService::Instance()->getNames();
535 for (std::vector<std::string>::iterator i = comps.begin(); i!= comps.end(); ++i ) {
536 if ( i->find( component ) == 0 )
537 completes.push_back( peerpath + *i );
542 bool try_deeper =
false;
544 Parser parser(GlobalEngine::Instance());
545 DataSourceBase::shared_ptr result = parser.parseExpression( peerpath + component_found, context );
546 if (result && !component.empty() ) {
547 DataSource<PropertyBag>::shared_ptr bag = DataSource<PropertyBag>::narrow(result.get());
548 vector<string> members;
550 members = bag->rvalue().getPropertyNames();
553 members = result->getMemberNames();
555 for (std::vector<std::string>::iterator i = members.begin(); i!= members.end(); ++i ) {
556 if (
string( component_found +
"." + *i ).find( component ) == 0 )
557 completes.push_back( peerpath + component_found +
"." + *i );
558 if ( component_found +
"." + *i == component )
568 Parser parser(GlobalEngine::Instance());
569 DataSourceBase::shared_ptr result = parser.parseExpression( peerpath + component, context );
570 if (result && !component.empty() ) {
571 DataSource<PropertyBag>::shared_ptr bag = DataSource<PropertyBag>::narrow(result.get());
572 vector<string> members;
574 members = bag->rvalue().getPropertyNames();
577 members = result->getMemberNames();
579 for (std::vector<std::string>::iterator i = members.begin(); i!= members.end(); ++i ) {
580 if (component_found +
"." != component )
581 completes.push_back( peerpath + component +
"." + *i );
588 void TaskBrowser::find_peers( std::string::size_type startpos )
592 taskobject = context->provides();
594 std::string to_parse = text.substr(startpos);
596 std::string::size_type endpos = 0;
601 while (endpos != std::string::npos )
603 bool itemfound =
false;
604 endpos = to_parse.find(
".");
605 if ( endpos == startpos ) {
609 std::string item = to_parse.substr(startpos, endpos);
611 if ( taskobject->hasService( item ) ) {
612 taskobject = taskobject->provides(item);
615 if ( peer->hasPeer( item ) ) {
616 peer = peer->getPeer( item );
617 taskobject = peer->provides();
619 }
else if ( GlobalService::Instance()->hasService(item) ) {
620 taskobject = GlobalService::Instance()->provides(item);
624 peerpath += to_parse.substr(startpos, endpos) +
".";
625 if ( endpos != std::string::npos )
626 to_parse = to_parse.substr(endpos + 1);
634 component_found = to_parse.substr(startpos, to_parse.rfind(
"."));
636 component = to_parse.substr(startpos, std::string::npos);
650 RTT::TaskContext::PeerList v;
651 if ( taskobject == peer->provides() ) {
653 v = peer->getPeerList();
654 for (RTT::TaskContext::PeerList::iterator i = v.begin(); i != v.end(); ++i) {
655 if ( i->find( component ) == 0 ) {
656 completes.push_back( peerpath + *i );
657 completes.push_back( peerpath + *i +
"." );
663 v = taskobject->getProviderNames();
664 for (RTT::TaskContext::PeerList::iterator i = v.begin(); i != v.end(); ++i) {
665 if ( i->find( component ) == 0 ) {
666 completes.push_back( peerpath + *i );
668 completes.push_back( peerpath + *i +
"." );
673 if ( peer == context && taskobject == peer->provides() ) {
674 v = GlobalService::Instance()->getProviderNames();
675 for (RTT::TaskContext::PeerList::iterator i = v.begin(); i != v.end(); ++i) {
676 if ( i->find( component ) == 0 ) {
677 completes.push_back( peerpath + *i );
679 completes.push_back( peerpath + *i +
"." );
687 char ** TaskBrowser::orocos_hmi_completion (
const char *text,
int start,
int end )
690 matches = (
char ** ) 0;
692 matches = rl_completion_matches ( text, &TaskBrowser::command_generator );
696 #endif // USE_READLINE 699 :
RTT::TaskContext(
"TaskBrowser"),
702 lastc(0), storedname(
""), storedline(-1),
705 macrorecording(false)
713 rl_catch_sigwinch = 0;
714 rl_catch_signals = 0;
716 rl_completion_append_character =
'\0';
717 rl_attempted_completion_function = &TaskBrowser::orocos_hmi_completion;
718 rl_getc_function = &TaskBrowser::rl_getc;
721 histfile = getenv(
"ORO_TB_HISTFILE");
723 histfile =
".tb_history";
724 if ( read_history(histfile) != 0 ) {
725 read_history(
"~/.tb_history");
729 sa.sa_sigaction = &TaskBrowser::rl_sigwinch_handler;
730 sa.sa_flags = SA_SIGINFO | SA_RESTART;
731 sigemptyset( &sa.sa_mask );
732 sigaction(SIGWINCH, &sa, 0);
734 sa.sa_sigaction = &(TaskBrowser::rl_signal_handler);
735 sa.sa_flags = SA_SIGINFO;
736 sigaction(SIGINT, &sa, 0);
737 sigaction(SIGTERM, &sa, 0);
738 #endif // USE_SIGNALS 739 #endif // USE_READLINE 741 this->setColorTheme(
darkbg );
745 TaskBrowser::~TaskBrowser() {
751 if ( write_history(histfile) != 0 ) {
752 write_history(
"~/.tb_history");
762 if (t->inFatalError())
764 if (t->inRunTimeError())
766 if (t->inException())
770 if (t->isConfigured() )
775 char getStateMachineStatusChar(RTT::TaskContext* t,
string progname)
777 string ps = t->getProvider<Scripting>(
"scripting")->getStateMachineStatusStr(progname);
778 return toupper(ps[0]);
781 char getProgramStatusChar(RTT::TaskContext* t,
string progname)
783 string ps = t->getProvider<Scripting>(
"scripting")->getProgramStatusStr(progname);
784 return toupper(ps[0]);
787 void str_trim(
string& str,
char to_trim)
789 string::size_type pos1 = str.find_first_not_of(to_trim);
790 string::size_type pos2 = str.find_last_not_of(to_trim);
791 if (pos1 == string::npos)
794 str = str.substr(pos1, pos2 - pos1 + 1);
806 " This console reader allows you to browse and manipulate TaskContexts."<<nl<<
807 " You can type in an operation, expression, create or change variables."<<nl;
811 cout <<
" TAB completion and HISTORY is available ('bash' like)" <<nl<<nl;
813 cout <<
" TAB completion and history is NOT available (LGPL-version)" <<nl<<nl;
819 if (!macrorecording) {
827 prompt = taskcontext->getName() +
" [" + state +
"]> ";
833 for (PTrace::iterator it = ptraces.begin(); it != ptraces.end(); ++it) {
834 RTT::TaskContext* progpeer = it->first.first;
835 int line = progpeer->getProvider<Scripting>(
"scripting")->getProgramLine(it->first.second);
836 if ( line != it->second ) {
842 for (PTrace::iterator it = straces.begin(); it != straces.end(); ++it) {
843 RTT::TaskContext* progpeer = it->first.first;
844 int line = progpeer->getProvider<Scripting>(
"scripting")->getStateMachineLine(it->first.second);
845 if ( line != it->second ) {
858 const char*
const commandStr = rl_gets();
860 command = commandStr ? commandStr :
"quit";
863 getline(cin,command);
867 }
catch(std::exception& e) {
868 cerr <<
"The command line reader throwed a std::exception: '"<< e.what()<<
"'."<<endl;
870 cerr <<
"The command line reader throwed an exception." <<endlog();
872 str_trim( command,
' ');
874 if ( command ==
"quit" ) {
878 }
else if ( command ==
"help") {
880 }
else if ( command.find(
"help ") == 0) {
881 printHelp( command.substr(command.rfind(
' ')));
882 }
else if ( command ==
"#debug") {
884 }
else if ( command.find(
"list ") == 0 || command ==
"list" ) {
886 }
else if ( command.find(
"trace ") == 0 || command ==
"trace" ) {
888 }
else if ( command.find(
"untrace ") == 0 || command ==
"untrace" ) {
890 }
else if ( command.find(
"ls") == 0 ) {
891 std::string::size_type pos = command.find(
"ls")+2;
892 command = std::string(command, pos, command.length());
893 str_trim( command,
' ');
895 }
else if ( command ==
"" ) {
896 }
else if ( command.find(
"cd ..") == 0 ) {
898 }
else if ( command.find(
"enter") == 0 ) {
900 }
else if ( command.find(
"leave") == 0 ) {
902 }
else if ( command.find(
"cd ") == 0 ) {
903 std::string::size_type pos = command.find(
"cd")+2;
904 command = std::string(command, pos, command.length());
906 }
else if ( command.find(
".") == 0 ) {
907 command = std::string(command, 1, command.length());
909 }
else if ( macrorecording) {
910 macrotext += command +
'\n';
914 }
catch(std::exception& e) {
915 cerr <<
"The command '"<<command<<
"' caused a std::exception: '"<< e.what()<<
"' and could not be completed."<<endl;
917 cerr <<
"The command '"<<command<<
"' caused an unknown exception and could not be completed."<<endl;
924 }
catch(std::exception& e) {
925 cerr <<
"Warning: The command caused a std::exception: '"<< e.what()<<
"' in the TaskBrowser's loop() function."<<endl;
927 cerr <<
"Warning: The command caused an exception in the TaskBrowser's loop() function." << endl;
932 void TaskBrowser::enterTask()
934 if ( context == taskcontext ) {
935 log(Info) <<
"Already in Task "<< taskcontext->getName()<<endlog();
938 context = taskcontext;
939 log(Info) <<
"Entering Task "<< taskcontext->getName()<<endlog();
942 void TaskBrowser::leaveTask()
944 if ( context == tb ) {
945 log(Info) <<
"Already watching Task "<< taskcontext->getName()<<endlog();
949 log(Info) <<
"Watching Task "<< taskcontext->getName()<<endlog();
952 void TaskBrowser::recordMacro(std::string name)
954 if (macrorecording) {
955 log(Error)<<
"Macro already active." <<endlog();
958 if (context->provides()->hasService(
"scripting") ==
false) {
959 log(Error)<<
"Can not create a macro in a TaskContext without scripting service." <<endlog();
962 if ( name.empty() ) {
963 cerr <<
"Please specify a macro name." <<endl;
966 cout <<
"Recording macro "<< name <<endl;
967 cout <<
"Use program scripting syntax (do, set,...) !" << endl <<endl;
968 cout <<
"export function "<< name<<
" {"<<endl;
970 macrorecording =
true;
974 void TaskBrowser::cancelMacro() {
975 if (!macrorecording) {
976 log(Warning)<<
"Macro recording was not active." <<endlog();
979 cout <<
"Canceling macro "<< macroname <<endl;
980 macrorecording =
false;
984 void TaskBrowser::endMacro() {
985 if (!macrorecording) {
986 log(Warning)<<
"Macro recording was not active." <<endlog();
989 string fname = macroname +
".ops";
990 macrorecording =
false;
992 cout <<
"Saving file "<< fname <<endl;
993 ofstream macrofile( fname.c_str() );
994 macrofile <<
"/* TaskBrowser macro '"<<macroname<<
"' */" <<endl<<endl;
995 macrofile <<
"export function "<<macroname<<
" {"<<endl;
996 macrofile << macrotext.c_str();
997 macrofile <<
"}"<<endl;
1000 cout <<
"Loading file "<< fname <<endl;
1001 context->getProvider<Scripting>(
"Scripting")->loadPrograms(fname);
1006 if ( taskHistory.size() == 0)
1011 taskHistory.pop_front();
1014 void TaskBrowser::checkPorts()
1018 DataFlowInterface::Ports ports;
1019 ports = this->ports()->getPorts();
1020 for( DataFlowInterface::Ports::iterator i=ports.begin(); i != ports.end(); ++i) {
1022 base::PortInterface* p = *i;
1023 base::PortInterface* tcp = taskcontext->ports()->getPort( p->getName() );
1024 if ( p->connected() ==
false || tcp == 0 || tcp->connected() ==
false) {
1025 this->ports()->removePort( p->getName() );
1031 void TaskBrowser::setColorTheme(
ColorTheme t)
1034 const char* dbg =
"\033[01;";
1035 const char* wbg =
"\033[02;";
1037 const char* r =
"31m";
1038 const char* g =
"32m";
1039 const char* b =
"34m";
1040 const char* con =
"31m";
1041 const char* coff =
"\33[0m";
1042 const char* und =
"\33[4m";
1081 if ( this->findPeer( c +
"." ) == 0 ) {
1082 cerr <<
"No such peer: "<< c <<nl;
1086 if ( peer == taskcontext ) {
1087 cerr <<
"Already in "<< c <<nl;
1092 cerr <<
"Can not switch to TaskBrowser." <<nl;
1102 if (taskHistory.size() == 20 )
1103 taskHistory.pop_back();
1104 if ( taskcontext && store)
1105 taskHistory.push_front( taskcontext );
1111 DataFlowInterface::Ports tports = this->ports()->getPorts();
1112 for( DataFlowInterface::Ports::iterator i=tports.begin(); i != tports.end(); ++i) {
1113 this->ports()->removePort( (*i)->getName() );
1118 if ( context == taskcontext )
1124 this->addPeer( taskcontext );
1128 tports = taskcontext->ports()->getPorts();
1129 if ( !tports.empty() )
1130 cout <<nl <<
"TaskBrowser connects to all data ports of "<<taskcontext->getName()<<endl;
1131 for( DataFlowInterface::Ports::iterator i=tports.begin(); i != tports.end(); ++i) {
1132 if (this->ports()->getPort( (*i)->getName() ) == 0 )
1133 this->ports()->addPort( *(*i)->antiClone() );
1135 RTT::connectPorts(
this,taskcontext);
1139 cerr <<
" Switched to : " << taskcontext->getName() <<endl;
1143 RTT::TaskContext* TaskBrowser::findPeer(std::string c) {
1147 our_pos_iter_t parsebegin( s.begin(), s.end(),
"teststring" );
1148 our_pos_iter_t parseend;
1151 scripting::PeerParser pp( peer, cp,
true );
1152 bool skipref =
true;
1154 parse( parsebegin, parseend, pp.parser(), SKIP_PARSER );
1158 log(Debug) <<
"No such peer : "<< c <<endlog();
1161 taskobject = pp.taskObject();
1168 std::stringstream ss(act);
1172 if ( instr ==
"list" ) {
1173 if (context->provides()->hasService(
"scripting") ==
false) {
1174 log(Error)<<
"Can not list a program in a TaskContext without scripting service." <<endlog();
1206 if ( instr ==
"trace") {
1207 if (context->provides()->hasService(
"scripting") ==
false) {
1208 log(Error)<<
"Can not trace a program in a TaskContext without scripting service." <<endlog();
1215 bool pi = context->getProvider<Scripting>(
"scripting")->hasProgram(arg);
1217 ptraces[make_pair(context, arg)] = context->getProvider<Scripting>(
"scripting")->getProgramLine(arg);
1221 pi = context->getProvider<Scripting>(
"scripting")->hasStateMachine(arg);
1223 straces[make_pair(context, arg)] = context->getProvider<Scripting>(
"scripting")->getStateMachineLine(arg);
1227 cerr <<
"No such program or state machine: "<< arg <<endl;
1232 std::vector<std::string> names;
1233 names = context->getProvider<Scripting>(
"scripting")->getProgramList();
1234 for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
1235 bool pi = context->getProvider<Scripting>(
"scripting")->hasProgram(arg);
1237 ptraces[make_pair(context, arg)] = context->getProvider<Scripting>(
"scripting")->getProgramLine(arg);
1240 names = context->getProvider<Scripting>(
"scripting")->getStateMachineList();
1241 for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
1242 bool pi = context->getProvider<Scripting>(
"scripting")->hasStateMachine(arg);
1244 straces[make_pair(context, arg)] = context->getProvider<Scripting>(
"scripting")->getStateMachineLine(arg);
1247 cerr <<
"Tracing all programs and state machines in "<< context->getName() << endl;
1251 if ( instr ==
"untrace") {
1252 if (context->provides()->hasService(
"scripting") ==
false) {
1253 log(Error)<<
"Can not untrace a program in a TaskContext without scripting service." <<endlog();
1259 ptraces.erase( make_pair(context, arg) );
1260 straces.erase( make_pair(context, arg) );
1261 cerr <<
"Untracing "<< arg <<
" of "<< context->getName()<<endl;
1265 std::vector<std::string> names;
1266 names = context->getProvider<Scripting>(
"scripting")->getProgramList();
1267 for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
1268 bool pi = context->getProvider<Scripting>(
"scripting")->hasProgram(arg);
1270 ptraces.erase(make_pair(context, arg));
1273 names = context->getProvider<Scripting>(
"scripting")->getStateMachineList();
1274 for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
1275 bool pi = context->getProvider<Scripting>(
"scripting")->hasStateMachine(arg);
1277 straces.erase(make_pair(context, arg));
1280 cerr <<
"Untracing all programs and state machines of "<< context->getName() << endl;
1286 if ( instr ==
"dark") {
1287 this->setColorTheme(
darkbg);
1288 cout << nl <<
"Setting Color Theme for "+
green+
"dark"+
coloroff+
" backgrounds."<<endl;
1291 if ( instr ==
"light") {
1293 cout << nl <<
"Setting Color Theme for "+
green+
"light"+
coloroff+
" backgrounds."<<endl;
1296 if ( instr ==
"nocolors") {
1298 cout <<nl <<
"Disabling all colors"<<endl;
1301 if ( instr ==
"record") {
1305 if ( instr ==
"cancel") {
1309 if ( instr ==
"end") {
1313 if ( instr ==
"hex") {
1315 cout <<
"Switching to hex notation for output (use .nohex to revert)." <<endl;
1318 if ( instr ==
"nohex") {
1320 cout <<
"Turning off hex notation for output." <<endl;
1323 if ( instr ==
"provide") {
1325 cout <<
"Trying to locate service '" << arg <<
"'..."<<endl;
1326 if ( PluginLoader::Instance()->loadService(arg, context) )
1327 cout <<
"Service '"<< arg <<
"' loaded in " << context->getName() << endl;
1329 cout <<
"Service not found." <<endl;
1334 if (instr ==
"services") {
1335 vector<string> names = PluginLoader::Instance()->listServices();
1336 cout <<
"Available Services: ";
1337 for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
1343 if (instr ==
"typekits") {
1344 vector<string> names = PluginLoader::Instance()->listTypekits();
1345 cout <<
"Available Typekits: ";
1346 for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
1352 if (instr ==
"types") {
1353 vector<string> names = TypeInfoRepository::Instance()->getDottedTypes();
1354 cout <<
"Available data types: ";
1355 for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
1361 cerr <<
"Unknown Browser Action : "<< act <<endl;
1362 cerr <<
"See 'help' for valid syntax."<<endl;
1369 Service::shared_ptr TaskBrowser::stringToService(
string const& names) {
1370 Service::shared_ptr serv;
1371 std::vector<std::string> strs;
1372 boost::split(strs, names, boost::is_any_of(
"."));
1375 if (strs.empty())
return serv;
1377 string component = strs.front();
1378 if (! context->hasPeer(component) && !context->provides()->hasService(component) ) {
1382 if ( context->hasPeer(component) )
1383 serv = context->getPeer(component)->provides();
1384 else if (context->provides()->hasService(component))
1385 serv = context->provides(component);
1388 strs.erase( strs.begin() );
1391 while ( !strs.empty() && serv) {
1392 serv = serv->getService( strs.front() );
1394 strs.erase( strs.begin() );
1402 bool result =
false;
1403 Service::shared_ptr ops = stringToService(name);
1404 ServiceRequester::shared_ptr sr;
1406 if ( ops || GlobalService::Instance()->hasService( name ) )
1409 ops = GlobalService::Instance()->provides(name);
1410 sresult << nl <<
"Printing Interface of '"<<
coloron << ops->getName() <<
coloroff <<
"' :"<<nl<<nl;
1411 vector<string> methods = ops->getNames();
1413 cout << sresult.str();
1417 if ( context->requires()->requiresService( name ) )
1419 sr = context->requires(name);
1420 sresult << nl <<
"Requiring '"<<
coloron << sr->getRequestName() <<
coloroff <<
"' with methods: ";
1421 vector<string> methods = sr->getOperationCallerNames();
1423 std::for_each( methods.begin(), methods.end(), sresult << lambda::_1 <<
" " );
1424 cout << sresult.str() <<
coloroff << nl;
1440 if ( context->provides()->getValue( comm ) ) {
1442 cerr <<
"Found value..."<<nl;
1443 this->
printResult( context->provides()->getValue( comm )->getDataSource().get(), true );
1444 cout << sresult.str()<<nl;
1456 scripting::Parser _parser( GlobalEngine::Instance() );
1459 cerr <<
"Trying ValueStatement..."<<nl;
1462 last_expr = _parser.parseValueStatement( comm, context );
1466 assert( comm.size() != 0 );
1467 if ( comm[ comm.size() - 1 ] !=
';' ) {
1469 cout << sresult.str() << nl <<endl;
1472 last_expr->evaluate();
1475 cerr <<
"returned (null) !"<<nl;
1478 }
catch ( fatal_semantic_parse_exception& pe ) {
1481 cerr <<
"fatal_semantic_parse_exception: ";
1482 cerr << pe.what() <<nl;
1484 }
catch ( syntactic_parse_exception& pe ) {
1487 cerr <<
"syntactic_parse_exception: ";
1488 cerr << pe.what() <<nl;
1490 }
catch ( parse_exception_parser_fail &pe )
1494 cerr <<
"Ignoring ValueStatement exception :"<<nl;
1495 cerr << pe.what() <<nl;
1497 }
catch ( parse_exception& pe ) {
1500 cerr <<
"parse_exception :";
1501 cerr << pe.what() <<nl;
1505 cerr <<
"Trying Expression..."<<nl;
1508 last_expr = _parser.parseExpression( comm, context );
1512 assert( comm.size() != 0 );
1513 if ( comm[ comm.size() - 1 ] !=
';' ) {
1515 cout << sresult.str() << nl << endl;
1518 last_expr->evaluate();
1521 cerr <<
"returned (null) !"<<nl;
1522 }
catch ( syntactic_parse_exception& pe ) {
1525 cerr <<
"syntactic_parse_exception :";
1526 cerr << pe.what() <<nl;
1528 }
catch ( fatal_semantic_parse_exception& pe ) {
1531 cerr <<
"fatal_semantic_parse_exception :";
1532 cerr << pe.what() <<nl;
1534 }
catch ( parse_exception_parser_fail &pe )
1538 cerr <<
"Ignoring Expression exception :"<<nl;
1539 cerr << pe.what() <<nl;
1541 }
catch ( parse_exception& pe ) {
1544 cerr <<
"Ignoring Expression parse_exception :"<<nl;
1545 cerr << pe.what() <<nl;
1550 std::string
prompt(
" = ");
1552 sresult <<prompt<< setw(20)<<left;
1554 doPrint( ds, recurse );
1556 sresult <<
"(null)";
1560 void TaskBrowser::doPrint( base::DataSourceBase::shared_ptr ds,
bool recurse) {
1562 sresult <<
"(null)";
1573 DataSource<RTT::PropertyBag>* dspbag = DataSource<RTT::PropertyBag>::narrow(ds.get());
1575 RTT::PropertyBag bag( dspbag->get() );
1577 int siz = bag.getProperties().size();
1578 int wdth = siz ? (20 - (siz / 10 + 1)) : 20;
1579 sresult <<setw(0)<< siz <<setw( wdth )<<
" Properties";
1581 if ( ! bag.empty() ) {
1582 sresult <<setw(0)<<nl;
1583 for( RTT::PropertyBag::iterator it= bag.getProperties().begin(); it!=bag.getProperties().end(); ++it) {
1584 sresult <<setw(14)<<right<< Types()->toDot( (*it)->getType() )<<
" "<<
coloron<<setw(14)<< (*it)->getName()<<
coloroff;
1585 base::DataSourceBase::shared_ptr propds = (*it)->getDataSource();
1587 sresult <<
" ("<<(*it)->getDescription()<<
')' << nl;
1590 sresult <<
prompt<<
"(empty RTT::PropertyBag)";
1597 base::DataSourceBase::shared_ptr dsb(ds);
1598 if (dsb->getMemberNames().empty() || dsb->getTypeInfo()->isStreamable() ) {
1599 if (debug) cerr <<
"terminal item " << dsb->getTypeName() << nl;
1601 sresult << std::hex << dsb;
1603 sresult << std::dec << dsb;
1607 vector<string> names = dsb->getMemberNames();
1608 if ( find(names.begin(), names.end(),
"capacity") != names.end() &&
1609 find(names.begin(), names.end(),
"size") != names.end() ) {
1611 DataSource<int>::shared_ptr seq_size = dynamic_pointer_cast<DataSource<int> >(dsb->getMember(
"size"));
1613 ValueDataSource<unsigned int>::shared_ptr index =
new ValueDataSource<unsigned int>(0);
1616 for (
int i=0; i != seq_size->get(); ++i) {
1619 sresult <<
"...("<< seq_size->get() - 10 <<
" items omitted)...";
1622 DataSourceBase::shared_ptr element = dsb->getMember(index, DataSourceBase::shared_ptr() );
1623 doPrint(element,
true);
1624 if (i+1 != seq_size->get())
1631 for(vector<string>::iterator it = names.begin(); it != names.end(); ) {
1632 sresult << *it <<
" = ";
1633 doPrint( dsb->getMember(*it),
true);
1634 if (++it != names.end())
1643 const char* command;
1644 comcol(
const char* c) :command(c) {}
1645 std::ostream& operator()( std::ostream& os )
const {
1646 os<<
"'"<< TaskBrowser::coloron<< TaskBrowser::underline << command << TaskBrowser::coloroff<<
"'";
1653 const char* command;
1654 keycol(
const char* c) :command(c) {}
1655 std::ostream& operator()( std::ostream& os )
const {
1656 os<<
"<"<< TaskBrowser::coloron<< TaskBrowser::underline << command << TaskBrowser::coloroff<<
">";
1663 const char* command;
1664 titlecol(
const char* c) :command(c) {}
1665 std::ostream& operator()( std::ostream& os )
const {
1666 os<<endl<<
"["<< TaskBrowser::coloron<< TaskBrowser::underline << command << TaskBrowser::coloroff<<
"]";
1671 std::ostream& operator<<(std::ostream& os,
comcol f ){
1675 std::ostream& operator<<(std::ostream& os,
keycol f ){
1679 std::ostream& operator<<(std::ostream& os,
titlecol f ){
1686 cout <<
titlecol(
"Task Browsing")<<nl;
1687 cout <<
" To switch to another task, type "<<
comcol(
"cd <path-to-taskname>")<<nl;
1688 cout <<
" and type "<<
comcol(
"cd ..")<<
" to go back to the previous task (History size is 20)."<<nl;
1689 cout <<
" Pressing "<<
keycol(
"tab")<<
" multiple times helps you to complete your command."<<nl;
1690 cout <<
" It is not mandatory to switch to a task to interact with it, you can type the"<<nl;
1691 cout <<
" peer-path to the task (dot-separated) and then type command or expression :"<<nl;
1692 cout <<
" PeerTask.OtherTask.FinalTask.countTo(3) [enter] "<<nl;
1693 cout <<
" Where 'countTo' is a method of 'FinalTask'."<<nl;
1694 cout <<
" The TaskBrowser starts by default 'In' the current component. In order to watch"<<nl;
1695 cout <<
" the TaskBrowser itself, type "<<
comcol(
"leave")<<
" You will notice that it"<<nl;
1696 cout <<
" has connected to the data ports of the visited component. Use "<<
comcol(
"enter")<<
" to enter"<<nl;
1697 cout <<
" the visited component again. The "<<
comcol(
"cd")<<
" command works transparantly in both"<<nl;
1698 cout <<
" modi."<<nl;
1700 cout <<
" "<<
titlecol(
"Task Context Info")<<nl;
1701 cout <<
" To see the contents of a task, type "<<
comcol(
"ls")<<nl;
1702 cout <<
" For a detailed argument list (and helpful info) of the object's methods, "<<nl;
1703 cout <<
" type the name of one of the listed task objects : " <<nl;
1704 cout <<
" this [enter]" <<nl<<nl;
1705 cout <<
" factor( int number ) : bool" <<nl;
1706 cout <<
" Factor a value into its primes." <<nl;
1707 cout <<
" number : The number to factor in primes." <<nl;
1708 cout <<
" isRunning( ) : bool" <<nl;
1709 cout <<
" Is this RTT::TaskContext started ?" <<nl;
1710 cout <<
" loadProgram( const& std::string Filename ) : bool" <<nl;
1711 cout <<
" Load an Orocos Program Script from a file." <<nl;
1712 cout <<
" Filename : An ops file." <<nl;
1715 cout <<
" A status character shows the TaskState of a component."<<nl;
1716 cout <<
" 'E':RunTimeError, 'S':Stopped, 'R':Running, 'U':PreOperational (Unconfigured)"<<nl;
1717 cout <<
" 'X':Exception, 'F':FatalError" << nl;
1719 cout <<
titlecol(
"Expressions")<<nl;
1720 cout <<
" You can evaluate any script expression by merely typing it :"<<nl;
1721 cout <<
" 1+1 [enter]" <<nl;
1722 cout <<
" = 2" <<nl;
1723 cout <<
" or inspect the status of a program :"<<nl;
1724 cout <<
" myProgram.isRunning [enter]" <<nl;
1725 cout <<
" = false" <<nl;
1726 cout <<
" and display the contents of complex data types (vector, array,...) :"<<nl;
1727 cout <<
" array(6)" <<nl;
1728 cout <<
" = {0, 0, 0, 0, 0, 0}" <<nl;
1730 cout <<
titlecol(
"Changing Attributes and Properties")<<nl;
1731 cout <<
" To change the value of a Task's attribute, type "<<
comcol(
"varname = <newvalue>")<<nl;
1732 cout <<
" If you provided a correct assignment, the browser will inform you of the success"<<nl;
1733 cout <<
" with the set value." <<nl;
1736 cout <<
" An Operation is sent or called (evaluated) "<<nl;
1737 cout <<
" immediately and print the result. An example could be :"<<nl;
1738 cout <<
" someTask.bar.getNumberOfBeers(\"Palm\") [enter] "<<nl;
1739 cout <<
" = 99" <<nl;
1740 cout <<
" You can ask help on an operation by using the 'help' command: "<<nl;
1741 cout <<
" help start"<<nl;
1742 cout <<
" start( ) : bool"<<nl;
1743 cout <<
" Start this TaskContext (= startHook() + updateHook() )." <<nl;
1745 cout <<
titlecol(
"Program and scripting::StateMachine Scripts")<<nl;
1746 cout <<
" To load a program script use the scripting service."<<nl;
1747 cout <<
" Use "<<
comcol(
".provide scripting")<<
" to load the scripting service in a TaskContext."<<nl;
1748 cout <<
" You can use "<<
comcol(
"ls progname")<<nl;
1749 cout <<
" to see the programs operations and variables. You can manipulate each one of these"<<nl;
1750 cout <<
" using the service object of the program."<<nl;
1752 cout <<
" To print a program or state machine listing, use "<<
comcol(
"list progname [linenumber]")<<nl;
1753 cout <<
" to list the contents of the current program lines being executed,"<<nl;
1754 cout <<
" or 10 lines before or after <linenumber>. When only "<<
comcol(
"list [n]")<<nl;
1755 cout <<
" is typed, 20 lines of the last listed program are printed from line <n> on "<<nl;
1756 cout <<
" ( default : list next 20 lines after previous list )."<<nl;
1758 cout <<
" To trace a program or state machine listing, use "<<
comcol(
"trace [progname]")<<
" this will"<<nl;
1759 cout <<
" cause the TaskBrowser to list the contents of a traced program,"<<nl;
1760 cout <<
" each time the line number of the traced program changes."<<nl;
1761 cout <<
" Disable tracing with "<<
comcol(
"untrace [progname]")<<
""<<nl;
1762 cout <<
" If no arguments are given to "<<
comcol(
"trace")<<
" and "<<
comcol(
"untrace")<<
", it applies to all programs."<<nl;
1764 cout <<
" A status character shows which line is being executed."<<nl;
1765 cout <<
" For programs : 'E':Error, 'S':Stopped, 'R':Running, 'P':Paused"<<nl;
1766 cout <<
" For state machines : <the same as programs> + 'A':Active, 'I':Inactive"<<nl;
1768 cout <<
titlecol(
"Changing Colors")<<nl;
1769 cout <<
" You can inform the TaskBrowser of your background color by typing "<<
comcol(
".dark")<<nl;
1770 cout <<
" "<<
comcol(
".light")<<
", or "<<
comcol(
".nocolors")<<
" to increase readability."<<nl;
1772 cout <<
titlecol(
"Output Formatting")<<nl;
1773 cout <<
" Use the commands "<<
comcol(
".hex") <<
" or " <<
comcol(
".nohex") <<
" to turn hexadecimal "<<nl;
1774 cout <<
" notation of integers on or off."<<nl;
1776 cout <<
titlecol(
"Macro Recording / RTT::Command line history")<<nl;
1777 cout <<
" You can browse the commandline history by using the up-arrow key or press "<<
comcol(
"Ctrl r")<<nl;
1778 cout <<
" and a search term. Hit enter to execute the current searched command."<<nl;
1779 cout <<
" Macros can be recorded using the "<<
comcol(
".record 'macro-name'")<<
" command."<<nl;
1780 cout <<
" You can cancel the recording by typing "<<
comcol(
".cancel")<<
" ."<<nl;
1781 cout <<
" You can save and load the macro by typing "<<
comcol(
".end")<<
" . The macro becomes"<<nl;
1782 cout <<
" available as a command with name 'macro-name' in the current TaskContext." << nl;
1783 cout <<
" While you enter the macro, it is not executed, as you must use scripting syntax which"<<nl;
1784 cout <<
" may use loop or conditional statements, variables etc."<<nl;
1786 cout <<
titlecol(
"Connecting Ports")<<nl;
1787 cout <<
" You can instruct the TaskBrowser to connect to the ports of the current Peer by"<<nl;
1788 cout <<
" typing "<<
comcol(
".connect [port-name]")<<
", which will temporarily create connections"<<nl;
1789 cout <<
" to all ports if [port-name] is omitted or to the specified port otherwise."<<nl;
1790 cout <<
" The TaskBrowser disconnects these ports when it visits another component, but the"<<nl;
1791 cout <<
" created connection objects remain in place (this is more or less a bug)!"<<nl;
1793 cout <<
titlecol(
"Plugins, Typekits and Services")<<nl;
1794 cout <<
" Use "<<
comcol(
".provide [servicename]")<<
" to load a service in a TaskContext."<<nl;
1795 cout <<
" For example, to add XML marshalling, type: "<<
comcol(
".provide marshalling")<<
"."<<nl;
1796 cout <<
" Use "<<
comcol(
".services")<<
" to get a list of available services."<<nl;
1797 cout <<
" Use "<<
comcol(
".typekits")<<
" to get a list of available typekits."<<nl;
1798 cout <<
" Use "<<
comcol(
".types")<<
" to get a list of available data types."<<nl;
1804 str_trim(helpstring,
' ');
1805 str_trim(helpstring,
'.');
1810 if ( findPeer( helpstring ) ) {
1814 if (helpstring.rfind(
'.') != string::npos )
1815 printOperation( helpstring.substr(helpstring.rfind(
'.')+1 ), taskobject );
1818 cout << sresult.str();
1820 cerr<<
" help: No such operation known: '"<< helpstring <<
"'"<<nl;
1823 cerr<<
" help: No such operation known (peer not found): '"<< helpstring <<
"'"<<nl;
1841 if ( progpeer->getProvider<Scripting>(
"scripting")->hasProgram( progname ) ) {
1842 s = getProgramStatusChar(progpeer, progname);
1843 txtss.str( progpeer->getProvider<Scripting>(
"scripting")->getProgramText(progname) );
1844 ln = progpeer->getProvider<Scripting>(
"scripting")->getProgramLine(progname);
1845 if ( cl < 0 ) cl = ln;
1846 start = cl < 10 ? 1 : cl - 10;
1848 this->listText( txtss, start, end, ln, s);
1853 if ( progpeer->getProvider<Scripting>(
"scripting")->hasStateMachine( progname ) ) {
1854 s = getStateMachineStatusChar(progpeer, progname);
1855 txtss.str( progpeer->getProvider<Scripting>(
"scripting")->getStateMachineText(progname) );
1856 ln = progpeer->getProvider<Scripting>(
"scripting")->getStateMachineLine(progname);
1857 if ( cl < 0 ) cl = ln;
1858 start = cl <= 10 ? 1 : cl - 10;
1860 this->listText( txtss, start, end, ln, s);
1864 cerr <<
"Error : No such program or state machine found : "<<progname;
1865 cerr <<
" in "<< progpeer->getName() <<
"."<<endl;
1868 storedname = progname;
1879 if ( context->getProvider<Scripting>(
"scripting")->hasProgram( storedname ) ) {
1880 s = getProgramStatusChar(context, storedname);
1881 txtss.str( context->getProvider<Scripting>(
"scripting")->getProgramText(storedname) );
1882 ln = context->getProvider<Scripting>(
"scripting")->getProgramLine(storedname);
1883 if ( cl < 0 ) cl = storedline;
1884 if (storedline < 0 ) cl = ln -10;
1887 this->listText( txtss, start, end, ln, s);
1890 if ( context->getProvider<Scripting>(
"scripting")->hasStateMachine(storedname) ) {
1891 s = getStateMachineStatusChar(context, storedname);
1892 txtss.str( context->getProvider<Scripting>(
"scripting")->getStateMachineText(storedname) );
1893 ln = context->getProvider<Scripting>(
"scripting")->getStateMachineLine(storedname);
1894 if ( cl < 0 ) cl = storedline;
1895 if (storedline < 0 ) cl = ln -10;
1898 this->listText( txtss, start, end, ln, s);
1902 cerr <<
"Error : No such program or state machine found : "<<storedname<<endl;
1905 void TaskBrowser::listText(stringstream& txtss,
int start,
int end,
int ln,
char s) {
1908 while ( start > 1 && curln != start ) {
1909 getline( txtss, line,
'\n' );
1914 while ( end > start && curln != end ) {
1915 getline( txtss, line,
'\n' );
1918 if ( curln == ln ) {
1923 cout<< setw(int(log(double(end)))) <<right << curln<< left; 1924 cout << ' ' << line <<endl; 1931 void TaskBrowser::printInfo(const std::string& peerp) 1933 // this sets this->peer to the peer given 1935 taskobject = peer->provides(); 1936 if ( !peerp.empty() && peerp != "." && this->findPeer( peerp+"." ) == 0 ) { 1937 cerr << "No such peer or object: " << peerp << endl; 1941 if ( !peer || !peer->ready()) { 1942 cout << nl << " Connection to peer "+peerp+" lost (peer->ready() == false)." <<endlog(); 1946 // sresult << *it << "["<<getTaskStatusChar(peer->getPeer(*it))<<"] "; 1949 if ( peer->provides() == taskobject ) 1950 sresult <<nl<<" Listing TaskContext "<< green << peer->getName()<<coloroff << "["<<getTaskStatusChar(peer)<<"] :"<<nl; 1952 sresult <<nl<<" Listing Service "<< green << taskobject->getName()<<coloroff<< "["<<getTaskStatusChar(peer)<<"] :"<<nl; 1954 sresult <<nl<<" Configuration Properties: "; 1955 RTT::PropertyBag* bag = taskobject->properties(); 1956 if ( bag && bag->size() != 0 ) { 1957 // Print Properties: 1958 for( RTT::PropertyBag::iterator it = bag->begin(); it != bag->end(); ++it) { 1959 base::DataSourceBase::shared_ptr pds = (*it)->getDataSource(); 1960 sresult << nl << setw(11)<< right << Types()->toDot( (*it)->getType() )<< " " 1961 << coloron <<setw(14)<<left<< (*it)->getName() << coloroff; 1962 this->printResult( pds.get(), false ); // do not recurse 1963 sresult<<" ("<< (*it)->getDescription() <<')
'; 1966 sresult << "(none)"; 1970 // Print "this" interface (without detail) and then list objects... 1971 sresult <<nl<< " Provided Interface:"; 1973 sresult <<nl<< " Attributes : "; 1974 std::vector<std::string> objlist = taskobject->getAttributeNames(); 1975 if ( !objlist.empty() ) { 1977 // Print Attributes: 1978 for( std::vector<std::string>::iterator it = objlist.begin(); it != objlist.end(); ++it) { 1979 base::DataSourceBase::shared_ptr pds = taskobject->getValue(*it)->getDataSource(); 1980 sresult << setw(11)<< right << Types()->toDot( pds->getType() )<< " " 1981 << coloron <<setw( 14 )<<left<< *it << coloroff; 1982 this->printResult( pds.get(), false ); // do not recurse 1986 sresult << coloron << "(none)"; 1989 sresult <<coloroff<<nl<< " Operations : "<<coloron; 1990 objlist = taskobject->getNames(); 1991 if ( !objlist.empty() ) { 1992 std::copy(objlist.begin(), objlist.end(), std::ostream_iterator<std::string>(sresult, " ")); 1994 sresult << "(none)"; 1996 sresult << coloroff << nl; 1998 sresult <<nl<< " Data Flow Ports: "; 1999 objlist = taskobject->getPortNames(); 2000 if ( !objlist.empty() ) { 2001 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it) { 2002 base::PortInterface* port = taskobject->getPort(*it); 2003 bool writer = dynamic_cast<OutputPortInterface*>(port) ? true : false; 2005 sresult << nl << " " << ( !writer ? 2007 // Port data type + name 2008 if ( !port->connected() ) 2009 sresult << "(U) " << setw(11)<<right<< Types()->toDot( port->getTypeInfo()->getTypeName() ); 2011 sresult << "(C) " << setw(11)<<right<< Types()->toDot( port->getTypeInfo()->getTypeName() ); 2013 << coloron <<setw( 14 )<<left<< *it << coloroff; 2015 InputPortInterface* iport = dynamic_cast<InputPortInterface*>(port); 2017 sresult << " <= ( use '"<< iport->getName() << ".read(sample)
' to read a sample from this port)"; 2019 OutputPortInterface* oport = dynamic_cast<OutputPortInterface*>(port); 2021 if ( oport->keepsLastWrittenValue()) { 2022 DataSourceBase::shared_ptr dsb = oport->getDataSource(); 2023 dsb->evaluate(); // read last written value. 2024 sresult << " => " << dsb; 2026 sresult << " => (keepsLastWrittenValue() == false. Enable it for this port in order to see it in the TaskBrowser.)"; 2029 // only show if we're connected to it
2030 if (peer == taskcontext && peer->provides() == taskobject) {
2033 InputPortInterface* iport =
dynamic_cast<InputPortInterface*
>(ports()->getPort(port->getName()));
2036 iport->getDataSource()->evaluate();
2039 sresult <<
" <= " << DataSourceBase::shared_ptr( iport->getDataSource());
2041 sresult <<
" => " << DataSourceBase::shared_ptr( iport->getDataSource());
2043 OutputPortInterface* oport =
dynamic_cast<OutputPortInterface*
>(ports()->getPort(port->getName()));
2046 DataSourceBase::shared_ptr ds = oport->getDataSource();
2049 sresult <<
" => " << ds;
2051 sresult <<
" <= " << ds <<
" (sent from TaskBrowser)";
2053 sresult <<
"(no last written value kept)";
2057 sresult <<
"(TaskBrowser not connected to this port)";
2065 sresult <<
"(none)";
2069 objlist = taskobject->getProviderNames();
2070 sresult <<nl<<
" Services: "<<nl;
2071 if ( !objlist.empty() ) {
2072 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it)
2073 sresult <<
coloron<<
" " << setw(14) << *it <<
coloroff<<
" ( "<< taskobject->provides(*it)->doc() <<
" ) "<<nl;
2079 if ( peer->provides() == taskobject ) {
2081 objlist = peer->requires()->getOperationCallerNames();
2082 sresult <<nl<<
" Requires Operations :";
2083 if ( !objlist.empty() ) {
2084 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it)
2085 sresult <<
coloron<<
" " << *it <<
coloroff <<
'[' << (peer->requires()->getOperationCaller(*it)->ready() ?
"R]" :
"!]");
2090 objlist = peer->requires()->getRequesterNames();
2091 sresult <<
" Requests Services :";
2092 if ( !objlist.empty() ) {
2093 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it)
2094 sresult <<
coloron<<
" " << *it <<
coloroff <<
'[' << (peer->requires(*it)->ready() ?
"R]" :
"!]");
2100 if (peer->provides()->hasService(
"scripting")) {
2101 objlist = peer->getProvider<Scripting>(
"scripting")->getProgramList();
2102 if ( !objlist.empty() ) {
2103 sresult <<
" Programs : "<<
coloron;
2104 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it)
2105 sresult << *it <<
"["<<getProgramStatusChar(peer,*it)<<
"] ";
2109 objlist = peer->getProvider<Scripting>(
"scripting")->getStateMachineList();
2110 if ( !objlist.empty() ) {
2111 sresult <<
" StateMachines: "<<
coloron;
2112 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it)
2113 sresult << *it <<
"["<<getStateMachineStatusChar(peer,*it)<<
"] ";
2119 if ( context == tb )
2120 sresult <<nl<<
" "<<peer->getName()<<
" Peers : "<<
coloron;
2122 sresult << nl <<
" Peers : "<<
coloron;
2124 objlist = peer->getPeerList();
2125 if ( !objlist.empty() )
2126 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it) {
2127 if( peer->getPeer(*it) )
2130 sresult << *it <<
"[X] ";
2133 sresult <<
"(none)";
2136 cout << sresult.str();
2142 std::vector<ArgumentDescription> args;
2143 Service::shared_ptr ops;
2145 args = the_ops->getArgumentList( m );
2148 args = GlobalService::Instance()->getArgumentList( m );
2149 ops = GlobalService::Instance();
2152 for (std::vector<ArgumentDescription>::iterator it = args.begin(); it != args.end(); ++it) {
2153 sresult << Types()->toDot( it->type ) <<
" ";
2155 if ( it+1 != args.end() )
2160 sresult <<
") : "<< Types()->toDot( ops->getResultType(m) )<<nl;
2161 sresult <<
" " << ops->getDescription( m )<<nl;
2162 for (std::vector<ArgumentDescription>::iterator it = args.begin(); it != args.end(); ++it)
2163 sresult <<
" "<< it->name <<
" : " << it->description << nl;
static std::string coloron
The 'turn color on' escape sequence.
static std::string underline
The 'underline' escape sequence.
Use colors suitable for a white background.
static std::string green
The green color.
void evaluate(std::string &comm)
Execute/evaluate a string which may be a command, method, expression etc.
void printResult(RTT::base::DataSourceBase *ds, bool recurse)
Evaluate a internal::DataSource and print the result.
void evalCommand(std::string &comm)
Evaluate command.
void browserAction(std::string &act)
Execute a specific browser action, such as "loadProgram pname", "loadStateMachine smname"...
char getTaskStatusChar(RTT::TaskContext *t)
Helper functions to display task and script states.
void printProgram(const std::string &pn, int line=-1, RTT::TaskContext *progpeer=0)
Print a program listing of a loaded program centered at line line.
static std::string blue
The blue color.
The Orocos Component Library.
bool printService(const std::string name)
Print the synopsis of a Service.
void printHelp()
Print the help page.
void switchTaskContext(std::string &path)
Switch to a peer RTT::TaskContext using a path .
TaskBrowser(RTT::TaskContext *c)
Create a TaskBrowser which initially visits a given RTT::TaskContext c.
void loop()
Call this method from ORO_main() to process keyboard input and thus startup the TaskBrowser.
void printInfo(const std::string &peerpath)
Print info this peer or another peer at "peerpath".
ColorTheme
The kinds of color themes the TaskBrowser supports.
static std::string prompt
The prompt.
static std::string coloroff
The 'turn color off' escape sequence.
Use colors suitable for a dark background.
void switchBack()
Go to the previous peer in the visit history.
void printOperation(const std::string m, Service::shared_ptr ops)
Print the synopsis of an Operation.
static std::string red
The red color.