524 lines
13 KiB
C++
524 lines
13 KiB
C++
#include "AdsDebug.h"
|
|
|
|
#include <QDockWidget>
|
|
#include <QTreeWidget>
|
|
#include <QAction>
|
|
#include <QMainWindow>
|
|
#include <QStatusBar>
|
|
#include <QLabel>
|
|
#include <QHBoxLayout>
|
|
#include <QPlainTextEdit>
|
|
#include <QDebug>
|
|
|
|
#include "time_metrics.h"
|
|
#include "itc_multibuffer.h"
|
|
|
|
|
|
|
|
//static metricRegistered mShowUpd("dbg-update", 20000);
|
|
|
|
class MWidget;
|
|
class MbWidget;
|
|
|
|
class StsLed: public QLabel
|
|
{
|
|
public:
|
|
StsLed(const QString& lbl):
|
|
QLabel(lbl)
|
|
{
|
|
level=0;
|
|
}
|
|
|
|
void setLevel(int lvl)
|
|
{
|
|
if (level==lvl)
|
|
return;
|
|
level=lvl;
|
|
if (level<1)
|
|
setStyleSheet("");
|
|
if (level<2)
|
|
setStyleSheet("background-color: green");
|
|
else if (level<3)
|
|
setStyleSheet("background-color: yellow");
|
|
else
|
|
setStyleSheet("background-color: red");
|
|
}
|
|
|
|
int level;
|
|
|
|
};
|
|
|
|
struct dbg_widgets_t
|
|
{
|
|
QDockWidget* dockMetrics;
|
|
QDockWidget* dockLog;
|
|
QDockWidget* dockBuffers;
|
|
|
|
MWidget* metricW;
|
|
MbWidget* bufferW;
|
|
QPlainTextEdit* logW;
|
|
|
|
StsLed* dlLabel;
|
|
|
|
int timer_id;
|
|
|
|
//QWidget* stsLineWidget;
|
|
//QHBoxLayout* stsLayout;
|
|
StsLed* logErrLabel;
|
|
|
|
AdsDebug* instance;
|
|
|
|
int last_log_level;
|
|
};
|
|
|
|
static dbg_widgets_t dbg;
|
|
|
|
static QPlainTextEdit* dbgQtOutput;
|
|
|
|
static void my_qdebug_output(QtMsgType type, const char *msg)
|
|
{
|
|
if (dbgQtOutput)
|
|
{
|
|
QString tmp;
|
|
|
|
switch (type) {
|
|
case QtDebugMsg:
|
|
tmp=QString("[QT]D: %1").arg(msg);
|
|
break;
|
|
case QtWarningMsg:
|
|
tmp=QString("[QT]W: %1").arg(msg);
|
|
break;
|
|
case QtCriticalMsg:
|
|
tmp=QString("[QT]C: %1").arg(msg);
|
|
break;
|
|
case QtFatalMsg:
|
|
tmp=QString("[QT]F: %1").arg(msg);
|
|
break;
|
|
default:
|
|
tmp=QString("[QT]: %1").arg(msg);
|
|
}
|
|
dbgQtOutput->appendPlainText(tmp);
|
|
}
|
|
}
|
|
|
|
class MbWidget: public QTreeWidget
|
|
{
|
|
public:
|
|
int t_id;
|
|
|
|
MbWidget(QWidget* parent):
|
|
QTreeWidget(parent)
|
|
{
|
|
setObjectName("MOnMbTreeWidget");
|
|
this->setHeaderLabels(
|
|
QStringList()
|
|
<<QString("Name")
|
|
<<QString("Produced")
|
|
<<QString("Consumed")
|
|
<<QString("Not Prod.")
|
|
<<QString("Not Cons."));
|
|
this->setAlternatingRowColors(true);
|
|
|
|
{
|
|
itc_multibuffer_register* mb=itc_multibuffer_register::root();
|
|
for( ; mb; mb=mb->next())
|
|
{
|
|
QTreeWidgetItem* item=new QTreeWidgetItem(this);
|
|
|
|
item->setText(0, mb->name());
|
|
item->setData(0, Qt::UserRole, (unsigned int)mb);
|
|
}
|
|
}
|
|
//t_id=startTimer(1000);
|
|
}
|
|
|
|
void update()
|
|
{
|
|
if (!isHidden())
|
|
{
|
|
QTreeWidgetItem* r=invisibleRootItem();
|
|
|
|
for(int i=0; i<r->childCount(); ++i)
|
|
{
|
|
QTreeWidgetItem* c=r->child(i);
|
|
itc_multibuffer_register* mb=(itc_multibuffer_register*)c->data(0, Qt::UserRole).toUInt();
|
|
if (!mb)
|
|
continue;
|
|
c->setData(1, Qt::DisplayRole, mb->mb()->produced());
|
|
c->setData(2, Qt::DisplayRole, mb->mb()->consumed());
|
|
c->setData(3, Qt::DisplayRole, mb->mb()->not_produced());
|
|
c->setData(4, Qt::DisplayRole, mb->mb()->not_consumed());
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
class MWidget: public QObject /*: public QTreeWidget*/
|
|
{
|
|
public:
|
|
QTreeWidget w;
|
|
QAction* actReset;
|
|
QAction* actResetAll;
|
|
QAction* actRefresh;
|
|
QAction* actResize;
|
|
|
|
//QLabel stsLabel;
|
|
|
|
int some_dl_miss;
|
|
|
|
MWidget(QWidget* parent):
|
|
w(parent)
|
|
{
|
|
setObjectName("MonMetricsWidget");
|
|
|
|
w.setHeaderLabels(
|
|
QStringList()
|
|
<<QString("Name")
|
|
<<QString("samples")
|
|
<<QString("Last")
|
|
<<QString("avg")
|
|
<<QString("min")
|
|
<<QString("max")
|
|
<<QString("miss")
|
|
<<QString("p-last")
|
|
<<QString("p-avg")
|
|
<<QString("p-min")
|
|
<<QString("p-max")
|
|
<<QString("dl-miss")
|
|
);
|
|
m_update_turn=false;
|
|
/*
|
|
QTreeWidgetItem* root=new QTreeWidgetItem(this);
|
|
root->setText(0, "Time Metrics");
|
|
root->setText(1, "");
|
|
root->setExpanded(true);
|
|
*/
|
|
w.setAlternatingRowColors(true);
|
|
|
|
fillMetrics(metricRegistered::first(), w.invisibleRootItem());
|
|
//t_id=startTimer(1000);
|
|
|
|
actReset=new QAction(QString("Reset Selected"), &w);
|
|
actResetAll=new QAction(QString("Reset All"), &w);
|
|
actRefresh=new QAction(QString("Refresh"), &w);
|
|
actResize=new QAction(QString("Resize"), &w);
|
|
w.addAction(actReset);
|
|
w.addAction(actResetAll);
|
|
w.addAction(actRefresh);
|
|
w.addAction(actResize);
|
|
w.setContextMenuPolicy(Qt::ActionsContextMenu);
|
|
|
|
//stsLabel.setText("DL");
|
|
//dbg.stsLayout.addWidget(&stsLabel);
|
|
|
|
some_dl_miss=0;
|
|
}
|
|
|
|
void resize()
|
|
{
|
|
for(int i=0; i<12; ++i)
|
|
w.resizeColumnToContents(i);
|
|
}
|
|
|
|
void fillMetrics(metricRegistered* m, QTreeWidgetItem* p)
|
|
{
|
|
static int level;
|
|
for(; m; m=m->next())
|
|
{
|
|
QTreeWidgetItem* item=new QTreeWidgetItem(p);
|
|
item->setText(0, m->name());
|
|
item->setData(0, Qt::UserRole, /*QVariant((unsigned int)m)*/(unsigned int)m);
|
|
item->setData(0, Qt::UserRole+1, 0);
|
|
item->setToolTip(0,
|
|
QString("Deadlines: %1, %2").arg(m->time().get_deadline()).arg(m->period().get_deadline())
|
|
);
|
|
for(int i=1; i<12; ++i)
|
|
item->setData(i, Qt::TextAlignmentRole, Qt::AlignRight);
|
|
//if (p)
|
|
// p->addChild(item);
|
|
++level;
|
|
fillMetrics(m->sons(), item);
|
|
--level;
|
|
}
|
|
}
|
|
|
|
void resetTimes(QTreeWidgetItem* i)
|
|
{
|
|
if (!i)
|
|
return;
|
|
QVariant v=i->data(0, Qt::UserRole);
|
|
|
|
metricRegistered* m=(metricRegistered*)v.toUInt();
|
|
|
|
if (m)
|
|
{
|
|
m->reset();
|
|
i->setData(0, Qt::UserRole+1, 0);
|
|
i->setBackground(0, Qt::NoBrush);
|
|
}
|
|
for(int c=0; c<i->childCount(); ++c)
|
|
{
|
|
resetTimes(i->child(c));
|
|
}
|
|
}
|
|
|
|
bool updateM(QTreeWidgetItem* i)
|
|
{
|
|
if (!i)
|
|
return false;
|
|
|
|
unsigned long miss=0;
|
|
|
|
QVariant v=i->data(0, Qt::UserRole);
|
|
|
|
metricRegistered* m=(metricRegistered*)v.toUInt();
|
|
|
|
if (m)
|
|
{
|
|
i->setData(1, Qt::DisplayRole, (unsigned int)m->samples());
|
|
|
|
miss=m->time().dl_miss() + m->period().dl_miss();
|
|
|
|
if (miss)
|
|
{
|
|
//some_dl_miss=true;
|
|
unsigned long n=i->data(0, Qt::UserRole+1).toInt();
|
|
if (n==miss)
|
|
{
|
|
i->setData(0, Qt::BackgroundRole, Qt::yellow);
|
|
if (some_dl_miss<3)
|
|
some_dl_miss=2;
|
|
}
|
|
else
|
|
{
|
|
i->setData(0, Qt::BackgroundRole, Qt::red);
|
|
i->setData(0, Qt::UserRole+1, (unsigned int)miss);
|
|
some_dl_miss=3;
|
|
}
|
|
}
|
|
|
|
|
|
i->setData(2, Qt::DisplayRole, m->time().last_us());
|
|
i->setData(3, Qt::DisplayRole, m->time().avg_us());
|
|
i->setData(4, Qt::DisplayRole, m->time().min_us());
|
|
i->setData(5, Qt::DisplayRole, m->time().max_us());
|
|
i->setData(6, Qt::DisplayRole, (unsigned int)m->time().dl_miss());
|
|
i->setData(7, Qt::DisplayRole, m->period().last_us());
|
|
i->setData(8, Qt::DisplayRole, m->period().avg_us());
|
|
i->setData(9, Qt::DisplayRole, m->period().min_us());
|
|
i->setData(10, Qt::DisplayRole, m->period().max_us());
|
|
i->setData(11, Qt::DisplayRole, (unsigned int)m->period().dl_miss());
|
|
}
|
|
for(int c=0; c<i->childCount(); ++c)
|
|
{
|
|
bool xx=updateM(i->child(c));
|
|
if (xx && miss==0)
|
|
{
|
|
i->setData(0, Qt::BackgroundRole, Qt::lightGray);
|
|
}
|
|
}
|
|
return miss!=0;
|
|
}
|
|
|
|
void update()
|
|
{
|
|
if (some_dl_miss>2)
|
|
some_dl_miss=2;
|
|
|
|
if (1) //!w.isHidden())
|
|
{
|
|
//metricMeasure xx(mShowUpd);
|
|
//blockSignals(true);
|
|
//setUpdatesEnabled(false);
|
|
updateM(w.invisibleRootItem());
|
|
|
|
m_update_turn=!m_update_turn;
|
|
|
|
//setUpdatesEnabled(true);
|
|
//blockSignals(false);
|
|
}
|
|
}
|
|
bool m_update_turn;
|
|
};
|
|
|
|
|
|
AdsDebug::AdsDebug(QObject *parent) :
|
|
QObject(parent)
|
|
{
|
|
}
|
|
|
|
AdsDebug& AdsDebug::instance()
|
|
{
|
|
return *dbg.instance;
|
|
}
|
|
|
|
bool AdsDebug::createDebugWindows(QMainWindow *parent)
|
|
{
|
|
|
|
if (dbg.instance)
|
|
return false;
|
|
|
|
dbg.instance=new AdsDebug(parent);
|
|
|
|
return dbg.instance->create(parent);
|
|
}
|
|
|
|
static void log_(QString msg, int lvl=0)
|
|
{
|
|
if (!dbg.logW)
|
|
{
|
|
dbg.logW=new QPlainTextEdit;
|
|
dbg.logW->setReadOnly(true);
|
|
dbg.logW->setLineWrapMode(QPlainTextEdit::NoWrap);
|
|
dbg.logW->setMaximumBlockCount(1000);
|
|
dbg.logW->setCenterOnScroll(true);
|
|
dbg.logW->setUndoRedoEnabled(false);
|
|
|
|
dbgQtOutput=dbg.logW;
|
|
qInstallMsgHandler(my_qdebug_output);
|
|
|
|
qDebug()<<"debug log ready";
|
|
if (!dbg.logErrLabel)
|
|
dbg.logErrLabel=new StsLed("LOG");
|
|
}
|
|
dbg.logW->appendPlainText(msg);
|
|
if (lvl>0)
|
|
{
|
|
//dbg.logW->setStyleSheet("");
|
|
}
|
|
dbg.logW->ensureCursorVisible();
|
|
//dbg.logErrLabel->setBackgroundRole(QPalette::Highlight);
|
|
//dbg.logErrLabel->setForegroundRole(QPalette::HighlightedText);
|
|
//dbg.logErrLabel->setStyleSheet("background-color: red;");
|
|
//dbg.logErrLabel->setLevel(1);
|
|
|
|
//dbg.logW->appendPlainText("\n");
|
|
if (lvl)
|
|
dbg.last_log_level=5;
|
|
}
|
|
|
|
void AdsDebug::log_qmsg(int level, const char* const msg)
|
|
{
|
|
log_(QString("[%1] %2").arg(level).arg(msg), level);
|
|
}
|
|
|
|
void AdsDebug::log_print(const QString& msg)
|
|
{
|
|
log_(msg);
|
|
}
|
|
|
|
|
|
bool AdsDebug::create(QMainWindow *parent)
|
|
{
|
|
|
|
//dbg.stsLineWidget.setLayout(&dbg.stsLayout);
|
|
|
|
dbg.dlLabel=new StsLed("DL");
|
|
|
|
dbg.dockMetrics=new QDockWidget("Dbg: Time Metrics", parent);
|
|
dbg.dockMetrics->setObjectName("MonMetricsDockWindow");
|
|
dbg.metricW=new MWidget(dbg.dockMetrics);
|
|
dbg.dockMetrics->setWidget(&(dbg.metricW->w));
|
|
parent->addDockWidget(Qt::BottomDockWidgetArea, dbg.dockMetrics);
|
|
|
|
dbg.dockBuffers=new QDockWidget("Dbg: Shared Buffers", parent);
|
|
dbg.dockBuffers->setObjectName("MonBuffersDockWindow");
|
|
dbg.bufferW=new MbWidget(dbg.dockBuffers);
|
|
dbg.dockBuffers->setWidget(dbg.bufferW);
|
|
parent->addDockWidget(Qt::BottomDockWidgetArea, dbg.dockBuffers);
|
|
|
|
dbg.dockLog=new QDockWidget("Dbg: Log", parent);
|
|
dbg.dockLog->setObjectName("MonLogDockWindow");
|
|
|
|
if (!dbg.logW)
|
|
log_print(" ");
|
|
// log_print(QString("Hello fomr Adm Debug Monitor"));
|
|
dbg.logW->setParent(dbg.dockLog);
|
|
dbg.dockLog->setWidget(dbg.logW);
|
|
parent->addDockWidget(Qt::BottomDockWidgetArea, dbg.dockLog);
|
|
|
|
if (!dbg.logErrLabel)
|
|
{
|
|
dbg.logErrLabel=new StsLed("LOG");
|
|
}
|
|
//dbg.logErrLabel.setFrameShape(QFrame::Panel);
|
|
//dbg.stsLayout.addWidget(&dbg.logErrLabel);
|
|
//dbg.stsLayout.setContentsMargins(0, 0, 0, 0);
|
|
|
|
QStatusBar* sBar=parent->statusBar();
|
|
//sBar->addPermanentWidget(&dbg.metricW->stsLabel);
|
|
sBar->addPermanentWidget(dbg.dlLabel);
|
|
sBar->addPermanentWidget(dbg.logErrLabel);
|
|
|
|
//Connection:
|
|
connect(dbg.metricW->actResetAll, SIGNAL(triggered()), SLOT(resetAllTimesMetrics()));
|
|
connect(dbg.metricW->actReset, SIGNAL(triggered()), SLOT(resetSelectedTimesMetrics()));
|
|
connect(dbg.metricW->actResize, SIGNAL(triggered()), SLOT(resizeTimesMetrics()));
|
|
|
|
//dbgQtOutput=dbg.logW;
|
|
//qInstallMsgHandler(my_qdebug_output);
|
|
//qDebug()<<"debug log ready";
|
|
|
|
return true;
|
|
}
|
|
|
|
void AdsDebug::resizeTimesMetrics()
|
|
{
|
|
dbg.metricW->resize();
|
|
}
|
|
|
|
void AdsDebug::resetAllTimesMetrics()
|
|
{
|
|
log_print(QString("Reset all time metrics"));
|
|
dbg.metricW->resetTimes(dbg.metricW->w.invisibleRootItem());
|
|
}
|
|
|
|
void AdsDebug::resetSelectedTimesMetrics()
|
|
{
|
|
dbg.metricW->resetTimes(dbg.metricW->w.currentItem());
|
|
}
|
|
|
|
void AdsDebug::startMonitoring(unsigned int interval_ms)
|
|
{
|
|
dbg.timer_id=dbg.instance->startTimer(interval_ms);
|
|
}
|
|
|
|
void AdsDebug::timerEvent(QTimerEvent *)
|
|
{
|
|
dbg.metricW->update();
|
|
dbg.bufferW->update();
|
|
|
|
if (dbg.metricW->some_dl_miss)
|
|
{
|
|
dbg.dlLabel->setLevel(dbg.metricW->some_dl_miss);
|
|
//dbg.dlLabel->setBackgroundRole(QPalette::Highlight);
|
|
//dbg.dlLabel->setForegroundRole(QPalette::HighlightedText);
|
|
}
|
|
if (dbg.last_log_level>3)
|
|
{
|
|
dbg.logErrLabel->setLevel(3);
|
|
--dbg.last_log_level;
|
|
}
|
|
else if (dbg.last_log_level>2)
|
|
{
|
|
dbg.logErrLabel->setLevel(2);
|
|
--dbg.last_log_level;
|
|
}
|
|
|
|
}
|
|
|
|
AdsDebug::~AdsDebug()
|
|
{
|
|
|
|
}
|
|
|
|
void AdsDebug::destroyDebugWindow()
|
|
{
|
|
qInstallMsgHandler(0);
|
|
if (!dbg.instance)
|
|
return;
|
|
dbg.instance->killTimer(dbg.timer_id);
|
|
delete dbg.instance;
|
|
dbg.instance=0;
|
|
}
|