#include "AdsDebug.h" #include #include #include #include #include #include #include #include #include #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() <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; ichildCount(); ++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() <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; cchildCount(); ++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; cchildCount(); ++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; }