Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • cberge/dynamic-graph
  • ostasse/dynamic-graph
  • gsaurel/dynamic-graph
  • stack-of-tasks/dynamic-graph
4 results
Show changes
Showing
with 1295 additions and 1620 deletions
/*
* Copyright 2010,
* François Bleibel,
* Olivier Stasse,
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
// JRL, CNRS/AIST.
//
#include <dynamic-graph/exception-abstract.h>
#include <dynamic-graph/debug.h>
#include <dynamic-graph/exception-abstract.h>
using namespace std;
using namespace dynamicgraph;
/* ------------------------------------------------------------------------- */
/* --- CONSTRUCTORS -------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
#include <cstring>
namespace dynamicgraph {
const std::string ExceptionAbstract::EXCEPTION_NAME = "Abstract";
ExceptionAbstract::ExceptionAbstract(const int &_code, const std::string &_msg)
: code(_code), message(_msg) {}
ExceptionAbstract::
ExceptionAbstract (const int& _code,
const string & _msg)
:
code (_code),
message (_msg)
{
return ;
const char *ExceptionAbstract::getMessage() const {
return (this->message).c_str();
}
/* ------------------------------------------------------------------------ */
/* --- ACCESSORS ---------------------------------------------------------- */
/* ------------------------------------------------------------------------ */
const char *ExceptionAbstract::
getMessage (void)
{
return (this->message) .c_str();
const std::string &ExceptionAbstract::getStringMessage() const {
return this->message;
}
const string& ExceptionAbstract::
getStringMessage (void) const
{
return this->message;
int ExceptionAbstract::getCode() const { return this->code; }
ExceptionAbstract::Param &ExceptionAbstract::Param::initCopy(const Param &p) {
if (&p == this) return *this;
dgDEBUGIN(25);
if (p.pointersSet) {
strncpy(function, p.functionPTR, BUFFER_SIZE);
strncpy(file, p.filePTR, BUFFER_SIZE);
line = p.line;
pointersSet = false;
set = true;
} else
set = false;
dgDEBUGOUT(25);
return *this;
}
int ExceptionAbstract::
getCode (void)
{
return this->code;
ExceptionAbstract::Param::Param(const int &_line, const char *_function,
const char *_file)
: functionPTR(_function), line(_line), filePTR(_file), pointersSet(true) {
dgDEBUGINOUT(25);
}
std::ostream &operator<<(std::ostream &os, const ExceptionAbstract &error) {
os << error.getExceptionName() << "Error [#" << error.code
<< "]: " << error.message << std::endl;
/* ------------------------------------------------------------------------- */
/* --- MODIFIORS ----------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
#ifdef DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
if (error.p.set)
os << "Thrown from " << error.p.file << ": " << error.p.function << " (#"
<< error.p.line << ")" << std::endl;
#endif // DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
ExceptionAbstract::Param& ExceptionAbstract::Param::
initCopy( const Param& p )
{
dgDEBUGIN(25);
if( p.pointersSet )
{
strncpy( function,p.functionPTR,BUFFER_SIZE);
strncpy( file,p.filePTR,BUFFER_SIZE);
line = p.line;
pointersSet=false;
set=true;
} else set=false;
dgDEBUGOUT(25);
return *this;
}
ExceptionAbstract::Param::
Param( const int& _line, const char * _function, const char * _file )
: functionPTR(_function),line(_line),filePTR(_file),pointersSet(true)
{
dgDEBUGINOUT(25);
return os;
}
#endif //#ifdef DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
/* ------------------------------------------------------------------------- */
/* --- OP << --------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
namespace dynamicgraph {
ostream &
operator << (ostream & os,
const ExceptionAbstract & error)
{
os << error.getExceptionName()<<"Error [#" << error.code << "]: " << error.message << endl;
#ifdef DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
if( error.p.set )
os << "Thrown from "<<error.p.file << ": "<<error.p.function
<<" (#"<<error.p.line << ")"<<endl;
#endif //#ifdef DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
return os;
}
} // namespace dynamicgraph
/** \file $Source$
*/
/*
* Local variables:
* c-basic-offset: 4
* End:
*/
} // end of namespace dynamicgraph.
......@@ -5,22 +5,12 @@
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/
#include <dynamic-graph/exception-factory.h>
#include <dynamic-graph/debug.h>
#include <dynamic-graph/exception-factory.h>
#include <stdarg.h>
#include <cstdio>
using namespace dynamicgraph;
......@@ -31,40 +21,36 @@ using namespace dynamicgraph;
const std::string ExceptionFactory::EXCEPTION_NAME = "Factory";
ExceptionFactory::
ExceptionFactory ( const ExceptionFactory::ErrorCodeEnum& errcode,
const std::string & msg )
:ExceptionAbstract(errcode,msg)
{
dgDEBUGF( 15,"Created with message <%s>.",msg.c_str());
dgDEBUG( 1) <<"Created with message <%s>."<<msg<<std::endl;
ExceptionFactory::ExceptionFactory(
const ExceptionFactory::ErrorCodeEnum &errcode, const std::string &msg)
: ExceptionAbstract(errcode, msg) {
dgDEBUGF(15, "Created with message <%s>.", msg.c_str());
dgDEBUG(1) << "Created with message <%s>." << msg << std::endl;
}
ExceptionFactory::
ExceptionFactory ( const ExceptionFactory::ErrorCodeEnum& errcode,
const std::string & msg,const char* format, ... )
:ExceptionAbstract(errcode,msg)
{
ExceptionFactory::ExceptionFactory(
const ExceptionFactory::ErrorCodeEnum &errcode, const std::string &msg,
const char *format, ...)
: ExceptionAbstract(errcode, msg) {
va_list args;
va_start(args,format);
va_start(args, format);
const unsigned int SIZE = 256;
char buffer[SIZE];
vsnprintf(buffer,SIZE,format,args);
char buffer[SIZE];
vsnprintf(buffer, SIZE, format, args);
dgDEBUG(15) <<"Created "<<" with message <"
<<msg<<"> and buffer <"<<buffer<<">. "<<std::endl;
dgDEBUG(15) << "Created "
<< " with message <" << msg << "> and buffer <" << buffer << ">. "
<< std::endl;
message += buffer;
va_end(args);
dgDEBUG(1) << "Throw exception " << EXCEPTION_NAME << "[#" << errcode<<"]: "
<<"<"<< message << ">."<<std::endl;
dgDEBUG(1) << "Throw exception " << EXCEPTION_NAME << "[#" << errcode << "]: "
<< "<" << message << ">." << std::endl;
}
/*
* Local variables:
* c-basic-offset: 2
......
......@@ -5,21 +5,11 @@
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/
#include <dynamic-graph/exception-signal.h>
#include <stdarg.h>
#include <cstdio>
using namespace dynamicgraph;
......@@ -30,32 +20,26 @@ using namespace dynamicgraph;
const std::string ExceptionSignal::EXCEPTION_NAME = "Signal";
ExceptionSignal::
ExceptionSignal ( const ExceptionSignal::ErrorCodeEnum& errcode,
const std::string & msg )
:ExceptionAbstract(errcode,msg)
{
}
ExceptionSignal::ExceptionSignal(const ExceptionSignal::ErrorCodeEnum &errcode,
const std::string &msg)
: ExceptionAbstract(errcode, msg) {}
ExceptionSignal::
ExceptionSignal ( const ExceptionSignal::ErrorCodeEnum& errcode,
const std::string & msg,const char* format, ... )
:ExceptionAbstract(errcode,msg)
{
ExceptionSignal::ExceptionSignal(const ExceptionSignal::ErrorCodeEnum &errcode,
const std::string &msg, const char *format,
...)
: ExceptionAbstract(errcode, msg) {
va_list args;
va_start(args,format);
va_start(args, format);
const unsigned int SIZE = 256;
char buffer[SIZE];
vsnprintf(buffer,SIZE,format,args);
char buffer[SIZE];
vsnprintf(buffer, SIZE, format, args);
message += buffer;
va_end(args);
}
/*
* Local variables:
* c-basic-offset: 2
......
......@@ -5,23 +5,12 @@
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/
#include <dynamic-graph/exception-traces.h>
#include <stdarg.h>
#include <cstdio>
#include <cstdio>
using namespace dynamicgraph;
/* --------------------------------------------------------------------- */
......@@ -30,32 +19,26 @@ using namespace dynamicgraph;
const std::string ExceptionTraces::EXCEPTION_NAME = "Traces";
ExceptionTraces::
ExceptionTraces ( const ExceptionTraces::ErrorCodeEnum& errcode,
const std::string & msg )
:ExceptionAbstract(errcode,msg)
{
}
ExceptionTraces::ExceptionTraces(const ExceptionTraces::ErrorCodeEnum &errcode,
const std::string &msg)
: ExceptionAbstract(errcode, msg) {}
ExceptionTraces::
ExceptionTraces ( const ExceptionTraces::ErrorCodeEnum& errcode,
const std::string & msg,const char* format, ... )
:ExceptionAbstract(errcode,msg)
{
ExceptionTraces::ExceptionTraces(const ExceptionTraces::ErrorCodeEnum &errcode,
const std::string &msg, const char *format,
...)
: ExceptionAbstract(errcode, msg) {
va_list args;
va_start(args,format);
va_start(args, format);
const unsigned int SIZE = 256;
char buffer[SIZE];
vsnprintf(buffer,SIZE,format,args);
char buffer[SIZE];
vsnprintf(buffer, SIZE, format, args);
message += buffer;
va_end(args);
}
/*
* Local variables:
* c-basic-offset: 2
......
/* Copyright LAAS, CNRS
* Author: O. Stasse, 2019
* See LICENSE file in the root directory of this repository.
*/
#include <dynamic-graph/process-list.hh>
#include <fstream>
#include <sstream>
#include <string>
using namespace dynamicgraph::CPU;
CPUData::CPUData()
: user_mode_time_(0),
nice_time_(0),
system_time_(0),
idle_time_(0),
iowait_time_(0),
irq_time_(0),
softirq_time_(0),
steal_time_(0),
guest_time_(0),
guest_nice_time_(0),
percent_(0.0) {}
void CPUData::ProcessLine(std::istringstream &aCPULine) {
unsigned long long int luser_mode_time = 0, lnice_time = 0, lsystem_time = 0,
lidle_time = 0, liowait_time = 0, lirq_time = 0,
lsoftirq_time = 0, lsteal_time = 0, lguest_time = 0,
lguest_nice_time;
aCPULine >> luser_mode_time;
aCPULine >> lnice_time;
aCPULine >> lsystem_time;
aCPULine >> lidle_time;
aCPULine >> liowait_time;
aCPULine >> lirq_time;
aCPULine >> lsoftirq_time;
aCPULine >> lsteal_time;
aCPULine >> lguest_time;
aCPULine >> lguest_nice_time;
// Remove guest time already in user_time:
luser_mode_time -= lguest_time;
lnice_time -= lguest_nice_time;
// Compute cumulative time
unsigned long long int lidle_all_time = 0, lsystem_all_time = 0,
lguest_all_time = 0, ltotal_time = 0;
lidle_all_time = lidle_time + liowait_time;
lsystem_all_time = lsystem_time + lirq_time + lsoftirq_time;
lguest_all_time = lguest_time + lguest_nice_time;
ltotal_time = luser_mode_time + lnice_time + lsystem_all_time +
lidle_all_time + lsteal_time + lguest_all_time;
// Update periodic computation.
user_mode_period_ = computePeriod(luser_mode_time, user_mode_time_);
nice_period_ = computePeriod(lnice_time, nice_time_);
system_period_ = computePeriod(lsystem_time, system_time_);
system_all_period_ = computePeriod(lsystem_all_time, system_all_time_);
idle_period_ = computePeriod(lidle_time, idle_time_);
idle_all_period_ = computePeriod(lidle_all_time, idle_all_time_);
iowait_period_ = computePeriod(liowait_time, idle_time_);
irq_period_ = computePeriod(lirq_time, irq_time_);
softirq_period_ = computePeriod(lsoftirq_time, softirq_time_);
steal_period_ = computePeriod(lsteal_time, steal_time_);
guest_period_ = computePeriod(lguest_all_time, guest_time_);
total_period_ = computePeriod(ltotal_time, total_time_);
/// Update time.
user_mode_time_ = luser_mode_time;
nice_time_ = lnice_time;
system_time_ = lsystem_time;
system_all_time_ = lsystem_all_time;
idle_time_ = lidle_time;
idle_all_time_ = lidle_all_time;
iowait_time_ = liowait_time;
irq_time_ = lirq_time;
softirq_time_ = lsoftirq_time;
steal_time_ = lsteal_time;
guest_time_ = lguest_all_time;
total_time_ = ltotal_time;
if (total_period_ != 0) {
percent_ = (double)(user_mode_period_) / (double)(total_period_)*100.0;
percent_ += (double)(nice_period_) / (double)(total_period_)*100.0;
percent_ += (double)(system_period_) / (double)(total_period_)*100.0;
percent_ += (double)(irq_period_) / (double)(total_period_)*100.0;
percent_ += (double)(softirq_period_) / (double)(total_period_)*100.0;
percent_ += (double)(steal_period_) / (double)(total_period_)*100.0;
percent_ += (double)(iowait_period_) / (double)(total_period_)*100.0;
}
}
System::System() {
vCPUData_.clear();
init();
}
void System::init() {
init_ = false;
readProcStat();
init_ = true;
}
void System::ProcessCPULine(unsigned int cpunb, std::istringstream &aCPULine) {
vCPUData_[cpunb].ProcessLine(aCPULine);
}
void System::readProcStat() {
std::ifstream aif;
cpuNb_ = 1;
aif.open("/proc/stat", std::ifstream::in);
std::string aline;
aline.clear();
while (std::getline(aif, aline)) {
// Read on line of the file
std::istringstream anISSLine(aline);
std::string line_hdr;
anISSLine >> line_hdr;
// Check if the line start with cpu
std::size_t pos = line_hdr.find("cpu");
std::string str_cpunbr = line_hdr.substr(pos + 3);
// Check if this is the first line
if (pos == 0 and str_cpunbr.empty()) {
gCPUData_.ProcessLine(anISSLine);
gCPUData_.cpu_id_ = -1;
} else {
// If not then check if there is a CPU number
if (pos == 0) {
std::istringstream iss(str_cpunbr);
unsigned int lcpunb;
iss >> lcpunb;
// If we did not initialize
if (!init_) {
// Count the number of CPU.
if (lcpunb > cpuNb_) cpuNb_ = lcpunb;
} else
// Otherwise process the line.
ProcessCPULine(lcpunb, anISSLine);
}
}
}
if (!init_) {
/// The number of CPU has been detected by going through /proc/stat.
vCPUData_.resize(cpuNb_ + 1);
for (unsigned long i = 0; i < (unsigned long)cpuNb_; i++)
vCPUData_[i].cpu_id_ = (int)i;
}
aif.close();
}
/*
* Copyright 2010,
* François Bleibel,
* Olivier Stasse,
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/
#include <dynamic-graph/functions.h>
#include <dynamic-graph/plugin-loader.h>
#include <dynamic-graph/factory.h>
#include <dynamic-graph/debug.h>
#include <dynamic-graph/entity.h>
#include <dynamic-graph/signal.h>
#include <dynamic-graph/exception-signal.h>
#ifdef WIN32
#include <Windows.h>
#endif
#include <fstream>
using namespace std;
using namespace dynamicgraph;
extern "C" {
ShellFunctionRegisterer regFun1
( "try",boost::bind(ShellFunctions::cmdTry,_1,_2,_3) );
ShellFunctionRegisterer regFun2
( "loadPlugins",boost::bind(ShellFunctions::cmdLoadPlugins,_1,_2,_3) );
ShellFunctionRegisterer regFun3
( "displayPlugins",boost::bind(ShellFunctions::cmdDisplayPlugins,_1,_2,_3) );
ShellFunctionRegisterer regFun4
( "factory",boost::bind(ShellFunctions::cmdDisplayFactory,_1,_2,_3) );
ShellFunctionRegisterer regFun5
( "#",boost::bind(ShellFunctions::cmdCommentary,_1,_2,_3) );
ShellFunctionRegisterer regFun7
( "unplug",boost::bind(ShellFunctions::cmdUnplug,_1,_2,_3) );
ShellFunctionRegisterer regFun8
( "clearPlugin",boost::bind(ShellFunctions::cmdClearPlugin,_1,_2,_3) );
ShellFunctionRegisterer regFun9
( "signalTime",boost::bind(ShellFunctions::cmdSignalTime,_1,_2,_3) );
ShellFunctionRegisterer regFun10
( "synchro",boost::bind(ShellFunctions::cmdSynchroSignal,_1,_2,_3) );
ShellFunctionRegisterer regFun11
( "echo",boost::bind(ShellFunctions::cmdEcho,_1,_2,_3) );
ShellFunctionRegisterer regFun12
( "copy",boost::bind(ShellFunctions::cmdCopy,_1,_2,_3) );
ShellFunctionRegisterer regFun13
( "freeze",boost::bind(ShellFunctions::cmdFreeze,_1,_2,_3) );
ShellFunctionRegisterer regFun13b
( "squeeze",boost::bind(ShellFunctions::cmdSqueeze,_1,_2,_3) );
ShellFunctionRegisterer regFun14
( "debugtrace",boost::bind(ShellFunctions::cmdEnableTrace,_1,_2,_3) );
ShellFunctionRegisterer regFun15
( "prompt",boost::bind(ShellFunctions::cmdSetPrompt,_1,_2,_3) );
ShellFunctionRegisterer regFun16
( "sleep",boost::bind(ShellFunctions::cmdSleep,_1,_2,_3) );
ShellFunctionRegisterer regFun17
( "beep",boost::bind(ShellFunctions::cmdBeep,_1,_2,_3) );
ShellFunctionRegisterer regFun19
( "completion",boost::bind(ShellFunctions::cmdCompletionList,_1,_2,_3) );
}
/*
* Copyright 2010,
* François Bleibel,
* Olivier Stasse,
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/
#include <dynamic-graph/shell-procedure.h>
#include <dynamic-graph/plugin-loader.h>
#include <dynamic-graph/factory.h>
#include <dynamic-graph/debug.h>
#include <dynamic-graph/entity.h>
#include <fstream>
using namespace std;
using namespace dynamicgraph;
void ShellProcedure::
cmdStartProcedure( const std::string& cmdLine,std::istringstream& args,std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - proc <name>"
<< "\t\t\t\tProcedure header." <<endl;
return;
}
args>>procName;
dgDEBUG(5)<<"Proc <" <<procName<<">"<<endl;
currentProc.clear();
args >> ws;
while( args.good() )
{
std::string next;
args>>next>>ws;
currentProc.params.push_back(next);
}
}
void ShellProcedure::
cmdContinueProcedure( const std::string& cmdLine,std::istringstream& args,std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - -> cmd args..."
<< "\t\t\t\tProcedure body." <<endl;
return;
}
std::string cmd2;
args>>ws>>cmd2;
dgDEBUG(5)<<"Proc <" <<procName<<">: "<<cmd2<<endl;
Instruction ins; ins.cmd=cmd2;
args >> ws;
while( args.good() )
{
std::string next; int param=-1;
args>>next>>ws;
for( unsigned int i=0;i<currentProc.params.size();++i )
{ if( next==currentProc.params[i] ) { param=i; break; } }
ins.args.push_back(next);
ins.params.push_back( param );
}
currentProc.instructions.push_back( ins );
}
void ShellProcedure::
cmdEndProcedure( const std::string& cmdLine,std::istringstream& args,std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - endproc..."
<< "\t\t\t\tProcedure end." <<endl;
return;
}
dgDEBUG(5)<<"Proc <" <<procName<<">: endproc"<<endl;
procedureList[ procName ] = currentProc;
// std::string toto="toto";
// for( Procedure::iterator ins=procedureList[ toto ].begin();
// ins!=procedureList[ toto ].end(); ++ins )
// {
// dgDEBUG(15) << "Proc <" << procName << "> : "
// << ins->cmd << " -> " << ins->args <<endl;
// }
currentProc.clear();
if( g_shell.deregisterFunction( procName ))
{ os<< "Redefining proc <"<<procName<<">: procedure already defined. "
<< "Overwrite it."<<endl; }
ShellFunctionRegisterer registration
( procName.c_str(),boost::bind(&ShellProcedure::cmdProcedure,
this,procName,_1,_2,_3) );
}
void ShellProcedure::
cmdProcedure( const std::string& procname,
const std::string& cmdLine,std::istringstream& args,std::ostream& os )
{
if( cmdLine == "help" )
{
os<<" - "<<procname<<"\t\t\t\t\tUser-defined procedure"<<endl;
args >> ws;
if( args.good() )
{
std::string argname;
const unsigned int gc = args.tellg();
args >> argname;
args.seekg(gc); args.clear();
if( procname==argname )
{
/* if cmdline = "Help <procname>", then display
* the proc instruction. */
ProcedureList::iterator pair = procedureList.find( argname );
if( pair==procedureList.end() )
{
DG_THROW ExceptionFactory( ExceptionFactory::UNREFERED_FUNCTION,
"Undefined procedure",
": procedure <%s> not defined.",
argname.c_str() );
}
Procedure & proc = pair->second;
unsigned int cmdnum=1;
for( std::list<Instruction>::iterator ins=proc.instructions.begin();
ins!=proc.instructions.end(); ++ins )
{
os<<"\t#" <<cmdnum++<<" "<<ins->cmd; // <<" "<<ins->args <<endl;
for( unsigned int i=0;i<ins->args.size();++i )
{ os << " " << ins->args[i]; }
os << endl;
}
}
}
return;
}
dgDEBUG(15) << " Calling procedure <" <<cmdLine<<"> " <<endl;
ProcedureList::iterator pair = procedureList.find( cmdLine );
if( pair==procedureList.end() )
{
DG_THROW ExceptionFactory( ExceptionFactory::UNREFERED_FUNCTION,
"Undefined procedure",
": procedure <%s> not defined.",cmdLine.c_str() );
}
/* You need a copy here, in case the proc is removed from the
* list by itself:
* % proc next
* % -> proc next
* % -> -> echo TOTO
* % -> endproc
* % endproc
*/
Procedure proc = pair->second;
std::vector< std::string > paramValue;
for( unsigned int i=0;i<proc.params.size();++i )
{
args>>ws;
if( args.good() )
{
std::string next; args>>next>>ws;
paramValue.push_back( next );
dgDEBUG(25) << "Args : <" << next << ">"<<endl;
}
else { paramValue.push_back(""); }
}
istringstream iss; ostringstream oss;
for( std::list<Instruction>::iterator ins=proc.instructions.begin();
ins!=proc.instructions.end(); ++ins )
{
dgDEBUG(15) << "Proc <" << cmdLine << "> : " << ins->cmd << endl;
oss.clear(); oss.str("");
for( unsigned int i=0;i<ins->params.size();++i )
{
int paramArg = ins->params[i];
if( paramArg==-1 ) oss << ins->args[i] << " ";
else oss << paramValue[paramArg] << " ";
}
dgDEBUG(15) << " Args = " << oss.str() << endl;
iss.str(oss.str()); iss.clear();
g_shell.cmd(ins->cmd,iss,os);
}
}
void ShellProcedure::
cmdFor( const std::string& cmdLine,std::istringstream& args,std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - for 1 5 instruction "<<endl;
return;
}
std::string cmd2,idx;
int istart,iend;
{
stringstream oss;
args >> cmd2; oss.str( cmd2 );
const unsigned int SIZE = 32; char b1[SIZE],b2[SIZE],b3[SIZE];
oss.getline( b1,SIZE,'=' );
oss.getline( b2,SIZE,':' );
oss.getline( b3,SIZE );
dgDEBUG(15) << b1 << "/" << b2 << "/" << b3 << endl;
idx = b1; istart = atoi(b2); iend = atoi(b3);
args >> cmd2;
dgDEBUG(15) << "FOR <" << idx << "> = " << istart << " TO " << iend
<< " DO " << cmd2 <<endl;
}
string argsstr;
{
const unsigned int SIZE = 1024; char buffer[SIZE];
args.getline( buffer,SIZE );
argsstr = buffer;
}
for( int i=istart;i<=iend;++i )
{
istringstream iss; stringstream oss;
std::string insp;
istringstream issargs( argsstr );
while( issargs.good() )
{
issargs >> insp;
if( insp == idx ) { oss << i << " "; } else { oss<<insp<< " "; }
}
iss.str( oss.str() );
g_shell.cmd(cmd2,iss,os);
}
}
ShellProcedure sotShellProceduror;
extern "C" {
ShellFunctionRegisterer regFun1
( "proc",boost::bind(&ShellProcedure::cmdStartProcedure,
&sotShellProceduror,_1,_2,_3) );
ShellFunctionRegisterer regFun2
( "->",boost::bind(&ShellProcedure::cmdContinueProcedure,
&sotShellProceduror,_1,_2,_3) );
ShellFunctionRegisterer regFun3
( "endproc",boost::bind(&ShellProcedure::cmdEndProcedure,
&sotShellProceduror,_1,_2,_3) );
ShellFunctionRegisterer regFun4
( "for",boost::bind(&ShellProcedure::cmdFor,
_1,_2,_3) );
}
/*
* Copyright 2010,
* François Bleibel,
* Olivier Stasse,
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/
#include <dynamic-graph/functions.h>
#include <dynamic-graph/plugin-loader.h>
#include <dynamic-graph/factory.h>
#include <dynamic-graph/debug.h>
#include <dynamic-graph/entity.h>
#include <dynamic-graph/signal.h>
#include <dynamic-graph/exception-signal.h>
#ifdef WIN32
#include <Windows.h>
#endif
#include <fstream>
using namespace std;
using namespace dynamicgraph;
void ShellFunctions::
cmdTry( const std::string cmdLine, istringstream& cmdArg, std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - try <cmd...>"
<< "\t\t\t\tTry <cmd> and display the caught exception." <<endl;
return;
}
string cmdLine2;
cmdArg>>cmdLine2;
dgDEBUG(5)<<"Try <" <<cmdLine2<<">"<<endl;
try{
g_shell.cmd(cmdLine2,cmdArg,os);
} catch ( const ExceptionAbstract& e ) { os << "dgERROR catch: " <<endl<< e<<endl; }
catch( ... ) { os<<"Unknown error catch." <<endl; }
}
void ShellFunctions::
cmdLoadPlugins( const std::string cmdLine, std::istringstream& cmdArg, std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - loadPlugins <file.txt> <directory>"
<< "\t\tLoad the plugins listed in the file." <<endl;
return;
}
if( NULL!=g_shell.dlPtr )
{
string pluginName,directory;
cmdArg >> pluginName;
cmdArg >> directory;
dgDEBUG(15) << "Load plugin list <" <<pluginName<<"> from dir <" << directory<<">."<<endl;
if( directory.length() != 0 ) g_shell.dlPtr->setDirectory( directory );
g_shell.dlPtr ->loadPluginList( pluginName );
g_shell.dlPtr->loadPlugins();
}
else { os << "!! Dynamic loading functionalities not accessible through the shell." <<endl; }
}
void ShellFunctions::
cmdClearPlugin( const std::string cmdLine, std::istringstream& cmdArg, std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - clearPlugin <className>"
<< "\t\tDestroy all the objects of type <className>." <<endl;
return;
}
string pluginName;
cmdArg >> pluginName;
g_pool.clearPlugin( pluginName );
}
void ShellFunctions::
cmdDisplayPlugins( const std::string cmdLine, std::istringstream& cmdArg, std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - displayPlugins "
<< "\t\t\t\tDisplay the name of the loaded plugins." <<endl;
return;
}
if( NULL!=g_shell.dlPtr )
{
std::map< std::string,std::string > m = g_shell.dlPtr->getLoadedPluginNames();
for( std::map< std::string,std::string >::const_iterator iter = m.begin();
iter!=m.end(); ++iter )
{
os << " - <"<<iter->first<<">:\t"<<iter->second<<endl;
}
}
else { os << "!! Dynamic loading functionalities not accessible through the shell." <<endl; }
}
void ShellFunctions::
cmdDisplayFactory( const std::string cmdLine, std::istringstream& cmdArg,
std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - "; g_factory.commandLine(cmdLine,cmdArg,os);
return;
}
string cmd2; cmdArg >> cmd2;
g_factory.commandLine( cmd2,cmdArg,os );
}
void ShellFunctions::
cmdCommentary( const std::string cmdLine, std::istringstream& cmdArg, std::ostream& os )
{
if( cmdLine == "help" )
{ os << " # comment with '#': ignore the end of the line." <<endl; }
return;
}
void ShellFunctions::
cmdUnplug( const std::string cmdLine, istringstream& cmdArg, std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - unplug <obj2.sig2>"
<< "\t\t\t\tPlug on sig2 (consumer) in sig1->sig2." <<endl;
return;
}
string ssig;
cmdArg>>ssig;
string obj2,fun2;
istringstream str2(ssig);
if( !Interpreter::objectNameParser(str2,obj2,fun2) )
{
DG_THROW ExceptionFactory( ExceptionFactory::SYNTAX_ERROR,
"Plug function: syntax is unplug OBJ2.SIG2.",
"(while calling plug %s %s).",ssig.c_str() );
}
dgDEBUG(20) << "Get Ent2 <"<<obj2<<"> ."<<endl;
Entity& ent2 = g_pool.getEntity(obj2);
dgDEBUG(20) << "Get Sig2 <"<<fun2<<"> ."<<endl;
SignalBase<int> &sig2 = ent2.getSignal(fun2);
dgDEBUG(25) << "Unplug..."<<endl;
sig2.unplug();
}
void ShellFunctions::
cmdSignalTime( const std::string cmdLine, istringstream& cmdArg, std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - signalTime <obj.sig>"
<< "\t\t\t\tDisplay the time of sig." <<endl;
return;
}
string ssig;
cmdArg>>ssig;
string obj2,fun2;
istringstream str2(ssig);
if( !Interpreter::objectNameParser(str2,obj2,fun2) )
{
DG_THROW ExceptionFactory( ExceptionFactory::SYNTAX_ERROR,
"signalTime function: syntax is signalTime OBJ2.SIG2.",
"(while calling signalTime %s).",ssig.c_str() );
}
dgDEBUG(20) << "Get Ent2 <"<<obj2<<"> ."<<endl;
Entity& ent2 = g_pool.getEntity(obj2);
dgDEBUG(20) << "Get Sig2 <"<<fun2<<"> ."<<endl;
SignalBase<int> &sig2 = ent2.getSignal(fun2);
os << sig2.getTime() << endl;
}
void ShellFunctions::
cmdSynchroSignal( const std::string cmdLine, std::istringstream& cmdArg, std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - synchro <obj.sig> [<period>]"
<< "\t\t\t\tGet/Set the syncho of a signal <sig>." <<endl;
return;
}
SignalBase<int> & sig = g_pool.getSignal( cmdArg );
cmdArg >>ws;
if( cmdArg.good() )
{
int period; cmdArg>>period;
sig.setPeriodTime( period );
cmdArg >>ws;
if( cmdArg.good() )
{
/* The sig is recomputed at the given period from the
* current time, at any time T so that T%p==0, p the period.
* By modifying the current time, the sig reomputation is done
* at T s.t. T%p=d, d the desynchro. */
int currTime = sig.getTime ();
int desynchro; cmdArg>>desynchro;
sig.setTime( currTime+desynchro );
}
}
else
{
os << "period = " << sig.getPeriodTime() << std::endl;
}
}
void ShellFunctions::
cmdEcho( const std::string cmdLine, std::istringstream& cmdArg, std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - echo <string>"
<< "\t\t\t\tPrint <string. on the standard output." <<endl;
return;
}
cmdArg >>ws;
while( cmdArg.good() )
{
std::string toPrint; cmdArg>>toPrint;
os<<toPrint<<" ";
}
os<<std::endl;
}
void ShellFunctions::
cmdCopy( const std::string cmdLine, istringstream& cmdArg, std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - copy <obj1.sig1> <obj2.sig2>"
<< "\t\tCopy the value of sig1 to constant value in sig2." <<endl;
return;
}
string ssig1,ssig2;
cmdArg>>ssig1>>ssig2;
istringstream str1(ssig1),str2(ssig2);
try {
SignalBase<int> &sig1 = g_pool.getSignal( str1 );
SignalBase<int> &sig2 = g_pool.getSignal( str2 );
dgDEBUG(25) << "Copy..."<<endl;
sig2.plug(&sig1);
sig2.setConstantDefault();
sig2.plug(&sig2);
} catch( ExceptionAbstract & err ) { throw; }
catch( ... ) {
DG_THROW ExceptionFactory( ExceptionFactory::SYNTAX_ERROR,
"Copy: syntax is copy OBJ1.SIG1 OBJ2.SIG2.",
"(while calling copy %s %s).",ssig1.c_str(),
ssig2.c_str() );
}
}
void ShellFunctions::
cmdFreeze( const std::string cmdLine, istringstream& cmdArg, std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - freeze <obj.sig> "
<< "\t\tOn a ptr-sig: save the current value from the source "
<< "and unplug the signal." <<endl;
return;
}
string ssig1;
cmdArg>>ssig1;
istringstream str1(ssig1);
try {
SignalBase<int> &sig1 = g_pool.getSignal( str1 );
dgDEBUG(25) << "Unplug..."<<endl;
sig1.setConstantDefault();
sig1.plug(&sig1);
} catch( ... ) {
DG_THROW ExceptionFactory( ExceptionFactory::SYNTAX_ERROR,
"Freeze: syntax is freeze OBJ.SIG.",
"(while calling freeze %s ).",ssig1.c_str());
}
}
void ShellFunctions::
cmdSqueeze( const std::string cmdLine, istringstream& cmdArg, std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - squeeze <mainObj.mainSig> <squeezeObj.sigIn> <squeezeObj.sigOut>"
<< "\t\tIntercalate squeezeObj between mainObj and its source." <<endl;
return;
}
string ssigMain,ssigIn,ssigOut;
cmdArg>>ssigMain>>ssigIn>>ssigOut;
istringstream strMain(ssigMain);
istringstream strIn(ssigIn);
istringstream strOut(ssigOut);
try {
SignalBase<int> &sigMain = g_pool.getSignal(strMain );
SignalBase<int> &sigIn = g_pool.getSignal( strIn );
SignalBase<int> &sigOut = g_pool.getSignal( strOut );
SignalBase<int> *sigMainSource = sigMain.getPluged();
if( sigMainSource==&sigMain )
{
DG_THROW ExceptionFactory( ExceptionFactory::SYNTAX_ERROR,
"The main signal is autopluged (or set constant). ",
"(while calling freeze %s ).",ssigMain.c_str());
}
sigMain.plug( &sigOut );
sigIn.plug( sigMainSource );
}
catch( ExceptionFactory& exc ) {
switch( exc.getCode() )
{
case ExceptionFactory::UNREFERED_SIGNAL:
DG_THROW ExceptionFactory( ExceptionFactory::SYNTAX_ERROR,
"Sqeeze: unknown signal. ",
"(error while searching signal: %s ).",
exc.getMessage() );
break;
default:
throw;
}
}
}
void ShellFunctions::
cmdEnableTrace( const std::string cmdLine, istringstream& cmdArg, std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - debugtrace [{true|false}] [<filename>="
<< DebugTrace::DEBUG_FILENAME_DEFAULT <<"]"
<< "\t\tOpen/close the file <filename> for debug tracing." <<endl;
return;
}
string opt,filename;
cmdArg >> ws;
if( cmdArg.good() )
{
cmdArg>>opt>>ws;
if( opt=="true" )
if( cmdArg.good() )
{
cmdArg>>filename;
DebugTrace::openFile( filename.c_str() );
}
else { DebugTrace::openFile(); }
else DebugTrace::closeFile();
}
else
{
if( dgDEBUGFLOW.outputbuffer.good() ) os << "true" <<endl;
else os << "false" <<endl;
}
}
void ShellFunctions::
cmdSetPrompt( const std::string cmdLine, istringstream& cmdArg, std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - prompt [<string>] "
<< "\t\tSet/get the default prompt." <<endl;
return;
}
string opt;
cmdArg >> ws;
if( cmdArg. good() )
{
char buffer [80]; cmdArg .getline(buffer,80);
g_shell .prompt = buffer;
} else { os << "Current prompt is <" << g_shell. prompt << ">." << endl; }
}
void ShellFunctions::
cmdSleep( const std::string cmdLine, istringstream& cmdArg, std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - sleep [<float> secs] "
<< "\t\tSleep (time in secs)." <<endl;
return;
}
string opt;
cmdArg >> ws;
if( cmdArg. good() )
{
double secs; cmdArg >> secs;
if( secs > 0 )
#ifndef WIN32
usleep( int(secs*1000000) );
#else
Sleep( int(secs*1000) );
#endif
} else { /* TODO ERROR */ }
}
void ShellFunctions::
cmdBeep( const std::string cmdLine, istringstream& cmdArg, std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - beep [<float> secs] "
<< "\t\tSend a bip to the std::cout." <<endl;
return;
}
os << char(7) << "Beep!" << std::endl;
}
void ShellFunctions::
cmdCompletionList( const std::string cmdLine, istringstream& cmdArg, std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - completion <filename>"
<< "\t\tGenerate the completion list for current graph." <<endl;
return;
}
try {
std::string aFileName; cmdArg >> aFileName;
std::ofstream completionFile((char *)aFileName.c_str());
g_pool.writeCompletionList( completionFile );
} catch( ExceptionAbstract & err ) { throw; }
catch( ... ) {
DG_THROW ExceptionFactory( ExceptionFactory::SYNTAX_ERROR,
"setflag: sig should be of flag type. ",
"(while calling setflag).");
}
}
......@@ -5,21 +5,10 @@
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/
#include <dynamic-graph/signal-array.h>
namespace dynamicgraph {
SignalArray<int> sotNOSIGNAL(0);
SignalArray<int> sotNOSIGNAL(0);
}
/*
* Copyright 2010,
* François Bleibel,
* Olivier Stasse,
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/
#include <dynamic-graph/signal-caster.h>
#include <dynamic-graph/dynamic-graph-api.h>
#include <exception>
#include <boost/lambda/bind.hpp>
#include <string>
#include <sstream>
#include <algorithm>
#include <dynamic-graph/exception-signal.h>
using namespace std;
using namespace boost;
namespace dynamicgraph {
SignalCaster::SignalCaster() {
// nothing to initialize
}
SignalCaster::~SignalCaster() {
// no special cleanup to do
}
void SignalCaster::registerCast(const type_info& type, SignalCaster::displayer_type displayer,
SignalCaster::caster_type caster, SignalCaster::tracer_type tracer) {
if ( existsCast(type) ) {
std::string typeName(type.name());
std::ostringstream os;
os << "cast already registered for type " << typeName << ".";
throw ExceptionSignal(ExceptionSignal::GENERIC,
os.str()); //TODO: throw "cast already registered for type" exception
}
functions_[type.name()] = cast_functions_type(displayer,caster, tracer);
}
void SignalCaster::unregisterCast(const std::type_info& type) {
size_t n = functions_.erase(type.name());
if ( 0 == n ) // erase did not find element
throw ExceptionSignal(ExceptionSignal::GENERIC); // TODO: throw Cast not registered exception
}
bool SignalCaster::existsCast(const type_info& type) {
return functions_.find(type.name()) != functions_.end();
}
void SignalCaster::disp(const any& object, ostream& os) {
const char* type_name = object.type().name();
map<string, cast_functions_type>::iterator it =
functions_.find(type_name);
if ( it == functions_.end() )
throw ExceptionSignal(ExceptionSignal::BAD_CAST, "bad cast");
//TODO: throw "cast not registered" exception
(*it).second.get<0>()(object, os); // call display function (tuple index 0)
}
void SignalCaster::trace(const any& object, ostream& os) {
const char* type_name = object.type().name();
map<string, cast_functions_type>::iterator it =
functions_.find(type_name);
if ( it == functions_.end() )
throw ExceptionSignal(ExceptionSignal::BAD_CAST, "bad cast");;
//TODO: throw "cast not registered" exception
(*it).second.get<2>()(object, os); // call trace function (tuple index 2)
}
any SignalCaster::cast(const type_info& type, istringstream& iss) {
const char* type_name = type.name();
map<string, cast_functions_type>::iterator it = functions_.find(type_name);
if ( it == functions_.end() )
{
throw ExceptionSignal(ExceptionSignal::BAD_CAST,
"caster not in functions_ map.");
}
//TODO: throw "cast not registered" exception
return (*it).second.get<1>()(iss); // call cast function (tuple index 1)
}
/// The global instance of the caster class.
SignalCaster g_caster;
/// Registers useful casts
namespace {
DefaultCastRegisterer<double> double_reg;
DefaultCastRegisterer<int> int_reg;
DefaultCastRegisterer<unsigned int> uint_reg;
}
} // namespace dynamicgraph
......@@ -5,17 +5,6 @@
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/
/* --------------------------------------------------------------------- */
......@@ -23,149 +12,159 @@
/* --------------------------------------------------------------------- */
/* DG */
#include <iomanip>
#include <boost/bind.hpp>
#include <dynamic-graph/tracer-real-time.h>
#include <dynamic-graph/all-commands.h>
#include <dynamic-graph/debug.h>
#include <dynamic-graph/pool.h>
#include <dynamic-graph/factory.h>
#include <dynamic-graph/pool.h>
#include <dynamic-graph/tracer-real-time.h>
#include <boost/bind.hpp>
#include <iomanip>
using namespace std;
using namespace dynamicgraph;
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(TracerRealTime,"TracerRealTime");
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(TracerRealTime, "TracerRealTime");
/* --------------------------------------------------------------------- */
/* --- DGOUTSTRINGSTREAM ---------------------------------------------- */
/* --------------------------------------------------------------------- */
OutStringStream::
OutStringStream( void )
: std::ostringstream()
,buffer( 0 ),index(0),bufferSize(0),full(false)
{
OutStringStream::OutStringStream()
: std::ostringstream(), buffer(0), index(0), bufferSize(0), full(false) {
dgDEBUGINOUT(15);
}
OutStringStream::
~OutStringStream( void )
{
OutStringStream::~OutStringStream() {
dgDEBUGIN(15);
if( buffer ) delete [] buffer ;
delete[] buffer;
dgDEBUGOUT(15);
}
void OutStringStream::
resize( const unsigned int & size )
{
void OutStringStream::resize(const std::streamsize &size) {
dgDEBUGIN(15);
index=0; bufferSize = size; full=false;
if( 0!=buffer ) delete [] buffer;
buffer = new char [size];
index = 0;
bufferSize = size;
full = false;
delete[] buffer;
buffer = new char[static_cast<size_t>(size)];
dgDEBUGOUT(15);
}
bool OutStringStream::
addData( const char * data, const unsigned int & size )
{
bool OutStringStream::addData(const char *data, const std::streamoff &size) {
dgDEBUGIN(15);
unsigned int towrite = size;
if( index+towrite>bufferSize )
{
dgDEBUGOUT(15);
full=true;
return false;
}//towrite=bufferSize-index;
memcpy( buffer+index,data,towrite );
index+=towrite;
std::streamsize towrite = static_cast<std::streamsize>(size);
if (index + towrite > bufferSize) {
dgDEBUGOUT(15);
full = true;
return false;
}
memcpy(buffer + index, data, static_cast<size_t>(towrite));
index += towrite;
dgDEBUGOUT(15);
return true;
}
}
void OutStringStream::
dump( std::ostream& os )
{
void OutStringStream::dump(std::ostream &os) {
dgDEBUGIN(15);
os.write( buffer,index );
os.write(buffer, index);
dgDEBUGOUT(15);
}
void OutStringStream::
empty( void )
{
void OutStringStream::empty() {
dgDEBUGIN(15);
index=0; full=false;
index = 0;
full = false;
dgDEBUGOUT(15);
}
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
TracerRealTime::TracerRealTime( const std::string n )
:Tracer(n)
,bufferSize( BUFFER_SIZE_DEFAULT )
{
TracerRealTime::TracerRealTime(const std::string &n)
: Tracer(n), bufferSize(BUFFER_SIZE_DEFAULT) {
dgDEBUGINOUT(15);
/* --- Commands --- */
{
using namespace dynamicgraph::command;
std::string doc = docCommandVoid0(
"Trash the current content of the buffers, without saving it.");
addCommand("empty",
makeCommandVoid0(*this, &TracerRealTime::emptyBuffers, doc));
addCommand("getBufferSize",
makeDirectGetter(*this, &bufferSize,
docDirectGetter("bufferSize", "int")));
addCommand("setBufferSize",
makeDirectSetter(*this, &bufferSize,
docDirectSetter("bufferSize", "int")));
} // using namespace command
dgDEBUGOUT(15);
}
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
void TracerRealTime::
openFile( const SignalBase<int> & sig,
const std::string& givenname )
{
void TracerRealTime::openFile(const SignalBase<int> &sig,
const std::string &givenname) {
dgDEBUGIN(15);
string signame;
if( givenname.length() )
{ signame = givenname; } else { signame = sig.shortName(); }
if (givenname.length()) {
signame = givenname;
} else {
signame = sig.shortName();
}
string filename = rootdir + basename + signame + suffix;
dgDEBUG(5) << "Sig <"<<sig.getName()
<< ">: new file "<< filename << endl;
std::ofstream * newfile = new std::ofstream( filename.c_str() );
dgDEBUG(5) << "Newfile:" << (void*) newfile << endl;
hardFiles.push_back( newfile );
dgDEBUG(5) << "Sig <" << sig.getName() << ">: new file " << filename << endl;
std::ofstream *newfile = new std::ofstream(filename.c_str());
if (!newfile->good()) {
delete newfile;
DG_THROW ExceptionTraces(
ExceptionTraces::NOT_OPEN,
"Could not open file " + filename + " for signal " + signame, "");
}
dgDEBUG(5) << "Newfile:" << (void *)newfile << endl;
hardFiles.push_back(newfile);
dgDEBUG(5) << "Creating Outstringstream" << endl;
//std::stringstream * newbuffer = new std::stringstream();
OutStringStream * newbuffer = new OutStringStream(); // std::stringstream();
newbuffer->resize( bufferSize );
// std::stringstream * newbuffer = new std::stringstream ();
OutStringStream *newbuffer = new OutStringStream(); // std::stringstream ();
newbuffer->resize(bufferSize);
newbuffer->givenname = givenname;
files.push_back( newbuffer );
files.push_back(newbuffer);
dgDEBUGOUT(15);
}
void TracerRealTime::
closeFiles( void )
{
void TracerRealTime::closeFiles() {
dgDEBUGIN(15);
std::lock_guard<std::mutex> files_lock(files_mtx);
FileList::iterator iter = files.begin();
HardFileList::iterator hardIter = hardFiles.begin();
while( files.end()!=iter )
{
dgDEBUG(25) << "Close the files." << endl;
while (files.end() != iter) {
dgDEBUG(25) << "Close the files." << endl;
std::stringstream * file = dynamic_cast< stringstream* >(*iter);
std::ofstream * hardFile = *hardIter;
std::stringstream *file = dynamic_cast<stringstream *>(*iter);
std::ofstream *hardFile = *hardIter;
(*hardFile) <<flush; hardFile->close();
delete file;
delete hardFile;
(*hardFile) << flush;
hardFile->close();
delete file;
delete hardFile;
++iter; ++hardIter;
}
++iter;
++hardIter;
}
dgDEBUG(25) << "Clear the lists." << endl;
files.clear();
......@@ -174,207 +173,133 @@ closeFiles( void )
dgDEBUGOUT(15);
}
void TracerRealTime::
trace( void )
{
void TracerRealTime::trace() {
dgDEBUGIN(15);
FileList::iterator iter = files.begin();
HardFileList::iterator hardIter = hardFiles.begin();
while( files.end()!=iter )
{
dgDEBUG(35) << "Next" << endl;
std::ostream * os = *iter;
if( NULL==os )
{ DG_THROW ExceptionTraces( ExceptionTraces::NOT_OPEN,
"The buffer is null",""); }
//std::stringstream & file = * dynamic_cast< stringstream* >(os);
OutStringStream * file = dynamic_cast< OutStringStream* >(os); // segfault
if( NULL==file )
{ DG_THROW ExceptionTraces( ExceptionTraces::NOT_OPEN,
"The buffer is not open",""); }
std::ofstream & hardFile = **hardIter;
if(! hardFile.good() )
{ DG_THROW ExceptionTraces( ExceptionTraces::NOT_OPEN,
"The file is not open",""); }
if( (hardFile.good())&&(NULL!=file) )
{
// const unsigned int SIZE = 1024*8;
// char buffer[SIZE];
// streambuf * pbuf = file.rdbuf();
// pbuf->pubseekpos(0);
// const unsigned int NB_BYTE = pbuf->in_avail();
// dgDEBUG(35) << "Bytes in buffer: " << NB_BYTE << endl;
// //dgDEBUG(35) << "Copie" <<endl<<file.str()<< endl;
// for( unsigned int index=0;index<NB_BYTE;index+=SIZE )
// {
// pbuf->pubseekpos( index );
// int nget = pbuf->sgetn( buffer,SIZE );
// dgDEBUG(35) << "Copie ["<<nget<<"] " <<buffer<<endl;
// hardFile.write( buffer,nget );
// }
//hardFile << file.str() << flush;
//file.seekp(0);
file->dump( hardFile );
file->empty();
hardFile.flush();
//file.str("");
}
++iter; ++hardIter;
while (files.end() != iter) {
dgDEBUG(35) << "Next" << endl;
std::ostream *os = *iter;
if (NULL == os) {
DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN, "The buffer is null",
"");
}
// std::stringstream & file = * dynamic_cast< stringstream* >(os);
OutStringStream *file = dynamic_cast<OutStringStream *>(os); // segfault
if (NULL == file) {
DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN,
"The buffer is not open", "");
}
std::ofstream &hardFile = **hardIter;
if (!hardFile.good()) {
DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN,
"The file is not open", "");
}
if ((hardFile.good()) && (NULL != file)) {
file->dump(hardFile);
file->empty();
hardFile.flush();
}
++iter;
++hardIter;
}
dgDEBUGOUT(15);
}
void TracerRealTime::
emptyBuffers( void )
{
void TracerRealTime::emptyBuffers() {
dgDEBUGIN(15);
for( FileList::iterator iter = files.begin();files.end()!=iter;++iter )
{
//std::stringstream & file = * dynamic_cast< stringstream* >(*iter);
try {
OutStringStream & file = * dynamic_cast< OutStringStream* >(*iter);
file.empty();
//file.str("");
}
catch( ... ) { DG_THROW ExceptionTraces( ExceptionTraces::NOT_OPEN,
"The buffer is not open",""); }
for (FileList::iterator iter = files.begin(); files.end() != iter; ++iter) {
// std::stringstream & file = * dynamic_cast< stringstream* >(*iter);
try {
OutStringStream &file = *dynamic_cast<OutStringStream *>(*iter);
file.empty();
// file.str("");
} catch (...) {
DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN,
"The buffer is not open", "");
}
}
dgDEBUGOUT(15);
}
// void TracerRealTime::
// emptyBuffer( std::stringstream & file )
// {
// streambuf * pbuf = file.rdbuf();
// pbuf->file.rdbuf() ->pubsetbuf( fileBuffer,10 );
// }
void TracerRealTime::
recordSignal( std::ostream& os,
const SignalBase<int>& sig )
{
void TracerRealTime::recordSignal(std::ostream &os,
const SignalBase<int> &sig) {
dgDEBUGIN(15);
try {
OutStringStream & file = dynamic_cast< OutStringStream& >(os);
OutStringStream &file = dynamic_cast<OutStringStream &>(os);
file.str("");
dgDEBUG(45) << "Empty file [" << file.tellp()
<< "] <" << file.str().c_str() <<"> " <<endl;
Tracer::recordSignal( file,sig );
file.addData( file.str().c_str(),file.tellp() );
dgDEBUG(35) << "Write data [" << file.tellp()
<< "] <" << file.str().c_str() <<"> " <<endl;
} catch( ExceptionAbstract & exc ) { throw exc; }
catch( ... ) {
DG_THROW ExceptionTraces( ExceptionTraces::NOT_OPEN,
"The buffer is not open","");
dgDEBUG(45) << "Empty file [" << file.tellp() << "] <" << file.str().c_str()
<< "> " << endl;
Tracer::recordSignal(file, sig);
file.addData(file.str().c_str(), file.tellp());
dgDEBUG(35) << "Write data [" << file.tellp() << "] <" << file.str().c_str()
<< "> " << endl;
} catch (ExceptionAbstract &exc) {
throw;
} catch (...) {
DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN,
"The buffer is not open", "");
}
dgDEBUGOUT(15);
return ;
return;
}
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
void TracerRealTime::
display( std::ostream& os ) const
{
os << CLASS_NAME << " " << name << " [mode=" << (play?"play":"pause")
<< "] : "<< endl
<< " - Dep list: "<<endl;
void TracerRealTime::display(std::ostream &os) const {
os << CLASS_NAME << " " << name << " [mode=" << (play ? "play" : "pause")
<< "] : " << endl
<< " - Dep list: " << endl;
FileList::const_iterator iterFile = files.begin();
for( SignalList::const_iterator iter = toTraceSignals.begin();
toTraceSignals.end()!=iter;++iter )
{
dgDEBUG(35) << "Next" << endl;
const OutStringStream * file = dynamic_cast< OutStringStream* >(*iterFile);
os << " -> "<<(*iter)->getName();
if( file->givenname.length() ) os << " (in " << file->givenname << ")" ;
os << "\t";
if( file )
{
const std::streamsize PRECISION = os.precision();
const unsigned int SIZE = file->index;
const unsigned int MSIZE = file->bufferSize;
unsigned int dec=0; std::string unit ="";
if( (SIZE>>30)||(MSIZE>>30) ) { dec = 30; unit="Go"; }
else if( (SIZE>>20)||(MSIZE>>20) ) { dec = 20; unit="Mo"; }
else if( (SIZE>>10)||(MSIZE>>10) ) { dec = 10; unit="Ko"; }
os << "[" << std::setw(1)<<std::setprecision(1)
<< ((SIZE+0.0)/(1<<dec)) << unit << "/"
<< std::setprecision(2)<<((MSIZE+0.0)/(1<<dec))
<< unit << "]\t";
if( file->full ) os << "(FULL)";
os.precision(PRECISION);
}
os<<endl;
iterFile++;
for (SignalList::const_iterator iter = toTraceSignals.begin();
toTraceSignals.end() != iter; ++iter) {
dgDEBUG(35) << "Next" << endl;
const OutStringStream *file = dynamic_cast<OutStringStream *>(*iterFile);
os << " -> " << (*iter)->getName();
if (file->givenname.length()) os << " (in " << file->givenname << ")";
os << "\t";
if (file) {
const std::streamsize PRECISION = os.precision();
const std::streamsize SIZE = file->index;
const std::streamsize MSIZE = file->bufferSize;
unsigned int dec = 0;
std::string unit = "";
if ((SIZE >> 30) || (MSIZE >> 30)) {
dec = 30;
unit = "Go";
} else if ((SIZE >> 20) || (MSIZE >> 20)) {
dec = 20;
unit = "Mo";
} else if ((SIZE >> 10) || (MSIZE >> 10)) {
dec = 10;
unit = "Ko";
}
os << "[" << std::setw(1) << std::setprecision(1)
<< (((double)SIZE + 0.0) / (1 << dec)) << unit << "/"
<< std::setprecision(2) << (((double)MSIZE + 0.0) / (1 << dec)) << unit
<< "]\t";
if (file->full) os << "(FULL)";
os.precision(PRECISION);
}
os << endl;
++iterFile;
}
}
std::ostream& operator<< ( std::ostream& os,const TracerRealTime& t )
{
std::ostream &operator<<(std::ostream &os, const TracerRealTime &t) {
t.display(os);
return os;
}
void TracerRealTime::
commandLine( const std::string& cmdLine
,std::istringstream& cmdArgs
,std::ostream& os )
{
if( cmdLine=="help" )
{
os << "TracerRealTime: "<<endl
<< " - empty: trash the buffers." <<endl
<< " - bufferSize [<size>]: get/set the buffer size." <<endl;
Tracer::commandLine( cmdLine,cmdArgs,os );
}
else if( cmdLine=="empty" )
{
emptyBuffers();
}
else if( cmdLine=="bufferSize" )
{
cmdArgs>>ws;
if( cmdArgs.good() )
{
int s; cmdArgs>>s;
setBufferSize( s );
}
else os << getBufferSize() << endl;
}
else
Tracer::commandLine( cmdLine,cmdArgs,os );
}
......@@ -5,17 +5,6 @@
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/
/* --------------------------------------------------------------------- */
......@@ -23,55 +12,108 @@
/* --------------------------------------------------------------------- */
/* DG */
#include <dynamic-graph/tracer.h>
#include <dynamic-graph/all-commands.h>
#include <dynamic-graph/debug.h>
#include <dynamic-graph/pool.h>
#include <dynamic-graph/factory.h>
#include <dynamic-graph/pool.h>
#include <dynamic-graph/tracer.h>
#include <dynamic-graph/value.h>
#include <boost/bind.hpp>
using namespace std;
using namespace dynamicgraph;
using namespace dynamicgraph::command;
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(Tracer,"Tracer");
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(Tracer, "Tracer");
/* --------------------------------------------------------------------- */
/* --- CLASS ----------------------------------------------------------- */
/* --------------------------------------------------------------------- */
Tracer::Tracer( const std::string n )
:Entity(n)
,toTraceSignals()
,traceStyle(TRACE_STYLE_DEFAULT)
,frequency(1)
,basename()
,suffix(".dat")
,rootdir()
,namesSet( false )
,files()
,names()
,play(false)
,timeStart(0)
,triger( boost::bind(&Tracer::recordTrigger,this,_1,_2),
sotNOSIGNAL,
"Tracer("+n+")::triger" )
{
signalRegistration( triger );
Tracer::Tracer(const std::string n)
: Entity(n),
toTraceSignals(),
traceStyle(TRACE_STYLE_DEFAULT),
frequency(1),
basename(),
suffix(".dat"),
rootdir(),
namesSet(false),
files(),
names(),
play(false),
timeStart(0),
triger(boost::bind(&Tracer::recordTrigger, this, _1, _2), sotNOSIGNAL,
"Tracer(" + n + ")::triger") {
signalRegistration(triger);
/* --- Commands --- */
{
using namespace dynamicgraph::command;
std::string doc;
doc = docCommandVoid2("Add a new signal to trace.", "string (signal name)",
"string (filename, empty for default");
addCommand("add",
makeCommandVoid2(*this, &Tracer::addSignalToTraceByName, doc));
doc =
docCommandVoid0("Remove all signals. If necessary, close open files.");
addCommand("clear",
makeCommandVoid0(*this, &Tracer::clearSignalToTrace, doc));
doc = docCommandVoid3(
"Gives the args for file opening, and "
"if signals have been set, open the corresponding files.",
"string (dirname)", "string (prefix)", "string (suffix)");
addCommand("open", makeCommandVoid3(*this, &Tracer::openFiles, doc));
doc = docCommandVoid0("Close all the open files.");
addCommand("close", makeCommandVoid0(*this, &Tracer::closeFiles, doc));
doc = docCommandVoid0(
"If necessary, dump "
"(can be done automatically for some traces type).");
addCommand("dump", makeCommandVoid0(*this, &Tracer::trace, doc));
doc = docCommandVoid0("Start the tracing process.");
addCommand("start", makeCommandVoid0(*this, &Tracer::start, doc));
doc = docCommandVoid0("Stop temporarily the tracing process.");
addCommand("stop", makeCommandVoid0(*this, &Tracer::stop, doc));
addCommand("getTimeStart",
makeDirectGetter(*this, &timeStart,
docDirectGetter("timeStart", "int")));
addCommand("setTimeStart",
makeDirectSetter(*this, &timeStart,
docDirectSetter("timeStart", "int")));
} // using namespace command
}
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
void Tracer::addSignalToTrace(const SignalBase<int> &sig,
const string &filename) {
dgDEBUGIN(15);
// openFile may throw so it should be called first.
if (namesSet) openFile(sig, filename);
toTraceSignals.push_back(&sig);
dgDEBUGF(15, "%p", &sig);
names.push_back(filename);
triger.addDependency(sig);
dgDEBUGOUT(15);
}
void Tracer::
addSignalToTrace( const SignalBase<int>& sig,
const string& filename )
{
void Tracer::addSignalToTraceByName(const string &signame,
const string &filename) {
dgDEBUGIN(15);
toTraceSignals.push_back( &sig ); dgDEBUGF(15,"%p",&sig);
names.push_back( filename );
if( namesSet ) openFile( sig,filename );
triger.addDependency( sig );
istringstream iss(signame);
SignalBase<int> &sig = PoolStorage::getInstance()->getSignal(iss);
addSignalToTrace(sig, filename);
dgDEBUGOUT(15);
}
......@@ -79,76 +121,70 @@ addSignalToTrace( const SignalBase<int>& sig,
* does not modify the file list (it does not close
* the files in particular.
*/
void Tracer::
clearSignalToTrace( void )
{
void Tracer::clearSignalToTrace() {
closeFiles();
toTraceSignals.clear();
triger.clearDependencies();
}
// void Tracer::
// parasite( SignalBase<int>& sig )
// {
// triger.parasite(sig);
// }
void Tracer::
openFiles( const std::string& rootdir_, const std::string& basename_,
const std::string& suffix_ )
{
void Tracer::openFiles(const std::string &rootdir_,
const std::string &basename_,
const std::string &suffix_) {
dgDEBUGIN(15);
int n = rootdir_.length();
rootdir=rootdir_;
if( (0<n)&('/'!=rootdir[n-1]) ) rootdir+='/';
std::basic_string<char>::size_type n = rootdir_.length();
rootdir = rootdir_;
if ((0 < n) & ('/' != rootdir[n - 1])) rootdir += '/';
basename=basename_;
suffix=suffix_;
basename = basename_;
suffix = suffix_;
if( files.size() ) closeFiles();
if (files.size()) closeFiles();
SignalList::const_iterator iter = toTraceSignals.begin();
NameList::const_iterator iterName = names.begin();
while( toTraceSignals.end()!=iter )
{
dgDEBUG(15) << "Open <" << (*iter)->getName()
<< "> in <" << *iterName << ">." << std::endl;
openFile( **iter,*iterName );
++iter; ++iterName;
}
while (toTraceSignals.end() != iter) {
dgDEBUG(15) << "Open <" << (*iter)->getName() << "> in <" << *iterName
<< ">." << std::endl;
openFile(**iter, *iterName);
++iter;
++iterName;
}
namesSet = true;
dgDEBUGOUT(15);
}
void Tracer::
openFile( const SignalBase<int> & sig,
const string& givenname )
{
void Tracer::openFile(const SignalBase<int> &sig, const string &givenname) {
dgDEBUGIN(15);
string signame;
if( givenname.length() )
{ signame = givenname; } else { signame = sig.shortName(); }
if (givenname.length()) {
signame = givenname;
} else {
signame = sig.shortName();
}
string filename = rootdir + basename + signame + suffix;
dgDEBUG(5) << "Sig <"<< sig.getName() << ">: new file "<< filename << endl;
std::ofstream * newfile = new std::ofstream( filename.c_str() );
files.push_back( newfile );
dgDEBUG(5) << "Sig <" << sig.getName() << ">: new file " << filename << endl;
std::ofstream *newfile = new std::ofstream(filename.c_str());
files.push_back(newfile);
dgDEBUGOUT(15);
}
void Tracer::
closeFiles( void )
{
void Tracer::closeFiles() {
dgDEBUGIN(15);
std::lock_guard<std::mutex> files_lock(files_mtx);
for( FileList::iterator iter = files.begin();files.end()!=iter;++iter )
{
std::ostream * filePtr = *iter;
delete filePtr;
}
for (FileList::iterator iter = files.begin(); files.end() != iter; ++iter) {
std::ostream *filePtr = *iter;
delete filePtr;
}
files.clear();
dgDEBUGOUT(15);
......@@ -158,164 +194,83 @@ closeFiles( void )
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
void Tracer::
record( void )
{
if(! play) { dgDEBUGINOUT(15); return;}
void Tracer::record() {
if (!play) {
dgDEBUGINOUT(15);
return;
}
dgDEBUGIN(15);
if( files.size()!=toTraceSignals.size() )
{ DG_THROW ExceptionTraces( ExceptionTraces::NOT_OPEN,
"No files open for tracing"," (file=%d != %d=sig).",
files.size(),toTraceSignals.size()); }
// Ensure record() never hangs. If the attempt to acquire the lock fails,
// then closeFiles() is active and we shouldn't write to files anyways.
std::unique_lock<std::mutex> files_lock(files_mtx, std::try_to_lock);
if (!files_lock.owns_lock()) {
dgDEBUGOUT(15);
return;
}
if (files.size() != toTraceSignals.size()) {
DG_THROW
ExceptionTraces(ExceptionTraces::NOT_OPEN, "No files open for tracing",
" (file=%d != %d=sig).", files.size(),
toTraceSignals.size());
}
FileList::iterator iterFile = files.begin();
SignalList::iterator iterSig = toTraceSignals.begin();
while( toTraceSignals.end()!=iterSig )
{
dgDEBUG(45) << "Try..." <<endl;
recordSignal( **iterFile,**iterSig );
++iterSig; ++iterFile;
}
while (toTraceSignals.end() != iterSig) {
dgDEBUG(45) << "Try..." << endl;
recordSignal(**iterFile, **iterSig);
++iterSig;
++iterFile;
}
dgDEBUGOUT(15);
}
void Tracer::
recordSignal( std::ostream& os,
const SignalBase<int>& sig )
{
void Tracer::recordSignal(std::ostream &os, const SignalBase<int> &sig) {
dgDEBUGIN(15);
try {
if( sig.getTime()>timeStart )
{
os<< sig.getTime() << "\t";
sig.trace(os); os<<endl;
}
if (sig.getTime() > timeStart) {
os << sig.getTime() << "\t";
sig.trace(os);
os << endl;
}
} catch (ExceptionAbstract &exc) {
os << exc << std::endl;
} catch (...) {
os << "Unknown error occurred while reading signal." << std::endl;
}
catch( ExceptionAbstract& exc ) { os << exc << std::endl; }
catch( ... ) { os << "Unknown error occured while reading signal." << std::endl; }
dgDEBUGOUT(15);
dgDEBUGOUT(15);
}
int& Tracer::
recordTrigger( int& dummy, const int& time )
{
dgDEBUGIN(15) << " time="<<time <<endl;
int &Tracer::recordTrigger(int &dummy, const int &time) {
dgDEBUGIN(15) << " time=" << time << endl;
record();
dgDEBUGOUT(15);
return dummy;
}
void Tracer::
trace( void )
{
}
void Tracer::trace() {}
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
void Tracer::
display( std::ostream& os ) const
{
os << CLASS_NAME << " " << name << " [mode=" << (play?"play":"pause")
<< "] : "<< endl
<< " - Dep list: "<<endl;
for( SignalList::const_iterator iter = toTraceSignals.begin();
toTraceSignals.end()!=iter;++iter )
{ os << " -> "<<(*iter)->getName()<<endl; }
void Tracer::display(std::ostream &os) const {
os << CLASS_NAME << " " << name << " [mode=" << (play ? "play" : "pause")
<< "] : " << endl
<< " - Dep list: " << endl;
for (SignalList::const_iterator iter = toTraceSignals.begin();
toTraceSignals.end() != iter; ++iter) {
os << " -> " << (*iter)->getName() << endl;
}
}
std::ostream& operator<< ( std::ostream& os,const Tracer& t )
{
std::ostream &operator<<(std::ostream &os, const Tracer &t) {
t.display(os);
return os;
}
void Tracer::
commandLine( const std::string& cmdLine
,std::istringstream& cmdArgs
,std::ostream& os )
{
if( cmdLine=="help" )
{
os << "Tracer: "<<endl
<< " - add <obj.signal> [<filename>=<signal>] "<<endl
<< " - clear"<<endl
<< " - open [<root> [<file> [<suffix>=.dat]]]"<<endl
<< " - close "<<endl
<< " - record "<<endl
<< " - trace "<<endl
<< " - start/stop" << endl;
// << " - parasite <obj.signal> "<<endl;
Entity::commandLine( cmdLine,cmdArgs,os );
}
else if( cmdLine=="add" )
{
SignalBase<int> &sig = g_pool.getSignal(cmdArgs);
string r; cmdArgs>>ws>>r;
addSignalToTrace(sig,r);
dgDEBUG(14)<<"Add <" <<sig.getName()<<"> with nick \""<<r<<"\""<<endl;
}
else if( cmdLine=="clear" )
{ closeFiles(); toTraceSignals.clear(); }
else if( cmdLine=="open" )
{
string n,r="",s=".dat";
cmdArgs>>ws>>r;
if( cmdArgs.good() )
{
cmdArgs>>ws>>n;
if( cmdArgs.good() )
{
cmdArgs>>ws>>s;
}
}
//>>r>>s;
dgDEBUGF( 15,"Close files.");
closeFiles();
dgDEBUGF( 15,"Open files \"%s\" \"%s\" \"%s\".",
r.c_str(),n.c_str(),s.c_str());
openFiles(r,n,s);
}
else if( cmdLine=="close" ) { closeFiles(); }
else if( cmdLine=="trace" ) { trace(); }
else if( cmdLine=="record" )
{
//unsigned int t;
//cmdArgs >> ws>>t; if(! cmdArgs.good() ) t=0;
record();
}
// else if( cmdLine=="parasite" )
// {
// SignalBase<int> &sig = g_pool.getSignal( cmdArgs );
// parasite(sig);
// }
else if( cmdLine == "start" ) { play=true; }
else if( cmdLine == "stop" ) { play=false; }
else if( cmdLine == "timeStart" )
{
cmdArgs >> std::ws; if(! cmdArgs.good() )
{ os << "timeStart = " << timeStart << std::endl; }
else { cmdArgs >> timeStart; }
}
else //sotTaskAbstract::
Entity::commandLine( cmdLine,cmdArgs,os );
}
# Copyright 2010-2020, Olivier Stasse, Guilhem Saurel, JRL, CNRS/AIST, LAAS-CNRS
add_definitions(-DBOOST_TEST_DYN_LINK -DBOOST_TEST_MAIN)
add_definitions(-DTESTS_DATADIR="${CMAKE_CURRENT_SOURCE_DIR}/data")
add_definitions(-DTESTS_PLUGINDIR="${LIBRARY_OUTPUT_PATH}")
add_definitions(-DTESTS_DYNLIBSUFFIX="${CMAKE_SHARED_LIBRARY_SUFFIX}")
macro(DYNAMIC_GRAPH_TEST NAME)
add_unit_test(${NAME} "${NAME}.cpp")
target_link_libraries(${NAME} PRIVATE ${PROJECT_NAME}
Boost::unit_test_framework)
endmacro(DYNAMIC_GRAPH_TEST)
# Signal cast test.
set(signalcast_libs signal-cast-registerer-libA signal-cast-registerer-libB)
foreach(lib ${signalcast_libs})
add_library(${lib} SHARED "${lib}.cpp")
target_link_libraries(${lib} PRIVATE ${PROJECT_NAME})
endforeach()
dynamic_graph_test(signal-cast-registerer)
# Unit testing.
if(NOT APPLE)
dynamic_graph_test(entity)
endif(NOT APPLE)
dynamic_graph_test(custom-entity)
dynamic_graph_test(factory)
dynamic_graph_test(pool)
dynamic_graph_test(signal-time-dependent)
dynamic_graph_test(value)
dynamic_graph_test(signal-ptr)
dynamic_graph_test(real-time-logger)
dynamic_graph_test(debug-trace)
dynamic_graph_test(debug-tracer)
target_link_libraries(debug-tracer PRIVATE tracer)
dynamic_graph_test(debug-real-time-tracer)
target_link_libraries(debug-real-time-tracer PRIVATE tracer-real-time tracer)
dynamic_graph_test(debug-logger)
dynamic_graph_test(debug-logger-winit)
dynamic_graph_test(signal-all)
dynamic_graph_test(command-test)
dynamic_graph_test(test-mt)
target_link_libraries(test-mt PRIVATE tracer)
dynamic_graph_test(exceptions)
/* Copyright 2019, LAAS-CNRS
*
* Olivier Stasse
*
* See LICENSE file
*
*/
#include <dynamic-graph/entity.h>
#include <dynamic-graph/exception-factory.h>
#include <iostream>
#include <sstream>
#include "dynamic-graph/command-bind.h"
#include "dynamic-graph/factory.h"
#include "dynamic-graph/pool.h"
#define ENABLE_RT_LOG
#include <dynamic-graph/logger.h>
#include <dynamic-graph/real-time-logger.h>
#define BOOST_TEST_MODULE debug - logger
#if BOOST_VERSION >= 105900
#include <boost/test/tools/output_test_stream.hpp>
#else
#include <boost/test/output_test_stream.hpp>
#endif
#include <boost/test/unit_test.hpp>
using boost::test_tools::output_test_stream;
using namespace dynamicgraph::command;
namespace dynamicgraph {
class CustomEntity : public Entity {
public:
static const std::string CLASS_NAME;
bool test_zero_arg_;
bool test_one_arg_;
bool test_two_args_;
bool test_three_args_;
bool test_four_args_;
bool test_one_arg_ret_;
bool test_two_args_ret_;
virtual const std::string &getClassName() const { return CLASS_NAME; }
explicit CustomEntity(const std::string &n) : Entity(n) {
test_zero_arg_ = false;
test_one_arg_ = false;
test_two_args_ = false;
test_three_args_ = false;
test_four_args_ = false;
test_one_arg_ret_ = false;
test_two_args_ret_ = false;
addCommand("0_arg", makeCommandVoid0(*this, &CustomEntity::zero_arg,
docCommandVoid0("zero arg")));
addCommand("1_arg", makeCommandVoid1(*this, &CustomEntity::one_arg,
docCommandVoid1("one arg", "int")));
addCommand("2_args",
makeCommandVoid2(*this, &CustomEntity::two_args,
docCommandVoid2("two args", "int", "int")));
addCommand("3_args", makeCommandVoid3(*this, &CustomEntity::three_args,
docCommandVoid3("three args", "int",
"int", "int")));
addCommand("4_args",
makeCommandVoid4(
*this, &CustomEntity::four_args,
docCommandVoid4("four args", "int", "int", "int", "int")));
addCommand("1_arg_r",
makeCommandReturnType1(*this, &CustomEntity::one_arg_ret,
docCommandVoid1("one arg", "int")));
addCommand("2_args_r", makeCommandReturnType2(
*this, &CustomEntity::two_args_ret,
docCommandVoid2("two args", "int", "int")));
addCommand(
"cmd_verbose",
makeCommandVerbose(*this, &CustomEntity::cmd_verbose,
docCommandVerbose("Display some information")));
/// Generating an exception by adding a command which already exist
bool res = false;
std::string e_1_arg("1_arg");
try {
addCommand(e_1_arg, getNewStyleCommand(e_1_arg));
} catch (dynamicgraph::ExceptionFactory &aef) {
res = (aef.getCode() == dynamicgraph::ExceptionFactory::OBJECT_CONFLICT);
}
BOOST_CHECK(res);
}
~CustomEntity() {}
void zero_arg() { test_zero_arg_ = true; }
void one_arg(const int &) { test_one_arg_ = true; }
void two_args(const int &, const int &) { test_two_args_ = true; }
void three_args(const int &, const int &, const int &) {
test_three_args_ = true;
}
void four_args(const int &, const int &, const int &, const int &) {
test_four_args_ = true;
}
int one_arg_ret(const int &) {
test_one_arg_ret_ = true;
return 2;
}
std::string two_args_ret(const int &, const int &) {
test_two_args_ret_ = true;
return std::string("return");
}
void cmd_verbose(std::ostream &oss) {
std::string as("print verbose");
oss << as;
}
};
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(CustomEntity, "CustomEntity");
} // namespace dynamicgraph
BOOST_AUTO_TEST_CASE(command_test) {
dynamicgraph::CustomEntity *ptr_entity =
(dynamic_cast<dynamicgraph::CustomEntity *>(
dynamicgraph::FactoryStorage::getInstance()->newEntity("CustomEntity",
"my-entity")));
dynamicgraph::CustomEntity &entity = *ptr_entity;
std::map<const std::string, Command *> aCommandMap =
entity.getNewStyleCommandMap();
std::map<const std::string, Command *>::iterator it_map;
it_map = aCommandMap.find("0_arg");
if (it_map == aCommandMap.end()) BOOST_CHECK(false);
it_map->second->execute();
BOOST_CHECK(entity.test_zero_arg_);
int first_arg = 1;
Value aValue(first_arg);
std::vector<std::string> vec_fname(4);
vec_fname[0] = "1_arg";
vec_fname[1] = "2_args";
vec_fname[2] = "3_args";
vec_fname[3] = "4_args";
std::vector<Value> values;
for (unsigned int i = 0; i < 4; i++) {
it_map = aCommandMap.find(vec_fname[i]);
if (it_map == aCommandMap.end()) BOOST_CHECK(false);
values.push_back(aValue);
it_map->second->setParameterValues(values);
it_map->second->execute();
it_map->second->owner();
it_map->second->getDocstring();
}
BOOST_CHECK(entity.test_one_arg_);
BOOST_CHECK(entity.test_two_args_);
BOOST_CHECK(entity.test_three_args_);
BOOST_CHECK(entity.test_four_args_);
// With return type.
vec_fname.clear();
vec_fname.push_back(std::string("1_arg_r"));
vec_fname.push_back(std::string("2_args_r"));
values.clear();
for (unsigned int i = 0; i < 2; i++) {
it_map = aCommandMap.find(vec_fname[i]);
if (it_map == aCommandMap.end()) {
BOOST_CHECK(false);
exit(-1);
}
values.push_back(aValue);
it_map->second->setParameterValues(values);
Value aValue = it_map->second->execute();
it_map->second->owner();
it_map->second->getDocstring();
}
BOOST_CHECK(entity.test_one_arg_ret_);
BOOST_CHECK(entity.test_two_args_ret_);
std::vector<Value> values_two;
values_two.push_back(aValue);
/// Wrong number of arguments
bool res = false;
it_map = aCommandMap.find(std::string("2_args"));
try {
it_map->second->setParameterValues(values_two);
} catch (const dynamicgraph::ExceptionAbstract &aea) {
res = (aea.getCode() == dynamicgraph::ExceptionAbstract::ABSTRACT);
}
BOOST_CHECK(res);
double snd_arg_db = 10.0;
Value aValue2(snd_arg_db);
values_two.push_back(aValue2);
/// Wrong types of arguments
res = false;
it_map = aCommandMap.find(std::string("2_args"));
try {
it_map->second->setParameterValues(values_two);
} catch (const dynamicgraph::ExceptionAbstract &aea) {
res = (aea.getCode() == dynamicgraph::ExceptionAbstract::TOOLS);
}
BOOST_CHECK(res);
/// Try to find the command 1_arg
res = false;
entity.getNewStyleCommand(vec_fname[0]);
BOOST_CHECK(true);
/// Generate an exception by searching a command with an empty name.w
std::string empty("");
try {
entity.getNewStyleCommand(empty);
} catch (dynamicgraph::ExceptionFactory &aef) {
res = (aef.getCode() == dynamicgraph::ExceptionFactory::UNREFERED_FUNCTION);
}
BOOST_CHECK(res);
/// delete the entity.
delete ptr_entity;
}
// Copyright 2010 Thomas Moulard.
//
#include <dynamic-graph/entity.h>
#include <dynamic-graph/exception-factory.h>
#include <dynamic-graph/factory.h>
#include <dynamic-graph/pool.h>
#include <sstream>
#define BOOST_TEST_MODULE customEntity
#if BOOST_VERSION >= 105900
#include <boost/test/tools/output_test_stream.hpp>
#else
#include <boost/test/output_test_stream.hpp>
#endif
#include <boost/test/unit_test.hpp>
using boost::test_tools::output_test_stream;
struct CustomEntity : public dynamicgraph::Entity {
static const std::string CLASS_NAME;
virtual const std::string &getClassName() const { return CLASS_NAME; }
explicit CustomEntity(const std::string &n) : Entity(n) {}
virtual ~CustomEntity() {}
void display(std::ostream &os) const { os << "custom entity"; }
};
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(CustomEntity, "CustomEntity");
BOOST_AUTO_TEST_CASE(constructor) {
BOOST_CHECK_EQUAL(CustomEntity::CLASS_NAME, "CustomEntity");
dynamicgraph::Entity *entity =
dynamicgraph::FactoryStorage::getInstance()->newEntity("CustomEntity",
"my-entity");
BOOST_CHECK_EQUAL(entity->getName(), "my-entity");
BOOST_CHECK_EQUAL(entity->Entity::getClassName(), "Entity");
BOOST_CHECK_EQUAL(entity->getClassName(), CustomEntity::CLASS_NAME);
// CustomEntity entity2 ("");
// Deregister entities before destroying them
dynamicgraph::PoolStorage::destroy();
}
BOOST_AUTO_TEST_CASE(display) {
dynamicgraph::Entity *entity =
dynamicgraph::FactoryStorage::getInstance()->newEntity("CustomEntity",
"my-entity");
output_test_stream output;
entity->display(output);
BOOST_CHECK(output.is_equal("custom entity"));
// Deregister entities before destroying them
dynamicgraph::PoolStorage::destroy();
}
import "tracer"
new Tracer tracer
tracer.open /tmp debug.dat
tracer.add tracer.triger
tracer.start
tracer.stop
tracer.clear
tracer.record
tracer.close
/* Copyright 2019, LAAS-CNRS
*
* Olivier Stasse
*
* See LICENSE file
*
*/
#include <iostream>
#include <sstream>
#define ENABLE_RT_LOG
#include <dynamic-graph/entity.h>
#include <dynamic-graph/exception-factory.h>
#include <dynamic-graph/logger.h>
#include <dynamic-graph/real-time-logger.h>
#include "dynamic-graph/factory.h"
#include "dynamic-graph/pool.h"
#define BOOST_TEST_MODULE debug - logger
#if BOOST_VERSION >= 105900
#include <boost/test/tools/output_test_stream.hpp>
#else
#include <boost/test/output_test_stream.hpp>
#endif
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/thread/thread.hpp>
using boost::test_tools::output_test_stream;
namespace dynamicgraph {
class CustomEntity : public Entity {
public:
static const std::string CLASS_NAME;
virtual const std::string &getClassName() const { return CLASS_NAME; }
explicit CustomEntity(const std::string &n) : Entity(n) {
logger_.setTimeSample(0.001);
logger_.setStreamPrintPeriod(0.005);
logger_.setVerbosity(VERBOSITY_ALL);
LoggerVerbosity alv = logger_.getVerbosity();
BOOST_CHECK(alv == VERBOSITY_ALL);
}
~CustomEntity() {}
void testDebugTrace() {
sendMsg("This is a message of level MSG_TYPE_DEBUG", MSG_TYPE_DEBUG);
sendMsg("This is a message of level MSG_TYPE_INFO", MSG_TYPE_INFO);
sendMsg("This is a message of level MSG_TYPE_WARNING", MSG_TYPE_WARNING);
sendMsg("This is a message of level MSG_TYPE_ERROR", MSG_TYPE_ERROR);
sendMsg("This is a message of level MSG_TYPE_DEBUG_STREAM",
MSG_TYPE_DEBUG_STREAM);
sendMsg("This is a message of level MSG_TYPE_INFO_STREAM",
MSG_TYPE_INFO_STREAM);
sendMsg("This is a message of level MSG_TYPE_WARNING_STREAM",
MSG_TYPE_WARNING_STREAM);
sendMsg("This is a message of level MSG_TYPE_ERROR_STREAM",
MSG_TYPE_ERROR_STREAM);
logger_.countdown();
}
};
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(CustomEntity, "CustomEntity");
} // namespace dynamicgraph
BOOST_AUTO_TEST_CASE(debug_logger_wrong_initialization) {
dynamicgraph::RealTimeLogger::instance();
BOOST_CHECK_EQUAL(dynamicgraph::CustomEntity::CLASS_NAME, "CustomEntity");
dynamicgraph::CustomEntity &entity =
*(dynamic_cast<dynamicgraph::CustomEntity *>(
dynamicgraph::FactoryStorage::getInstance()->newEntity(
"CustomEntity", "my-entity-2")));
for (unsigned int i = 0; i < 1000; i++) {
entity.testDebugTrace();
}
dynamicgraph::RealTimeLogger::destroy();
}
/* Copyright 2019, LAAS-CNRS
*
* Olivier Stasse
*
* See LICENSE file
*
*/
#include <dynamic-graph/entity.h>
#include <dynamic-graph/exception-factory.h>
#include <iostream>
#include <sstream>
#include "dynamic-graph/factory.h"
#include "dynamic-graph/pool.h"
#define ENABLE_RT_LOG
#include <dynamic-graph/logger.h>
#include <dynamic-graph/real-time-logger.h>
#define BOOST_TEST_MODULE debug - logger
#if BOOST_VERSION >= 105900
#include <boost/test/tools/output_test_stream.hpp>
#else
#include <boost/test/output_test_stream.hpp>
#endif
#include <boost/test/unit_test.hpp>
using boost::test_tools::output_test_stream;
namespace dynamicgraph {
class CustomEntity : public Entity {
public:
static const std::string CLASS_NAME;
virtual const std::string &getClassName() const { return CLASS_NAME; }
explicit CustomEntity(const std::string &n) : Entity(n) {
logger_.setTimeSample(0.001);
logger_.setStreamPrintPeriod(0.005);
logger_.setVerbosity(VERBOSITY_NONE);
BOOST_CHECK_EQUAL(logger_.getVerbosity(), VERBOSITY_NONE);
BOOST_CHECK(logger_.stream(MSG_TYPE_DEBUG).isNull());
BOOST_CHECK(logger_.stream(MSG_TYPE_INFO).isNull());
BOOST_CHECK(logger_.stream(MSG_TYPE_WARNING).isNull());
BOOST_CHECK(logger_.stream(MSG_TYPE_ERROR).isNull());
logger_.setVerbosity(VERBOSITY_ERROR);
BOOST_CHECK_EQUAL(logger_.getVerbosity(), VERBOSITY_ERROR);
BOOST_CHECK(logger_.stream(MSG_TYPE_DEBUG).isNull());
BOOST_CHECK(logger_.stream(MSG_TYPE_INFO).isNull());
BOOST_CHECK(logger_.stream(MSG_TYPE_WARNING).isNull());
BOOST_CHECK(!logger_.stream(MSG_TYPE_ERROR).isNull());
logger_.setVerbosity(VERBOSITY_WARNING_ERROR);
BOOST_CHECK_EQUAL(logger_.getVerbosity(), VERBOSITY_WARNING_ERROR);
BOOST_CHECK(logger_.stream(MSG_TYPE_DEBUG).isNull());
BOOST_CHECK(logger_.stream(MSG_TYPE_INFO).isNull());
BOOST_CHECK(!logger_.stream(MSG_TYPE_WARNING).isNull());
BOOST_CHECK(!logger_.stream(MSG_TYPE_ERROR).isNull());
logger_.setVerbosity(VERBOSITY_INFO_WARNING_ERROR);
BOOST_CHECK_EQUAL(logger_.getVerbosity(), VERBOSITY_INFO_WARNING_ERROR);
BOOST_CHECK(logger_.stream(MSG_TYPE_DEBUG).isNull());
BOOST_CHECK(!logger_.stream(MSG_TYPE_INFO).isNull());
BOOST_CHECK(!logger_.stream(MSG_TYPE_WARNING).isNull());
BOOST_CHECK(!logger_.stream(MSG_TYPE_ERROR).isNull());
logger_.setVerbosity(VERBOSITY_ALL);
BOOST_CHECK_EQUAL(logger_.getVerbosity(), VERBOSITY_ALL);
BOOST_CHECK(!logger_.stream(MSG_TYPE_DEBUG).isNull());
BOOST_CHECK(!logger_.stream(MSG_TYPE_INFO).isNull());
BOOST_CHECK(!logger_.stream(MSG_TYPE_WARNING).isNull());
BOOST_CHECK(!logger_.stream(MSG_TYPE_ERROR).isNull());
}
~CustomEntity() {}
void testDebugTrace() {
logger_.stream(MSG_TYPE_DEBUG)
<< "This is a message of level MSG_TYPE_DEBUG\n";
dynamicgraph::RealTimeLogger::instance().spinOnce();
logger_.stream(MSG_TYPE_INFO)
<< "This is a message of level MSG_TYPE_INFO\n";
dynamicgraph::RealTimeLogger::instance().spinOnce();
logger_.stream(MSG_TYPE_WARNING)
<< "This is a message of level MSG_TYPE_WARNING\n";
dynamicgraph::RealTimeLogger::instance().spinOnce();
logger_.stream(MSG_TYPE_ERROR)
<< "This is a message of level MSG_TYPE_ERROR\n";
dynamicgraph::RealTimeLogger::instance().spinOnce();
logger_.stream(MSG_TYPE_DEBUG_STREAM)
<< "This is a message of level MSG_TYPE_DEBUG_STREAM\n";
dynamicgraph::RealTimeLogger::instance().spinOnce();
logger_.stream(MSG_TYPE_INFO_STREAM)
<< "This is a message of level MSG_TYPE_INFO_STREAM\n";
dynamicgraph::RealTimeLogger::instance().spinOnce();
logger_.stream(MSG_TYPE_WARNING_STREAM)
<< "This is a message of level MSG_TYPE_WARNING_STREAM\n";
dynamicgraph::RealTimeLogger::instance().spinOnce();
logger_.stream(MSG_TYPE_ERROR_STREAM)
<< "This is a message of level MSG_TYPE_ERROR_STREAM\n";
/* Add test toString */
dynamicgraph::RealTimeLogger::instance().spinOnce();
double q = 1.0;
logger_.stream() << "Value to display: " + toString(q) << '\n';
dynamicgraph::RealTimeLogger::instance().spinOnce();
std::vector<double> vq;
vq.resize(3);
vq[0] = 1.0;
vq[1] = 2.0;
vq[2] = 3.0;
logger_.stream(MSG_TYPE_INFO)
<< "Value to display: " << toString(vq) << '\n';
dynamicgraph::RealTimeLogger::instance().spinOnce();
logger_.stream(MSG_TYPE_INFO)
<< "Value to display: " << toString(vq, 3, 10) << '\n';
dynamicgraph::RealTimeLogger::instance().spinOnce();
Eigen::Matrix<double, 3, 3> an_eig_m;
an_eig_m.setOnes();
logger_.stream(MSG_TYPE_INFO)
<< "Value to display: " << toString(an_eig_m) << '\n';
dynamicgraph::RealTimeLogger::instance().spinOnce();
logger_.countdown();
}
};
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(CustomEntity, "CustomEntity");
} // namespace dynamicgraph
BOOST_AUTO_TEST_CASE(debug_logger) {
std::ofstream of;
dynamicgraph::RealTimeLogger::instance();
of.open("/tmp/dg-LOGS.txt", std::ofstream::out | std::ofstream::app);
dgADD_OSTREAM_TO_RTLOG(of);
BOOST_CHECK_EQUAL(dynamicgraph::CustomEntity::CLASS_NAME, "CustomEntity");
dynamicgraph::CustomEntity &entity =
*(dynamic_cast<dynamicgraph::CustomEntity *>(
dynamicgraph::FactoryStorage::getInstance()->newEntity("CustomEntity",
"my-entity")));
entity.setTimeSample(0.002);
BOOST_CHECK_EQUAL(entity.getTimeSample(), 0.002);
entity.setStreamPrintPeriod(0.002);
BOOST_CHECK_EQUAL(entity.getStreamPrintPeriod(), 0.002);
for (unsigned int i = 0; i < 10000; i++) {
entity.testDebugTrace();
}
dynamicgraph::RealTimeLogger::destroy();
}
/* Copyright 2019, LAAS-CNRS
*
* Olivier Stasse
*
*/
#include <dynamic-graph/command.h>
#include <dynamic-graph/entity.h>
#include <dynamic-graph/exception-factory.h>
#include <dynamic-graph/factory.h>
#include <dynamic-graph/pool.h>
#include <dynamic-graph/signal-ptr.h>
#include <dynamic-graph/signal-time-dependent.h>
#include <dynamic-graph/tracer-real-time.h>
#include <iostream>
#define BOOST_TEST_MODULE debug - tracer
#if BOOST_VERSION >= 105900
#include <boost/test/tools/output_test_stream.hpp>
#else
#include <boost/test/output_test_stream.hpp>
#endif
#include <boost/test/unit_test.hpp>
using boost::test_tools::output_test_stream;
namespace dynamicgraph {
struct MyEntity : public dynamicgraph::Entity {
static const std::string CLASS_NAME;
dynamicgraph::Signal<double, int> m_sigdSIN;
dynamicgraph::SignalTimeDependent<double, int> m_sigdTimeDepSOUT;
dynamicgraph::SignalTimeDependent<double, int> m_sigdTwoTimeDepSOUT;
explicit MyEntity(const std::string &name)
: Entity(name),
m_sigdSIN("MyEntity(" + name + ")::input(double)::in_double"),
m_sigdTimeDepSOUT(boost::bind(&MyEntity::update, this, _1, _2),
m_sigdSIN,
"MyEntity(" + name + ")::input(double)::out_double"),
m_sigdTwoTimeDepSOUT(
boost::bind(&MyEntity::update, this, _1, _2), m_sigdSIN,
"MyEntity(" + name + ")::input(double)::out2double")
{
signalRegistration(m_sigdSIN << m_sigdTimeDepSOUT << m_sigdTwoTimeDepSOUT);
}
double &update(double &res, const int &inTime) {
const double &aDouble = m_sigdSIN(inTime);
res = aDouble;
return res;
}
};
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(MyEntity, "MyEntity");
} // namespace dynamicgraph
BOOST_AUTO_TEST_CASE(test_tracer) {
using namespace dynamicgraph;
// Creates a tracer.
TracerRealTime &atracer = *dynamic_cast<TracerRealTime *>(
FactoryStorage::getInstance()->newEntity("TracerRealTime", "my-tracer"));
MyEntity &entity = *dynamic_cast<MyEntity *>(
FactoryStorage::getInstance()->newEntity("MyEntity", "my-entity"));
std::string rootdir("/tmp");
std::string basename("my-tracer");
std::string suffix(".dat");
atracer.setBufferSize(1 << 14);
// Check that an exception is thrown if the filename is invalid.
atracer.openFiles(rootdir, "invalid/filename", suffix);
BOOST_CHECK_THROW(
atracer.addSignalToTraceByName("my-entity.out_double", "output"),
ExceptionTraces);
// Test openfiles
atracer.openFiles(rootdir, basename, suffix);
// Add trace by name
atracer.addSignalToTraceByName("my-entity.out_double", "output");
/// Add trace by name
SignalBase<int> &out_double = entity.getSignal("out_double");
SignalBase<int> &out_double_2 = entity.getSignal("out2double");
Signal<double, int> &in_double =
*(dynamic_cast<Signal<double, int> *>(&entity.getSignal("in_double")));
in_double.setConstant(1.5);
atracer.start();
std::string emptybuf_cmd_str("empty");
command::Command *acmd = atracer.getNewStyleCommand(emptybuf_cmd_str);
acmd->execute();
for (int i = 0; i < 1000; i++) {
in_double.setTime(i);
out_double.recompute(i);
out_double_2.recompute(i);
atracer.recordTrigger(i, i);
}
output_test_stream output;
atracer.display(output);
atracer.stop();
atracer.trace();
atracer.clearSignalToTrace();
atracer.closeFiles();
acmd->execute();
atracer.record();
BOOST_CHECK(output.is_equal(
"TracerRealTime my-tracer [mode=play] : \n"
" - Dep list: \n"
" -> MyEntity(my-entity)::input(double)::out_double (in output)"
" [8Ko/16Ko] \n"));
}