Move Trace Analyzer to open source tree

Move the code for the Trace Analyzer to the open source tree and only
keep the extensions behind a compiler flag.
This commit is contained in:
2024-07-05 10:53:44 +02:00
parent cfd980373b
commit 82027bfa83
96 changed files with 679 additions and 1418 deletions

View File

@@ -0,0 +1,104 @@
# Copyright (c) 2020, RPTU Kaiserslautern-Landau
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors:
# Matthias Jung
# Lukas Steiner
# Derek Christ
# Iron Prando da Silva
########################################
### TraceAnalyzer ###
########################################
project(TraceAnalyzer)
file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS *.cpp)
file(GLOB_RECURSE HEADER_FILES CONFIGURE_DEPENDS *.h;*.hpp)
# Add Python3 Dependency:
find_package(Python3 COMPONENTS Development Interpreter)
FetchContent_Declare(
pybind11
URL https://github.com/pybind/pybind11/archive/refs/tags/v2.13.1.zip
)
FetchContent_MakeAvailable(pybind11)
# Add QWT Dependency:
find_library(QWT_LIBRARY NAMES "qwt" "qwt-qt5" PATHS
"$ENV{QWT_HOME}/lib"
"/opt/homebrew/opt/qwt-qt5/lib"
)
find_path(QWT_INCLUDE_DIRS NAMES "qwt_plot.h" PATHS
"$ENV{QWT_HOME}/include"
"/usr/include/qwt-qt5"
"/usr/include/qwt"
"/opt/homebrew/opt/qwt-qt5/include"
"/opt/homebrew/opt/qwt-qt5/lib/qwt.framework/Headers"
)
# Add QT Library:
if (APPLE)
set(Qt5_DIR "/opt/homebrew/opt/qt@5/lib/cmake/Qt5")
endif(APPLE)
find_package(Qt5 COMPONENTS Core Gui Widgets Sql REQUIRED)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(TraceAnalyzer ${SOURCE_FILES} ${HEADER_FILES})
target_include_directories(TraceAnalyzer
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${QWT_INCLUDE_DIRS}
)
target_link_libraries(TraceAnalyzer
PRIVATE
pybind11::embed
${QWT_LIBRARY}
Qt5::Widgets
Qt5::Sql
DRAMSys::util
DRAMSys::config
)
set(DRAMSYS_TRACE_ANALYZER_EXTENSION_DIR "${CMAKE_SOURCE_DIR}/extensions/apps/traceAnalyzer")
target_compile_definitions(${PROJECT_NAME}
PRIVATE
DRAMSYS_TRACE_ANALYZER_EXTENSION_DIR="${DRAMSYS_TRACE_ANALYZER_EXTENSION_DIR}"
)
build_source_group()

View File

@@ -0,0 +1,13 @@
## TraceAnalyzer
### Python Dependencies
The used Python dependencies of this project include:
- matplotlib
- numpy
- pyvcd
- tqdm
To install all required packages, a `requirements.txt` file is provided, which can be found in `scripts/requirements.txt`.
Install the packages using this command:
```
python3 -m pip install -r scripts/requirements.txt
```

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
*/
#ifndef METRIC_H
#define METRIC_H
#include <QString>
struct CalculatedMetric
{
std::string name;
double value;
};
#endif // METRIC_H

View File

@@ -0,0 +1,123 @@
/*
* Copyright (c) 2019, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Lukas Steiner
*/
#ifndef COMMANDLENGTHS_H
#define COMMANDLENGTHS_H
struct CommandLengths
{
double NOP = 1;
double RD = 1;
double WR = 1;
double MWR = 1;
double RDA = 1;
double WRA = 1;
double MWRA = 1;
double ACT = 1;
double PREPB = 1;
double REFPB = 1;
double RFMPB = 1;
double REFP2B = 1;
double RFMP2B = 1;
double PRESB = 1;
double REFSB = 1;
double RFMSB = 1;
double PREAB = 1;
double REFAB = 1;
double RFMAB = 1;
double PDEA = 1;
double PDXA = 1;
double PDEP = 1;
double PDXP = 1;
double SREFEN = 1;
double SREFEX = 1;
CommandLengths(double NOP,
double RD,
double WR,
double MWR,
double RDA,
double WRA,
double MWRA,
double ACT,
double PREPB,
double REFPB,
double RFMPB,
double REFP2B,
double RFMP2B,
double PRESB,
double REFSB,
double RFMSB,
double PREAB,
double REFAB,
double RFMAB,
double PDEA,
double PDXA,
double PDEP,
double PDXP,
double SREFEN,
double SREFEX) :
NOP(NOP),
RD(RD),
WR(WR),
MWR(MWR),
RDA(RDA),
WRA(WRA),
MWRA(MWRA),
ACT(ACT),
PREPB(PREPB),
REFPB(REFPB),
RFMPB(RFMPB),
REFP2B(REFP2B),
RFMP2B(RFMP2B),
PRESB(PRESB),
REFSB(REFSB),
RFMSB(RFMSB),
PREAB(PREAB),
REFAB(REFAB),
RFMAB(RFMAB),
PDEA(PDEA),
PDXA(PDXA),
PDEP(PDEP),
PDXP(PDXP),
SREFEN(SREFEN),
SREFEX(SREFEX)
{
}
CommandLengths() = default;
};
#endif // COMMANDLENGTHS_H

View File

@@ -0,0 +1,328 @@
/*
* Copyright (c) 2021, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Derek Christ
*/
#include "commentmodel.h"
#include <QItemSelectionModel>
#include <QKeyEvent>
#include <QMenu>
CommentModel::CommentModel(QObject* parent) :
QAbstractTableModel(parent),
gotoAction(new QAction("Goto comment", this)),
editAction(new QAction("Edit comment", this)),
deleteAction(new QAction("Delete comment", this)),
selectAllAction(new QAction("Select all comments", this)),
deselectAllAction(new QAction("Deselect all comments", this)),
internalSelectionModel(new QItemSelectionModel(this, this))
{
setUpActions();
}
void CommentModel::setUpActions()
{
QObject::connect(gotoAction,
&QAction::triggered,
this,
[=]()
{
const QModelIndexList indexes = internalSelectionModel->selectedRows();
for (const QModelIndex& currentIndex : indexes)
{
emit gotoCommentTriggered(currentIndex);
}
});
QObject::connect(editAction,
&QAction::triggered,
this,
[=]()
{
const QModelIndexList indexes = internalSelectionModel->selectedRows();
for (const QModelIndex& currentIndex : indexes)
emit editTriggered(
index(currentIndex.row(), static_cast<int>(Column::Comment)));
});
QObject::connect(deleteAction,
&QAction::triggered,
this,
[=]()
{
const QModelIndexList indexes = internalSelectionModel->selectedRows();
for (const QModelIndex& currentIndex : indexes)
removeComment(currentIndex);
});
QObject::connect(selectAllAction,
&QAction::triggered,
this,
[=]()
{
QModelIndex topLeft = index(0, 0);
QModelIndex bottomRight = index(rowCount() - 1, columnCount() - 1);
internalSelectionModel->select(QItemSelection(topLeft, bottomRight),
QItemSelectionModel::Select |
QItemSelectionModel::Rows);
});
QObject::connect(deselectAllAction,
&QAction::triggered,
internalSelectionModel,
&QItemSelectionModel::clearSelection);
}
int CommentModel::rowCount(const QModelIndex& parent) const
{
Q_UNUSED(parent)
return comments.size();
}
int CommentModel::columnCount(const QModelIndex& parent) const
{
Q_UNUSED(parent)
return static_cast<int>(Column::COLUMNCOUNT);
}
QVariant CommentModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid())
return QVariant();
// Qt::UserRole is used to get the raw time without pretty formatting.
if (role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::UserRole)
return QVariant();
const Comment& comment = comments.at(index.row());
if (role == Qt::UserRole && static_cast<Column>(index.column()) == Column::Time)
return QVariant(comment.time);
switch (static_cast<Column>(index.column()))
{
case Column::Time:
return QVariant(prettyFormatTime(comment.time));
case Column::Comment:
return QVariant(comment.text);
default:
break;
}
return QVariant();
}
bool CommentModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
if (!index.isValid())
return false;
if (role != Qt::EditRole)
return false;
if (static_cast<Column>(index.column()) != Column::Comment)
return false;
QString newText = value.toString();
Comment& comment = comments.at(index.row());
comment.text = newText;
emit dataChanged(index, index);
return true;
}
QVariant CommentModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
if (orientation == Qt::Horizontal)
{
switch (static_cast<Column>(section))
{
case Column::Time:
return "Time";
case Column::Comment:
return "Comment";
default:
break;
}
}
return QVariant();
}
Qt::ItemFlags CommentModel::flags(const QModelIndex& index) const
{
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
if (index.isValid() && index.column() == static_cast<int>(Column::Comment))
flags |= Qt::ItemIsEditable;
return flags;
}
void CommentModel::openContextMenu()
{
if (!internalSelectionModel->hasSelection())
return;
QMenu* menu = new QMenu();
menu->addActions({gotoAction, editAction, deleteAction});
menu->addSeparator();
menu->addActions({selectAllAction, deselectAllAction});
QObject::connect(menu, &QMenu::aboutToHide, [=]() { menu->deleteLater(); });
menu->popup(QCursor::pos());
}
QItemSelectionModel* CommentModel::selectionModel() const
{
return internalSelectionModel;
}
void CommentModel::addComment(traceTime time)
{
auto commentIt = std::find_if(comments.rbegin(),
comments.rend(),
[time](const Comment& comment) { return comment.time <= time; });
int insertIndex = std::distance(comments.begin(), commentIt.base());
beginInsertRows(QModelIndex(), insertIndex, insertIndex);
comments.insert(comments.begin() + insertIndex, {time, "Enter comment text..."});
endInsertRows();
internalSelectionModel->setCurrentIndex(
index(insertIndex, 0), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
emit editTriggered(index(insertIndex, 1));
}
void CommentModel::addComment(traceTime time, QString text)
{
auto commentIt = std::find_if(comments.rbegin(),
comments.rend(),
[time](const Comment& comment) { return comment.time <= time; });
int insertIndex = std::distance(comments.begin(), commentIt.base());
beginInsertRows(QModelIndex(), insertIndex, insertIndex);
comments.insert(comments.begin() + insertIndex, {time, text});
endInsertRows();
}
void CommentModel::removeComment(traceTime time)
{
auto commentIt = std::find_if(comments.begin(),
comments.end(),
[time](const Comment& comment) { return comment.time == time; });
if (commentIt == comments.end())
return;
int removeIndex = std::distance(comments.begin(), commentIt);
beginRemoveRows(QModelIndex(), removeIndex, removeIndex);
comments.erase(commentIt);
endRemoveRows();
}
void CommentModel::removeComment(const QModelIndex& index)
{
beginRemoveRows(QModelIndex(), index.row(), index.row());
comments.erase(comments.begin() + index.row());
endRemoveRows();
}
const std::vector<CommentModel::Comment>& CommentModel::getComments() const
{
return comments;
}
traceTime CommentModel::getTimeFromIndex(const QModelIndex& index) const
{
Q_ASSERT(index.row() > 0 && comments.size() > static_cast<unsigned>(index.row()));
return comments[index.row()].time;
}
QModelIndex CommentModel::hoveredComment(Timespan timespan) const
{
auto commentIt =
std::find_if(comments.begin(),
comments.end(),
[timespan](const Comment& comment)
{ return timespan.Begin() < comment.time && comment.time < timespan.End(); });
if (commentIt == comments.end())
return QModelIndex();
int commentIndex = std::distance(comments.begin(), commentIt);
return index(commentIndex, 0);
}
bool CommentModel::eventFilter(QObject* object, QEvent* event)
{
Q_UNUSED(object)
if (event->type() == QEvent::KeyPress)
{
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Delete)
{
const QModelIndexList indexes = internalSelectionModel->selectedRows();
for (const QModelIndex& currentIndex : indexes)
{
removeComment(currentIndex);
}
}
}
return false;
}
void CommentModel::rowDoubleClicked(const QModelIndex& index)
{
if (!index.isValid())
return;
if (static_cast<Column>(index.column()) == Column::Time)
Q_EMIT gotoCommentTriggered(index);
}

View File

@@ -0,0 +1,122 @@
/*
* Copyright (c) 2021, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Derek Christ
*/
#ifndef COMMENTMODEL_H
#define COMMENTMODEL_H
#include "timespan.h"
#include "tracetime.h"
#include <QAbstractTableModel>
#include <utility>
class QAction;
class QItemSelectionModel;
class CommentModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit CommentModel(QObject* parent = nullptr);
struct Comment
{
traceTime time;
QString text;
};
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
QVariant
headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
Qt::ItemFlags flags(const QModelIndex& index) const override;
enum class Column
{
Time = 0,
Comment,
COLUMNCOUNT
};
void openContextMenu();
QItemSelectionModel* selectionModel() const;
void addComment(traceTime time);
void addComment(traceTime time, QString text);
void removeComment(traceTime time);
void removeComment(const QModelIndex& index);
const std::vector<Comment>& getComments() const;
traceTime getTimeFromIndex(const QModelIndex& index) const;
QModelIndex hoveredComment(Timespan timespan) const;
public Q_SLOTS:
void rowDoubleClicked(const QModelIndex& index);
protected:
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
/**
* The eventFilter is used to delete comments using the delete key.
*/
bool eventFilter(QObject* object, QEvent* event) override;
Q_SIGNALS:
void editTriggered(const QModelIndex& index);
void gotoCommentTriggered(const QModelIndex& index);
private:
void setUpActions();
std::vector<Comment> comments;
QAction* gotoAction;
QAction* editAction;
QAction* deleteAction;
QAction* selectAllAction;
QAction* deselectAllAction;
QItemSelectionModel* internalSelectionModel;
};
#endif // COMMENTMODEL_H

View File

@@ -0,0 +1,300 @@
/*
* Copyright (c) 2021, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Derek Christ
*/
#include "configmodels.h"
#include <QJsonDocument>
#include <QJsonObject>
McConfigModel::McConfigModel(const TraceDB& traceFile, QObject* parent) :
QAbstractTableModel(parent)
{
QSqlDatabase db = traceFile.getDatabase();
QString query = "SELECT MCconfig FROM GeneralInfo";
QSqlQuery sqlQuery = db.exec(query);
// The whole configuration is stored in a single cell.
sqlQuery.next();
QString mcConfigJson = sqlQuery.value(0).toString();
addAdditionalInfos(traceFile.getGeneralInfo());
parseJson(mcConfigJson);
}
void McConfigModel::parseJson(const QString& jsonString)
{
QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonString.toUtf8());
QJsonObject mcConfigJson = jsonDocument.object()["mcconfig"].toObject();
for (auto key : mcConfigJson.keys())
{
QJsonValue currentValue = mcConfigJson.value(key);
if (currentValue.isDouble())
{
entries.push_back({key, QString::number(currentValue.toDouble())});
}
else if (currentValue.isString())
{
entries.push_back({key, currentValue.toString()});
}
else if (currentValue.isBool())
{
entries.push_back({key, currentValue.toBool() ? "True" : "False"});
}
}
}
void McConfigModel::addAdditionalInfos(const GeneralInfo& generalInfo)
{
auto addEntry = [this](const QString& key, const QString& value) {
entries.push_back({key, value});
};
addEntry("Number of Transactions", QString::number(generalInfo.numberOfTransactions));
addEntry("Clock period",
QString::number(generalInfo.clkPeriod) + " " + generalInfo.unitOfTime.toLower());
addEntry("Length of trace", prettyFormatTime(generalInfo.span.End()));
addEntry("Window size", QString::number(generalInfo.windowSize));
}
int McConfigModel::rowCount(const QModelIndex& parent) const
{
Q_UNUSED(parent)
return entries.size();
}
int McConfigModel::columnCount(const QModelIndex& parent) const
{
Q_UNUSED(parent)
return 2;
}
QVariant McConfigModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid())
return QVariant();
if (role != Qt::DisplayRole)
return QVariant();
auto entry = entries.at(index.row());
if (index.column() == 0)
return entry.first;
else if (index.column() == 1)
return entry.second;
return QVariant();
}
QVariant McConfigModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
if (orientation == Qt::Horizontal)
{
switch (section)
{
case 0:
return "Field";
case 1:
return "Value";
default:
break;
}
}
return QVariant();
}
MemSpecModel::MemSpecModel(const TraceDB& traceFile, QObject* parent) : QAbstractItemModel(parent)
{
QSqlDatabase db = traceFile.getDatabase();
QString query = "SELECT Memspec FROM GeneralInfo";
QSqlQuery sqlQuery = db.exec(query);
// The whole configuration is stored in a single cell.
sqlQuery.next();
QString memSpecJson = sqlQuery.value(0).toString();
parseJson(memSpecJson);
}
int MemSpecModel::Node::getRow() const
{
if (!parent)
return 0;
const auto& siblings = parent->children;
const auto siblingsIt =
std::find_if(siblings.begin(),
siblings.end(),
[this](const std::unique_ptr<Node>& node) { return node.get() == this; });
Q_ASSERT(siblingsIt != siblings.end());
return std::distance(siblings.begin(), siblingsIt);
}
void MemSpecModel::parseJson(const QString& jsonString)
{
QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonString.toUtf8());
QJsonObject memSpecJson = jsonDocument.object()["memspec"].toObject();
std::function<void(const QJsonObject&, std::unique_ptr<Node>&)> addNodes;
addNodes = [&addNodes](const QJsonObject& obj, std::unique_ptr<Node>& parentNode)
{
for (auto key : obj.keys())
{
QJsonValue currentValue = obj.value(key);
QString value;
if (currentValue.isDouble())
{
value = QString::number(currentValue.toDouble());
}
else if (currentValue.isString())
{
value = currentValue.toString();
}
else if (currentValue.isBool())
{
value = currentValue.toBool() ? "True" : "False";
}
std::unique_ptr<Node> node =
std::unique_ptr<Node>(new Node({key, value}, parentNode.get()));
addNodes(obj[key].toObject(), node);
parentNode->children.push_back(std::move(node));
}
};
addNodes(memSpecJson, rootNode);
}
int MemSpecModel::rowCount(const QModelIndex& parent) const
{
if (parent.column() > 0)
return 0;
const Node* parentNode;
if (!parent.isValid())
parentNode = rootNode.get();
else
parentNode = static_cast<const Node*>(parent.internalPointer());
return parentNode->childCount();
}
int MemSpecModel::columnCount(const QModelIndex& parent) const
{
Q_UNUSED(parent)
return 2;
}
QVariant MemSpecModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid())
return QVariant();
if (role != Qt::DisplayRole && role != Qt::ToolTipRole)
return QVariant();
auto* node = static_cast<const Node*>(index.internalPointer());
if (index.column() == 0)
return QVariant(node->data.first);
else
return QVariant(node->data.second);
}
QVariant MemSpecModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
if (orientation == Qt::Horizontal)
{
switch (section)
{
case 0:
return "Field";
case 1:
return "Value";
default:
break;
}
}
return QVariant();
}
QModelIndex MemSpecModel::index(int row, int column, const QModelIndex& parent) const
{
if (!hasIndex(row, column, parent))
return QModelIndex();
const Node* parentNode;
if (!parent.isValid())
parentNode = rootNode.get();
else
parentNode = static_cast<const Node*>(parent.internalPointer());
const Node* node = parentNode->children[row].get();
return createIndex(row, column, const_cast<Node*>(node));
}
QModelIndex MemSpecModel::parent(const QModelIndex& index) const
{
if (!index.isValid())
return QModelIndex();
const Node* childNode = static_cast<const Node*>(index.internalPointer());
const Node* parentNode = childNode->parent;
if (!parentNode || parentNode == rootNode.get())
return QModelIndex();
return createIndex(parentNode->getRow(), 0, const_cast<Node*>(parentNode));
}

View File

@@ -0,0 +1,133 @@
/*
* Copyright (c) 2021, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Derek Christ
*/
#ifndef CONFIGMODELS_H
#define CONFIGMODELS_H
#include "data/tracedb.h"
#ifdef EXTENSION_ENABLED
#include "businessObjects/phases/dependencyinfos.h"
#endif
#include <QAbstractTableModel>
#include <utility>
#include <vector>
class McConfigModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit McConfigModel(const TraceDB& traceFile, QObject* parent = nullptr);
protected:
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
QVariant
headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
private:
/**
* Parses the json file and adds json entries to the entries vector.
* In case of failure, nothing is added and therefore the model
* will stay empty.
*/
void parseJson(const QString& jsonString);
/**
* Add additional infos about the tracefile which were
* previously displayed in the fileDescription widget.
*/
void addAdditionalInfos(const GeneralInfo& generalInfo);
std::vector<std::pair<QString, QString>> entries;
};
class MemSpecModel : public QAbstractItemModel
{
Q_OBJECT
public:
explicit MemSpecModel(const TraceDB& traceFile, QObject* parent = nullptr);
protected:
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
int columnCount(const QModelIndex& parent) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
QVariant
headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
QModelIndex index(int row, int column, const QModelIndex& parent) const override;
QModelIndex parent(const QModelIndex& index) const override;
private:
/**
* Parses the json file and adds json entries to the entries vector.
* In case of failure, nothing is added and therefore the model
* will stay empty.
*/
void parseJson(const QString& jsonString);
struct Node
{
using NodeData = std::pair<QString, QString>;
/**
* Constructor only used for the root node that does not contain any data.
*/
Node() = default;
Node(NodeData data, const Node* parent) : data(data), parent(parent) {}
/**
* Gets the row relative to its parent.
*/
int getRow() const;
int childCount() const { return children.size(); }
NodeData data;
const Node* parent = nullptr;
std::vector<std::unique_ptr<Node>> children;
};
std::unique_ptr<Node> rootNode = std::unique_ptr<Node>(new Node);
};
#endif // CONFIGMODELS_H

View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
*/
#ifndef GENERALINFO_H
#define GENERALINFO_H
#include "timespan.h"
#include <QString>
#include <climits>
struct GeneralInfo
{
uint64_t numberOfTransactions = 0;
uint64_t numberOfPhases = 0;
Timespan span = Timespan();
unsigned int numberOfRanks = 1;
unsigned int numberOfBankGroups = 1;
unsigned int numberOfBanks = 1;
unsigned int banksPerRank = 1;
unsigned int groupsPerRank = 1;
unsigned int banksPerGroup = 1;
QString description = "empty";
QString unitOfTime = "PS";
uint64_t clkPeriod = 1000;
uint64_t windowSize = 0;
unsigned int refreshMaxPostponed = 0;
unsigned int refreshMaxPulledin = 0;
unsigned int controllerThread = UINT_MAX;
unsigned int maxBufferDepth = 8;
unsigned int per2BankOffset = 1;
bool rowColumnCommandBus = false;
bool pseudoChannelMode = false;
GeneralInfo() = default;
GeneralInfo(uint64_t numberOfTransactions,
uint64_t numberOfPhases,
Timespan span,
unsigned int numberOfRanks,
unsigned int numberOfBankgroups,
unsigned int numberOfBanks,
QString description,
QString unitOfTime,
uint64_t clkPeriod,
uint64_t windowSize,
unsigned int refreshMaxPostponed,
unsigned int refreshMaxPulledin,
unsigned int controllerThread,
unsigned int maxBufferDepth,
unsigned int per2BankOffset,
bool rowColumnCommandBus,
bool pseudoChannelMode) :
numberOfTransactions(numberOfTransactions),
numberOfPhases(numberOfPhases),
span(span),
numberOfRanks(numberOfRanks),
numberOfBankGroups(numberOfBankgroups),
numberOfBanks(numberOfBanks),
banksPerRank(numberOfBanks / numberOfRanks),
groupsPerRank(numberOfBankgroups / numberOfRanks),
banksPerGroup(numberOfBanks / numberOfBankgroups),
description(std::move(description)),
unitOfTime(std::move(unitOfTime)),
clkPeriod(clkPeriod),
windowSize(windowSize),
refreshMaxPostponed(refreshMaxPostponed),
refreshMaxPulledin(refreshMaxPulledin),
controllerThread(controllerThread),
maxBufferDepth(maxBufferDepth),
per2BankOffset(per2BankOffset),
rowColumnCommandBus(rowColumnCommandBus),
pseudoChannelMode(pseudoChannelMode)
{
}
};
#endif // GENERALINFO_H

View File

@@ -0,0 +1,428 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
* Iron Prando da Silva
*/
#include "phase.h"
#include "businessObjects/traceplotlinemodel.h"
#include "businessObjects/transaction.h"
#include "presentation/tracedrawing.h"
#include <cmath>
void Phase::draw(QPainter* painter,
const QwtScaleMap& xMap,
const QwtScaleMap& yMap,
const QRectF& canvasRect,
bool highlight,
const TraceDrawingProperties& drawingProperties) const
{
Q_UNUSED(canvasRect);
QColor color = getColor(drawingProperties);
painter->setBrush(QBrush(getColor(drawingProperties), getBrushStyle()));
if (!drawingProperties.drawBorder)
{
painter->setPen(color);
}
else
{
painter->setPen(Qt::black);
}
if (highlight)
{
QPen pen(Qt::red);
pen.setWidth(3);
painter->setPen(pen);
}
for (auto yVal : getYVals(drawingProperties))
{
drawPhaseSymbol(span.Begin(),
span.End(),
yVal,
drawingProperties.drawText,
getPhaseSymbol(),
painter,
xMap,
yMap,
drawingProperties.textColor);
DependencyOptions drawDependenciesOptions = drawingProperties.drawDependenciesOption;
if (drawDependenciesOptions.draw == DependencyOption::All ||
(drawDependenciesOptions.draw == DependencyOption::Selected && highlight))
{
drawPhaseDependencies(
span.Begin(), span.End(), yVal, drawingProperties, painter, xMap, yMap);
}
}
for (Timespan spanOnCommandBus : spansOnCommandBus)
{
for (const auto& line : drawingProperties.getTracePlotLines())
{
if (line->data.type == AbstractTracePlotLineModel::RowCommandBusLine)
{
if (isColumnCommand())
continue;
}
else if (line->data.type == AbstractTracePlotLineModel::ColumnCommandBusLine)
{
if (!isColumnCommand())
continue;
}
else if (line->data.type != AbstractTracePlotLineModel::CommandBusLine)
continue;
drawPhaseSymbol(spanOnCommandBus.Begin(),
spanOnCommandBus.End(),
line->data.yVal,
false,
PhaseSymbol::Hexagon,
painter,
xMap,
yMap,
drawingProperties.textColor);
}
}
if (spanOnDataStrobe.End() != 0)
{
for (const auto& line : drawingProperties.getTracePlotLines())
{
if (line->data.type == AbstractTracePlotLineModel::PseudoChannel0Line)
{
if (rank != 0)
continue;
}
else if (line->data.type == AbstractTracePlotLineModel::PseudoChannel1Line)
{
if (rank != 1)
continue;
}
else if (line->data.type != AbstractTracePlotLineModel::DataBusLine)
continue;
drawPhaseSymbol(spanOnDataStrobe.Begin(),
spanOnDataStrobe.End(),
line->data.yVal,
false,
PhaseSymbol::Hexagon,
painter,
xMap,
yMap,
drawingProperties.textColor);
}
}
}
void Phase::drawPhaseSymbol(traceTime begin,
traceTime end,
double y,
bool drawtext,
PhaseSymbol symbol,
QPainter* painter,
const QwtScaleMap& xMap,
const QwtScaleMap& yMap,
const QColor& textColor) const
{
double yVal = yMap.transform(y);
double symbolHeight = yMap.transform(0) - yMap.transform(hexagonHeight);
// Increase display size of phases with zero span
traceTime offset = (begin == end) ? static_cast<traceTime>(0.05 * clk) : 0;
if (symbol == PhaseSymbol::Hexagon)
{
QPoint hexFrom(static_cast<int>(xMap.transform(begin)), static_cast<int>(yVal));
QPoint hexTo(static_cast<int>(xMap.transform(end + offset)), static_cast<int>(yVal));
drawHexagon(painter, hexFrom, hexTo, symbolHeight);
}
else
{
QPoint upperLeft(static_cast<int>(xMap.transform(begin)),
static_cast<int>(yVal - symbolHeight / 2));
QPoint bottomRight(static_cast<int>(xMap.transform(end)),
static_cast<int>(yVal + symbolHeight / 2));
painter->drawRect(QRect(upperLeft, bottomRight));
}
if (drawtext)
drawText(painter,
Name(),
QPoint(static_cast<int>(xMap.transform(begin)),
static_cast<int>(yVal + symbolHeight / 2)),
TextPositioning::bottomRight,
textColor);
}
void Phase::drawPhaseDependencies(traceTime begin,
traceTime end,
double y,
const TraceDrawingProperties& drawingProperties,
QPainter* painter,
const QwtScaleMap& xMap,
const QwtScaleMap& yMap) const
{
QPen pen;
pen.setWidth(2);
painter->save();
painter->setPen(pen);
painter->setRenderHint(QPainter::Antialiasing);
double yVal = yMap.transform(y);
double symbolHeight = yMap.transform(0) - yMap.transform(hexagonHeight);
traceTime offset = (begin == end) ? static_cast<traceTime>(0.05 * clk) : 0;
size_t invisibleDeps = 0;
QPoint depLineTo(static_cast<int>(xMap.transform(begin /* + (end + offset - begin)/4*/)),
static_cast<int>(yVal));
#ifdef EXTENSION_ENABLED
for (const auto& dep : mDependencies)
{
if (dep->isVisible())
{
if (!dep->draw(depLineTo, drawingProperties, painter, xMap, yMap))
{
invisibleDeps += 1;
}
}
else
{
invisibleDeps += 1;
}
}
#endif
if (invisibleDeps > 0)
{
QPoint invisibleDepsPoint(
static_cast<int>(xMap.transform(begin + (end + offset - begin) / 2)),
static_cast<int>(yVal + 0.1 * symbolHeight));
drawText(painter,
QString::number(invisibleDeps),
invisibleDepsPoint,
TextPositioning::centerCenter);
}
painter->restore();
}
std::vector<int> Phase::getYVals(const TraceDrawingProperties& drawingProperties) const
{
std::vector<int> yVals;
for (const auto& line : drawingProperties.getTracePlotLines())
{
if (line->data.type != AbstractTracePlotLineModel::BankLine)
continue;
unsigned int yVal = line->data.yVal;
unsigned int drawnRank = line->data.rank;
unsigned int drawnBank = line->data.bank;
bool shouldBeDrawn = false;
switch (getGranularity())
{
case Granularity::Rankwise:
shouldBeDrawn = (rank == drawnRank);
break;
case Granularity::Groupwise:
shouldBeDrawn = (rank == drawnRank) && (bank % drawingProperties.banksPerGroup ==
drawnBank % drawingProperties.banksPerGroup);
break;
case Granularity::Bankwise:
shouldBeDrawn = (bank == drawnBank);
break;
case Granularity::TwoBankwise:
shouldBeDrawn =
(bank == drawnBank) || ((bank + drawingProperties.per2BankOffset) == drawnBank);
break;
}
if (shouldBeDrawn)
yVals.push_back(yVal);
}
return yVals;
}
std::vector<int> REQ::getYVals(const TraceDrawingProperties& drawingProperties) const
{
std::vector<int> yVals;
for (const auto& line : drawingProperties.getTracePlotLines())
{
if (line->data.type != AbstractTracePlotLineModel::RequestLine)
continue;
yVals.push_back(line->data.yVal);
}
return yVals;
}
std::vector<int> RESP::getYVals(const TraceDrawingProperties& drawingProperties) const
{
std::vector<int> yVals;
for (const auto& line : drawingProperties.getTracePlotLines())
{
if (line->data.type != AbstractTracePlotLineModel::ResponseLine)
continue;
yVals.push_back(line->data.yVal);
}
return yVals;
}
QColor Phase::getColor(const TraceDrawingProperties& drawingProperties) const
{
switch (drawingProperties.colorGrouping)
{
case ColorGrouping::PhaseType:
return getPhaseColor();
break;
case ColorGrouping::Thread:
return ColorGenerator::getColor(static_cast<unsigned int>(transaction.lock()->thread));
break;
case ColorGrouping::RainbowTransaction:
return ColorGenerator::getRainbowColored(transaction.lock()->id, ColorName::HSV15);
break;
case ColorGrouping::Transaction:
default:
return ColorGenerator::getColor(transaction.lock()->id);
}
}
Qt::BrushStyle Phase::getBrushStyle() const
{
return Qt::SolidPattern;
}
bool Phase::isSelected(Timespan timespan,
double yVal,
const TraceDrawingProperties& drawingProperties) const
{
if (span.overlaps(timespan))
{
for (auto lineYVal : getYVals(drawingProperties))
if (fabs(yVal - lineYVal) <= hexagonHeight / 2)
return true;
}
for (Timespan _span : spansOnCommandBus)
{
if (_span.overlaps(timespan))
{
for (const auto& line : drawingProperties.getTracePlotLines())
{
if (line->data.type == AbstractTracePlotLineModel::RowCommandBusLine)
{
if (isColumnCommand())
continue;
}
else if (line->data.type == AbstractTracePlotLineModel::ColumnCommandBusLine)
{
if (!isColumnCommand())
continue;
}
else if (line->data.type != AbstractTracePlotLineModel::CommandBusLine)
continue;
if (fabs(yVal - line->data.yVal) <= hexagonHeight / 2)
return true;
}
}
}
if (spanOnDataStrobe.End() != 0 && spanOnDataStrobe.overlaps(timespan))
{
for (const auto& line : drawingProperties.getTracePlotLines())
{
if (line->data.type == AbstractTracePlotLineModel::PseudoChannel0Line)
{
if (rank != 0)
continue;
}
else if (line->data.type == AbstractTracePlotLineModel::PseudoChannel1Line)
{
if (rank != 1)
continue;
}
else if (line->data.type != AbstractTracePlotLineModel::DataBusLine)
continue;
if (fabs(yVal - line->data.yVal) <= hexagonHeight / 2)
return true;
}
}
return false;
}
bool Phase::isColumnCommand() const
{
if (dynamic_cast<const RD*>(this) || dynamic_cast<const RDA*>(this) ||
dynamic_cast<const WR*>(this) || dynamic_cast<const WRA*>(this))
return true;
else
return false;
}
Phase::PhaseSymbol Phase::getPhaseSymbol() const
{
return PhaseSymbol::Hexagon;
}
#ifdef EXTENSION_ENABLED
void Phase::addDependency(const std::shared_ptr<PhaseDependency>& dependency)
{
mDependencies.push_back(dependency);
}
#endif

View File

@@ -0,0 +1,671 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
* Iron Prando da Silva
*/
#ifndef BANKPHASE_H
#define BANKPHASE_H
#ifdef EXTENSION_ENABLED
#include "businessObjects/phases/phasedependency.h"
#endif
#include "businessObjects/timespan.h"
#include "presentation/tracedrawingproperties.h"
#include "presentation/util/colorgenerator.h"
#include <QPainter>
#include <QString>
#include <memory>
#include <qwt_scale_map.h>
#include <utility>
#include <vector>
typedef unsigned int ID;
// enum TextPositioning;
class Transaction;
enum class RelevantAttributes
{
Rank = 0x01,
BankGroup = 0x02,
Bank = 0x04,
Row = 0x08,
Column = 0x10,
BurstLength = 0x20
};
inline RelevantAttributes operator|(RelevantAttributes a, RelevantAttributes b)
{
return static_cast<RelevantAttributes>(static_cast<int>(a) | static_cast<int>(b));
}
inline RelevantAttributes operator&(RelevantAttributes a, RelevantAttributes b)
{
return static_cast<RelevantAttributes>(static_cast<int>(a) & static_cast<int>(b));
}
class Phase
{
public:
Phase(ID id,
Timespan span,
Timespan spanOnDataStrobe,
unsigned int rank,
unsigned int bankGroup,
unsigned int bank,
unsigned int row,
unsigned int column,
unsigned int burstLength,
traceTime clk,
const std::shared_ptr<Transaction>& transaction,
std::vector<Timespan> spansOnCommandBus,
unsigned int groupsPerRank,
unsigned int banksPerGroup) :
id(id),
span(span),
spanOnDataStrobe(spanOnDataStrobe),
rank(rank),
bankGroup(bankGroup),
bank(bank),
row(row),
column(column),
burstLength(burstLength),
groupsPerRank(groupsPerRank),
banksPerGroup(banksPerGroup),
clk(clk),
transaction(transaction),
spansOnCommandBus(std::move(spansOnCommandBus)),
hexagonHeight(0.6),
captionPosition(TextPositioning::bottomRight)
{
}
void draw(QPainter* painter,
const QwtScaleMap& xMap,
const QwtScaleMap& yMap,
const QRectF& canvasRect,
bool highlight,
const TraceDrawingProperties& drawingProperties) const;
bool isSelected(Timespan timespan,
double yVal,
const TraceDrawingProperties& drawingproperties) const;
bool isColumnCommand() const;
const Timespan& Span() const { return span; }
ID Id() const { return id; }
unsigned int getRank() const { return rank; }
unsigned int getBankGroup() const { return bankGroup % groupsPerRank; }
unsigned int getBank() const { return bank % banksPerGroup; }
unsigned int getRow() const { return row; }
unsigned int getColumn() const { return column; }
unsigned int getBurstLength() const { return burstLength; }
virtual RelevantAttributes getRelevantAttributes() const = 0;
virtual QString Name() const = 0;
#ifdef EXTENSION_ENABLED
void addDependency(const std::shared_ptr<PhaseDependency>& dependency);
#endif
protected:
ID id;
Timespan span;
Timespan spanOnDataStrobe;
unsigned int rank, bankGroup, bank, row, column, burstLength;
unsigned int groupsPerRank, banksPerGroup;
traceTime clk;
std::weak_ptr<Transaction> transaction;
std::vector<Timespan> spansOnCommandBus;
#ifdef EXTENSION_ENABLED
std::vector<std::shared_ptr<PhaseDependency>> mDependencies;
#endif
double hexagonHeight;
TextPositioning captionPosition;
enum PhaseSymbol
{
Hexagon,
Rect
};
virtual PhaseSymbol getPhaseSymbol() const;
virtual Qt::BrushStyle getBrushStyle() const;
virtual QColor getColor(const TraceDrawingProperties& drawingProperties) const;
virtual QColor getPhaseColor() const = 0;
virtual std::vector<int> getYVals(const TraceDrawingProperties& drawingProperties) const;
virtual void drawPhaseSymbol(traceTime begin,
traceTime end,
double y,
bool drawtext,
PhaseSymbol symbol,
QPainter* painter,
const QwtScaleMap& xMap,
const QwtScaleMap& yMap,
const QColor& textColor) const;
virtual void drawPhaseDependencies(traceTime begin,
traceTime end,
double y,
const TraceDrawingProperties& drawingProperties,
QPainter* painter,
const QwtScaleMap& xMap,
const QwtScaleMap& yMap) const;
enum class Granularity
{
Bankwise,
TwoBankwise,
Groupwise,
Rankwise
};
virtual Granularity getGranularity() const { return Granularity::Bankwise; }
friend class PhaseDependency;
};
class REQ final : public Phase
{
public:
using Phase::Phase;
protected:
QColor getPhaseColor() const override { return ColorGenerator::getColor(1); }
QString Name() const final { return "REQ"; }
RelevantAttributes getRelevantAttributes() const override
{
return static_cast<RelevantAttributes>(0);
}
std::vector<int> getYVals(const TraceDrawingProperties& drawingProperties) const override;
};
class RESP final : public Phase
{
public:
using Phase::Phase;
protected:
QColor getPhaseColor() const override { return ColorGenerator::getColor(1); }
QString Name() const override { return "RESP"; }
RelevantAttributes getRelevantAttributes() const override
{
return static_cast<RelevantAttributes>(0);
}
std::vector<int> getYVals(const TraceDrawingProperties& drawingProperties) const override;
};
class PREPB final : public Phase
{
public:
using Phase::Phase;
protected:
QColor getPhaseColor() const override { return ColorGenerator::getColor(1); }
QString Name() const override { return "PREPB"; }
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank;
}
};
class PRESB final : public Phase
{
public:
using Phase::Phase;
protected:
QString Name() const override { return "PRESB"; }
virtual std::vector<traceTime> getTimesOnCommandBus() const { return {span.Begin()}; }
QColor getColor(const TraceDrawingProperties& drawingProperties) const override
{
Q_UNUSED(drawingProperties)
return getPhaseColor();
}
QColor getPhaseColor() const override { return ColorGenerator::getColor(1); }
Granularity getGranularity() const override { return Granularity::Groupwise; }
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::Bank;
}
};
class PREAB final : public Phase
{
public:
using Phase::Phase;
protected:
QString Name() const override { return "PREAB"; }
virtual std::vector<traceTime> getTimesOnCommandBus() const { return {span.Begin()}; }
QColor getColor(const TraceDrawingProperties& drawingProperties) const override
{
Q_UNUSED(drawingProperties)
return getPhaseColor();
}
QColor getPhaseColor() const override { return ColorGenerator::getColor(10); }
Granularity getGranularity() const override { return Granularity::Rankwise; }
RelevantAttributes getRelevantAttributes() const override { return RelevantAttributes::Rank; }
};
class ACT final : public Phase
{
public:
using Phase::Phase;
protected:
QColor getPhaseColor() const override { return ColorGenerator::getColor(3); }
QString Name() const override { return "ACT"; }
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank |
RelevantAttributes::Row;
}
};
class RD final : public Phase
{
public:
using Phase::Phase;
protected:
QColor getPhaseColor() const override { return ColorGenerator::getColor(4); }
QString Name() const override { return "RD"; }
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank |
RelevantAttributes::Column | RelevantAttributes::BurstLength;
}
};
class RDA final : public Phase
{
public:
using Phase::Phase;
protected:
QColor getPhaseColor() const override { return ColorGenerator::getColor(5); }
QString Name() const override { return "RDA"; }
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank |
RelevantAttributes::Column | RelevantAttributes::BurstLength;
}
};
class WR final : public Phase
{
public:
using Phase::Phase;
protected:
QColor getPhaseColor() const override { return ColorGenerator::getColor(6); }
QString Name() const override { return "WR"; }
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank |
RelevantAttributes::Column | RelevantAttributes::BurstLength;
}
};
class MWR final : public Phase
{
public:
using Phase::Phase;
protected:
QColor getPhaseColor() const override { return ColorGenerator::getColor(6); }
QString Name() const override { return "MWR"; }
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank |
RelevantAttributes::Column | RelevantAttributes::BurstLength;
}
};
class WRA final : public Phase
{
public:
using Phase::Phase;
protected:
QColor getPhaseColor() const override { return ColorGenerator::getColor(7); }
QString Name() const override { return "WRA"; }
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank |
RelevantAttributes::Column | RelevantAttributes::BurstLength;
}
};
class MWRA final : public Phase
{
public:
using Phase::Phase;
protected:
QColor getPhaseColor() const override { return ColorGenerator::getColor(7); }
QString Name() const override { return "MWRA"; }
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank |
RelevantAttributes::Column | RelevantAttributes::BurstLength;
}
};
class AUTO_REFRESH : public Phase
{
public:
using Phase::Phase;
protected:
QString Name() const override { return "REF"; }
virtual std::vector<traceTime> getTimesOnCommandBus() const { return {span.Begin()}; }
QColor getColor(const TraceDrawingProperties& drawingProperties) const override
{
Q_UNUSED(drawingProperties)
return getPhaseColor();
}
QColor getPhaseColor() const override
{
auto phaseColor = QColor(Qt::darkCyan);
phaseColor.setAlpha(130);
return phaseColor;
}
};
class REFAB final : public AUTO_REFRESH
{
public:
using AUTO_REFRESH::AUTO_REFRESH;
protected:
QString Name() const override { return "REFAB"; }
Granularity getGranularity() const override { return Granularity::Rankwise; }
RelevantAttributes getRelevantAttributes() const override { return RelevantAttributes::Rank; }
};
class RFMAB final : public AUTO_REFRESH
{
public:
using AUTO_REFRESH::AUTO_REFRESH;
protected:
QString Name() const override { return "RFMAB"; }
Granularity getGranularity() const override { return Granularity::Rankwise; }
QColor getPhaseColor() const override
{
auto phaseColor = QColor(Qt::darkRed);
phaseColor.setAlpha(130);
return phaseColor;
}
RelevantAttributes getRelevantAttributes() const override { return RelevantAttributes::Rank; }
};
class REFPB final : public AUTO_REFRESH
{
public:
using AUTO_REFRESH::AUTO_REFRESH;
protected:
QString Name() const override { return "REFPB"; }
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank;
}
};
class RFMPB final : public AUTO_REFRESH
{
public:
using AUTO_REFRESH::AUTO_REFRESH;
protected:
QString Name() const override { return "RFMPB"; }
QColor getPhaseColor() const override
{
auto phaseColor = QColor(Qt::darkRed);
phaseColor.setAlpha(130);
return phaseColor;
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank;
}
};
class REFP2B final : public AUTO_REFRESH
{
public:
using AUTO_REFRESH::AUTO_REFRESH;
protected:
QString Name() const override { return "REFP2B"; }
Granularity getGranularity() const override { return Granularity::TwoBankwise; }
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank;
}
};
class RFMP2B final : public AUTO_REFRESH
{
public:
using AUTO_REFRESH::AUTO_REFRESH;
protected:
QString Name() const override { return "RFMP2B"; }
Granularity getGranularity() const override { return Granularity::TwoBankwise; }
QColor getPhaseColor() const override
{
auto phaseColor = QColor(Qt::darkRed);
phaseColor.setAlpha(130);
return phaseColor;
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank;
}
};
class REFSB final : public AUTO_REFRESH
{
public:
using AUTO_REFRESH::AUTO_REFRESH;
protected:
QString Name() const override { return "REFSB"; }
Granularity getGranularity() const override { return Granularity::Groupwise; }
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::Bank;
}
};
class RFMSB final : public AUTO_REFRESH
{
public:
using AUTO_REFRESH::AUTO_REFRESH;
protected:
QString Name() const override { return "RFMSB"; }
Granularity getGranularity() const override { return Granularity::Groupwise; }
QColor getPhaseColor() const override
{
auto phaseColor = QColor(Qt::darkRed);
phaseColor.setAlpha(130);
return phaseColor;
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::Bank;
}
};
class PDNAB : public Phase
{
public:
using Phase::Phase;
virtual ~PDNAB() = default;
protected:
QString Name() const override { return "PDNAB"; }
Qt::BrushStyle getBrushStyle() const override { return Qt::Dense6Pattern; }
QColor getColor(const TraceDrawingProperties& drawingProperties) const override
{
Q_UNUSED(drawingProperties)
return getPhaseColor();
}
QColor getPhaseColor() const override { return {Qt::black}; }
Phase::PhaseSymbol getPhaseSymbol() const override { return PhaseSymbol::Rect; }
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank;
}
};
class PDNA final : public PDNAB
{
public:
using PDNAB::PDNAB;
protected:
QString Name() const override { return "PDNA"; }
Granularity getGranularity() const override { return Granularity::Rankwise; }
RelevantAttributes getRelevantAttributes() const override { return RelevantAttributes::Rank; }
};
class PDNPB : public Phase
{
public:
using Phase::Phase;
virtual ~PDNPB() = default;
protected:
QString Name() const override { return "PDNPB"; }
Qt::BrushStyle getBrushStyle() const override { return Qt::Dense4Pattern; }
QColor getColor(const TraceDrawingProperties& drawingProperties) const override
{
Q_UNUSED(drawingProperties)
return getPhaseColor();
}
QColor getPhaseColor() const override { return {Qt::black}; }
Phase::PhaseSymbol getPhaseSymbol() const override { return PhaseSymbol::Rect; }
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank;
}
};
class PDNP final : public PDNPB
{
public:
using PDNPB::PDNPB;
protected:
QString Name() const override { return "PDNP"; }
Granularity getGranularity() const override { return Granularity::Rankwise; }
RelevantAttributes getRelevantAttributes() const override { return RelevantAttributes::Rank; }
};
class SREFB : public Phase
{
public:
using Phase::Phase;
virtual ~SREFB() = default;
protected:
QString Name() const override { return "SREFB"; }
Qt::BrushStyle getBrushStyle() const override { return Qt::Dense1Pattern; }
QColor getColor(const TraceDrawingProperties& drawingProperties) const override
{
Q_UNUSED(drawingProperties)
return getPhaseColor();
}
QColor getPhaseColor() const override { return {Qt::black}; }
Phase::PhaseSymbol getPhaseSymbol() const override { return PhaseSymbol::Rect; }
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank;
}
};
class SREF : public SREFB
{
public:
using SREFB::SREFB;
protected:
QString Name() const override { return "SREF"; }
Granularity getGranularity() const override { return Granularity::Rankwise; }
RelevantAttributes getRelevantAttributes() const override { return RelevantAttributes::Rank; }
};
#endif // BANKPHASE_H

View File

@@ -0,0 +1,450 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#include "phasefactory.h"
#include "businessObjects/timespan.h"
#include "businessObjects/transaction.h"
#include "data/tracedb.h"
#include "phase.h"
#include <exception>
std::shared_ptr<Phase> PhaseFactory::createPhase(ID id,
const QString& dbPhaseName,
Timespan span,
Timespan spanOnDataStrobe,
unsigned int rank,
unsigned int bankGroup,
unsigned int bank,
unsigned int row,
unsigned int column,
unsigned int burstLength,
const std::shared_ptr<Transaction>& trans,
TraceDB& database)
{
auto clk = static_cast<traceTime>(database.getGeneralInfo().clkPeriod);
unsigned int groupsPerRank = database.getGeneralInfo().groupsPerRank;
unsigned int banksPerGroup = database.getGeneralInfo().banksPerGroup;
const CommandLengths& cl = database.getCommandLengths();
if (dbPhaseName == "REQ")
return std::shared_ptr<Phase>(new REQ(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "RESP")
return std::shared_ptr<Phase>(new RESP(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "PREPB")
return std::shared_ptr<Phase>(
new PREPB(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.PREPB)},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "ACT")
return std::shared_ptr<Phase>(new ACT(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.ACT)},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "PREAB")
return std::shared_ptr<Phase>(
new PREAB(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.PREAB)},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "REFAB")
return std::shared_ptr<Phase>(
new REFAB(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.REFAB)},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "RFMAB")
return std::shared_ptr<Phase>(
new RFMAB(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.RFMAB)},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "REFPB")
return std::shared_ptr<Phase>(
new REFPB(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.REFPB)},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "RFMPB")
return std::shared_ptr<Phase>(
new RFMPB(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.RFMPB)},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "REFP2B")
return std::shared_ptr<Phase>(
new REFP2B(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.REFP2B)},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "RFMP2B")
return std::shared_ptr<Phase>(
new RFMP2B(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.RFMP2B)},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "PRESB")
return std::shared_ptr<Phase>(
new PRESB(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.PRESB)},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "REFSB")
return std::shared_ptr<Phase>(
new REFSB(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.REFSB)},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "RFMSB")
return std::shared_ptr<Phase>(
new RFMSB(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.RFMSB)},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "RD")
return std::shared_ptr<Phase>(new RD(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.RD)},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "RDA")
return std::shared_ptr<Phase>(new RDA(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.RDA)},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "WR")
return std::shared_ptr<Phase>(new WR(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.WR)},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "MWR")
return std::shared_ptr<Phase>(new MWR(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.WR)},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "WRA")
return std::shared_ptr<Phase>(new WRA(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.WRA)},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "MWRA")
return std::shared_ptr<Phase>(new MWRA(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.WR)},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "PDNA")
return std::shared_ptr<Phase>(
new PDNA(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.PDEA),
Timespan(span.End() - clk * cl.PDXA, span.End())},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "PDNP")
return std::shared_ptr<Phase>(
new PDNP(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.PDEP),
Timespan(span.End() - clk * cl.PDXP, span.End())},
groupsPerRank,
banksPerGroup));
if (dbPhaseName == "SREF")
return std::shared_ptr<Phase>(
new SREF(id,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
clk,
trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.SREFEN),
Timespan(span.End() - clk * cl.SREFEX, span.End())},
groupsPerRank,
banksPerGroup));
throw std::runtime_error("DB phasename " + dbPhaseName.toStdString() +
" unkown to phasefactory");
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef PHASEFACTORY_H
#define PHASEFACTORY_H
#include "businessObjects/transaction.h"
#include "phase.h"
#include <QStringList>
#include <memory>
class TraceDB;
class PhaseFactory
{
public:
PhaseFactory() = delete;
static std::shared_ptr<Phase> createPhase(ID id,
const QString& dbPhaseName,
Timespan span,
Timespan spanOnDataStrobe,
unsigned int rank,
unsigned int bankGroup,
unsigned int bank,
unsigned int row,
unsigned int column,
unsigned int burstLength,
const std::shared_ptr<Transaction>& trans,
TraceDB& database);
};
#endif // PHASEFACTORY_H

View File

@@ -0,0 +1,120 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Felipe S. Prado
* Derek Christ
*/
#include "pythoncaller.h"
#include <exception>
#include <iostream>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <string>
std::string PythonCaller::generatePlots(std::string_view pathToTrace)
{
try
{
pybind11::module_ metricsModule = pybind11::module_::import("plots");
auto result = metricsModule.attr("generatePlots")(pathToTrace).cast<std::string>();
return result;
}
catch (std::exception const& err)
{
std::cout << err.what() << std::endl;
}
return {};
}
std::vector<std::string> PythonCaller::availableMetrics(std::string_view pathToTrace)
{
try
{
pybind11::module_ metricsModule = pybind11::module_::import("metrics");
pybind11::list result = metricsModule.attr("getMetrics")(pathToTrace);
return result.cast<std::vector<std::string>>();
}
catch (std::exception const& err)
{
std::cout << err.what() << std::endl;
}
return {};
}
TraceCalculatedMetrics PythonCaller::evaluateMetrics(std::string_view pathToTrace,
std::vector<long> selectedMetrics)
{
TraceCalculatedMetrics metrics(pathToTrace.data());
try
{
pybind11::module_ metricsModule = pybind11::module_::import("metrics");
pybind11::list result =
metricsModule.attr("calculateMetrics")(pathToTrace, selectedMetrics);
auto metricList = result.cast<std::vector<pybind11::tuple>>();
for (auto metricPair : metricList)
{
std::string name = metricPair[0].cast<std::string>();
double value = metricPair[1].cast<double>();
metrics.addCalculatedMetric({name, value});
}
}
catch (std::exception const& err)
{
std::cout << err.what() << std::endl;
}
return metrics;
}
std::string PythonCaller::dumpVcd(std::string_view pathToTrace)
{
try
{
pybind11::module_ vcdModule = pybind11::module_::import("vcdExport");
pybind11::str result = vcdModule.attr("dumpVcd")(pathToTrace);
return result.cast<std::string>();
}
catch (std::exception const& err)
{
std::cout << err.what() << std::endl;
}
return {};
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Felipe S. Prado
* Derek Christ
*/
#ifndef PYTHONCALLER_H
#define PYTHONCALLER_H
// Workaround for CMAKE and Python
#ifdef slots
#undef slots
#endif
#include "businessObjects/tracecalculatedmetrics.h"
#include <string>
class PythonCaller
{
public:
static std::vector<std::string> availableMetrics(std::string_view pathToTrace);
static TraceCalculatedMetrics evaluateMetrics(std::string_view pathToTrace,
std::vector<long> selectedMetrics);
static std::string generatePlots(std::string_view pathToTrace);
static std::string dumpVcd(std::string_view pathToTrace);
};
#endif // PYTHONCALLER_H

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef TESTRESULT_H
#define TESTRESULT_H
#include <QString>
class TestResult
{
public:
TestResult(const QString& testName, bool passed, QString& message) :
testName(testName),
passed(passed),
message(message)
{
}
QString getTestName() const { return testName; }
QString getMessage() const { return message; }
bool hasPassed() const { return passed; }
private:
QString testName;
bool passed;
QString message;
};
#endif // TESTRESULT_H

View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#include "timespan.h"
bool Timespan::contains(traceTime time) const
{
return (begin <= time && time <= end);
}
bool Timespan::overlaps(const Timespan& other) const
{
return other.Begin() < this->end && this->begin < other.End();
}
void Timespan::shift(traceTime offset)
{
begin += offset;
end += offset;
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef TIMESPAN_H
#define TIMESPAN_H
#include "tracetime.h"
#include <QString>
#include <cstdlib>
class Timespan
{
traceTime begin;
traceTime end;
public:
explicit Timespan(traceTime begin = 0, traceTime end = 0) : begin(begin), end(end) {}
traceTime timeCovered() const { return std::abs(End() - Begin()); }
traceTime Begin() const { return begin; }
void setBegin(traceTime time) { begin = time; }
traceTime End() const { return end; }
traceTime Middle() const { return (begin + end) / 2; }
void setEnd(traceTime time) { end = time; }
bool contains(traceTime time) const;
bool overlaps(const Timespan& other) const;
void shift(traceTime offset);
};
#endif // TIMESPAN_H

View File

@@ -0,0 +1,85 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef TRACEMETRICRESULTS_H
#define TRACEMETRICRESULTS_H
#include "calculatedMetric.h"
#include <QString>
#include <vector>
class TraceCalculatedMetrics
{
public:
TraceCalculatedMetrics(const QString& traceName) : traceName(traceName) {}
void addCalculatedMetric(const CalculatedMetric& result)
{
calculatedMetrics.push_back(result);
}
QString getTraceName() const { return traceName; }
const std::vector<CalculatedMetric>& getCalculatedMetrics() const { return calculatedMetrics; }
QString toCSVHeader()
{
QString result = "";
result.append("Trace");
for (CalculatedMetric calculatedMetric : calculatedMetrics)
{
result.append(",");
result.append(calculatedMetric.name.c_str());
}
return result;
}
QString toCSVLine()
{
QString result = "";
result.append(traceName);
for (CalculatedMetric calculatedMetric : calculatedMetrics)
{
result.append(",");
result.append(QString::number(calculatedMetric.value));
}
return result;
}
private:
QString traceName;
std::vector<CalculatedMetric> calculatedMetrics;
};
#endif // TRACEMETRICRESULTS_H

View File

@@ -0,0 +1,692 @@
/*
* Copyright (c) 2021, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Derek Christ
*/
#include "traceplotlinemodel.h"
#include "../presentation/traceplot.h"
#include "../presentation/util/customlabelscaledraw.h"
#include <QItemSelectionModel>
#include <QKeyEvent>
#include <QMimeData>
AbstractTracePlotLineModel::AbstractTracePlotLineModel(const GeneralInfo& generalInfo,
QObject* parent) :
QAbstractItemModel(parent),
internalSelectionModel(new QItemSelectionModel(this, this)),
rootNode(std::make_shared<Node>()),
numberOfRanks(generalInfo.numberOfRanks),
groupsPerRank(generalInfo.groupsPerRank),
banksPerGroup(generalInfo.banksPerGroup),
banksPerRank(generalInfo.banksPerRank),
commandBusType(getCommandBusType(generalInfo)),
dataBusType(getDataBusType(generalInfo))
{
createInitialNodes();
}
AvailableTracePlotLineModel::AvailableTracePlotLineModel(const GeneralInfo& generalInfo,
QObject* parent) :
AbstractTracePlotLineModel(generalInfo, parent)
{
}
SelectedTracePlotLineModel::SelectedTracePlotLineModel(const GeneralInfo& generalInfo,
QObject* parent) :
AbstractTracePlotLineModel(generalInfo, parent)
{
}
void AbstractTracePlotLineModel::addTopLevelNode(std::shared_ptr<Node>&& node)
{
rootNode->children.push_back(std::move(node));
}
void AbstractTracePlotLineModel::createInitialNodes()
{
addTopLevelNode(std::unique_ptr<Node>(
new Node({LineType::RequestLine, getLabel(LineType::RequestLine)}, rootNode.get())));
addTopLevelNode(std::unique_ptr<Node>(
new Node({LineType::ResponseLine, getLabel(LineType::ResponseLine)}, rootNode.get())));
for (unsigned int rank = 0; rank < numberOfRanks; rank++)
addTopLevelNode(createRankGroupNode(rank));
if (commandBusType == CommandBusType::SingleCommandBus)
{
addTopLevelNode(std::unique_ptr<Node>(new Node(
{LineType::CommandBusLine, getLabel(LineType::CommandBusLine)}, rootNode.get())));
}
else // commandBusType == CommandBusType::RowColumnCommandBus
{
addTopLevelNode(std::unique_ptr<Node>(new Node(
{LineType::RowCommandBusLine, getLabel(LineType::RowCommandBusLine)}, rootNode.get())));
addTopLevelNode(std::unique_ptr<Node>(
new Node({LineType::ColumnCommandBusLine, getLabel(LineType::ColumnCommandBusLine)},
rootNode.get())));
}
if (dataBusType == DataBusType::LegacyMode)
{
addTopLevelNode(std::unique_ptr<Node>(
new Node({LineType::DataBusLine, getLabel(LineType::DataBusLine)}, rootNode.get())));
}
else // dataBusType == DataBusType::PseudoChannelMode
{
addTopLevelNode(std::unique_ptr<Node>(
new Node({LineType::PseudoChannel0Line, getLabel(LineType::PseudoChannel0Line)},
rootNode.get())));
addTopLevelNode(std::unique_ptr<Node>(
new Node({LineType::PseudoChannel1Line, getLabel(LineType::PseudoChannel1Line)},
rootNode.get())));
}
}
std::shared_ptr<AbstractTracePlotLineModel::Node>
AbstractTracePlotLineModel::createRankGroupNode(unsigned int rank) const
{
auto rankGroup = std::unique_ptr<Node>(
new Node({LineType::RankGroup, getLabel(rank), rank}, rootNode.get()));
for (unsigned int group = 0; group < groupsPerRank; group++)
{
for (unsigned int bank = 0; bank < banksPerGroup; bank++)
{
unsigned int absoluteRank = rank;
unsigned int absoluteGroup = group + rank * groupsPerRank;
unsigned int absoluteBank = bank + rank * banksPerRank + group * banksPerGroup;
auto bankLine = std::unique_ptr<Node>(new Node({LineType::BankLine,
getLabel(rank, group, bank),
absoluteRank,
absoluteGroup,
absoluteBank},
rankGroup.get()));
rankGroup->children.push_back(std::move(bankLine));
}
}
return rankGroup;
}
int AbstractTracePlotLineModel::rowCount(const QModelIndex& parent) const
{
if (parent.column() > 0)
return 0;
const Node* parentNode;
if (!parent.isValid())
parentNode = rootNode.get();
else
parentNode = static_cast<const Node*>(parent.internalPointer());
return parentNode->childCount();
}
int AbstractTracePlotLineModel::columnCount(const QModelIndex& parent) const
{
Q_UNUSED(parent)
return 1;
}
QVariant AbstractTracePlotLineModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid())
return QVariant();
auto* node = static_cast<const Node*>(index.internalPointer());
switch (role)
{
case Qt::DisplayRole:
return node->data.label;
case Role::TypeRole:
return QVariant::fromValue(node->data.type);
case Role::CollapsedRole:
return node->data.collapsed;
}
return QVariant();
}
bool SelectedTracePlotLineModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
if (!index.isValid())
return false;
auto* node = static_cast<Node*>(index.internalPointer());
switch (role)
{
case Role::CollapsedRole:
node->data.collapsed = value.toBool();
emit dataChanged(index, index, {role});
return true;
case Qt::DisplayRole:
case Role::TypeRole:
// Not allowed
return false;
}
return false;
}
QVariant
AvailableTracePlotLineModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
if (orientation == Qt::Horizontal && section == 0)
return "Available Items";
return QVariant();
}
QVariant
SelectedTracePlotLineModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
if (orientation == Qt::Horizontal && section == 0)
{
return "Selected Items";
}
return QVariant();
}
QModelIndex AbstractTracePlotLineModel::index(int row, int column, const QModelIndex& parent) const
{
if (!hasIndex(row, column, parent))
return QModelIndex();
const Node* parentNode;
if (!parent.isValid())
parentNode = rootNode.get();
else
parentNode = static_cast<const Node*>(parent.internalPointer());
const Node* node = parentNode->children[row].get();
return createIndex(row, column, const_cast<Node*>(node));
}
QModelIndex AbstractTracePlotLineModel::parent(const QModelIndex& index) const
{
if (!index.isValid())
return QModelIndex();
const Node* childNode = static_cast<const Node*>(index.internalPointer());
const Node* parentNode = childNode->parent;
if (!parentNode || parentNode == rootNode.get())
return QModelIndex();
return createIndex(parentNode->getRow(), 0, const_cast<Node*>(parentNode));
}
void SelectedTracePlotLineModel::recreateCollapseButtons(TracePlot* tracePlot,
CustomLabelScaleDraw* customLabelScaleDraw)
{
// Remove old buttons
for (auto button : collapseButtons)
{
button->hide();
button->deleteLater();
}
collapseButtons.clear();
for (const auto& node : rootNode->children)
{
if (node->data.type != LineType::RankGroup)
continue;
QPushButton* collapseButton = new QPushButton(tracePlot);
unsigned int yVal = [node]()
{
if (node->data.collapsed)
return node->data.yVal;
else
return node->children.at(0)->data.yVal;
}();
bool isCollapsed = node->data.collapsed;
QModelIndex nodeIndex = index(node->getRow(), 0);
auto repositionButton = [=]()
{
QPointF point = tracePlot->axisScaleDraw(QwtPlot::yLeft)->labelPosition(yVal);
collapseButton->setGeometry(point.x(), point.y() - 4, 25, 25);
};
repositionButton();
auto updateLabel = [=]() { collapseButton->setText(isCollapsed ? "+" : "-"); };
updateLabel();
auto toggleCollapsed = [=]()
{
setData(nodeIndex, !isCollapsed, Role::CollapsedRole);
recreateCollapseButtons(tracePlot, customLabelScaleDraw);
};
// Important: The context of the connection is `collapseButton` as it should be disconnected
// when the button ceases to exist.
connect(customLabelScaleDraw,
&CustomLabelScaleDraw::scaleRedraw,
collapseButton,
repositionButton);
connect(collapseButton, &QPushButton::pressed, this, toggleCollapsed);
connect(
collapseButton, &QPushButton::pressed, tracePlot, &TracePlot::recreateCollapseButtons);
collapseButton->show();
collapseButtons.push_back(collapseButton);
}
}
int AbstractTracePlotLineModel::Node::getRow() const
{
if (!parent)
return 0;
const auto& siblings = parent->children;
const auto siblingsIt =
std::find_if(siblings.begin(),
siblings.end(),
[this](const std::shared_ptr<Node>& node) { return node.get() == this; });
Q_ASSERT(siblingsIt != siblings.end());
return std::distance(siblings.begin(), siblingsIt);
}
std::shared_ptr<AbstractTracePlotLineModel::Node>
AbstractTracePlotLineModel::Node::cloneNode(const Node* node, const Node* parent)
{
std::shared_ptr<Node> clonedNode = std::make_shared<Node>(node->data, parent);
for (const auto& child : node->children)
clonedNode->children.push_back(cloneNode(child.get(), clonedNode.get()));
return clonedNode;
}
QString AbstractTracePlotLineModel::getLabel(LineType type)
{
switch (type)
{
case LineType::RequestLine:
return "REQ";
case LineType::ResponseLine:
return "RESP";
case LineType::CommandBusLine:
return "Command Bus";
case LineType::RowCommandBusLine:
return "Command Bus [R]";
case LineType::ColumnCommandBusLine:
return "Command Bus [C]";
case LineType::DataBusLine:
return "Data Bus";
case LineType::PseudoChannel0Line:
return "Data Bus [PC0]";
case LineType::PseudoChannel1Line:
return "Data Bus [PC1]";
default:
return "";
}
}
QString AbstractTracePlotLineModel::getLabel(unsigned int rank) const
{
std::string_view rankLabel = dataBusType == DataBusType::LegacyMode ? "RA" : "PC";
return rankLabel.data() + QString::number(rank);
}
QString
AbstractTracePlotLineModel::getLabel(unsigned int rank, unsigned int group, unsigned int bank) const
{
std::string_view rankLabel = dataBusType == DataBusType::LegacyMode ? "RA" : "PC";
return rankLabel.data() + QString::number(rank) + " BG" + QString::number(group) + " BA" +
QString::number(bank);
}
AbstractTracePlotLineModel::CommandBusType
AbstractTracePlotLineModel::getCommandBusType(const GeneralInfo& generalInfo)
{
if (generalInfo.rowColumnCommandBus)
return CommandBusType::RowColumnCommandBus;
else
return CommandBusType::SingleCommandBus;
}
AbstractTracePlotLineModel::DataBusType
AbstractTracePlotLineModel::getDataBusType(const GeneralInfo& generalInfo)
{
if (generalInfo.pseudoChannelMode)
return DataBusType::PseudoChannelMode;
else
return DataBusType::LegacyMode;
}
bool SelectedTracePlotLineModel::removeRows(int row, int count, const QModelIndex& parent)
{
if (parent != QModelIndex())
return false;
// Note: beginRemoveRows requires [first, last], but erase requires [first, last)
beginRemoveRows(QModelIndex(), row, row + count - 1);
rootNode->children.erase(rootNode->children.begin() + row,
rootNode->children.begin() + row + count);
endRemoveRows();
return true;
}
void AvailableTracePlotLineModel::itemsDoubleClicked(const QModelIndex& index)
{
QModelIndexList indexList({index});
emit returnPressed(indexList);
}
void SelectedTracePlotLineModel::itemsDoubleClicked(const QModelIndex& index)
{
if (index.parent() != QModelIndex())
return;
removeRow(index.row(), QModelIndex());
}
bool AvailableTracePlotLineModel::eventFilter(QObject* object, QEvent* event)
{
Q_UNUSED(object)
if (event->type() == QEvent::KeyPress)
{
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Return)
{
const QModelIndexList indexes = internalSelectionModel->selectedRows();
emit returnPressed(indexes);
}
else
{
return false;
}
}
return false;
}
bool SelectedTracePlotLineModel::eventFilter(QObject* object, QEvent* event)
{
Q_UNUSED(object)
if (event->type() == QEvent::KeyPress)
{
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Delete)
{
// Note: This implementation requires the selection to be contiguous
const QModelIndexList indexes = internalSelectionModel->selectedRows();
if (indexes.count() == 0)
return true;
for (const auto& index : indexes)
{
// Only remove toplevel indexes
if (index.parent() != QModelIndex())
return true;
}
removeRows(indexes.at(0).row(), indexes.size(), QModelIndex());
return true;
}
else
{
return false;
}
}
return false;
}
void SelectedTracePlotLineModel::addIndexesFromAvailableModel(const QModelIndexList& indexes)
{
for (const auto& index : indexes)
{
auto node = static_cast<const Node*>(index.internalPointer());
auto clonedNode = Node::cloneNode(node, rootNode.get());
beginInsertRows(QModelIndex(), rootNode->children.size(), rootNode->children.size());
addTopLevelNode(std::move(clonedNode));
endInsertRows();
}
}
QItemSelectionModel* AbstractTracePlotLineModel::selectionModel() const
{
return internalSelectionModel;
}
QStringList AbstractTracePlotLineModel::mimeTypes() const
{
QStringList types = QAbstractItemModel::mimeTypes();
types << TRACELINE_MIMETYPE;
return types;
}
QMimeData* AbstractTracePlotLineModel::mimeData(const QModelIndexList& indexes) const
{
QByteArray traceLineData;
QDataStream dataStream(&traceLineData, QIODevice::WriteOnly);
for (const auto& index : indexes)
{
const Node* node = static_cast<const Node*>(index.internalPointer());
dataStream << node->data.type << node->data.label << node->data.rank << node->data.group
<< node->data.bank << node->data.collapsed;
}
QMimeData* mimeData = new QMimeData;
mimeData->setData(TRACELINE_MIMETYPE, traceLineData);
return mimeData;
}
bool AbstractTracePlotLineModel::canDropMimeData(const QMimeData* data,
Qt::DropAction action,
int row,
int column,
const QModelIndex& parent) const
{
Q_UNUSED(action);
Q_UNUSED(row);
Q_UNUSED(parent);
if (!data->hasFormat(TRACELINE_MIMETYPE))
return false;
if (column > 0)
return false;
return true;
}
bool AbstractTracePlotLineModel::dropMimeData(
const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent)
{
if (!canDropMimeData(data, action, row, column, parent))
return false;
if (action == Qt::IgnoreAction)
return true;
bool dropHandled = false;
int beginRow;
if (row != -1)
beginRow = row;
else
beginRow = rowCount(QModelIndex());
if (action == Qt::CopyAction || action == Qt::MoveAction)
{
dropHandled = true;
QByteArray traceLineData = data->data(TRACELINE_MIMETYPE);
QDataStream dataStream(&traceLineData, QIODevice::ReadOnly);
std::vector<std::shared_ptr<Node>> droppedNodes;
while (!dataStream.atEnd())
{
LineType type;
QString label;
unsigned int rank, group, bank;
bool isCollapsed;
dataStream >> type >> label >> rank >> group >> bank >> isCollapsed;
std::shared_ptr<Node> node;
if (type == LineType::BankLine)
node = std::make_shared<Node>(Node::NodeData{type, label, rank, group, bank},
rootNode.get());
else if (type == LineType::RankGroup)
node = createRankGroupNode(rank);
else
node = std::make_shared<Node>(Node::NodeData{type, label}, rootNode.get());
if (node->data.type == RankGroup)
node->data.collapsed = isCollapsed;
droppedNodes.push_back(std::move(node));
}
// Note: beginRemoveRows requires [first, last]
beginInsertRows(QModelIndex(), beginRow, beginRow + droppedNodes.size() - 1);
rootNode->children.insert(rootNode->children.begin() + beginRow,
std::make_move_iterator(droppedNodes.begin()),
std::make_move_iterator(droppedNodes.end()));
endInsertRows();
}
else
{
dropHandled = QAbstractItemModel::dropMimeData(data, action, row, column, parent);
}
return dropHandled;
}
Qt::DropActions AbstractTracePlotLineModel::supportedDropActions() const
{
return (Qt::MoveAction | Qt::CopyAction);
}
Qt::ItemFlags AbstractTracePlotLineModel::flags(const QModelIndex& index) const
{
Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index);
if (index.isValid())
return Qt::ItemIsDragEnabled | defaultFlags;
else
return Qt::ItemIsDropEnabled | defaultFlags;
}
std::shared_ptr<AbstractTracePlotLineModel::Node> SelectedTracePlotLineModel::getClonedRootNode()
{
return Node::cloneNode(rootNode.get(), nullptr);
}
void SelectedTracePlotLineModel::setRootNode(std::shared_ptr<AbstractTracePlotLineModel::Node> node)
{
removeRows(0, rootNode->childCount(), QModelIndex());
beginInsertRows(QModelIndex(), 0, node->childCount() - 1);
rootNode = std::move(node);
endInsertRows();
}
TracePlotLineDataSource::TracePlotLineDataSource(SelectedTracePlotLineModel* selectedModel,
QObject* parent) :
selectedModel(selectedModel)
{
Q_UNUSED(parent)
updateModel();
}
void TracePlotLineDataSource::updateModel()
{
entries.clear();
std::function<void(std::shared_ptr<AbstractTracePlotLineModel::Node> & parent)> addNodes;
addNodes = [=, &addNodes](std::shared_ptr<AbstractTracePlotLineModel::Node>& parent)
{
for (auto& childNode : parent->children)
{
if (childNode->data.type == AbstractTracePlotLineModel::RankGroup &&
!childNode->data.collapsed)
{
addNodes(childNode);
continue; // Don't add the parent node itself when not collapsed.
}
entries.push_back(childNode);
}
};
addNodes(selectedModel->rootNode);
emit modelChanged();
}

View File

@@ -0,0 +1,288 @@
/*
* Copyright (c) 2021, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Derek Christ
*/
#ifndef TRACEPLOTLINEMODEL_H
#define TRACEPLOTLINEMODEL_H
#include "generalinfo.h"
#include <QAbstractItemModel>
#include <QPushButton>
#include <memory>
class TracePlot;
class CustomLabelScaleDraw;
class QItemSelectionModel;
class AbstractTracePlotLineModel : public QAbstractItemModel
{
Q_OBJECT
public:
explicit AbstractTracePlotLineModel(const GeneralInfo& generalInfo, QObject* parent = nullptr);
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
QModelIndex
index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex& index) const override;
QItemSelectionModel* selectionModel() const;
enum Role
{
TypeRole = Qt::UserRole + 1,
CollapsedRole
};
Q_ENUM(Role)
enum LineType
{
RequestLine,
ResponseLine,
CommandBusLine,
RowCommandBusLine,
ColumnCommandBusLine,
DataBusLine,
PseudoChannel0Line,
PseudoChannel1Line,
RankGroup,
BankLine
};
Q_ENUM(LineType)
struct Node
{
struct NodeData
{
NodeData() = default;
NodeData(LineType type, const QString& label) : type(type), label(label) {}
NodeData(LineType type, const QString& label, unsigned int rank) :
type(type),
label(label),
rank(rank)
{
}
NodeData(LineType type,
const QString& label,
unsigned int rank,
unsigned int group,
unsigned int bank) :
type(type),
label(label),
rank(rank),
group(group),
bank(bank)
{
}
LineType type;
QString label;
unsigned int yVal = 0;
/**
* Used to store the collapsed state in the traceplot.
* The value has only an effect when the type is Type::RankGroup.
*/
bool collapsed = true;
/**
* Only used when the type is Type::BankLine.
* (Absolute numbering)
*/
unsigned int rank = 0, group = 0, bank = 0;
};
/**
* Constructor only used for the root node that does not contain any data.
*/
Node() = default;
Node(NodeData data, const Node* parent) : data(data), parent(parent) {}
/**
* Gets the row relative to its parent.
*/
int getRow() const;
int childCount() const { return children.size(); }
static std::shared_ptr<Node> cloneNode(const Node* node, const Node* parent);
NodeData data;
const Node* parent = nullptr;
std::vector<std::shared_ptr<Node>> children;
};
protected:
enum class CommandBusType
{
SingleCommandBus,
RowColumnCommandBus
};
enum class DataBusType
{
LegacyMode,
PseudoChannelMode
};
QStringList mimeTypes() const override;
QMimeData* mimeData(const QModelIndexList& indexes) const override;
bool dropMimeData(const QMimeData* data,
Qt::DropAction action,
int row,
int column,
const QModelIndex& parent) override;
bool canDropMimeData(const QMimeData* data,
Qt::DropAction action,
int row,
int column,
const QModelIndex& parent) const override;
Qt::DropActions supportedDropActions() const override;
Qt::ItemFlags flags(const QModelIndex& index) const override;
void addTopLevelNode(std::shared_ptr<Node>&& node);
void createInitialNodes();
std::shared_ptr<Node> createRankGroupNode(unsigned int rank) const;
static QString getLabel(LineType type);
QString getLabel(unsigned int rank) const;
QString getLabel(unsigned int rank, unsigned int group, unsigned int bank) const;
static CommandBusType getCommandBusType(const GeneralInfo& generalInfo);
static DataBusType getDataBusType(const GeneralInfo& generalInfo);
static constexpr auto TRACELINE_MIMETYPE = "application/x-tracelinedata";
QItemSelectionModel* const internalSelectionModel;
std::shared_ptr<Node> rootNode;
const unsigned int numberOfRanks;
const unsigned int groupsPerRank;
const unsigned int banksPerGroup;
const unsigned int banksPerRank;
const CommandBusType commandBusType;
const DataBusType dataBusType;
};
class AvailableTracePlotLineModel : public AbstractTracePlotLineModel
{
Q_OBJECT
public:
explicit AvailableTracePlotLineModel(const GeneralInfo& generalInfo, QObject* parent = nullptr);
public Q_SLOTS:
void itemsDoubleClicked(const QModelIndex& index);
Q_SIGNALS:
void returnPressed(const QModelIndexList& indexes);
protected:
QVariant
headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
bool eventFilter(QObject* object, QEvent* event) override;
};
class SelectedTracePlotLineModel : public AbstractTracePlotLineModel
{
Q_OBJECT
public:
explicit SelectedTracePlotLineModel(const GeneralInfo& generalInfo, QObject* parent = nullptr);
bool setData(const QModelIndex& index, const QVariant& value, int role) override;
void recreateCollapseButtons(TracePlot* tracePlot, CustomLabelScaleDraw* customLabelScaleDraw);
std::shared_ptr<Node> getClonedRootNode();
void setRootNode(std::shared_ptr<Node> node);
public Q_SLOTS:
void itemsDoubleClicked(const QModelIndex& index);
void addIndexesFromAvailableModel(const QModelIndexList& indexes);
protected:
bool eventFilter(QObject* object, QEvent* event) override;
QVariant
headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()) override;
private:
std::vector<QPushButton*> collapseButtons;
friend class TracePlotLineDataSource;
};
/*
* Simple list that is the true source for the traceplot.
*/
class TracePlotLineDataSource : public QObject
{
Q_OBJECT
public:
using TracePlotLine = AbstractTracePlotLineModel::Node;
explicit TracePlotLineDataSource(SelectedTracePlotLineModel* selectedModel,
QObject* parent = nullptr);
SelectedTracePlotLineModel* getSelectedModel() const { return selectedModel; };
std::vector<std::shared_ptr<TracePlotLine>>& getTracePlotLines() { return entries; }
public Q_SLOTS:
void updateModel();
Q_SIGNALS:
void modelChanged();
private:
SelectedTracePlotLineModel* selectedModel;
std::vector<std::shared_ptr<TracePlotLine>> entries;
};
#endif // TRACEPLOTLINEMODEL_H

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef TRACETIME_H
#define TRACETIME_H
#include <QString>
#include <math.h>
// time in picoseconds
typedef long long traceTime;
inline QString prettyFormatTime(traceTime time)
{
return QString::number(time / 1000.0, 'f') + QString(" ns");
}
inline QString formatInClks(traceTime time, unsigned int clkPeriod)
{
long long numberOfClockCovered = time / clkPeriod;
QString suffix = (numberOfClockCovered != 1) ? QString(" clks") : QString(" clk");
return QString::number(numberOfClockCovered) + suffix;
}
inline traceTime alignToClk(traceTime time, unsigned int clkPeriod)
{
return round(1.0 * time / clkPeriod) * clkPeriod;
}
#endif // TRACETIME_H

View File

@@ -0,0 +1,96 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Iron Prando da Silva
*/
#include "transaction.h"
#include <utility>
using namespace std;
unsigned int Transaction::mSNumTransactions = 0;
Transaction::Transaction(ID id,
QString command,
unsigned int address,
unsigned int dataLength,
unsigned int thread,
unsigned int channel,
Timespan span,
traceTime clk) :
clk(clk),
command(std::move(command)),
address(address),
dataLength(dataLength),
thread(thread),
channel(channel),
span(span),
id(id)
{
}
void Transaction::addPhase(const shared_ptr<Phase>& phase)
{
phases.push_back(phase);
}
void Transaction::draw(QPainter* painter,
const QwtScaleMap& xMap,
const QwtScaleMap& yMap,
const QRectF& canvasRect,
bool highlight,
const TraceDrawingProperties& drawingProperties) const
{
for (const shared_ptr<Phase>& phase : phases)
phase->draw(painter, xMap, yMap, canvasRect, highlight, drawingProperties);
}
bool Transaction::isSelected(Timespan timespan,
double yVal,
const TraceDrawingProperties& drawingproperties) const
{
if (span.overlaps(timespan))
{
for (const shared_ptr<Phase>& phase : phases)
{
if (phase->isSelected(timespan, yVal, drawingproperties))
return true;
}
}
return false;
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Iron Prando da Silva
*/
#ifndef TRANSACTION_H
#define TRANSACTION_H
#include "phases/phase.h"
#include "presentation/tracedrawingproperties.h"
#include "timespan.h"
#include <memory>
#include <vector>
typedef unsigned int ID;
class Transaction
{
private:
std::vector<std::shared_ptr<Phase>> phases;
traceTime clk;
public:
const QString command;
const uint64_t address;
const unsigned int dataLength, thread, channel;
const Timespan span;
const ID id;
Transaction(ID id,
QString command,
unsigned int address,
unsigned int dataLength,
unsigned int thread,
unsigned int channel,
Timespan span,
traceTime clk);
void draw(QPainter* painter,
const QwtScaleMap& xMap,
const QwtScaleMap& yMap,
const QRectF& canvasRect,
bool highlight,
const TraceDrawingProperties& drawingProperties) const;
void addPhase(const std::shared_ptr<Phase>& phase);
bool isSelected(Timespan timespan,
double yVal,
const TraceDrawingProperties& drawingproperties) const;
const std::vector<std::shared_ptr<Phase>>& Phases() const { return phases; }
public:
static void setNumTransactions(const unsigned int numTransactions)
{
mSNumTransactions = numTransactions;
}
static unsigned int getNumTransactions()
{
return mSNumTransactions;
}
private:
static unsigned int mSNumTransactions;
};
#endif // TRANSACTION_H

View File

@@ -0,0 +1,137 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Iron Prando da Silva
*/
#ifndef QUERYTEXTS_H
#define QUERYTEXTS_H
#include <QString>
struct TransactionQueryTexts
{
QString queryHead;
QString selectTransactionsByTimespan, selectTransactionById;
QString checkDependenciesExist, selectDependenciesByTimespan;
QString selectDependencyTypePercentages, selectTimeDependencyPercentages,
selectDelayedPhasePercentages, selectDependencyPhasePercentages;
TransactionQueryTexts()
{
queryHead = "SELECT Transactions.ID AS TransactionID, Ranges.begin, Ranges.end, Address, "
"DataLength, Thread, Channel, Command, Phases.ID AS PhaseID, PhaseName, "
"PhaseBegin, PhaseEnd, DataStrobeBegin, DataStrobeEnd, Rank, BankGroup, Bank, "
"Row, Column, BurstLength "
" FROM Transactions INNER JOIN Phases ON Phases.Transact = Transactions.ID "
"INNER JOIN Ranges ON Transactions.Range = Ranges.ID ";
selectTransactionsByTimespan =
queryHead + " WHERE Ranges.end >= :begin AND Ranges.begin <= :end";
selectTransactionById = queryHead + " WHERE Transactions.ID = :id";
checkDependenciesExist =
"SELECT CASE WHEN 0 < (SELECT count(*) FROM sqlite_master WHERE type = 'table' AND "
"name = 'DirectDependencies') THEN 1 ELSE 0 END AS result";
selectDependenciesByTimespan =
"WITH timespanTransactions AS (" + selectTransactionsByTimespan +
") SELECT * from DirectDependencies WHERE DelayedPhaseID IN ("
" SELECT DirectDependencies.DelayedPhaseID FROM DirectDependencies JOIN "
"timespanTransactions "
" ON DirectDependencies.DelayedPhaseID = timespanTransactions.PhaseID ) ";
// For some reason I could not use a parameter for these below
selectDependencyTypePercentages =
"WITH TotalDeps (total) AS ( "
"SELECT COUNT(*) FROM DirectDependencies "
"), "
"DependencyTypeDeps (param, ndeps) AS ( "
"SELECT "
"DependencyType, "
"COUNT(*) "
"FROM DirectDependencies "
"GROUP BY \"DependencyType\" "
") "
"SELECT param, ROUND(ndeps*100.0 / (SELECT total FROM TotalDeps), 3) as percentage "
"FROM DependencyTypeDeps "
"ORDER BY percentage DESC ;";
selectTimeDependencyPercentages =
"WITH TotalDeps (total) AS ( "
"SELECT COUNT(*) FROM DirectDependencies "
"), "
"DependencyTypeDeps (param, ndeps) AS ( "
"SELECT "
"TimeDependency, "
"COUNT(*) "
"FROM DirectDependencies "
"GROUP BY \"TimeDependency\" "
") "
"SELECT param, ROUND(ndeps*100.0 / (SELECT total FROM TotalDeps), 3) as percentage "
"FROM DependencyTypeDeps "
"ORDER BY percentage DESC ;";
selectDelayedPhasePercentages =
"WITH TotalDeps (total) AS ( "
"SELECT COUNT(*) FROM DirectDependencies "
"), "
"DependencyTypeDeps (param, ndeps) AS ( "
"SELECT "
"DelayedPhaseName, "
"COUNT(*) "
"FROM DirectDependencies "
"GROUP BY \"DelayedPhaseName\" "
") "
"SELECT param, ROUND(ndeps*100.0 / (SELECT total FROM TotalDeps), 3) as percentage "
"FROM DependencyTypeDeps "
"ORDER BY percentage DESC ;";
selectDependencyPhasePercentages =
"WITH TotalDeps (total) AS ( "
"SELECT COUNT(*) FROM DirectDependencies "
"), "
"DependencyTypeDeps (param, ndeps) AS ( "
"SELECT "
"DependencyPhaseName, "
"COUNT(*) "
"FROM DirectDependencies "
"GROUP BY \"DependencyPhaseName\" "
") "
"SELECT param, ROUND(ndeps*100.0 / (SELECT total FROM TotalDeps), 3) as percentage "
"FROM DependencyTypeDeps "
"ORDER BY percentage DESC ;";
}
};
#endif // QUERYTEXTS_H

View File

@@ -0,0 +1,790 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
* Iron Prando da Silva
*/
#include "data/tracedb.h"
#include "businessObjects/phases/phasefactory.h"
#include <QDebug>
#include <QFile>
#include <QFileInfo>
#include <QSqlError>
#include <QString>
#include <QStringList>
#include <QTextStream>
#include <iostream>
// define symbol printqueries if all queries should be printed to the console
// #define printqueries
TraceDB::TraceDB(const QString& path, bool openExisting)
{
this->pathToDB = path;
database = QSqlDatabase::database(path);
if (database.isValid() && database.isOpen())
{
// Close the database connection if it exists and was not closed yet.
database.close();
QSqlDatabase::removeDatabase(path);
}
database = QSqlDatabase::addDatabase("QSQLITE", path);
database.setDatabaseName(path);
if (!database.open())
{
qDebug() << database.lastError().text();
}
if (!openExisting)
dropAndCreateTables();
prepareQueries();
generalInfo = getGeneralInfoFromDB();
commandLengths = getCommandLengthsFromDB();
}
void TraceDB::prepareQueries()
{
selectTransactionsByTimespan = QSqlQuery(database);
if (!selectTransactionsByTimespan.prepare(queryTexts.selectTransactionsByTimespan))
qDebug() << database.lastError().text();
selectTransactionById = QSqlQuery(database);
if (!selectTransactionById.prepare(queryTexts.selectTransactionById))
qDebug() << database.lastError().text();
selectDebugMessagesByTimespan = QSqlQuery(database);
if (!selectDebugMessagesByTimespan.prepare(
"SELECT time, Message FROM DebugMessages WHERE :begin <= time AND time <= :end "))
qDebug() << database.lastError().text();
selectDebugMessagesByTimespanWithLimit = QSqlQuery(database);
if (!selectDebugMessagesByTimespanWithLimit.prepare(
"SELECT time, Message FROM DebugMessages WHERE :begin <= time AND time <= :end LIMIT "
":limit"))
qDebug() << database.lastError().text();
checkDependenciesExist = QSqlQuery(database);
if (!checkDependenciesExist.prepare(queryTexts.checkDependenciesExist))
qDebug() << database.lastError().text();
selectDependenciesByTimespan = QSqlQuery(database);
if (!selectDependenciesByTimespan.prepare(queryTexts.selectDependenciesByTimespan))
qDebug() << database.lastError().text();
}
void TraceDB::updateComments(const std::vector<CommentModel::Comment>& comments)
{
QSqlQuery query(database);
query.prepare("DELETE FROM Comments");
executeQuery(query);
query.prepare("insert into Comments values(:time,:text)");
for (const auto& comment : comments)
{
query.bindValue(":time", comment.time);
query.bindValue(":text", comment.text);
executeQuery(query);
}
}
void TraceDB::updateFileDescription(const QString& description)
{
QSqlQuery query(database);
query.prepare("UPDATE GeneralInfo SET Description=:description");
query.bindValue(":description", description);
executeQuery(query);
}
void TraceDB::refreshData()
{
prepareQueries();
generalInfo = getGeneralInfoFromDB();
}
// QueryText must select the fields
// TransactionID, Ranges.begin, Ranges.end, Address, TThread, TChannel, TBank, TRow, TColumn,
// Phases.ID AS PhaseID, PhaseName, PhaseBegin, PhaseEnd
std::vector<std::shared_ptr<Transaction>>
TraceDB::getTransactionsWithCustomQuery(const QString& queryText)
{
QSqlQuery query(database);
query.prepare(queryText);
executeQuery(query);
return parseTransactionsFromQuery(query);
}
std::vector<std::shared_ptr<Transaction>>
TraceDB::getTransactionsInTimespan(const Timespan& span, bool updateVisiblePhases)
{
selectTransactionsByTimespan.bindValue(":begin", span.Begin());
selectTransactionsByTimespan.bindValue(":end", span.End());
executeQuery(selectTransactionsByTimespan);
return parseTransactionsFromQuery(selectTransactionsByTimespan, updateVisiblePhases);
}
bool TraceDB::checkDependencyTableExists()
{
executeQuery(checkDependenciesExist);
bool exists = checkDependenciesExist.next() && checkDependenciesExist.value(0).toInt() == 1;
checkDependenciesExist.finish();
return exists;
}
#ifdef EXTENSION_ENABLED
void TraceDB::updateDependenciesInTimespan(const Timespan& span)
{
if (checkDependencyTableExists())
{
selectDependenciesByTimespan.bindValue(":begin", span.Begin());
selectDependenciesByTimespan.bindValue(":end", span.End());
executeQuery(selectDependenciesByTimespan);
mUpdateDependenciesFromQuery(selectDependenciesByTimespan);
}
}
#endif
// TODO Remove exception
std::shared_ptr<Transaction> TraceDB::getTransactionByID(ID id)
{
selectTransactionById.bindValue(":id", id);
executeQuery(selectTransactionById);
auto result = parseTransactionsFromQuery(selectTransactionById);
if (!result.empty())
return result[0];
else
throw sqlException(
("Transaction with ID " + QString::number(id) + " not in DB").toStdString(),
this->pathToDB.toStdString());
}
std::shared_ptr<Transaction> TraceDB::getNextActivate(traceTime time)
{
QSqlQuery query(database);
QString queryText =
queryTexts.queryHead +
"WHERE PhaseBegin > :traceTime AND PhaseName = 'ACT' ORDER BY PhaseBegin ASC LIMIT 1";
query.prepare(queryText);
query.bindValue(":traceTime", time);
executeQuery(query);
return parseTransactionFromQuery(query);
}
std::shared_ptr<Transaction> TraceDB::getNextPrecharge(traceTime time)
{
QSqlQuery query(database);
QString queryText = queryTexts.queryHead +
"WHERE PhaseBegin > :traceTime AND PhaseName "
"IN ('PRE','PREPB','PREA','PREAB','PRESB') ORDER BY PhaseBegin ASC LIMIT 1";
query.prepare(queryText);
query.bindValue(":traceTime", time);
executeQuery(query);
return parseTransactionFromQuery(query);
}
// shared_ptr<Transaction> TraceDB::getNextActb(ID currentTransactionId)
// {
// QSqlQuery query(database);
// QString queryText = queryTexts.queryHead +
// "WHERE TransactionID > :currentID AND PhaseName = 'ACTB' LIMIT 1";
//
// query.prepare(queryText);
// query.bindValue(":currentID", currentTransactionId);
// executeQuery(query);
// return parseTransactionFromQuery(query);
// }
// shared_ptr<Transaction> TraceDB::getNextPreb(ID currentTransactionId)
// {
// QSqlQuery query(database);
// QString queryText = queryTexts.queryHead +
// "WHERE TransactionID > :currentID AND PhaseName = 'PREB' LIMIT 1";
//
// query.prepare(queryText);
// query.bindValue(":currentID", currentTransactionId);
// executeQuery(query);
// return parseTransactionFromQuery(query);
// }
std::shared_ptr<Transaction> TraceDB::getNextRefresh(traceTime time)
{
QSqlQuery query(database);
QString queryText = queryTexts.queryHead +
"WHERE PhaseBegin > :traceTime AND PhaseName "
"IN ('REFAB','REFA','REFB','REFPB','REFP2B','REFSB','SREF','SREFB') ORDER "
"BY PhaseBegin ASC LIMIT 1";
query.prepare(queryText);
query.bindValue(":traceTime", time);
executeQuery(query);
return parseTransactionFromQuery(query);
}
std::shared_ptr<Transaction> TraceDB::getNextCommand(traceTime time)
{
QSqlQuery query(database);
QString queryText =
queryTexts.queryHead + "WHERE PhaseBegin > :traceTime ORDER BY PhaseBegin ASC LIMIT 1";
query.prepare(queryText);
query.bindValue(":traceTime", time);
executeQuery(query);
return parseTransactionFromQuery(query);
}
// shared_ptr<Transaction> TraceDB::getNextRefb(ID currentTransactionId)
// {
// QSqlQuery query(database);
// QString queryText = queryTexts.queryHead +
// "WHERE TransactionID > :currentID AND PhaseName = 'REFB' LIMIT 1";
//
// query.prepare(queryText);
// query.bindValue(":currentID", currentTransactionId);
// executeQuery(query);
// return parseTransactionFromQuery(query);
// }
ID TraceDB::getTransactionIDFromPhaseID(ID phaseID)
{
QSqlQuery query(database);
query.prepare("SELECT Transact FROM Phases WHERE ID=:id");
query.bindValue(":id", phaseID);
executeQuery(query);
if (query.next())
{
return query.value(0).toInt();
}
else
{
throw sqlException("Phase with ID " + std::to_string(phaseID) + " not in db",
this->pathToDB.toStdString());
}
}
GeneralInfo TraceDB::getGeneralInfoFromDB()
{
QVariant parameter;
parameter = getParameterFromTable("NumberOfRanks", "GeneralInfo");
unsigned numberOfRanks = parameter.isValid() ? parameter.toUInt() : 1;
parameter = getParameterFromTable("NumberOfBankgroups", "GeneralInfo");
unsigned numberOfBankGroups = parameter.isValid() ? parameter.toUInt() : numberOfRanks;
parameter = getParameterFromTable("NumberOfBanks", "GeneralInfo");
unsigned numberOfBanks = parameter.isValid() ? parameter.toUInt() : numberOfBankGroups;
parameter = getParameterFromTable("Clk", "GeneralInfo");
uint64_t clkPeriod = parameter.isValid() ? parameter.toULongLong() : 1000;
parameter = getParameterFromTable("UnitOfTime", "GeneralInfo");
QString unitOfTime = parameter.isValid() ? parameter.toString() : "PS";
parameter = getParameterFromTable("Traces", "GeneralInfo");
QString traces = parameter.isValid() ? "Traces: " + parameter.toString() : "Traces: empty";
parameter = getParameterFromTable("Memspec", "GeneralInfo");
QString memspec = parameter.isValid() ? "Memspec: " + parameter.toString() : "Memspec: empty";
parameter = getParameterFromTable("MCconfig", "GeneralInfo");
QString mcconfig =
parameter.isValid() ? "MCconfig: " + parameter.toString() : "MCconfig: empty";
parameter = getParameterFromTable("WindowSize", "GeneralInfo");
uint64_t windowSize = parameter.isValid() ? parameter.toULongLong() : 0;
parameter = getParameterFromTable("RefreshMaxPostponed", "GeneralInfo");
unsigned refreshMaxPostponed = parameter.isValid() ? parameter.toUInt() : 0;
parameter = getParameterFromTable("RefreshMaxPulledin", "GeneralInfo");
unsigned refreshMaxPulledin = parameter.isValid() ? parameter.toUInt() : 0;
parameter = getParameterFromTable("ControllerThread", "GeneralInfo");
unsigned controllerThread = parameter.isValid() ? parameter.toUInt() : UINT_MAX;
parameter = getParameterFromTable("MaxBufferDepth", "GeneralInfo");
unsigned maxBufferDepth = parameter.isValid() ? parameter.toUInt() : 8;
parameter = getParameterFromTable("Per2BankOffset", "GeneralInfo");
unsigned per2BankOffset = parameter.isValid() ? parameter.toUInt() : 1;
parameter = getParameterFromTable("RowColumnCommandBus", "GeneralInfo");
bool rowColumnCommandBus = parameter.isValid() && parameter.toBool();
parameter = getParameterFromTable("PseudoChannelMode", "GeneralInfo");
bool pseudoChannelMode = parameter.isValid() && parameter.toBool();
uint64_t numberOfPhases = getNumberOfPhases();
uint64_t numberOfTransactions = getNumberOfTransactions();
auto traceEnd = static_cast<traceTime>(getTraceLength());
QString description = (traces + "\n");
description += mcconfig + "\n";
description += memspec + "\n";
description += "Number of Transactions: " + QString::number(numberOfTransactions) + "\n";
description += "Clock period: " + QString::number(clkPeriod) + " " + unitOfTime + "\n";
description += "Length of trace: " + prettyFormatTime(traceEnd) + "\n";
description += "Window size: " + QString::number(windowSize) + "\n";
return {numberOfTransactions,
numberOfPhases,
Timespan(0, traceEnd),
numberOfRanks,
numberOfBankGroups,
numberOfBanks,
description,
unitOfTime,
clkPeriod,
windowSize,
refreshMaxPostponed,
refreshMaxPulledin,
controllerThread,
maxBufferDepth,
per2BankOffset,
rowColumnCommandBus,
pseudoChannelMode};
}
CommandLengths TraceDB::getCommandLengthsFromDB()
{
const std::string table = "CommandLengths";
auto getLengthFromDb = [=, &table](const std::string& command) -> QVariant
{
QSqlQuery query(
("SELECT Length FROM " + table + " WHERE Command = \"" + command + "\"").c_str(),
database);
if (query.first())
return query.value(0);
else
return {};
};
auto getCommandLength = [=, &table](const std::string& command) -> double
{
QVariant length = getLengthFromDb(command);
if (length.isValid())
return length.toDouble();
else
{
qDebug() << "CommandLength for" << command.c_str() << "not present in table"
<< table.c_str() << ". Defaulting to 1.";
return 1;
}
};
double NOP = getCommandLength("NOP");
double RD = getCommandLength("RD");
double WR = getCommandLength("WR");
double MWR = getCommandLength("MWR");
double RDA = getCommandLength("RDA");
double WRA = getCommandLength("WRA");
double MWRA = getCommandLength("MWRA");
double ACT = getCommandLength("ACT");
double PREPB = getCommandLength("PREPB");
double REFPB = getCommandLength("REFPB");
double RFMPB = getCommandLength("RFMPB");
double REFP2B = getCommandLength("REFP2B");
double RFMP2B = getCommandLength("RFMP2B");
double PRESB = getCommandLength("PRESB");
double REFSB = getCommandLength("REFSB");
double RFMSB = getCommandLength("RFMSB");
double PREAB = getCommandLength("PREAB");
double REFAB = getCommandLength("REFAB");
double RFMAB = getCommandLength("RFMAB");
double PDEA = getCommandLength("PDEA");
double PDXA = getCommandLength("PDXA");
double PDEP = getCommandLength("PDEP");
double PDXP = getCommandLength("PDXP");
double SREFEN = getCommandLength("SREFEN");
double SREFEX = getCommandLength("SREFEX");
return {NOP, RD, WR, MWR, RDA, WRA, MWRA, ACT, PREPB,
REFPB, RFMPB, REFP2B, RFMP2B, PRESB, REFSB, RFMSB, PREAB, REFAB,
RFMAB, PDEA, PDXA, PDEP, PDXP, SREFEN, SREFEX};
}
QVariant TraceDB::getParameterFromTable(const std::string& parameter, const std::string& table)
{
QSqlQuery query(("SELECT " + parameter + " FROM " + table).c_str(), database);
if (query.first())
return query.value(0);
else
{
qDebug() << "Parameter " << parameter.c_str() << " not present in table " << table.c_str();
return {};
}
}
uint64_t TraceDB::getTraceLength()
{
QSqlQuery query(database);
query.prepare("SELECT MAX(PhaseEnd) FROM Phases");
executeQuery(query);
query.next();
return query.value(0).toULongLong();
}
uint64_t TraceDB::getNumberOfTransactions()
{
QSqlQuery query(database);
query.prepare("SELECT COUNT(ID) FROM Transactions");
executeQuery(query);
query.next();
return query.value(0).toULongLong();
}
uint64_t TraceDB::getNumberOfPhases()
{
QSqlQuery query(database);
query.prepare("SELECT COUNT(ID) FROM Phases");
executeQuery(query);
query.next();
return query.value(0).toULongLong();
}
std::vector<CommentModel::Comment> TraceDB::getComments()
{
QSqlQuery query(database);
query.prepare("SELECT Time,Text From Comments");
executeQuery(query);
return parseCommentsFromQuery(query);
}
std::vector<CommentModel::Comment> TraceDB::getDebugMessagesInTimespan(const Timespan& span)
{
selectDebugMessagesByTimespan.bindValue(":begin", span.Begin());
selectDebugMessagesByTimespan.bindValue(":end", span.End());
executeQuery(selectDebugMessagesByTimespan);
return parseCommentsFromQuery(selectDebugMessagesByTimespan);
}
std::vector<CommentModel::Comment> TraceDB::getDebugMessagesInTimespan(const Timespan& span,
unsigned int limit = 50)
{
selectDebugMessagesByTimespanWithLimit.bindValue(":begin", span.Begin());
selectDebugMessagesByTimespanWithLimit.bindValue(":end", span.End());
selectDebugMessagesByTimespanWithLimit.bindValue(":limit", limit);
executeQuery(selectDebugMessagesByTimespanWithLimit);
return parseCommentsFromQuery(selectDebugMessagesByTimespanWithLimit);
}
#ifdef EXTENSION_ENABLED
DependencyInfos TraceDB::getDependencyInfos(DependencyInfos::Type infoType)
{
DependencyInfos dummy;
if (!checkDependencyTableExists())
{
return dummy;
}
switch (infoType)
{
case DependencyInfos::Type::DependencyType:
{
selectDependencyTypePercentages = QSqlQuery(database);
if (!selectDependencyTypePercentages.prepare(queryTexts.selectDependencyTypePercentages))
qDebug() << database.lastError().text();
executeQuery(selectDependencyTypePercentages);
return parseDependencyInfos(selectDependencyTypePercentages, infoType);
}
case DependencyInfos::Type::TimeDependency:
{
selectTimeDependencyPercentages = QSqlQuery(database);
if (!selectTimeDependencyPercentages.prepare(queryTexts.selectTimeDependencyPercentages))
qDebug() << database.lastError().text();
executeQuery(selectTimeDependencyPercentages);
return parseDependencyInfos(selectTimeDependencyPercentages, infoType);
}
case DependencyInfos::Type::DelayedPhase:
{
selectDelayedPhasePercentages = QSqlQuery(database);
if (!selectDelayedPhasePercentages.prepare(queryTexts.selectDelayedPhasePercentages))
qDebug() << database.lastError().text();
executeQuery(selectDelayedPhasePercentages);
return parseDependencyInfos(selectDelayedPhasePercentages, infoType);
}
case DependencyInfos::Type::DependencyPhase:
{
selectDependencyPhasePercentages = QSqlQuery(database);
if (!selectDependencyPhasePercentages.prepare(queryTexts.selectDependencyPhasePercentages))
qDebug() << database.lastError().text();
executeQuery(selectDependencyPhasePercentages);
return parseDependencyInfos(selectDependencyPhasePercentages, infoType);
}
}
return dummy;
}
#endif
QSqlDatabase TraceDB::getDatabase() const
{
return database;
}
/* Helpers
*
*
*
*/
std::shared_ptr<Transaction> TraceDB::parseTransactionFromQuery(QSqlQuery& query)
{
auto result = parseTransactionsFromQuery(query);
if (!result.empty())
return result[0];
else
return {};
}
std::vector<std::shared_ptr<Transaction>>
TraceDB::parseTransactionsFromQuery(QSqlQuery& query, bool updateVisiblePhases)
{
if (updateVisiblePhases)
{
_visiblePhases.clear();
}
std::vector<std::shared_ptr<Transaction>> result;
bool firstIteration = true;
ID currentID = 0;
int i = -1;
while (query.next())
{
ID id = query.value(0).toInt();
if (currentID != id || firstIteration)
{
++i;
firstIteration = false;
currentID = id;
Timespan span(query.value(1).toLongLong(), query.value(2).toLongLong());
uint64_t address = query.value(3).toULongLong();
unsigned int dataLength = query.value(4).toUInt();
unsigned int thread = query.value(5).toUInt();
unsigned int channel = query.value(6).toUInt();
QString command = query.value(7).toString();
result.push_back(std::make_shared<Transaction>(id,
std::move(command),
address,
dataLength,
thread,
channel,
span,
generalInfo.clkPeriod));
}
unsigned int phaseID = query.value(8).toInt();
QString phaseName = query.value(9).toString();
Timespan span(query.value(10).toLongLong(), query.value(11).toLongLong());
Timespan spanOnDataStrobe(query.value(12).toLongLong(), query.value(13).toLongLong());
unsigned int rank = query.value(14).toUInt();
unsigned int bankGroup = query.value(15).toUInt();
unsigned int bank = query.value(16).toUInt();
unsigned int row = query.value(17).toUInt();
unsigned int column = query.value(18).toUInt();
unsigned int burstLength = query.value(19).toUInt();
auto phase = PhaseFactory::createPhase(phaseID,
phaseName,
span,
spanOnDataStrobe,
rank,
bankGroup,
bank,
row,
column,
burstLength,
result.at(result.size() - 1),
*this);
result.at(result.size() - 1)->addPhase(phase);
if (updateVisiblePhases)
{
_visiblePhases[phaseID] = phase;
}
}
return result;
}
#ifdef EXTENSION_ENABLED
void TraceDB::mUpdateDependenciesFromQuery(QSqlQuery& query)
{
DependencyType type;
while (query.next())
{
ID delayedID = query.value(0).toInt();
ID dependencyID = query.value(4).toInt();
QString dependencyTypeStr = query.value(2).toString();
if (dependencyTypeStr == "bank")
{
type = DependencyType::IntraBank;
}
else if (dependencyTypeStr == "rank")
{
type = DependencyType::IntraRank;
}
else if (dependencyTypeStr == "interRank")
{
type = DependencyType::InterRank;
}
QString timeDependencyStr = query.value(3).toString();
if (_visiblePhases.count(delayedID) > 0)
{
if (_visiblePhases.count(dependencyID) > 0)
{
_visiblePhases[delayedID]->addDependency(std::make_shared<PhaseDependency>(
PhaseDependency(type, timeDependencyStr, _visiblePhases[dependencyID])));
}
else
{
_visiblePhases[delayedID]->addDependency(
std::make_shared<PhaseDependency>(PhaseDependency(type, timeDependencyStr)));
}
}
else
{
// TODO delayed phase not visible?
}
}
}
#endif
std::vector<CommentModel::Comment> TraceDB::parseCommentsFromQuery(QSqlQuery& query)
{
std::vector<CommentModel::Comment> result;
while (query.next())
{
result.push_back(
CommentModel::Comment{query.value(0).toLongLong(), query.value(1).toString()});
}
return result;
}
#ifdef EXTENSION_ENABLED
DependencyInfos TraceDB::parseDependencyInfos(QSqlQuery& query,
const DependencyInfos::Type infoType)
{
DependencyInfos infos(infoType);
while (query.next())
{
infos.addInfo({query.value(0).toString(), query.value(1).toFloat()});
}
query.finish();
return infos;
}
#endif
void TraceDB::executeQuery(QSqlQuery query)
{
// query.exec returns bool indicating if the query was sucessfull
if (query.exec())
{
#ifdef printqueries
cout << queryToString(query).toStdString() << endl;
#endif
}
else
{
query.finish();
throw sqlException(
("Query:\n " + queryToString(query) + "\n failed. Error: \n" + query.lastError().text())
.toStdString(),
this->pathToDB.toStdString());
}
}
QString TraceDB::queryToString(const QSqlQuery& query)
{
QString str = query.lastQuery();
QMapIterator<QString, QVariant> it(query.boundValues());
while (it.hasNext())
{
it.next();
str.replace(it.key(), it.value().toString());
}
return str;
}
void TraceDB::dropAndCreateTables()
{
executeScriptFile("common/static/createTraceDB.sql");
}
void TraceDB::executeScriptFile(const QString& fileName)
{
QSqlQuery query(database);
QFile scriptFile(fileName);
if (scriptFile.open(QIODevice::ReadOnly))
{
// The SQLite driver executes only a single (the first) query in the QSqlQuery
// if the script contains more queries, it needs to be splitted.
QStringList scriptQueries = QTextStream(&scriptFile).readAll().split(';');
for (QString& queryTxt : scriptQueries)
{
if (queryTxt.trimmed().isEmpty())
{
continue;
}
if (!query.exec(queryTxt))
{
throw sqlException("Querry failed:" + query.lastError().text().toStdString(),
this->pathToDB.toStdString());
}
query.finish();
}
}
}

View File

@@ -0,0 +1,174 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
* Iron Prando da Silva
*/
#ifndef TRACEDB_H
#define TRACEDB_H
#include "QueryTexts.h"
#ifdef EXTENSION_ENABLED
#include "businessObjects/phases/dependencyinfos.h"
#endif
#include "businessObjects/commandlengths.h"
#include "businessObjects/commentmodel.h"
#include "businessObjects/generalinfo.h"
#include "businessObjects/phases/phasefactory.h"
#include "businessObjects/transaction.h"
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlTableModel>
#include <QString>
#include <exception>
#include <string>
#include <vector>
/* TraceDB handles the connection to a SQLLite database containing trace data.
* A TraceDB object always holds an open connection to a valid database.
*/
class TraceDB : public QObject
{
Q_OBJECT
public:
TraceDB(const QString& path, bool openExisting);
const QString& getPathToDB() const { return pathToDB; }
void updateComments(const std::vector<CommentModel::Comment>& comments);
void updateFileDescription(const QString& description);
void refreshData();
#ifdef EXTENSION_ENABLED
void updateDependenciesInTimespan(const Timespan& span);
#endif
const GeneralInfo& getGeneralInfo() const { return generalInfo; }
const CommandLengths& getCommandLengths() const { return commandLengths; }
std::vector<std::shared_ptr<Transaction>>
getTransactionsWithCustomQuery(const QString& queryText);
std::vector<std::shared_ptr<Transaction>>
getTransactionsInTimespan(const Timespan& span, bool updateVisiblePhases = false);
std::shared_ptr<Transaction> getNextPrecharge(traceTime time);
std::shared_ptr<Transaction> getNextActivate(traceTime time);
std::shared_ptr<Transaction> getNextRefresh(traceTime time);
std::shared_ptr<Transaction> getNextCommand(traceTime time);
// std::shared_ptr<Transaction> getNextPreb(ID currentTransactionId);
// std::shared_ptr<Transaction> getNextActb(ID currentTransactionId);
// std::shared_ptr<Transaction> getNextRefb(ID currentTransactionId);
std::shared_ptr<Transaction> getTransactionByID(ID id);
ID getTransactionIDFromPhaseID(ID phaseID);
std::vector<CommentModel::Comment> getComments();
std::vector<CommentModel::Comment> getDebugMessagesInTimespan(const Timespan& span);
std::vector<CommentModel::Comment> getDebugMessagesInTimespan(const Timespan& span,
unsigned int limit);
bool checkDependencyTableExists();
#ifdef EXTENSION_ENABLED
DependencyInfos getDependencyInfos(DependencyInfos::Type infoType);
#endif
QSqlDatabase getDatabase() const;
private:
QString pathToDB;
QSqlDatabase database;
GeneralInfo generalInfo;
CommandLengths commandLengths;
QSqlQuery insertPhaseQuery;
QSqlQuery insertTransactionQuery;
QSqlQuery selectTransactionsByTimespan;
QSqlQuery selectTransactionById;
QSqlQuery selectDebugMessagesByTimespan;
QSqlQuery selectDebugMessagesByTimespanWithLimit;
QSqlQuery checkDependenciesExist;
QSqlQuery selectDependenciesByTimespan;
QSqlQuery selectDependencyTypePercentages;
QSqlQuery selectTimeDependencyPercentages;
QSqlQuery selectDelayedPhasePercentages;
QSqlQuery selectDependencyPhasePercentages;
TransactionQueryTexts queryTexts;
void prepareQueries();
void executeQuery(QSqlQuery query);
static QString queryToString(const QSqlQuery& query);
std::shared_ptr<Transaction> parseTransactionFromQuery(QSqlQuery& query);
std::vector<std::shared_ptr<Transaction>>
parseTransactionsFromQuery(QSqlQuery& query, bool updateVisiblePhases = false);
static std::vector<CommentModel::Comment> parseCommentsFromQuery(QSqlQuery& query);
#ifdef EXTENSION_ENABLED
void mUpdateDependenciesFromQuery(QSqlQuery& query);
static DependencyInfos parseDependencyInfos(QSqlQuery& query,
const DependencyInfos::Type infoType);
#endif
void executeScriptFile(const QString& fileName);
void dropAndCreateTables();
uint64_t getTraceLength();
uint64_t getNumberOfTransactions();
uint64_t getNumberOfPhases();
GeneralInfo getGeneralInfoFromDB();
CommandLengths getCommandLengthsFromDB();
QVariant getParameterFromTable(const std::string& parameter, const std::string& table);
std::map<unsigned int, std::shared_ptr<Phase>>
_visiblePhases; // Updated at parseTransactionsFromQuery
// At businessObjects/phasedependenciestracker.h
friend class PhaseDependenciesTracker;
};
class sqlException : public std::exception
{
private:
std::string message;
public:
sqlException(std::string message, std::string filename)
{
this->message = std::string("Error in file ") + filename + std::string(" ") + message;
}
const char* what() const noexcept override { return message.c_str(); }
};
#endif // TRACEDB_H

View File

@@ -0,0 +1,208 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Éder F. Zulian
* Felipe S. Prado
* Derek Christ
*/
#include "evaluationtool.h"
#include "ui_evaluationtool.h"
#include <QApplication>
#include <QDebug>
#include <QFile>
#include <QFileDialog>
#include <QFileInfo>
#include <QPainter>
#include <QTextStream>
#include <QtAlgorithms>
#include <iostream>
#include <stdio.h>
EvaluationTool::EvaluationTool(PythonCaller& pythonCaller, QWidget* parent) :
QWidget(parent),
ui(new Ui::EvaluationTool),
pythonCaller(pythonCaller)
{
ui->setupUi(this);
traceFilesModel = new QStandardItemModel(this);
ui->listView->setModel(traceFilesModel);
selectMetrics = new SelectMetrics(this);
QObject::connect(selectMetrics, SIGNAL(getSelectedMetrics()), this, SLOT(getSelectedMetrics()));
}
EvaluationTool::~EvaluationTool()
{
delete ui;
}
void EvaluationTool::showForFiles(QList<QString> paths)
{
cleanUpUI();
fillFileList(paths);
show();
ui->toolBox->setCurrentIndex(0);
}
void EvaluationTool::showAndEvaluateMetrics(QList<QString> paths)
{
cleanUpUI();
fillFileList(paths);
show();
ui->toolBox->setCurrentIndex(1);
selectMetrics->setMetrics(getMetrics());
}
std::vector<std::string> EvaluationTool::getMetrics()
{
std::vector<std::string> metrics;
for (int row = 0; row < traceFilesModel->rowCount(); ++row)
{
TraceFileItem* item = static_cast<TraceFileItem*>(traceFilesModel->item(row));
std::vector<std::string> result =
PythonCaller::availableMetrics(item->getPath().toStdString());
if (result.size() > metrics.size()) // TODO use std::set
metrics = result;
}
return metrics;
}
void EvaluationTool::cleanUpUI()
{
traceFilesModel->clear();
calculatedMetrics.clear();
ui->traceMetricTreeWidget->clear();
}
void EvaluationTool::fillFileList(QList<QString> paths)
{
std::sort(paths.begin(),
paths.end(),
[](const QString& path1, const QString& path2)
{ return QFileInfo(path1).baseName() < QFileInfo(path2).baseName(); });
for (const QString& path : paths)
{
traceFilesModel->appendRow(new TraceFileItem(path));
}
}
void EvaluationTool::on_btn_calculateMetrics_clicked()
{
selectMetrics->raise();
selectMetrics->activateWindow();
selectMetrics->show();
}
void EvaluationTool::getSelectedMetrics()
{
std::vector<long> selectedMetrics;
for (QCheckBox* metric : selectMetrics->metrics)
{
selectedMetrics.push_back(metric->isChecked());
}
calculateMetrics(selectedMetrics);
}
void EvaluationTool::calculateMetrics(std::vector<long> selectedMetrics)
{
ui->traceMetricTreeWidget->clear();
for (int row = 0; row < traceFilesModel->rowCount(); ++row)
{
TraceFileItem* item = static_cast<TraceFileItem*>(traceFilesModel->item(row));
if (item->checkState() == Qt::Checked)
{
TraceCalculatedMetrics result =
pythonCaller.evaluateMetrics(item->getPath().toStdString(), selectedMetrics);
calculatedMetrics.push_back(result);
ui->traceMetricTreeWidget->addTraceMetricResults(result);
}
}
ui->traceMetricTreeWidget->expandAll();
}
EvaluationTool::TraceFileItem::TraceFileItem(const QString& path)
{
this->path = path;
setText(QFileInfo(this->path).baseName());
setCheckable(true);
setCheckState(Qt::Checked);
setEditable(false);
}
void EvaluationTool::on_btn_exportCSV_clicked()
{
if (calculatedMetrics.size() > 0)
{
QString filename = QFileDialog::getSaveFileName(
this, "Export to CSV", "", "Comma separated Values(*.csv)");
if (filename != "")
{
QFile file(filename);
file.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream out(&file);
out << calculatedMetrics[0].toCSVHeader() << "\n";
for (TraceCalculatedMetrics& metrics : calculatedMetrics)
{
out << metrics.toCSVLine() << "\n";
}
file.close();
}
}
}
void EvaluationTool::on_btn_genPlots_clicked()
{
genPlots();
}
void EvaluationTool::genPlots()
{
ui->traceMetricTreeWidget->clear();
if (traceFilesModel->rowCount() == 0)
return;
for (int row = 0; row < traceFilesModel->rowCount(); ++row)
{
TraceFileItem* item = static_cast<TraceFileItem*>(traceFilesModel->item(row));
if (item->checkState() == Qt::Checked)
{
ui->traceMetricTreeWidget->addTracePlotResults(
QFileInfo(item->getPath()).baseName(),
PythonCaller::generatePlots(item->getPath().toStdString()).c_str());
}
}
ui->traceMetricTreeWidget->expandAll();
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Éder F. Zulian
* Felipe S. Prado
* Derek Christ
*/
#ifndef EVALUATIONTOOL_H
#define EVALUATIONTOOL_H
#include "selectmetrics.h"
#include "businessObjects/pythoncaller.h"
#include "businessObjects/tracecalculatedmetrics.h"
#include <QList>
#include <QStandardItem>
#include <QStandardItemModel>
#include <QString>
#include <QWidget>
#include <vector>
namespace Ui
{
class EvaluationTool;
}
class EvaluationTool : public QWidget
{
Q_OBJECT
public:
explicit EvaluationTool(PythonCaller& pythonCaller, QWidget* parent = nullptr);
~EvaluationTool();
void showForFiles(QList<QString> paths);
void showAndEvaluateMetrics(QList<QString> paths);
private Q_SLOTS:
void on_btn_calculateMetrics_clicked();
void on_btn_exportCSV_clicked();
void on_btn_genPlots_clicked();
void getSelectedMetrics();
private:
void fillFileList(QList<QString> paths);
void cleanUpUI();
void genPlots();
void calculateMetrics(std::vector<long> selectedMetrics);
std::vector<std::string> getMetrics();
Ui::EvaluationTool* ui;
QStandardItemModel* traceFilesModel;
std::vector<TraceCalculatedMetrics> calculatedMetrics;
SelectMetrics* selectMetrics;
PythonCaller& pythonCaller;
class TraceFileItem : public QStandardItem
{
public:
TraceFileItem(const QString& path);
QString getPath() { return path; }
private:
QString path;
};
};
#endif // EVALUATIONTOOL_H

View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>EvaluationTool</class>
<widget class="QWidget" name="EvaluationTool">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>869</width>
<height>514</height>
</rect>
</property>
<property name="windowTitle">
<string>Evaluate Traces</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QListView" name="listView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolBox" name="toolBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>5</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="page_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>707</width>
<height>464</height>
</rect>
</property>
<attribute name="label">
<string>Calculate Metrics</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btn_calculateMetrics">
<property name="text">
<string>Calculate metrics</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_genPlots">
<property name="text">
<string>Generate plots</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_exportCSV">
<property name="text">
<string>Export to CSV</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="TraceMetricTreeWidget" name="traceMetricTreeWidget">
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>TraceMetricTreeWidget</class>
<extends>QTreeWidget</extends>
<header>presentation/tracemetrictreewidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) 2024, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Derek Christ
*/
#ifndef EXTENSION_H
#define EXTENSION_H
#include <QLabel>
#include <QMessageBox>
inline constexpr std::string_view EXTENSION_DISCLAIMER =
"This feature is part of the full version of Trace Analyzer. For more information, please "
"contact <a href=\"mailto:DRAMSys@iese.fraunhofer.de\">DRAMSys@iese.fraunhofer.de</a>.";
inline void showExtensionDisclaimerMessageBox()
{
QMessageBox box;
box.setText("Feature unavailable");
box.setInformativeText(EXTENSION_DISCLAIMER.data());
box.setIcon(QMessageBox::Information);
box.exec();
}
inline QLabel* disclaimerLabel()
{
auto* label = new QLabel;
label->setText(EXTENSION_DISCLAIMER.data());
label->setAlignment(Qt::AlignHCenter);
label->setWordWrap(true);
return label;
}
#endif // EXTENSION_H

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#include "gototimedialog.h"
#include "ui_gototimedialog.h"
#include <QMessageBox>
GoToTimeDialog::GoToTimeDialog(double* goToSecond, QWidget* parent) :
QDialog(parent),
goToSecond(goToSecond),
ui(new Ui::GoToTimeDialog)
{
ui->setupUi(this);
}
GoToTimeDialog::~GoToTimeDialog()
{
delete ui;
}
void GoToTimeDialog::on_pushButton_clicked()
{
QLocale c(QLocale::C);
bool validNumber;
*goToSecond = c.toDouble(ui->timeEdit->text(), &validNumber);
if (validNumber)
accept();
else
{
QMessageBox::warning(this, "Invalid number", "Please enter a valid floating point number");
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef GOTOTIMEDIALOG_H
#define GOTOTIMEDIALOG_H
#include <QDialog>
namespace Ui
{
class GoToTimeDialog;
}
class GoToTimeDialog : public QDialog
{
Q_OBJECT
public:
explicit GoToTimeDialog(double* goToSecond, QWidget* parent = 0);
~GoToTimeDialog();
private:
double* goToSecond;
private Q_SLOTS:
void on_pushButton_clicked();
private:
Ui::GoToTimeDialog* ui;
};
#endif // GOTOTIMEDIALOG_H

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GoToTimeDialog</class>
<widget class="QDialog" name="GoToTimeDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>395</width>
<height>45</height>
</rect>
</property>
<property name="windowTitle">
<string>Go to time</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="timeEdit"/>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>ns</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Ok</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

126
src/traceAnalyzer/icon.svg Normal file
View File

@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="132"
height="132"
id="svg2"
inkscape:version="0.92.1 r15371"
sodipodi:docname="icon.svg"
viewBox="0 0 132 132">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1137"
id="namedview37"
showgrid="false"
inkscape:zoom="2.600739"
inkscape:cx="66.000744"
inkscape:cy="106.85864"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg2"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showguides="true"
inkscape:guide-bbox="true"
inkscape:document-units="px"
inkscape:document-rotation="0" />
<defs
id="defs4" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(-39.832809,-234.78106)"
id="g4392">
<rect
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="rect4395"
y="234.78108"
x="39.832809"
height="40"
width="40" />
<rect
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="rect4397"
y="234.78108"
x="85.832809"
height="40"
width="40" />
<rect
style="fill:#2d5016;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="rect4399"
y="234.78108"
x="131.83281"
height="40"
width="40" />
<rect
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="rect4401"
y="280.78107"
x="39.832809"
height="40"
width="40" />
<rect
style="fill:#2d5016;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="rect4403"
y="280.78107"
x="85.832809"
height="40"
width="40" />
<rect
style="fill:#338000;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="rect4405"
y="280.78107"
x="131.83281"
height="40"
width="40" />
<rect
style="fill:#2d5016;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="rect4407"
y="326.78107"
x="39.832809"
height="40"
width="40" />
<rect
style="fill:#338000;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="rect4409"
y="326.78107"
x="85.832809"
height="40"
width="40" />
<rect
style="fill:#71c837;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="rect4411"
y="326.78107"
x="131.83281"
height="40"
width="40" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

101
src/traceAnalyzer/main.cpp Normal file
View File

@@ -0,0 +1,101 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
*/
#include "traceanalyzer.h"
#include <QApplication>
#include <QFileDialog>
#include <QFileInfo>
#include <QSet>
#include <QString>
#include <filesystem>
#include <iostream>
#include <pybind11/embed.h>
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
QIcon icon(QStringLiteral(":/icon"));
QApplication::setWindowIcon(icon);
QApplication::setApplicationName(QStringLiteral("TraceAnalyzer"));
QApplication::setApplicationDisplayName(QStringLiteral("Trace Analyzer"));
std::filesystem::path extensionDir = DRAMSYS_TRACE_ANALYZER_EXTENSION_DIR;
std::filesystem::path modulesDir = extensionDir / "scripts";
pybind11::scoped_interpreter guard;
// Add scripts directory to local module search path
pybind11::module_ sys = pybind11::module_::import("sys");
pybind11::list path = sys.attr("path");
path.append(modulesDir.c_str());
if (argc > 1)
{
QSet<QString> arguments;
for (int i = 1; i < argc; ++i)
arguments.insert(QString(argv[i]));
QString openFolderFlag("-f");
if (arguments.contains(openFolderFlag))
{
arguments.remove(openFolderFlag);
QStringList nameFilter("*.tdb");
QSet<QString> paths = arguments;
arguments.clear();
for (QString path : paths)
{
QDir directory(path);
QStringList files = directory.entryList(nameFilter);
for (QString& file : files)
{
arguments.insert(path.append("/") + file);
}
}
}
TraceAnalyzer analyzer(arguments);
analyzer.show();
return QApplication::exec();
}
TraceAnalyzer analyzer;
analyzer.show();
return QApplication::exec();
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
*/
#ifndef MARKERPLOTITEM_H
#define MARKERPLOTITEM_H
#include "businessObjects/tracetime.h"
#include <QColor>
#include <qwt_plot_item.h>
class MarkerPlotItem : public QwtPlotItem
{
private:
traceTime time;
int width;
QColor color;
public:
MarkerPlotItem(traceTime time, int width = 4, QColor color = QColor(Qt::black)) :
time(time),
width(width),
color(color)
{
}
virtual int rtti() const;
virtual void draw(QPainter* painter,
const QwtScaleMap& xMap,
const QwtScaleMap& yMap,
const QRectF& canvasRect) const;
};
#endif // MARKERPLOTITEM_H

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Preferences</class>
<widget class="QWidget" name="Preferences">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Preferences</string>
</property>
<widget class="QGroupBox" name="verticalGroupBox">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>291</width>
<height>101</height>
</rect>
</property>
<property name="title">
<string>Color-Grouping:</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<item>
<widget class="QRadioButton" name="rb_grouping_phase">
<property name="text">
<string>Phase-Type</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rb_grouping_transaction">
<property name="text">
<string>Transaction</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rb_grouping_thread">
<property name="text">
<string>Thread</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,128 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#include "debugmessagetreewidget.h"
#include <QGuiApplication>
#include <qtooltip.h>
using namespace std;
void DebugMessageTreeWidget::init(TraceNavigator* navigator, TracePlot* traceplot)
{
Q_ASSERT(isInitialized == false);
isInitialized = true;
arrangeUiSettings();
connect(navigator, SIGNAL(currentTraceTimeChanged()), this, SLOT(currentTraceTimeChanged()));
connect(
navigator, SIGNAL(selectedTransactionsChanged()), this, SLOT(selectedTransactionChanged()));
this->traceplot = traceplot;
this->navigator = navigator;
currentTraceTimeChanged();
}
void DebugMessageTreeWidget::arrangeUiSettings()
{
QFont font = QGuiApplication::font();
font.setPointSize(10);
this->setFont(font);
setColumnCount(2);
setHeaderLabels(QStringList({"Time", "Message"}));
}
void DebugMessageTreeWidget::selectedTransactionChanged()
{
if (navigator->hasSelectedTransactions())
{
Timespan span = navigator->getSpanCoveredBySelectedTransaction();
showDebugMessages(navigator->TraceFile().getDebugMessagesInTimespan(span));
}
else
{
showDebugMessages(
navigator->TraceFile().getDebugMessagesInTimespan(traceplot->GetCurrentTimespan()));
}
}
void DebugMessageTreeWidget::currentTraceTimeChanged()
{
if (!navigator->hasSelectedTransactions())
showDebugMessages(
navigator->TraceFile().getDebugMessagesInTimespan(traceplot->GetCurrentTimespan()));
}
void DebugMessageTreeWidget::showDebugMessages(const vector<CommentModel::Comment>& comments)
{
clear();
if (comments.empty())
return;
traceTime currentTime = -1;
for (const auto& comment : comments)
{
if (currentTime != comment.time)
{
addTopLevelItem(new QTreeWidgetItem(
{prettyFormatTime(comment.time), formatDebugMessage(comment.text)}));
currentTime = comment.time;
}
else
{
addTopLevelItem(new QTreeWidgetItem({"", formatDebugMessage(comment.text)}));
}
}
this->resizeColumnToContents(0);
this->scrollToTop();
}
QString DebugMessageTreeWidget::formatDebugMessage(const QString& message)
{
QString formattedMessage = message;
formattedMessage.replace(hexAdressMatcher, "");
formattedMessage.replace(timeAnnotationMatcher, "");
formattedMessage.replace("\t", " ");
return formattedMessage;
}
void DebugMessageTreeWidget::mousePressEvent(QMouseEvent* event)
{
QTreeWidgetItem* itemUnderCursor = itemAt(event->pos());
if (itemUnderCursor != NULL)
{
QToolTip::showText(this->mapToGlobal(event->pos()), itemUnderCursor->text(1));
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef DEBUGMESSAGELISTWIDGET_H
#define DEBUGMESSAGELISTWIDGET_H
#include "businessObjects/commentmodel.h"
#include "tracenavigator.h"
#include "traceplot.h"
#include <QMouseEvent>
#include <QRegularExpression>
#include <QString>
#include <QTreeWidget>
#include <vector>
class DebugMessageTreeWidget : public QTreeWidget
{
Q_OBJECT
public:
DebugMessageTreeWidget(QWidget* parent = 0) :
QTreeWidget(parent),
isInitialized(false),
timeAnnotationMatcher(QString("@[0-9]+ n?s")),
hexAdressMatcher(QString("0x[0-9,a-f]+"))
{
}
void init(TraceNavigator* navigator, TracePlot* traceplot);
void showDebugMessages(const std::vector<CommentModel::Comment>& comments);
void arrangeUiSettings();
public Q_SLOTS:
void currentTraceTimeChanged();
void selectedTransactionChanged();
private:
bool isInitialized;
TracePlot* traceplot;
TraceNavigator* navigator;
QRegularExpression timeAnnotationMatcher;
QRegularExpression hexAdressMatcher;
QString formatDebugMessage(const QString& message);
void mousePressEvent(QMouseEvent* event);
};
#endif // DEBUGMESSAGELISTWIDGET_H

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#include "selectedtransactiontreewidget.h"
void SelectedTransactionTreeWidget::selectedTransactionsChanged()
{
this->clear();
for (const auto& transaction : navigator->SelectedTransactions())
{
AppendTransaction(transaction);
}
expandAll();
for (int k = 0; k < topLevelItemCount(); k++)
{
auto node = topLevelItem(k);
for (int i = 0; i < node->childCount(); i++)
{
if (node->child(i)->text(0) == "Phases")
{
auto phaseNode = node->child(i);
for (int j = 0; j < phaseNode->childCount(); j++)
phaseNode->child(j)->setExpanded(false);
}
}
}
resizeColumnToContents(0);
}
void SelectedTransactionTreeWidget::init(TraceNavigator* navigator)
{
TransactionTreeWidget::init(navigator);
QObject::connect(navigator,
SIGNAL(selectedTransactionsChanged()),
this,
SLOT(selectedTransactionsChanged()));
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef SELECTEDTRANSACTIONTREEWIDGET_H
#define SELECTEDTRANSACTIONTREEWIDGET_H
#include "transactiontreewidget.h"
class SelectedTransactionTreeWidget : public TransactionTreeWidget
{
Q_OBJECT
bool isInitialized;
public:
SelectedTransactionTreeWidget(QWidget* parent = 0) :
TransactionTreeWidget(parent),
isInitialized(false)
{
}
virtual void init(TraceNavigator* navigator);
public Q_SLOTS:
void selectedTransactionsChanged();
};
#endif // SELECTEDTRANSACTIONTREEWIDGET_H

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#include "tracePlotMouseLabel.h"
#include "businessObjects/tracetime.h"
#include <qwt_text.h>
void TracePlotMouseLabel::setMode(MouseLabelMode mode)
{
this->mode = mode;
}
QwtText TracePlotMouseLabel::trackerText(const QPoint& point) const
{
if (mode == MouseLabelMode::AbsoluteTime)
{
traceTime mouseTime =
static_cast<traceTime>(traceplot->invTransform(traceplot->xBottom, point.x()));
return QwtText(prettyFormatTime(alignToClk(mouseTime, clkPeriod)) + "(" +
formatInClks(mouseTime, clkPeriod) + ")");
}
else if (mode == MouseLabelMode::Timedifference)
{
traceTime mouseTime = timeDifferenceSpan.timeCovered();
return QwtText(prettyFormatTime(alignToClk(mouseTime, clkPeriod)) + "(" +
formatInClks(mouseTime, clkPeriod) + ")");
}
else
{
Q_ASSERT(false);
}
return QwtText(QString(""));
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef TRACEPLOTPICKER_H
#define TRACEPLOTPICKER_H
#include "traceplot.h"
#include <qwt_plot_picker.h>
enum class MouseLabelMode
{
AbsoluteTime,
Timedifference
};
class TracePlotMouseLabel : public QwtPlotPicker
{
public:
TracePlotMouseLabel(TracePlot* traceplot,
unsigned int clkPeriod,
Timespan& timeDifferenceSpan) :
QwtPlotPicker(QwtPlot::xBottom,
QwtPlot::yLeft,
QwtPlotPicker::VLineRubberBand,
QwtPicker::AlwaysOn,
traceplot->canvas()),
mode(MouseLabelMode::AbsoluteTime),
traceplot(traceplot),
clkPeriod(clkPeriod),
timeDifferenceSpan(timeDifferenceSpan)
{
}
void setMode(MouseLabelMode mode);
protected:
virtual QwtText trackerText(const QPoint& point) const;
private:
MouseLabelMode mode;
TracePlot* traceplot;
unsigned int clkPeriod;
Timespan& timeDifferenceSpan;
};
#endif // TRACEPLOTPICKER_H

View File

@@ -0,0 +1,168 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#include "tracedrawing.h"
void drawVerticalLine(QPainter* painter, int xPos, const QRectF& canvasRect)
{
/* P1 (xPos,lowerCanvasYBorder)
* |
* |
* |
* |
* P2 (xPos,upperCanvasYBorder)
*/
QPoint P1(xPos, static_cast<int>(canvasRect.top()));
QPoint P2(xPos, static_cast<int>(canvasRect.bottom()));
painter->drawLine(QLine(P1, P2));
}
void drawDoubleArrow(QPainter* painter, int xFrom, int xTo, int y)
{
/* P1 P3
// / \
// / {text} \
// from (-------------------------------------------) to
// \ /
// \ /
// P2 P4
*/
QPoint from(xFrom, y);
QPoint to(xTo, y);
QPoint P1(xFrom + 10, y - 5);
QPoint P2(xFrom + 10, y + 5);
QPoint P3(xTo - 10, y - 5);
QPoint P4(xTo - 10, y + 5);
painter->drawLine(from, to);
painter->drawLine(P1, from);
painter->drawLine(P2, from);
painter->drawLine(P3, to);
painter->drawLine(P4, to);
}
void drawDoubleArrow(
QPainter* painter, int xFrom, int xTo, int y, const QString& text, const QColor& textColor)
{
drawDoubleArrow(painter, xFrom, xTo, y);
drawText(painter, text, QPoint((xTo + xFrom) / 2, y), TextPositioning::topCenter, textColor);
}
void drawHexagon(QPainter* painter, const QPoint& from, const QPoint& to, double height)
{
// {text}
// P1------------------------P2
// From / \ To
// \ /
// P4-------------------------P3
int offset = 10;
if ((to.x() - from.x()) <= 20)
{
offset = 5;
}
if ((to.x() - from.x()) <= 10)
{
offset = 2;
}
if ((to.x() - from.x()) <= 4)
{
offset = 0;
}
QPointF P1(from.x() + offset, from.y() - height / 2);
QPointF P2(to.x() - offset, to.y() - height / 2);
QPointF P3(to.x() - offset, to.y() + height / 2);
QPointF P4(from.x() + offset, from.y() + height / 2);
QPolygonF polygon;
polygon << from << P1 << P2 << to << P3 << P4;
painter->drawPolygon(polygon);
}
void drawText(QPainter* painter,
const QString& text,
const QPoint& position,
const TextPositioning& positioning,
const QColor& textColor)
{
//*--------------*
//| | |
//|------x-------|
//| | |
//*--------------*
QPen saved = painter->pen();
painter->setPen(QPen(textColor));
QFontMetrics fm = painter->fontMetrics();
QPoint offset(fm.horizontalAdvance(text), fm.height());
QRect rect(position - offset, position + offset);
int flags;
switch (positioning)
{
case TextPositioning::topRight:
flags = Qt::AlignRight | Qt::AlignTop;
break;
case TextPositioning::bottomRight:
flags = Qt::AlignRight | Qt::AlignBottom;
break;
case TextPositioning::bottomLeft:
flags = Qt::AlignLeft | Qt::AlignBottom;
break;
case TextPositioning::topCenter:
flags = Qt::AlignHCenter | Qt::AlignTop;
break;
case TextPositioning::bottomCenter:
flags = Qt::AlignHCenter | Qt::AlignBottom;
break;
case TextPositioning::centerCenter:
flags = Qt::AlignHCenter | Qt::AlignCenter;
break;
case TextPositioning::topLeft:
default:
flags = Qt::AlignLeft | Qt::AlignTop;
break;
}
painter->drawText(rect, flags, text);
painter->setPen(saved);
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef TRACEDRAWING_H
#define TRACEDRAWING_H
#include <QColor>
#include <QPainter>
#include <QRectF>
#include <QString>
enum class TextPositioning
{
topRight,
topLeft,
bottomRight,
bottomLeft,
topCenter,
bottomCenter,
centerCenter
};
void drawVerticalLine(QPainter* painter, int xPos, const QRectF& canvasRect);
void drawDoubleArrow(QPainter* painter, int xFrom, int xTo, int y);
void drawDoubleArrow(QPainter* painter,
int xFrom,
int xTo,
int y,
const QString& text,
const QColor& textColor = QColor(Qt::black));
void drawHexagon(QPainter* painter, const QPoint& from, const QPoint& to, double height);
void drawText(QPainter* painter,
const QString& text,
const QPoint& position,
const TextPositioning& positioning,
const QColor& textColor = QColor(Qt::black));
#endif // TRACEDRAWING_H

View File

@@ -0,0 +1,90 @@
/*
* Copyright (c) 2021, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Author:
* Derek Christ
* Iron Prando da Silva
*/
#include "tracedrawingproperties.h"
#include "../businessObjects/traceplotlinemodel.h"
#include "util/customlabelscaledraw.h"
TraceDrawingProperties::TraceDrawingProperties(bool drawText,
bool drawBorder,
DependencyOptions drawDependenciesOption,
ColorGrouping colorGrouping) :
drawText(drawText),
drawBorder(drawBorder),
drawDependenciesOption(drawDependenciesOption),
colorGrouping(colorGrouping)
{
}
void TraceDrawingProperties::init(TracePlotLineDataSource* tracePlotLineDataSource)
{
this->tracePlotLineDataSource = tracePlotLineDataSource;
updateLabels();
}
void TraceDrawingProperties::updateLabels()
{
// Clear hash table, because otherwise not all old values will be overwritten.
labels->clear();
// The lowest line starts at the y value of 0.
int yVal = 0;
for (auto it = tracePlotLineDataSource->getTracePlotLines().rbegin();
it != tracePlotLineDataSource->getTracePlotLines().rend();
++it)
{
auto line = *it;
labels->operator[](yVal) = line->data.label;
line->data.yVal = yVal;
yVal++;
}
emit labelsUpdated();
}
std::shared_ptr<QHash<int, QString>> TraceDrawingProperties::getLabels() const
{
return labels;
}
unsigned int TraceDrawingProperties::getNumberOfDisplayedLines() const
{
return tracePlotLineDataSource->getTracePlotLines().size();
}

View File

@@ -0,0 +1,127 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
* Iron Prando da Silva
*/
#ifndef TRACECOLLECTIONDRAWINGPROPERTIES_H
#define TRACECOLLECTIONDRAWINGPROPERTIES_H
#include "businessObjects/traceplotlinemodel.h"
#include "tracedrawing.h"
#include <QAbstractProxyModel>
#include <QColor>
#include <QHash>
#include <QString>
#include <map>
enum class ColorGrouping
{
PhaseType,
Transaction,
Thread,
RainbowTransaction
};
class TracePlotLineDataSource;
enum class DependencyOption
{
Disabled,
Selected,
All
};
enum class DependencyTextOption
{
Enabled,
Disabled
};
struct DependencyOptions
{
DependencyOption draw;
DependencyTextOption text;
};
class TraceDrawingProperties : public QObject
{
Q_OBJECT
public:
bool drawText;
bool drawBorder;
DependencyOptions drawDependenciesOption;
ColorGrouping colorGrouping;
QColor textColor;
unsigned int numberOfRanks = 1;
unsigned int numberOfBankGroups = 1;
unsigned int numberOfBanks = 1;
unsigned int banksPerRank = 1;
unsigned int groupsPerRank = 1;
unsigned int banksPerGroup = 1;
unsigned int per2BankOffset = 0;
TraceDrawingProperties(bool drawText = true,
bool drawBorder = true,
DependencyOptions drawDependenciesOption =
{DependencyOption::Disabled, DependencyTextOption::Enabled},
ColorGrouping colorGrouping = ColorGrouping::PhaseType);
void init(TracePlotLineDataSource* tracePlotLineDataSource);
void updateLabels();
unsigned int getNumberOfDisplayedLines() const;
const std::vector<std::shared_ptr<TracePlotLineDataSource::TracePlotLine>>&
getTracePlotLines() const
{
return tracePlotLineDataSource->getTracePlotLines();
}
std::shared_ptr<QHash<int, QString>> getLabels() const;
Q_SIGNALS:
void labelsUpdated();
private:
std::shared_ptr<QHash<int, QString>> labels = std::make_shared<QHash<int, QString>>();
TracePlotLineDataSource* tracePlotLineDataSource;
};
#endif // TRACECOLLECTIONDRAWINGPROPERTIES_H

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Felipe S. Prado
*/
#include "tracemetrictreewidget.h"
TraceMetricTreeWidget::TraceMetricTreeWidget(QWidget* parent) : QTreeWidget(parent)
{
setHeaderHidden(true);
}
void TraceMetricTreeWidget::addTraceMetricResults(const TraceCalculatedMetrics& result)
{
QTreeWidgetItem* top = new QTreeWidgetItem({result.getTraceName()});
addTopLevelItem(top);
if (result.getCalculatedMetrics().empty())
{
new QTreeWidgetItem(top, {QString("Number of threads: 1")});
}
else
{
for (CalculatedMetric calculatedMetric : result.getCalculatedMetrics())
{
new QTreeWidgetItem(top,
{calculatedMetric.name.c_str() + QString(": ") +
QString::number(calculatedMetric.value, 'f')});
}
}
}
void TraceMetricTreeWidget::addTracePlotResults(QString traceName, QString outputFiles)
{
QTreeWidgetItem* top = new QTreeWidgetItem({traceName});
addTopLevelItem(top);
new QTreeWidgetItem(top, {outputFiles});
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Felipe S. Prado
*/
#ifndef TRACEMETRICTREEWIDGET_H
#define TRACEMETRICTREEWIDGET_H
#include "businessObjects/tracecalculatedmetrics.h"
#include <QTreeWidget>
class TraceMetricTreeWidget : public QTreeWidget
{
Q_OBJECT
public:
explicit TraceMetricTreeWidget(QWidget* parent = nullptr);
void addTraceMetricResults(const TraceCalculatedMetrics& result);
void addTracePlotResults(QString traceName, QString outputFiles);
};
#endif // TRACEMETRICTREEWIDGET_H

View File

@@ -0,0 +1,321 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
* Iron Prando da Silva
*/
#include "tracenavigator.h"
#include "businessObjects/commentmodel.h"
#include "vector"
#include <QInputDialog>
#include <QLineEdit>
using namespace std;
TraceNavigator::TraceNavigator(QString path, CommentModel* commentModel, QObject* parent) :
QObject(parent),
traceFile(path, true),
commentModel(commentModel),
changesToCommitExist(false)
{
getCommentsFromDB();
QObject::connect(commentModel,
&CommentModel::gotoCommentTriggered,
this,
[=](const QModelIndex& index)
{ navigateToTime(commentModel->getTimeFromIndex(index)); });
QObject::connect(
commentModel, &CommentModel::dataChanged, this, &TraceNavigator::traceFileModified);
QObject::connect(
commentModel, &CommentModel::rowsRemoved, this, &TraceNavigator::traceFileModified);
Transaction::setNumTransactions(GeneralTraceInfo().numberOfTransactions);
}
/* Navigation
*
*
*/
void TraceNavigator::navigateToTime(traceTime time)
{
if (time < 0)
time = 0;
else if (time > traceFile.getGeneralInfo().span.End())
time = traceFile.getGeneralInfo().span.End();
else
{
currentTraceTime = time;
Q_EMIT currentTraceTimeChanged();
}
}
void TraceNavigator::navigateToTransaction(ID id)
{
navigateToTime(traceFile.getTransactionByID(id)->span.Begin());
}
/* DB
*
*/
void TraceNavigator::commitChangesToDB()
{
traceFile.updateComments(commentModel->getComments());
changesToCommitExist = false;
}
void TraceNavigator::getCommentsFromDB()
{
for (const auto& comment : traceFile.getComments())
commentModel->addComment(comment.time, comment.text);
}
void TraceNavigator::refreshData()
{
traceFile.refreshData();
clearSelectedTransactions();
navigateToTime(currentTraceTime);
}
/* Transaction Selection
*
*
*/
void TraceNavigator::addSelectedTransactions(const vector<shared_ptr<Transaction>>& transactions)
{
for (const auto &transaction : transactions)
{
selectedTransactions.push_back(transaction);
}
Q_EMIT selectedTransactionsChanged();
}
void TraceNavigator::addSelectedTransaction(const shared_ptr<Transaction>& transaction)
{
selectedTransactions.push_back(transaction);
Q_EMIT selectedTransactionsChanged();
}
void TraceNavigator::addSelectedTransaction(ID id)
{
shared_ptr<Transaction> transaction = TraceFile().getTransactionByID(id);
selectedTransactions.push_back(transaction);
Q_EMIT selectedTransactionsChanged();
}
void TraceNavigator::selectTransaction(ID id)
{
clearSelectedTransactions();
addSelectedTransaction(id);
navigateToTransaction(id);
}
void TraceNavigator::selectTransaction(const shared_ptr<Transaction>& transaction)
{
selectTransaction(transaction->id);
}
void TraceNavigator::selectNextTransaction()
{
if (selectedTransactions.empty() ||
selectedTransactions.front()->id == traceFile.getGeneralInfo().numberOfTransactions)
selectFirstTransaction();
else
selectTransaction(selectedTransactions.front()->id + 1);
}
void TraceNavigator::selectPreviousTransaction()
{
if (selectedTransactions.empty() || selectedTransactions.front()->id == 1)
selectLastTransaction();
else
selectTransaction(selectedTransactions.front()->id - 1);
}
void TraceNavigator::selectFirstTransaction()
{
selectTransaction(1);
}
void TraceNavigator::selectLastTransaction()
{
selectTransaction(traceFile.getGeneralInfo().numberOfTransactions);
}
void TraceNavigator::selectNextRefresh(traceTime time)
{
shared_ptr<Transaction> nextRefresh;
nextRefresh = traceFile.getNextRefresh(time);
if (nextRefresh)
selectTransaction(nextRefresh);
}
void TraceNavigator::selectNextActivate(traceTime time)
{
shared_ptr<Transaction> nextActivate;
nextActivate = traceFile.getNextActivate(time);
if (nextActivate)
selectTransaction(nextActivate);
}
void TraceNavigator::selectNextPrecharge(traceTime time)
{
shared_ptr<Transaction> nextPrecharge;
nextPrecharge = traceFile.getNextPrecharge(time);
if (nextPrecharge)
selectTransaction(nextPrecharge);
}
void TraceNavigator::selectNextCommand(traceTime time)
{
shared_ptr<Transaction> nextCommand;
nextCommand = traceFile.getNextCommand(time);
if (nextCommand)
selectTransaction(nextCommand);
}
// void TraceNavigator::selectNextActb()
// {
// shared_ptr<Transaction> nextActb;
//
// if (!SelectedTransactions().empty())
// nextActb = traceFile.getNextActb(SelectedTransactions().front()->id);
// else
// nextActb = traceFile.getNextActb(0);
//
// if (nextActb)
// selectTransaction(nextActb);
// }
//
// void TraceNavigator::selectNextPreb()
// {
// shared_ptr<Transaction> nextPreb;
//
// if (!SelectedTransactions().empty())
// nextPreb = traceFile.getNextPreb(
// SelectedTransactions().front()->id);
// else
// nextPreb = traceFile.getNextPreb(0);
//
// if (nextPreb)
// selectTransaction(nextPreb);
// }
//
// void TraceNavigator::selectNextRefb()
// {
// shared_ptr<Transaction> n;
//
// if (!SelectedTransactions().empty())
// n = traceFile.getNextRefb(SelectedTransactions().front()->id);
// else
// n = traceFile.getNextRefb(0);
//
// if (n)
// selectTransaction(n);
// }
bool TraceNavigator::transactionIsSelected(const shared_ptr<Transaction>& transaction) const
{
return transactionIsSelected(transaction->id);
}
bool TraceNavigator::transactionIsSelected(ID id) const
{
for (const auto& transaction : selectedTransactions)
{
if (transaction->id == id)
return true;
}
return false;
}
void TraceNavigator::clearSelectedTransactions()
{
if (hasSelectedTransactions())
{
selectedTransactions.clear();
Q_EMIT selectedTransactionsChanged();
}
}
bool TraceNavigator::hasSelectedTransactions()
{
return !selectedTransactions.empty();
}
Timespan TraceNavigator::getSpanCoveredBySelectedTransaction()
{
if (!hasSelectedTransactions())
return Timespan(0, 0);
traceTime begin = SelectedTransactions().at(0)->span.Begin();
traceTime end = SelectedTransactions().at(0)->span.End();
for (const auto& transaction : selectedTransactions)
{
if (transaction->span.End() > end)
end = transaction->span.End();
}
return Timespan(begin, end);
}
const CommentModel* TraceNavigator::getCommentModel() const
{
return commentModel;
}
bool TraceNavigator::existChangesToCommit() const
{
return changesToCommitExist;
}
void TraceNavigator::traceFileModified()
{
changesToCommitExist = true;
}

View File

@@ -0,0 +1,128 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
*/
#ifndef TRACENAVIGATOR_H
#define TRACENAVIGATOR_H
#include "businessObjects/generalinfo.h"
#include "businessObjects/transaction.h"
#include "data/tracedb.h"
#include "memory"
#include <QObject>
#include <vector>
class CommentModel;
/* Class to navigate through a tracefile
*
*
*/
class TraceNavigator : public QObject
{
Q_OBJECT
public:
TraceNavigator(QString path, CommentModel* commentModel, QObject* parent = 0);
traceTime CurrentTraceTime() const { return currentTraceTime; }
TraceDB& TraceFile() { return traceFile; }
const GeneralInfo& GeneralTraceInfo() { return traceFile.getGeneralInfo(); }
void navigateToTime(traceTime time);
void navigateToTransaction(ID id);
/* Transaction selection
* (selecting a single transactions also navigates to that transaction)
*/
void selectTransaction(ID id);
void selectTransaction(const std::shared_ptr<Transaction>& transaction);
void selectNextTransaction();
void selectPreviousTransaction();
void selectLastTransaction();
void selectFirstTransaction();
void selectNextRefresh(traceTime time);
void selectNextActivate(traceTime time);
void selectNextPrecharge(traceTime time);
void selectNextCommand(traceTime time);
// void selectNextActb();
// void selectNextPreb();
// void selectNextRefb();
void addSelectedTransactions(const std::vector<std::shared_ptr<Transaction>>& transactions);
const std::vector<std::shared_ptr<Transaction>>& SelectedTransactions()
{
return selectedTransactions;
}
void addSelectedTransaction(const std::shared_ptr<Transaction>& Transaction);
void addSelectedTransaction(ID id);
void clearSelectedTransactions();
bool hasSelectedTransactions();
Timespan getSpanCoveredBySelectedTransaction();
bool transactionIsSelected(ID id) const;
bool transactionIsSelected(const std::shared_ptr<Transaction>& Transaction) const;
void commitChangesToDB();
void refreshData();
const CommentModel* getCommentModel() const;
bool existChangesToCommit() const;
Q_SIGNALS:
void currentTraceTimeChanged();
void selectedTransactionsChanged();
public Q_SLOTS:
void traceFileModified();
private:
TraceDB traceFile;
// represents the current position in the tracefile
// components drawing the tracefile center around that time
traceTime currentTraceTime = 0;
std::vector<std::shared_ptr<Transaction>> selectedTransactions;
CommentModel* commentModel;
void getCommentsFromDB();
bool changesToCommitExist;
};
#endif // TRACENAVIGATOR_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,238 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
* Iron Prando da Silva
*/
#ifndef TRACEPLOT_H
#define TRACEPLOT_H
#include "markerplotitem.h"
#include "queryeditor.h"
#include "tracenavigator.h"
#include "traceplotitem.h"
#include "util/togglecollapsedaction.h"
#include <QAction>
#include <QColor>
#include <QPushButton>
#include <QScrollBar>
#include <QString>
#include <qwt_plot.h>
#include <qwt_plot_marker.h>
#include <qwt_plot_zoneitem.h>
#include <qwt_scale_draw.h>
#include <vector>
class TracePlotMouseLabel;
class CustomLabelScaleDraw;
class CommentModel;
class TracePlotLineDataSource;
/* A plot that plots all phases and transactions of a trace file
* Y Axis : Bank0,...,Bank7,Trans,CC
* X Axis : Time
*
*/
class TracePlot : public QwtPlot
{
Q_OBJECT
public:
TracePlot(QWidget* parent = NULL);
void init(TraceNavigator* navigator,
QScrollBar* scrollBar,
TracePlotLineDataSource* tracePlotLineDataSource,
CommentModel* commentModel);
Timespan GetCurrentTimespan();
traceTime ZoomLevel() const;
void setZoomLevel(traceTime newZoomLevel);
CustomLabelScaleDraw* getCustomLabelScaleDraw() const;
const TraceDrawingProperties& getDrawingProperties() const;
public Q_SLOTS:
void currentTraceTimeChanged();
void selectedTransactionsChanged();
void commentsChanged();
void verticalScrollbarChanged(int value);
void updateScrollbar();
void recreateCollapseButtons();
void updateToggleCollapsedAction();
Q_SIGNALS:
void tracePlotZoomChanged();
void tracePlotLinesChanged();
void colorGroupingChanged(ColorGrouping colorgrouping);
private Q_SLOTS:
void on_executeQuery();
void on_selectNextRefresh();
void on_selectNextActivate();
void on_selectNextPrecharge();
void on_selectNextCommand();
// void on_selectNextActb();
// void on_selectNextPreb();
// void on_selectNextRefb();
void on_colorGroupingPhase();
void on_colorGroupingTransaction();
void on_colorGroupingThread();
void on_colorGroupingRainbowTransaction();
void on_goToTransaction();
void on_goToPhase();
void on_deselectAll();
void on_insertComment();
void on_goToTime();
void on_exportToPDF();
void on_toggleCollapsedState();
private:
bool isInitialized;
TraceNavigator* navigator;
TraceDrawingProperties drawingProperties;
TracePlotItem* tracePlotItem;
QwtPlotZoneItem* zoomZone;
std::vector<std::shared_ptr<Transaction>> transactions;
QueryEditor* queryEditor;
QMenu* contextMenu;
QScrollBar* scrollBar;
CustomLabelScaleDraw* customLabelScaleDraw;
CommentModel* commentModel;
TracePlotLineDataSource* tracePlotLineDataSource;
void setUpTracePlotItem();
void setUpDrawingProperties();
void setUpGrid();
void setUpAxis();
void setUpZoom();
void setUpQueryEditor();
void setUpActions();
void setUpContextMenu();
void connectNavigatorQ_SIGNALS();
void getAndDrawComments();
ToggleCollapsedAction::CollapsedState getCollapsedState() const;
void collapseOrExpandAllRanks(ToggleCollapsedAction::CollapseAction collapseAction);
/* zooming
*
*/
traceTime zoomLevel;
constexpr static int minZoomClks = 10;
constexpr static int maxZoomClks = 2000;
constexpr static int GridVisiblityClks = 100;
constexpr static int textVisibilityClks = 200;
traceTime minZoomLevel, maxZoomLevel, textVisibilityZoomLevel;
constexpr static double zoomFactor = 0.8;
void zoomIn(traceTime zoomCenter);
void zoomOut(traceTime zoomCenter);
void exitZoomMode();
void enterZoomMode();
/* keyboard an mouse events
*
*/
bool eventFilter(QObject* object, QEvent* event);
QAction* goToTime;
QAction* goToTransaction;
QAction* goToPhase;
QAction* showQueryEditor;
QAction* insertComment;
QAction* deselectAll;
QAction* selectNextRefresh;
QAction* selectNextActivate;
QAction* selectNextPrecharge;
QAction* selectNextCommand;
// QAction *selectNextActb;
// QAction *selectNextPreb;
// QAction *selectNextRefb;
QAction* setColorGroupingPhase;
QAction* setColorGroupingTransaction;
QAction* setColorGroupingThread;
QAction* setColorGroupingRainbowTransaction;
QAction* exportToPdf;
ToggleCollapsedAction* toggleCollapsedState;
QMenu* dependenciesSubMenu;
QAction* disabledDependencies;
QAction* selectedDependencies;
QAction* allDependencies;
QAction* switchDrawDependencyTextsOption;
TracePlotMouseLabel* mouseLabel;
void openContextMenu(const QPoint& pos, const QPoint& mouseDown);
QPoint contextMenuMouseDown;
void SelectTransaction(int x, int y) const;
void SelectComment(int x) const;
// const std::vector<std::shared_ptr<Comment>> hoveredComments(traceTime time) const;
Timespan hoveredTimespan(int x) const;
void keyPressEvent(QKeyEvent* keyPressedEvent);
void keyReleaseEvent(QKeyEvent* keyReleasedEvent);
struct KeyPressData
{
bool ctrlPressed, shiftPressed;
KeyPressData() : ctrlPressed(false), shiftPressed(false) {}
};
struct MouseDownData
{
traceTime mouseDownTime;
Timespan zoomSpan;
int mouseDownX;
bool mouseIsDownForDragging;
bool mouseIsDownForZooming;
MouseDownData() :
mouseDownTime(0),
mouseDownX(0),
mouseIsDownForDragging(false),
mouseIsDownForZooming(false)
{
}
};
MouseDownData mouseDownData;
KeyPressData keyPressData;
};
#endif // TRACEPLOT_H

View File

@@ -0,0 +1,77 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#include "traceplotitem.h"
#include "tracedrawing.h"
#include "util/colorgenerator.h"
#include <QRect>
#include <algorithm>
#include <qwt_painter.h>
#include <qwt_scale_map.h>
#include <tuple>
using namespace std;
int TracePlotItem::rtti() const
{
return QwtPlotItem::Rtti_PlotUserItem;
}
void TracePlotItem::draw(QPainter* painter,
const QwtScaleMap& xMap,
const QwtScaleMap& yMap,
const QRectF& canvasRect) const
{
for (const auto& transaction : transactions)
{
bool highlight = navigator.transactionIsSelected(transaction);
transaction->draw(painter, xMap, yMap, canvasRect, highlight, drawingProperties);
}
}
vector<shared_ptr<Transaction>> TracePlotItem::getSelectedTransactions(Timespan timespan,
double yVal)
{
vector<shared_ptr<Transaction>> result;
for (const auto& transaction : transactions)
{
if (transaction->isSelected(timespan, yVal, drawingProperties))
result.push_back(transaction);
}
return result;
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef TRACEPLOTITEM_H
#define TRACEPLOTITEM_H
#include "businessObjects/tracetime.h"
#include "businessObjects/transaction.h"
#include "presentation/tracedrawingproperties.h"
#include "presentation/tracenavigator.h"
#include "util/colorgenerator.h"
#include <QColor>
#include <QPoint>
#include <qwt_plot_item.h>
#include <vector>
class TracePlotItem : public QwtPlotItem
{
private:
const std::vector<std::shared_ptr<Transaction>>& transactions;
const TraceNavigator& navigator;
const TraceDrawingProperties& drawingProperties;
public:
TracePlotItem(const std::vector<std::shared_ptr<Transaction>>& transactions,
const TraceNavigator& navigator,
const TraceDrawingProperties& drawingProperties) :
transactions(transactions),
navigator(navigator),
drawingProperties(drawingProperties)
{
}
virtual int rtti() const;
virtual void draw(QPainter* painter,
const QwtScaleMap& xMap,
const QwtScaleMap& yMap,
const QRectF& canvasRect) const;
std::vector<std::shared_ptr<Transaction>> getSelectedTransactions(Timespan timespan,
double yVal);
};
#endif // TRACEPLOTITEM_H

View File

@@ -0,0 +1,353 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
*/
#include "tracescroller.h"
#include "traceplotitem.h"
#include "util/engineeringScaleDraw.h"
#include <QItemSelectionModel>
#include <QMouseEvent>
#include <QWheelEvent>
#include <qwt_plot_zoneitem.h>
TraceScroller::TraceScroller(QWidget* parent) :
QwtPlot(parent),
isInitialized(false),
drawingProperties(false,
false,
{DependencyOption::Disabled, DependencyTextOption::Disabled},
ColorGrouping::PhaseType)
{
setAxisScaleDraw(xBottom, new EngineeringScaleDraw);
canvas()->setCursor(Qt::ArrowCursor);
canvasClip = new QwtPlotZoneItem();
canvasClip->setZ(2);
canvasClip->attach(this);
}
void TraceScroller::init(TraceNavigator* navigator,
TracePlot* tracePlot,
TracePlotLineDataSource* tracePlotLineDataSource)
{
Q_ASSERT(isInitialized == false);
isInitialized = true;
this->tracePlotLineDataSource = tracePlotLineDataSource;
this->navigator = navigator;
connectNavigatorQ_SIGNALS();
const CommentModel* commentModel = navigator->getCommentModel();
QObject::connect(
commentModel, &CommentModel::dataChanged, this, &TraceScroller::commentsChanged);
QObject::connect(
commentModel, &CommentModel::rowsRemoved, this, &TraceScroller::commentsChanged);
QObject::connect(commentModel->selectionModel(),
&QItemSelectionModel::selectionChanged,
this,
&TraceScroller::commentsChanged);
QObject::connect(tracePlotLineDataSource,
&TracePlotLineDataSource::modelChanged,
this,
&TraceScroller::updateAxis);
setUpDrawingProperties();
setUpAxis();
setUpTracePlotItem();
updateAxis();
getAndDrawComments();
this->tracePlot = tracePlot;
QObject::connect(tracePlot, SIGNAL(tracePlotZoomChanged()), this, SLOT(tracePlotZoomChanged()));
tracePlotZoomChanged();
QObject::connect(tracePlot,
SIGNAL(colorGroupingChanged(ColorGrouping)),
this,
SLOT(colorGroupingChanged(ColorGrouping)));
QObject::connect(tracePlot, SIGNAL(tracePlotLinesChanged()), this, SLOT(updateAxis()));
}
void TraceScroller::setUpTracePlotItem()
{
TracePlotItem* tracePlotItem = new TracePlotItem(transactions, *navigator, drawingProperties);
tracePlotItem->setZ(1);
tracePlotItem->attach(this);
}
void TraceScroller::setUpDrawingProperties()
{
drawingProperties.init(tracePlotLineDataSource);
drawingProperties.textColor = palette().text().color();
drawingProperties.numberOfRanks = navigator->GeneralTraceInfo().numberOfRanks;
drawingProperties.numberOfBankGroups = navigator->GeneralTraceInfo().numberOfBankGroups;
drawingProperties.numberOfBanks = navigator->GeneralTraceInfo().numberOfBanks;
drawingProperties.banksPerRank =
drawingProperties.numberOfBanks / drawingProperties.numberOfRanks;
drawingProperties.groupsPerRank =
drawingProperties.numberOfBankGroups / drawingProperties.numberOfRanks;
drawingProperties.banksPerGroup =
drawingProperties.numberOfBanks / drawingProperties.numberOfBankGroups;
drawingProperties.per2BankOffset = navigator->GeneralTraceInfo().per2BankOffset;
}
void TraceScroller::setUpAxis()
{
axisScaleDraw(yLeft)->enableComponent(QwtAbstractScaleDraw::Labels, false);
axisScaleDraw(yLeft)->enableComponent(QwtAbstractScaleDraw::Ticks, false);
}
void TraceScroller::updateAxis()
{
setAxisScale(yLeft, -1, drawingProperties.getNumberOfDisplayedLines(), 1.0);
replot();
}
void TraceScroller::connectNavigatorQ_SIGNALS()
{
QObject::connect(
navigator, SIGNAL(currentTraceTimeChanged()), this, SLOT(currentTraceTimeChanged()));
QObject::connect(navigator,
SIGNAL(selectedTransactionsChanged()),
this,
SLOT(selectedTransactionsChanged()));
}
Timespan TraceScroller::GetCurrentTimespan()
{
traceTime deltaOnTracePlot = navigator->GeneralTraceInfo().span.End() - tracePlot->ZoomLevel();
traceTime deltaOnTraceScroller = navigator->GeneralTraceInfo().span.End() - zoomLevel;
traceTime newBegin = static_cast<traceTime>(tracePlot->GetCurrentTimespan().Begin() *
(1.0 * deltaOnTraceScroller) / deltaOnTracePlot);
Timespan span(newBegin, newBegin + zoomLevel);
if (span.Begin() < 0)
span.shift(-span.Begin());
else if (span.End() > navigator->GeneralTraceInfo().span.End())
span.shift(navigator->GeneralTraceInfo().span.End() - span.End());
return span;
}
void TraceScroller::getAndDrawComments()
{
const CommentModel* commentModel = navigator->getCommentModel();
QList<QModelIndex> selectedRows = commentModel->selectionModel()->selectedRows();
for (int row = 0; row < commentModel->rowCount(); row++)
{
QModelIndex timeIndex =
commentModel->index(row, static_cast<int>(CommentModel::Column::Time));
bool selected =
std::find(selectedRows.begin(), selectedRows.end(), commentModel->index(row, 0)) !=
selectedRows.end();
QwtPlotMarker* maker = new QwtPlotMarker();
maker->setXValue(static_cast<double>(timeIndex.data(Qt::UserRole).toLongLong()));
maker->setLineStyle(QwtPlotMarker::LineStyle::VLine);
maker->setLinePen(QColor(selected ? Qt::red : Qt::blue), 2);
maker->attach(this);
}
}
/* Q_SLOTS
*
*
*/
void TraceScroller::selectedTransactionsChanged()
{
replot();
}
void TraceScroller::colorGroupingChanged(ColorGrouping colorGrouping)
{
drawingProperties.colorGrouping = colorGrouping;
replot();
}
void TraceScroller::currentTraceTimeChanged()
{
bool drawDependencies =
drawingProperties.drawDependenciesOption.draw != DependencyOption::Disabled;
Timespan spanOnTracePlot = tracePlot->GetCurrentTimespan();
canvasClip->setInterval(spanOnTracePlot.Begin(), spanOnTracePlot.End());
Timespan span = GetCurrentTimespan();
transactions = navigator->TraceFile().getTransactionsInTimespan(span, drawDependencies);
#ifdef EXTENSION_ENABLED
if (drawDependencies)
{
navigator->TraceFile().updateDependenciesInTimespan(span);
}
#endif
setAxisScale(xBottom, span.Begin(), span.End());
replot();
}
void TraceScroller::commentsChanged()
{
detachItems(QwtPlotItem::Rtti_PlotMarker);
getAndDrawComments();
replot();
}
void TraceScroller::tracePlotZoomChanged()
{
zoomLevel = tracePlot->ZoomLevel() * tracePlotEnlargementFactor;
if (zoomLevel > navigator->GeneralTraceInfo().span.timeCovered())
zoomLevel = navigator->GeneralTraceInfo().span.timeCovered();
}
bool TraceScroller::eventFilter(QObject* object, QEvent* event)
{
if (object == canvas())
{
static bool clipDragged = false;
static bool leftMousePressed = false;
static int mouseDownX = 0;
static traceTime mouseDownTracePlotTime = 0;
switch (event->type())
{
case QEvent::Wheel:
{
QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event);
traceTime offset;
int speed = 4;
(wheelEvent->angleDelta().y() > 0) ? offset = -zoomLevel* speed
: offset = zoomLevel * speed;
navigator->navigateToTime(navigator->CurrentTraceTime() + offset);
return true;
}
case QEvent::MouseButtonDblClick:
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
traceTime time = invTransform(xBottom, mouseEvent->x());
navigator->navigateToTime(time);
return true;
}
case QEvent::MouseButtonPress:
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() == Qt::LeftButton)
{
canvas()->setCursor(Qt::ClosedHandCursor);
leftMousePressed = true;
mouseDownTracePlotTime = tracePlot->GetCurrentTimespan().Middle();
mouseDownX = mouseEvent->x();
if (tracePlot->GetCurrentTimespan().contains(
invTransform(xBottom, mouseEvent->x())))
clipDragged = true;
else
clipDragged = false;
return true;
}
else if (mouseEvent->button() == Qt::RightButton)
{
navigator->navigateToTime(
static_cast<traceTime>(invTransform(xBottom, mouseEvent->x())));
return true;
}
break;
}
case QEvent::MouseButtonRelease:
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() == Qt::LeftButton)
{
clipDragged = false;
leftMousePressed = false;
canvas()->setCursor(Qt::ArrowCursor);
return true;
}
break;
}
case QEvent::MouseMove:
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if (leftMousePressed)
{
if (clipDragged)
{
double clipWidth =
transform(xBottom, tracePlot->ZoomLevel()) - transform(xBottom, 0);
if (mouseEvent->x() < clipWidth / 2)
{
navigator->navigateToTime(0);
}
else if (mouseEvent->x() > canvas()->width() - clipWidth / 2)
{
navigator->navigateToTime(navigator->GeneralTraceInfo().span.End());
}
else
{
traceTime time = static_cast<traceTime>(
(mouseEvent->x() - clipWidth / 2) / (canvas()->width() - clipWidth) *
(navigator->GeneralTraceInfo().span.End() - tracePlot->ZoomLevel()));
navigator->navigateToTime(time);
}
}
else
{
traceTime deltaTime =
invTransform(xBottom, mouseDownX) - invTransform(xBottom, mouseEvent->x());
navigator->navigateToTime(mouseDownTracePlotTime + deltaTime);
}
return true;
}
}
default:
break;
}
}
return false;
}

View File

@@ -0,0 +1,90 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
* Iron Prando da Silva
*/
#ifndef TRACESCROLLER_H
#define TRACESCROLLER_H
#include "presentation/tracenavigator.h"
#include "traceplot.h"
#include <qwt_plot.h>
#include <qwt_plot_zoneitem.h>
#include <vector>
class TracePlotLineDataSource;
class TraceScroller : public QwtPlot
{
Q_OBJECT
private:
std::vector<std::shared_ptr<Transaction>> transactions;
bool isInitialized;
TraceNavigator* navigator;
TracePlot* tracePlot;
TracePlotLineDataSource* tracePlotLineDataSource;
constexpr static int tracePlotEnlargementFactor = 4;
void setUpTracePlotItem();
void setUpDrawingProperties();
void setUpAxis();
void connectNavigatorQ_SIGNALS();
void getAndDrawComments();
QwtPlotZoneItem* canvasClip;
traceTime zoomLevel;
bool eventFilter(QObject* object, QEvent* event);
TraceDrawingProperties drawingProperties;
public:
TraceScroller(QWidget* parent = NULL);
void init(TraceNavigator* navigator,
TracePlot* tracePlot,
TracePlotLineDataSource* tracePlotLineDataSource);
Timespan GetCurrentTimespan();
public Q_SLOTS:
void currentTraceTimeChanged();
void commentsChanged();
void tracePlotZoomChanged();
void selectedTransactionsChanged();
void colorGroupingChanged(ColorGrouping colorgrouping);
private Q_SLOTS:
void updateAxis();
};
#endif // TraceScroller_H

View File

@@ -0,0 +1,173 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#include "transactiontreewidget.h"
#include "data/tracedb.h"
#include <QHeaderView>
#include <memory>
#include <vector>
using namespace std;
TransactionTreeWidget::TransactionTreeWidget(QWidget* parent) :
QTreeWidget(parent),
isInitialized(false)
{
QObject::connect(
this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(ContextMenuRequested(QPoint)));
setContextMenuPolicy(Qt::CustomContextMenu);
goToTransaction = new QAction("Move to", this);
}
void TransactionTreeWidget::init(TraceNavigator* _navigator)
{
Q_ASSERT(isInitialized == false);
isInitialized = true;
this->navigator = _navigator;
setColumnCount(3);
setHeaderLabels(QStringList({"Transaction", "Value", "Value"}));
}
void TransactionTreeWidget::AppendTransaction(const shared_ptr<Transaction>& transaction)
{
QTreeWidgetItem* node =
new TransactionTreeItem(this, transaction, navigator->GeneralTraceInfo());
addTopLevelItem(node);
}
void TransactionTreeWidget::ContextMenuRequested(QPoint point)
{
if (selectedItems().count() > 0 &&
selectedItems().at(0)->type() ==
TransactionTreeWidget::TransactionTreeItem::transactionTreeItemType)
{
QMenu contextMenu;
contextMenu.addActions({goToTransaction});
QAction* selectedContextMenuItems = contextMenu.exec(mapToGlobal(point));
if (selectedContextMenuItems)
{
TransactionTreeItem* item = dynamic_cast<TransactionTreeItem*>(selectedItems().at(0));
navigator->selectTransaction(item->Id());
}
}
}
TransactionTreeWidget::TransactionTreeItem::TransactionTreeItem(
QTreeWidget* parent,
const shared_ptr<Transaction>& transaction,
const GeneralInfo& generalInfo) :
QTreeWidgetItem(parent, transactionTreeItemType)
{
this->setText(0, QString::number(transaction->id));
this->id = transaction->id;
bool isControllerTransaction = (transaction->thread == generalInfo.controllerThread);
auto* time = new QTreeWidgetItem({"Timespan"});
AppendTimespan(time, transaction->span);
this->addChild(time);
if (!isControllerTransaction)
{
if (transaction->command == "R")
this->addChild(new QTreeWidgetItem({"Command", "Read"}));
else // if (transaction->command == "W")
this->addChild(new QTreeWidgetItem({"Command", "Write"}));
}
this->addChild(
new QTreeWidgetItem({"Length", prettyFormatTime(transaction->span.timeCovered())}));
if (!isControllerTransaction)
this->addChild(new QTreeWidgetItem(
{"Address", QString("0x") + QString::number(transaction->address, 16)}));
if (!isControllerTransaction)
this->addChild(
new QTreeWidgetItem({"Data Length", QString::number(transaction->dataLength)}));
this->addChild(new QTreeWidgetItem({"Channel", QString::number(transaction->channel)}));
if (!isControllerTransaction)
this->addChild(new QTreeWidgetItem({"Thread", QString::number(transaction->thread)}));
auto* phasesNode = new QTreeWidgetItem(this);
phasesNode->setText(0, "Phases");
phasesNode->addChild(new QTreeWidgetItem({"", "Begin", "End"}));
for (const std::shared_ptr<Phase>& phase : transaction->Phases())
AppendPhase(phasesNode, *phase);
}
void TransactionTreeWidget::TransactionTreeItem::AppendPhase(QTreeWidgetItem* parent,
const Phase& phase)
{
auto* node = new QTreeWidgetItem(parent);
node->setText(0, phase.Name() + QString(" [") + QString::number(phase.Id()) + QString("]"));
AppendTimespan(node, phase.Span());
auto addMapping = [node](std::string_view label, unsigned value)
{
auto* mappingNode = new QTreeWidgetItem(node);
mappingNode->setText(0, label.data());
mappingNode->setText(1, QString::number(value));
};
{
if (static_cast<int>(phase.getRelevantAttributes() & RelevantAttributes::Rank))
addMapping("Rank", phase.getRank());
if (static_cast<int>(phase.getRelevantAttributes() & RelevantAttributes::BankGroup))
addMapping("Bank Group", phase.getBankGroup());
if (static_cast<int>(phase.getRelevantAttributes() & RelevantAttributes::Bank))
addMapping("Bank", phase.getBank());
if (static_cast<int>(phase.getRelevantAttributes() & RelevantAttributes::Row))
addMapping("Row", phase.getRow());
if (static_cast<int>(phase.getRelevantAttributes() & RelevantAttributes::Column))
addMapping("Column", phase.getColumn());
if (static_cast<int>(phase.getRelevantAttributes() & RelevantAttributes::BurstLength))
addMapping("Burst Length", phase.getBurstLength());
}
}
void TransactionTreeWidget::TransactionTreeItem::AppendTimespan(QTreeWidgetItem* parent,
const Timespan& timespan)
{
parent->setText(1, prettyFormatTime(timespan.Begin()));
parent->setText(2, prettyFormatTime(timespan.End()));
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef TRANSACTIONTREEWIDGET_H
#define TRANSACTIONTREEWIDGET_H
#include "tracenavigator.h"
#include <QMenu>
#include <QTreeWidget>
#include <iostream>
class TransactionTreeWidget : public QTreeWidget
{
Q_OBJECT
public:
explicit TransactionTreeWidget(QWidget* parent);
void AppendTransaction(const std::shared_ptr<Transaction>& transaction);
virtual void init(TraceNavigator* _navigator);
public Q_SLOTS:
void ContextMenuRequested(QPoint point);
protected:
TraceNavigator* navigator;
private:
bool isInitialized;
QAction* goToTransaction;
class TransactionTreeItem : public QTreeWidgetItem
{
public:
static constexpr int transactionTreeItemType = 1001;
TransactionTreeItem(QTreeWidget* parent,
const std::shared_ptr<Transaction>& trans,
const GeneralInfo& generalInfo);
ID Id() const { return id; }
private:
ID id;
static void AppendTimespan(QTreeWidgetItem* parent, const Timespan& timespan);
static void AppendPhase(QTreeWidgetItem* parent, const Phase& phase);
};
};
#endif // TRANSACTIONTREEWIDGET_H

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#include "clkgrid.h"
#include <iostream>
#include <qwt_interval.h>
#include <qwt_scale_div.h>
using namespace std;
void ClkGrid::updateScaleDiv(const QwtScaleDiv& xMap, const QwtScaleDiv& yMap)
{
QwtScaleDiv scaleDiv;
scaleDiv.setInterval(xMap.interval());
double min = xMap.interval().minValue();
double max = xMap.interval().maxValue();
if (min > max)
qSwap(min, max);
if ((max - min) < maxVisibility)
{
min = static_cast<long long>(min / clkPeriod) * clkPeriod;
QList<double> ticks;
for (double tick = min; tick <= max; tick += clkPeriod)
ticks += tick;
scaleDiv.setTicks(QwtScaleDiv::MajorTick, ticks);
}
QwtPlotGrid::updateScaleDiv(scaleDiv, yMap);
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef CLKGRID_H
#define CLKGRID_H
#include "businessObjects/tracetime.h"
#include <qwt_plot_grid.h>
class ClkGrid : public QwtPlotGrid
{
public:
virtual void updateScaleDiv(const QwtScaleDiv& xMap, const QwtScaleDiv& yMap);
ClkGrid(unsigned int clkPeriod, traceTime maxVisibility) :
clkPeriod(clkPeriod),
maxVisibility(maxVisibility)
{
}
private:
unsigned int clkPeriod;
double maxVisibility;
};
#endif // CLKGRID_H

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Iron Prando da Silva
*/
#include "colorgenerator.h"
#include <exception>
QColor ColorGenerator::getColor(unsigned int i, ColorName color)
{
switch (color)
{
case ColorName::Default:
return cDefault.getColor(i);
case ColorName::HSV15:
return cHSV15.getColor(i);
}
return {0, 0, 0};
}
QColor ColorGenerator::getRainbowColored(unsigned int i, ColorName color)
{
switch (color)
{
case ColorName::Default:
return cDefault.getRainbowColored(i);
case ColorName::HSV15:
return cHSV15.getRainbowColored(i);
}
return {0, 0, 0};
}
ColorDefault ColorGenerator::cDefault;
ColorHSV15 ColorGenerator::cHSV15;

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Iron Prando da Silva
*/
#ifndef COLORGENERATOR_H
#define COLORGENERATOR_H
#include "colorobject.h"
#include <QColor>
#include <stdint.h>
enum ColorName
{
Default,
HSV15
};
class ColorGenerator
{
private:
ColorGenerator() = delete;
static ColorDefault cDefault;
static ColorHSV15 cHSV15;
public:
static QColor getColor(unsigned int i, ColorName color = ColorName::Default);
static QColor getRainbowColored(unsigned int i, ColorName color = ColorName::Default);
};
#endif // RANDOMCOLORGENERATOR_H

View File

@@ -0,0 +1,179 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Iron Prando da Silva
*/
#include "colorobject.h"
QColor ColorObject::getColor(unsigned int i)
{
i = i % numberOfColors;
QColor result(r[i], g[i], b[i]);
result.setAlpha(130);
return result;
}
QColor ColorObject::getRainbowColored(unsigned int i)
{
const int minAlpha = 50;
const int alphaLevels = 20 - 255 / minAlpha;
const int alphaStep = (255. - minAlpha) / alphaLevels;
int alpha = minAlpha + (int)(alphaStep * (i % alphaLevels));
i = (i / alphaLevels) % numberOfColors;
QColor result(r[i], g[i], b[i]);
result.setAlpha(alpha);
return result;
}
ColorDefault::ColorDefault()
{
numberOfColors = 16;
r.resize(numberOfColors);
g.resize(numberOfColors);
b.resize(numberOfColors);
r[0] = 0xFF;
r[1] = 0x00;
r[2] = 0x00;
r[3] = 0xFF;
g[0] = 0x00;
g[1] = 0xFF;
g[2] = 0x00;
g[3] = 0xFF;
b[0] = 0x00;
b[1] = 0x00;
b[2] = 0xFF;
b[3] = 0x00;
r[4] = 0xFF;
r[5] = 0x00;
r[6] = 0xFF;
r[7] = 0x6B;
g[4] = 0x00;
g[5] = 0xFF;
g[6] = 0xA5;
g[7] = 0x8E;
b[4] = 0xFF;
b[5] = 0xFF;
b[6] = 0x00;
b[7] = 0x23;
r[8] = 0x8A;
r[9] = 0xFF;
r[10] = 0x7C;
r[11] = 0x00;
g[8] = 0x2B;
g[9] = 0xD7;
g[10] = 0xFC;
g[11] = 0x00;
b[8] = 0xE2;
b[9] = 0x00;
b[10] = 0x00;
b[11] = 0x80;
r[12] = 0x80;
r[13] = 0x00;
r[14] = 0xEE;
r[15] = 0xFF;
g[12] = 0x00;
g[13] = 0x80;
g[14] = 0x82;
g[15] = 0x45;
b[12] = 0x00;
b[13] = 0x00;
b[14] = 0xEE;
b[15] = 0x00;
}
ColorHSV15::ColorHSV15()
{
numberOfColors = 15;
r.resize(numberOfColors);
g.resize(numberOfColors);
b.resize(numberOfColors);
r[0] = 0XFF;
r[1] = 0XFF;
r[2] = 0XFF;
r[3] = 0XD1;
r[4] = 0X6C;
r[5] = 0X08;
r[6] = 0X00;
r[7] = 0X00;
r[8] = 0X00;
r[9] = 0X00;
r[10] = 0X00;
r[11] = 0X54;
r[12] = 0XB9;
r[13] = 0XFF;
r[14] = 0XFF;
g[0] = 0X00;
g[1] = 0X64;
g[2] = 0XC9;
g[3] = 0XFF;
g[4] = 0XFF;
g[5] = 0XFF;
g[6] = 0XFF;
g[7] = 0XFF;
g[8] = 0XD9;
g[9] = 0X74;
g[10] = 0X10;
g[11] = 0X00;
g[12] = 0X00;
g[13] = 0X00;
g[14] = 0X00;
b[0] = 0X00;
b[1] = 0X00;
b[2] = 0X00;
b[3] = 0X00;
b[4] = 0X00;
b[5] = 0X00;
b[6] = 0X5C;
b[7] = 0XC1;
b[8] = 0XFF;
b[9] = 0XFF;
b[10] = 0XFF;
b[11] = 0XFF;
b[12] = 0XFF;
b[13] = 0XE1;
b[14] = 0X7C;
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Iron Prando da Silva
*/
#pragma once
#include <QColor>
class ColorObject
{
protected:
int numberOfColors = 0;
std::vector<int> r;
std::vector<int> g;
std::vector<int> b;
// std::vector<int> a;
ColorObject(){};
public:
virtual QColor getColor(unsigned int i);
virtual QColor getRainbowColored(unsigned int i);
};
class ColorDefault : public ColorObject
{
public:
ColorDefault();
};
class ColorHSV15 : public ColorObject
{
public:
ColorHSV15();
};

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2021, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Author:
* Derek Christ
*/
#include "customlabelscaledraw.h"
CustomLabelScaleDraw::CustomLabelScaleDraw(std::shared_ptr<QHash<int, QString>> labels) :
QObject(nullptr),
labels(labels)
{
}
QwtText CustomLabelScaleDraw::label(double v) const
{
return QwtText((*labels)[static_cast<int>(v)]);
}
void CustomLabelScaleDraw::draw(QPainter* painter, const QPalette& palette) const
{
emit scaleRedraw();
QwtScaleDraw::draw(painter, palette);
}
void CustomLabelScaleDraw::clearCache()
{
invalidateCache();
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
*/
#ifndef CUSTOMLABELSCALEDRAW_H
#define CUSTOMLABELSCALEDRAW_H
#include <QHash>
#include <QObject>
#include <memory>
#include <qwt_scale_draw.h>
#include <qwt_text.h>
class CustomLabelScaleDraw : public QObject, public QwtScaleDraw
{
Q_OBJECT
private:
const std::shared_ptr<QHash<int, QString>> labels;
public:
CustomLabelScaleDraw(std::shared_ptr<QHash<int, QString>> labels);
~CustomLabelScaleDraw() = default;
virtual QwtText label(double v) const override;
void draw(QPainter* painter, const QPalette& palette) const override;
void clearCache();
Q_SIGNALS:
void scaleRedraw() const;
};
#endif // CUSTOMLABELSCALEDRAW_H

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef ENGINEERINGSCALEDRAW_H
#define ENGINEERINGSCALEDRAW_H
#include "businessObjects/tracetime.h"
#include <QString>
#include <qwt_scale_draw.h>
#include <qwt_text.h>
class EngineeringScaleDraw : public QwtScaleDraw
{
public:
virtual QwtText label(double number) const
{
return QwtText(QString::number(number / 1000, 'g', 9));
}
};
#endif // ENGINEERINGSCALEDRAW_H

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#include "testlight.h"
#include <QPainter>
TestLight::TestLight(QWidget* parent) : QWidget(parent)
{
setGray();
}
void TestLight::setGray()
{
lightColor = QColor(Qt::gray);
update();
}
void TestLight::setGreen()
{
lightColor = QColor(Qt::green);
update();
}
void TestLight::setRed()
{
lightColor = QColor(Qt::red);
update();
}
void TestLight::paintEvent(QPaintEvent* /*paintEvent*/)
{
QPainter painter(this);
painter.fillRect(this->rect(), lightColor);
painter.drawRect(this->rect());
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef TESTLIGHT_H
#define TESTLIGHT_H
#include <QColor>
#include <QPaintEvent>
#include <QWidget>
class TestLight : public QWidget
{
Q_OBJECT
public:
TestLight(QWidget* parent = 0);
void setGreen();
void setRed();
void setGray();
protected:
void paintEvent(QPaintEvent* paintEvent);
private:
QColor lightColor;
};
#endif // TESTLIGHT_H

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 2021, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Derek Christ
*/
#include "togglecollapsedaction.h"
ToggleCollapsedAction::ToggleCollapsedAction(QObject* parent) : QAction(parent)
{
updateCollapsedState(currentCollapsedState);
}
void ToggleCollapsedAction::updateCollapsedState(
ToggleCollapsedAction::CollapsedState collapsedState)
{
switch (collapsedState)
{
case CollapsedState::Expanded:
case CollapsedState::Mixed:
actionText = "Collapse all ranks";
collapseAction = CollapseAction::CollapseAllRanks;
break;
case CollapsedState::Collapsed:
actionText = "Expand all ranks";
collapseAction = CollapseAction::ExpandAllRanks;
break;
}
this->setText(actionText);
}
ToggleCollapsedAction::CollapseAction ToggleCollapsedAction::getCollapseAction() const
{
return collapseAction;
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) 2021, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Derek Christ
*/
#ifndef TOGGLECOLLAPSEDACTION_H
#define TOGGLECOLLAPSEDACTION_H
#include <QAction>
class ToggleCollapsedAction : public QAction
{
public:
explicit ToggleCollapsedAction(QObject* parent = nullptr);
enum class CollapsedState
{
Mixed,
Collapsed,
Expanded
};
enum class CollapseAction
{
ExpandAllRanks,
CollapseAllRanks
};
void updateCollapsedState(CollapsedState collapsedState);
CollapseAction getCollapseAction() const;
public Q_SLOTS:
private:
CollapsedState currentCollapsedState = CollapsedState::Collapsed;
CollapseAction collapseAction;
QString actionText;
};
#endif // TOGGLECOLLAPSEDACTION_H

View File

@@ -0,0 +1,77 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#include "queryeditor.h"
#include "ui_queryeditor.h"
#include <QMessageBox>
#include <vector>
QueryEditor::QueryEditor(QWidget* parent) : QWidget(parent), ui(new Ui::QueryEditor)
{
ui->setupUi(this);
ui->queryHead->setText(queryTexts.queryHead);
}
QueryEditor::~QueryEditor()
{
delete ui;
}
void QueryEditor::init(TraceNavigator* _navigator)
{
this->navigator = _navigator;
ui->transactiontreeWidget->init(_navigator);
}
void QueryEditor::on_executeQuery_clicked()
{
try
{
std::vector<std::shared_ptr<Transaction>> result =
navigator->TraceFile().getTransactionsWithCustomQuery(queryTexts.queryHead + " " +
ui->queryEdit->toPlainText());
ui->transactiontreeWidget->clear();
for (const auto& trans : result)
{
ui->transactiontreeWidget->AppendTransaction(trans);
}
}
catch (const sqlException& ex)
{
QMessageBox::warning(this, "Query failed", ex.what());
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef QUERYEDITOR_H
#define QUERYEDITOR_H
#include "data/QueryTexts.h"
#include "presentation/tracenavigator.h"
#include <QWidget>
namespace Ui
{
class QueryEditor;
}
class QueryEditor : public QWidget
{
Q_OBJECT
public:
explicit QueryEditor(QWidget* parent = 0);
~QueryEditor();
void init(TraceNavigator* _navigator);
private Q_SLOTS:
void on_executeQuery_clicked();
private:
Ui::QueryEditor* ui;
TraceNavigator* navigator;
TransactionQueryTexts queryTexts;
};
#endif // QUERYEDITOR_H

View File

@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QueryEditor</class>
<widget class="QWidget" name="QueryEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>667</width>
<height>451</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTextEdit" name="queryHead">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="queryEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="executeQuery">
<property name="text">
<string>Execute query</string>
</property>
</widget>
</item>
<item>
<widget class="TransactionTreeWidget" name="transactiontreeWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>5</verstretch>
</sizepolicy>
</property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>TransactionTreeWidget</class>
<extends>QTreeWidget</extends>
<header>presentation/transactiontreewidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file alias="icon">icon.svg</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,121 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Felipe S. Prado
* Matthias Jung
*/
#include "selectmetrics.h"
#include "ui_selectmetrics.h"
#include <QMessageBox>
SelectMetrics::SelectMetrics(QWidget* parent) : QDialog(parent), ui(new Ui::SelectMetrics)
{
ui->setupUi(this);
layout = new QVBoxLayout();
ui->scrollAreaWidgetContents->setLayout(layout);
ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
}
void SelectMetrics::on_okButton_clicked()
{
if (isThereAnyMetricSelected())
{
close();
Q_EMIT getSelectedMetrics();
}
else
{
QMessageBox::warning(this, "Warning", "Please select at least one metric");
}
}
void SelectMetrics::on_clearAllButton_clicked()
{
for (QCheckBox* checkBox : metrics)
{
checkBox->setChecked(false);
}
}
void SelectMetrics::on_selectAllButton_clicked()
{
for (QCheckBox* checkBox : metrics)
{
checkBox->setChecked(true);
}
}
bool SelectMetrics::isThereAnyMetricSelected()
{
for (QCheckBox* checkBox : metrics)
{
if (checkBox->isChecked())
return true;
}
return false;
}
void SelectMetrics::setMetrics(std::vector<std::string> metrics)
{
if (this->metrics.size() != metrics.size())
{
for (QCheckBox* checkBox : this->metrics)
{
layout->removeWidget(checkBox);
}
this->metrics.clear();
for (std::string metric : metrics)
{
QCheckBox* checkBox = new QCheckBox();
checkBox->setObjectName(QString::fromStdString(metric));
checkBox->setCheckable(true);
checkBox->setChecked(true);
checkBox->setGeometry(10, 25, 100, 17);
checkBox->setText(QString::fromStdString(metric));
this->metrics.push_back(checkBox);
layout->addWidget(checkBox, Qt::AlignLeft);
}
}
}
SelectMetrics::~SelectMetrics()
{
delete ui;
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Felipe S. Prado
* Matthias Jung
*/
#ifndef SELECTMETRICS_H
#define SELECTMETRICS_H
#include <QCheckBox>
#include <QDialog>
#include <QPushButton>
#include <QVBoxLayout>
namespace Ui
{
class SelectMetrics;
}
class SelectMetrics : public QDialog
{
Q_OBJECT
public:
explicit SelectMetrics(QWidget* parent = 0);
~SelectMetrics();
std::vector<QCheckBox*> metrics;
void setMetrics(std::vector<std::string> metrics);
Q_SIGNALS:
void getSelectedMetrics();
private Q_SLOTS:
void on_okButton_clicked();
void on_selectAllButton_clicked();
void on_clearAllButton_clicked();
private:
Ui::SelectMetrics* ui;
QVBoxLayout* layout;
bool isThereAnyMetricSelected();
};
#endif // SELECTMETRICS_H

View File

@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SelectMetrics</class>
<widget class="QDialog" name="SelectMetrics">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>498</width>
<height>666</height>
</rect>
</property>
<property name="windowTitle">
<string>Select Metrics</string>
</property>
<widget class="QPushButton" name="okButton">
<property name="geometry">
<rect>
<x>40</x>
<y>620</y>
<width>80</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Ok</string>
</property>
</widget>
<widget class="QPushButton" name="selectAllButton">
<property name="geometry">
<rect>
<x>180</x>
<y>620</y>
<width>80</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Select All</string>
</property>
</widget>
<widget class="QPushButton" name="clearAllButton">
<property name="geometry">
<rect>
<x>310</x>
<y>620</y>
<width>80</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Clear All</string>
</property>
</widget>
<widget class="QScrollArea" name="scrollArea">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>471</width>
<height>601</height>
</rect>
</property>
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>467</width>
<height>597</height>
</rect>
</property>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,280 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
*/
#include "traceanalyzer.h"
#include "extensionDisclaimer.h"
#include "tracefiletab.h"
#include "ui_traceanalyzer.h"
#include <QCloseEvent>
#include <QDateTime>
#include <QFileDialog>
#include <QFileInfo>
#include <QMessageBox>
void TraceAnalyzer::setUpStatusBar()
{
statusLabel = new QLabel(this);
statusBar()->addWidget(statusLabel);
}
TraceAnalyzer::TraceAnalyzer(QWidget* parent) :
QMainWindow(parent),
evaluationTool(pythonCaller),
ui(new Ui::TraceAnalyzer)
{
ui->setupUi(this);
setUpStatusBar();
ui->traceFileTabs->clear();
QObject::connect(ui->actionAbout_Qt, &QAction::triggered, qApp, &QApplication::aboutQt);
}
TraceAnalyzer::TraceAnalyzer(QSet<QString> paths, QWidget* parent) : TraceAnalyzer(parent)
{
for (const QString& path : paths)
openTracefileTab(path);
}
TraceAnalyzer::~TraceAnalyzer()
{
delete ui;
}
void TraceAnalyzer::on_actionOpen_triggered()
{
QStringList paths = QFileDialog::getOpenFileNames(
this, tr("Open Tracefile"), "../simulator/", tr("Tracefile (*.tdb)"));
if (paths.isEmpty())
return;
for (const QString& path : paths)
openTracefileTab(path);
}
TraceFileTab* TraceAnalyzer::createTraceFileTab(const QString& path)
{
auto* traceFileTab = new TraceFileTab(path.toStdString(), pythonCaller, this);
connect(traceFileTab, &TraceFileTab::statusChanged, this, &TraceAnalyzer::statusChanged);
return traceFileTab;
}
void TraceAnalyzer::openTracefileTab(const QString& path)
{
if (openedTraceFiles.contains(path))
return;
TraceFileTab* traceFileTab = createTraceFileTab(path);
ui->traceFileTabs->addTab(traceFileTab, QFileInfo(path).baseName());
openedTraceFiles.insert(path);
statusLabel->clear();
}
void TraceAnalyzer::on_menuFile_aboutToShow()
{
ui->actionOpen->setEnabled(true);
ui->actionQuit->setEnabled(true);
bool tabsOpen = ui->traceFileTabs->count() > 0;
ui->actionSave->setEnabled(tabsOpen);
ui->actionSave_all->setEnabled(tabsOpen);
ui->actionReload->setEnabled(tabsOpen);
ui->actionReload_all->setEnabled(tabsOpen);
ui->actionExportAsVCD->setEnabled(tabsOpen);
ui->actionMetrics->setEnabled(tabsOpen);
ui->actionClose->setEnabled(tabsOpen);
ui->actionClose_all->setEnabled(tabsOpen);
}
void TraceAnalyzer::closeTab(int index)
{
auto* traceFileTab = dynamic_cast<TraceFileTab*>(ui->traceFileTabs->widget(index));
if (traceFileTab->close())
{
openedTraceFiles.remove(traceFileTab->getPathToTraceFile());
ui->traceFileTabs->removeTab(index);
delete traceFileTab;
}
}
void TraceAnalyzer::on_traceFileTabs_tabCloseRequested(int index)
{
closeTab(index);
}
void TraceAnalyzer::on_actionClose_triggered()
{
closeTab(ui->traceFileTabs->currentIndex());
}
void TraceAnalyzer::on_actionClose_all_triggered()
{
for (unsigned int i = ui->traceFileTabs->count(); i--;)
closeTab(i);
statusLabel->clear();
}
void TraceAnalyzer::reloadTab(int index)
{
auto* traceFileTab = dynamic_cast<TraceFileTab*>(ui->traceFileTabs->widget(index));
QString traceFile = traceFileTab->getPathToTraceFile();
traceTime time = traceFileTab->getCurrentTraceTime();
traceTime zoomLevel = traceFileTab->getZoomLevel();
auto rootNode = traceFileTab->saveTraceSelectorState();
if (!traceFileTab->close())
return;
ui->traceFileTabs->removeTab(index);
delete traceFileTab;
traceFileTab = createTraceFileTab(traceFile);
traceFileTab->setZoomLevel(zoomLevel);
traceFileTab->navigateToTime(time);
traceFileTab->restoreTraceSelectorState(std::move(rootNode));
ui->traceFileTabs->insertTab(index, traceFileTab, QFileInfo(traceFile).baseName());
ui->traceFileTabs->setCurrentIndex(index);
}
void TraceAnalyzer::on_actionReload_triggered()
{
int index = ui->traceFileTabs->currentIndex();
reloadTab(index);
this->statusChanged(QString("Reloaded tab ") + QString::number(index) + " ");
}
void TraceAnalyzer::on_actionReload_all_triggered()
{
int index = ui->traceFileTabs->currentIndex();
for (unsigned int i = ui->traceFileTabs->count(); i--;)
reloadTab(i);
ui->traceFileTabs->setCurrentIndex(index);
this->statusChanged(QString("All databases reloaded "));
}
void TraceAnalyzer::on_actionSave_triggered()
{
auto* traceFileTab = dynamic_cast<TraceFileTab*>(ui->traceFileTabs->currentWidget());
traceFileTab->commitChangesToDB();
this->statusChanged(QString("Saved database ") +
QFileInfo(traceFileTab->getPathToTraceFile()).baseName() + " ");
}
void TraceAnalyzer::on_actionSave_all_triggered()
{
for (int index = 0; index < ui->traceFileTabs->count(); index++)
{
// Changes in the database files will trigger the file watchers from
// the TraceFileTab class. They generate signals connected to
// TraceAnalyzer::statusChanged().
auto* traceFileTab = dynamic_cast<TraceFileTab*>(ui->traceFileTabs->widget(index));
traceFileTab->commitChangesToDB();
}
}
void TraceAnalyzer::on_actionExportAsVCD_triggered()
{
#ifndef EXTENSION_ENABLED
showExtensionDisclaimerMessageBox();
return;
#endif
auto* traceFileTab = dynamic_cast<TraceFileTab*>(ui->traceFileTabs->currentWidget());
traceFileTab->exportAsVCD();
}
void TraceAnalyzer::statusChanged(const QString& message)
{
statusLabel->setText(message + QTime::currentTime().toString());
}
void TraceAnalyzer::on_actionMetrics_triggered()
{
#ifndef EXTENSION_ENABLED
showExtensionDisclaimerMessageBox();
return;
#endif
evaluationTool.raise();
evaluationTool.activateWindow();
evaluationTool.showAndEvaluateMetrics(openedTraceFiles.values());
}
void TraceAnalyzer::on_actionAbout_triggered()
{
QMessageBox::about(
this,
QStringLiteral("DRAMSys"),
QStringLiteral(
"<b>DRAMSys4.0</b> is a flexible DRAM subsystem design space exploration "
"framework based on SystemC "
"TLM-2.0. It was developed by the <a "
"href=\"https://ems.eit.uni-kl.de/en/start/\">Microelectronic Systems "
"Design Research Group</a>, by <a "
"href=\"https://www.iese.fraunhofer.de/en.html\">Fraunhofer IESE</a> and by the <a "
"href=\"https://www.informatik.uni-wuerzburg.de/ce\">Computer Engineering Group</a> at "
"<a href=\"https://www.uni-wuerzburg.de/en/home\">JMU Würzburg</a>."));
}
void TraceAnalyzer::closeEvent(QCloseEvent* event)
{
for (int i = 0; i < ui->traceFileTabs->count(); i++)
{
QWidget* tab = ui->traceFileTabs->widget(i);
if (!tab->close())
{
event->ignore();
return;
}
}
event->accept();
}

View File

@@ -0,0 +1,103 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
*/
#ifndef TRACEANALYZER_H
#define TRACEANALYZER_H
#include "evaluationtool.h"
#include <QLabel>
#include <QMainWindow>
#include <QSet>
#include <QString>
#include <vector>
namespace Ui
{
class TraceAnalyzer;
}
class TraceFileTab;
class TraceAnalyzer : public QMainWindow
{
Q_OBJECT
public:
explicit TraceAnalyzer(QWidget* parent = nullptr);
explicit TraceAnalyzer(QSet<QString> paths, QWidget* parent = nullptr);
~TraceAnalyzer();
void setUpStatusBar();
protected:
void closeEvent(QCloseEvent* event) override;
private:
TraceFileTab* createTraceFileTab(const QString& path);
void openTracefileTab(const QString& path);
void reloadTab(int index);
void closeTab(int index);
QLabel* statusLabel;
QSet<QString> openedTraceFiles;
EvaluationTool evaluationTool;
PythonCaller pythonCaller;
private Q_SLOTS:
void on_menuFile_aboutToShow();
void on_traceFileTabs_tabCloseRequested(int index);
void on_actionOpen_triggered();
void on_actionSave_triggered();
void on_actionSave_all_triggered();
void on_actionReload_triggered();
void on_actionReload_all_triggered();
void on_actionExportAsVCD_triggered();
void on_actionMetrics_triggered();
void on_actionClose_triggered();
void on_actionClose_all_triggered();
void on_actionAbout_triggered();
public Q_SLOTS:
void statusChanged(const QString& message);
private:
Ui::TraceAnalyzer* ui;
};
#endif // TRACEANALYZER_H

View File

@@ -0,0 +1,235 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TraceAnalyzer</class>
<widget class="QMainWindow" name="TraceAnalyzer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>Trace Analyzer</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTabWidget" name="traceFileTabs">
<property name="currentIndex">
<number>0</number>
</property>
<property name="documentMode">
<bool>false</bool>
</property>
<property name="tabsClosable">
<bool>true</bool>
</property>
<property name="movable">
<bool>true</bool>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Tab 1</string>
</attribute>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Tab 2</string>
</attribute>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>20</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>&amp;File</string>
</property>
<addaction name="actionOpen"/>
<addaction name="actionSave"/>
<addaction name="actionSave_all"/>
<addaction name="actionReload"/>
<addaction name="actionReload_all"/>
<addaction name="separator"/>
<addaction name="actionExportAsVCD"/>
<addaction name="separator"/>
<addaction name="actionMetrics"/>
<addaction name="separator"/>
<addaction name="actionClose"/>
<addaction name="actionClose_all"/>
<addaction name="separator"/>
<addaction name="actionQuit"/>
</widget>
<widget class="QMenu" name="menuHelp">
<property name="title">
<string>&amp;Help</string>
</property>
<addaction name="actionAbout"/>
<addaction name="actionAbout_Qt"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuHelp"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="actionOpen">
<property name="icon">
<iconset theme="document-open">
<normaloff>../../../../.designer/backup</normaloff>../../../../.designer/backup</iconset>
</property>
<property name="text">
<string>&amp;Open...</string>
</property>
<property name="shortcut">
<string>Ctrl+O</string>
</property>
</action>
<action name="actionReload">
<property name="icon">
<iconset theme="view-refresh">
<normaloff>../../../../.designer/backup</normaloff>../../../../.designer/backup</iconset>
</property>
<property name="text">
<string>&amp;Reload</string>
</property>
<property name="shortcut">
<string>Ctrl+R</string>
</property>
</action>
<action name="actionSave">
<property name="icon">
<iconset theme="document-save">
<normaloff>../../../../.designer/backup</normaloff>../../../../.designer/backup</iconset>
</property>
<property name="text">
<string>&amp;Save</string>
</property>
<property name="shortcut">
<string>Ctrl+S</string>
</property>
</action>
<action name="actionClose_all">
<property name="text">
<string>C&amp;lose all</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+W</string>
</property>
</action>
<action name="actionAbout">
<property name="text">
<string>&amp;About DRAMSys</string>
</property>
</action>
<action name="actionMetrics">
<property name="text">
<string>&amp;Metrics</string>
</property>
<property name="shortcut">
<string>Ctrl+M</string>
</property>
</action>
<action name="actionExportAsVCD">
<property name="icon">
<iconset theme="document-export">
<normaloff>../../../../.designer/backup</normaloff>../../../../.designer/backup</iconset>
</property>
<property name="text">
<string>Export as &amp;VCD...</string>
</property>
<property name="shortcut">
<string>Ctrl+V</string>
</property>
</action>
<action name="actionClose">
<property name="icon">
<iconset theme="document-close">
<normaloff>../../../../.designer/backup</normaloff>../../../../.designer/backup</iconset>
</property>
<property name="text">
<string>&amp;Close</string>
</property>
<property name="shortcut">
<string>Ctrl+W</string>
</property>
</action>
<action name="actionReload_all">
<property name="text">
<string>R&amp;eload all</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+R</string>
</property>
</action>
<action name="actionQuit">
<property name="icon">
<iconset theme="application-exit">
<normaloff>../../../../.designer/backup</normaloff>../../../../.designer/backup</iconset>
</property>
<property name="text">
<string>&amp;Quit</string>
</property>
<property name="shortcut">
<string>Ctrl+Q</string>
</property>
</action>
<action name="actionSave_all">
<property name="icon">
<iconset theme="document-save-all">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Save &amp;all</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+S</string>
</property>
</action>
<action name="actionSave_as">
<property name="icon">
<iconset theme="document-save-as">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Save &amp;as...</string>
</property>
</action>
<action name="actionAbout_Qt">
<property name="text">
<string>About &amp;Qt</string>
</property>
<property name="menuRole">
<enum>QAction::AboutQtRole</enum>
</property>
</action>
</widget>
<resources/>
<connections>
<connection>
<sender>actionQuit</sender>
<signal>triggered()</signal>
<receiver>TraceAnalyzer</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>299</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -0,0 +1,364 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
* Iron Prando da Silva
*/
#include "tracefiletab.h"
#include "businessObjects/pythoncaller.h"
#include "extensionDisclaimer.h"
#include <QFileDialog>
#include <QFileInfo>
#include <QMessageBox>
#include <QMouseEvent>
#include <qwt_plot_canvas.h>
#include <fstream>
TraceFileTab::TraceFileTab(std::string_view traceFilePath,
PythonCaller& pythonCaller,
QWidget* parent) :
QWidget(parent),
traceFilePath(traceFilePath),
ui(new Ui::TraceFileTab),
commentModel(new CommentModel(this)),
navigator(new TraceNavigator(traceFilePath.data(), commentModel, this)),
mcConfigModel(new McConfigModel(navigator->TraceFile(), this)),
memSpecModel(new MemSpecModel(navigator->TraceFile(), this)),
availableRowsModel(new AvailableTracePlotLineModel(navigator->GeneralTraceInfo(), this)),
selectedRowsModel(new SelectedTracePlotLineModel(navigator->GeneralTraceInfo(), this)),
tracePlotLineDataSource(new TracePlotLineDataSource(selectedRowsModel, this)),
#ifdef EXTENSION_ENABLED
depInfosView(new DependencyInfosModel(navigator->TraceFile(), this)),
#endif
pythonCaller(pythonCaller),
savingChangesToDB(false)
{
ui->setupUi(this);
std::cout << "Opening new tab for \"" << traceFilePath << "\"" << std::endl;
ui->mcConfigView->setModel(mcConfigModel);
ui->mcConfigView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
ui->memSpecView->setModel(memSpecModel);
ui->memSpecView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
#ifdef EXTENSION_ENABLED
ui->depInfosView->setModel(depInfosView);
ui->depInfosView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
#endif
setUpTraceSelector();
initNavigatorAndItsDependentWidgets();
setUpFileWatcher(traceFilePath.data());
setUpTraceplotScrollbar();
setUpCommentView();
#ifdef EXTENSION_ENABLED
setUpPossiblePhases();
#else
addDisclaimer();
#endif
tracefileChanged();
}
TraceFileTab::~TraceFileTab()
{
delete ui;
}
void TraceFileTab::commitChangesToDB()
{
savingChangesToDB = true;
navigator->commitChangesToDB();
}
void TraceFileTab::exportAsVCD()
{
std::string filename =
QFileDialog::getSaveFileName(this, "Export to VCD", "", "VCD files (*.vcd)").toStdString();
auto dump = PythonCaller::dumpVcd(traceFilePath);
std::ofstream file(filename);
file << dump;
Q_EMIT statusChanged(QString("VCD export finished."));
}
void TraceFileTab::setUpTraceSelector()
{
ui->availableTreeView->setModel(availableRowsModel);
ui->availableTreeView->setSelectionModel(availableRowsModel->selectionModel());
ui->availableTreeView->installEventFilter(availableRowsModel);
ui->selectedTreeView->setModel(selectedRowsModel);
ui->selectedTreeView->setSelectionModel(selectedRowsModel->selectionModel());
ui->selectedTreeView->installEventFilter(selectedRowsModel);
connect(availableRowsModel,
&AvailableTracePlotLineModel::returnPressed,
selectedRowsModel,
&SelectedTracePlotLineModel::addIndexesFromAvailableModel);
connect(ui->availableTreeView,
&QAbstractItemView::doubleClicked,
availableRowsModel,
&AvailableTracePlotLineModel::itemsDoubleClicked);
connect(ui->selectedTreeView,
&QAbstractItemView::doubleClicked,
selectedRowsModel,
&SelectedTracePlotLineModel::itemsDoubleClicked);
connect(selectedRowsModel,
&QAbstractItemModel::dataChanged,
tracePlotLineDataSource,
&TracePlotLineDataSource::updateModel);
connect(selectedRowsModel,
&QAbstractItemModel::rowsInserted,
tracePlotLineDataSource,
&TracePlotLineDataSource::updateModel);
connect(selectedRowsModel,
&QAbstractItemModel::rowsRemoved,
tracePlotLineDataSource,
&TracePlotLineDataSource::updateModel);
}
void TraceFileTab::setUpTraceplotScrollbar()
{
QObject::connect(ui->traceplotScrollbar,
SIGNAL(valueChanged(int)),
ui->traceplot,
SLOT(verticalScrollbarChanged(int)));
}
void TraceFileTab::initNavigatorAndItsDependentWidgets()
{
ui->traceplot->init(navigator, ui->traceplotScrollbar, tracePlotLineDataSource, commentModel);
ui->traceScroller->init(navigator, ui->traceplot, tracePlotLineDataSource);
connect(this,
SIGNAL(colorGroupingChanged(ColorGrouping)),
ui->traceScroller,
SLOT(colorGroupingChanged(ColorGrouping)));
ui->selectedTransactionTree->init(navigator);
// ui->debugMessages->init(navigator,ui->traceplot);
ui->bandwidthPlot->canvas()->installEventFilter(this);
ui->powerPlot->canvas()->installEventFilter(this);
ui->bufferPlot->canvas()->installEventFilter(this);
}
void TraceFileTab::setUpFileWatcher(QString path)
{
fileWatcher = new QFileSystemWatcher(QStringList(path), this);
QObject::connect(fileWatcher, SIGNAL(fileChanged(QString)), this, SLOT(tracefileChanged()));
}
void TraceFileTab::setUpCommentView()
{
ui->commentView->setModel(commentModel);
ui->commentView->setSelectionModel(commentModel->selectionModel());
ui->commentView->installEventFilter(commentModel);
ui->commentView->setContextMenuPolicy(Qt::CustomContextMenu);
QObject::connect(ui->commentView,
&QTableView::customContextMenuRequested,
commentModel,
&CommentModel::openContextMenu);
QObject::connect(commentModel,
&CommentModel::editTriggered,
ui->commentView,
[=](const QModelIndex& index)
{
ui->tabWidget->setCurrentWidget(ui->tabComments);
ui->commentView->edit(index);
ui->commentView->scrollTo(index);
});
QObject::connect(
ui->commentView, &QTableView::doubleClicked, commentModel, &CommentModel::rowDoubleClicked);
}
void TraceFileTab::addDisclaimer()
{
// Latency analysis
auto* latencyDisclaimerLabel = disclaimerLabel();
ui->latencyLayout->insertWidget(0, latencyDisclaimerLabel);
ui->latencyAnalysisProgressBar->setEnabled(false);
ui->startLatencyAnalysis->setEnabled(false);
ui->latencyPlot->setEnabled(false);
ui->latencyTreeView->setEnabled(false);
// Power analysis
auto* powerDisclaimerLabel = disclaimerLabel();
ui->powerLayout->insertWidget(0, powerDisclaimerLabel);
ui->startPowerAnalysis->setEnabled(false);
ui->powerBox->setEnabled(false);
ui->bandwidthBox->setEnabled(false);
ui->bufferBox->setEnabled(false);
// Dependencies
auto* dependenciesDisclaimerLabel = disclaimerLabel();
ui->verticalLayout_depInfos->insertWidget(0, dependenciesDisclaimerLabel);
ui->depInfoLabel->setEnabled(false);
ui->depInfosView->setEnabled(false);
ui->depTabPossiblePhases->setEnabled(false);
ui->calculateDependencies->setEnabled(false);
}
void TraceFileTab::tracefileChanged()
{
if (savingChangesToDB == true)
{
// Database has changed due to user action (e.g., saving comments).
// No need to disable the "Save changes to DB" menu.
savingChangesToDB = false;
Q_EMIT statusChanged(QString("Changes saved "));
}
else
{
// External event changed the database file (e.g., the database file
// was overwritten when running a new test).
// The "Save changes to DB" menu must be disabled to avoid saving
// changes to a corrupted or inconsistent file.
Q_EMIT statusChanged(QString("At least one database has changed on disk "));
}
navigator->refreshData();
}
void TraceFileTab::closeEvent(QCloseEvent* event)
{
if (navigator->existChangesToCommit())
{
QMessageBox saveDialog;
saveDialog.setWindowTitle(QFileInfo(traceFilePath.data()).baseName());
saveDialog.setText("The trace file has been modified.");
saveDialog.setInformativeText(
"Do you want to save your changes?<br><b>Unsaved changes will be lost.</b>");
saveDialog.setStandardButtons(QMessageBox::Save | QMessageBox::Discard |
QMessageBox::Cancel);
saveDialog.setDefaultButton(QMessageBox::Save);
saveDialog.setIcon(QMessageBox::Warning);
int returnCode = saveDialog.exec();
switch (returnCode)
{
case QMessageBox::Cancel:
event->ignore();
break;
case QMessageBox::Discard:
event->accept();
break;
case QMessageBox::Save:
commitChangesToDB();
event->accept();
break;
};
}
else
event->accept();
}
traceTime TraceFileTab::getCurrentTraceTime() const
{
return navigator->CurrentTraceTime();
}
void TraceFileTab::navigateToTime(traceTime time)
{
navigator->navigateToTime(time);
}
traceTime TraceFileTab::getZoomLevel() const
{
TracePlot* traceplot = static_cast<TracePlot*>(ui->traceplot);
return traceplot->ZoomLevel();
}
void TraceFileTab::setZoomLevel(traceTime zoomLevel)
{
TracePlot* traceplot = static_cast<TracePlot*>(ui->traceplot);
TraceScroller* tracescroller = static_cast<TraceScroller*>(ui->traceScroller);
traceplot->setZoomLevel(zoomLevel);
tracescroller->tracePlotZoomChanged();
}
std::shared_ptr<AbstractTracePlotLineModel::Node> TraceFileTab::saveTraceSelectorState() const
{
return selectedRowsModel->getClonedRootNode();
}
void TraceFileTab::restoreTraceSelectorState(
std::shared_ptr<AbstractTracePlotLineModel::Node> rootNode)
{
selectedRowsModel->setRootNode(std::move(rootNode));
}
bool TraceFileTab::eventFilter(QObject* object, QEvent* event)
{
if (auto canvas = qobject_cast<QwtPlotCanvas*>(object))
{
if (event->type() == QEvent::MouseButtonDblClick)
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() != Qt::LeftButton)
return false;
QwtPlot* plot = canvas->plot();
double realTime = plot->invTransform(QwtPlot::xBottom, mouseEvent->x());
// Convert from seconds to picoseconds
traceTime time = realTime * 1000 * 1000 * 1000 * 1000;
navigator->navigateToTime(time);
return true;
}
}
return QWidget::eventFilter(object, event);
}

View File

@@ -0,0 +1,147 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
* Iron Prando da Silva
*/
#ifndef TRACEFILETAB_H
#define TRACEFILETAB_H
#include "ui_tracefiletab.h"
#include "businessObjects/configmodels.h"
#ifdef EXTENSION_ENABLED
#include "businessObjects/dependencymodels.h"
#endif
#include "businessObjects/traceplotlinemodel.h"
#include "presentation/tracenavigator.h"
#include "presentation/traceplot.h"
#include "presentation/tracescroller.h"
#include <QFileSystemWatcher>
#include <QString>
#include <QTreeWidget>
#include <QWidget>
class CommentModel;
class McConfigModel;
class MemSpecModel;
class PythonCaller;
class TraceFileTab : public QWidget
{
Q_OBJECT
public:
explicit TraceFileTab(std::string_view traceFilePath,
PythonCaller& pythonCaller,
QWidget* parent);
~TraceFileTab();
void setUpFileWatcher(QString filename);
void setUpTraceplotScrollbar();
void setUpCommentView();
void setUpTraceSelector();
void addDisclaimer();
#ifdef EXTENSION_ENABLED
void setUpPossiblePhases();
#endif
void initNavigatorAndItsDependentWidgets();
QString getPathToTraceFile() { return traceFilePath.data(); }
void commitChangesToDB();
void exportAsVCD();
traceTime getCurrentTraceTime() const;
void navigateToTime(traceTime time);
traceTime getZoomLevel() const;
void setZoomLevel(traceTime zoomLevel);
std::shared_ptr<AbstractTracePlotLineModel::Node> saveTraceSelectorState() const;
void restoreTraceSelectorState(std::shared_ptr<AbstractTracePlotLineModel::Node> rootNode);
protected:
void closeEvent(QCloseEvent* event) override;
/**
* Used to respond to double click events in the analysis
* plots to navigate quickly to the corresponding tracetime.
* May be moved into a seperate class at a later point in time.
*/
bool eventFilter(QObject* object, QEvent* event) override;
private:
std::string traceFilePath;
Ui::TraceFileTab* ui;
QFileSystemWatcher* fileWatcher;
CommentModel* commentModel;
TraceNavigator* navigator;
McConfigModel* mcConfigModel;
MemSpecModel* memSpecModel;
AvailableTracePlotLineModel* availableRowsModel;
SelectedTracePlotLineModel* selectedRowsModel;
TracePlotLineDataSource* tracePlotLineDataSource;
#ifdef EXTENSION_ENABLED
QAbstractItemModel* depInfosView;
#endif
PythonCaller& pythonCaller;
void setUpQueryEditor(QString path);
bool savingChangesToDB;
public Q_SLOTS:
void tracefileChanged();
Q_SIGNALS:
void statusChanged(const QString& message);
void colorGroupingChanged(ColorGrouping colorgrouping);
private Q_SLOTS:
#ifdef EXTENSION_ENABLED
void on_latencyTreeView_doubleClicked(const QModelIndex& index);
void on_calculateDependencies_clicked();
void on_startLatencyAnalysis_clicked();
void on_startPowerAnalysis_clicked();
#endif
};
#endif // TRACEFILETAB_H

View File

@@ -0,0 +1,480 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TraceFileTab</class>
<widget class="QWidget" name="TraceFileTab">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1235</width>
<height>937</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QSplitter" name="splitter_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="baseSize">
<size>
<width>1000</width>
<height>0</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QSplitter" name="splitter">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QWidget" name="traceplotContainer" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>250</verstretch>
</sizepolicy>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="TracePlot" name="traceplot">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
</widget>
</item>
<item>
<widget class="QScrollBar" name="traceplotScrollbar">
<property name="enabled">
<bool>true</bool>
</property>
<property name="pageStep">
<number>25</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
<property name="invertedControls">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="TraceScroller" name="traceScroller">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>150</height>
</size>
</property>
</widget>
</widget>
<widget class="QTabWidget" name="tabWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>500</height>
</size>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tabSelectedTrans">
<attribute name="title">
<string>Selected Transaction</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="SelectedTransactionTreeWidget" name="selectedTransactionTree">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>3</horstretch>
<verstretch>3</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="itemsExpandable">
<bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
<property name="animated">
<bool>false</bool>
</property>
<property name="columnCount">
<number>0</number>
</property>
<attribute name="headerStretchLastSection">
<bool>true</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabSimConfig">
<attribute name="title">
<string>Configuration</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTableView" name="mcConfigView">
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="showGrid">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>
<widget class="QTreeView" name="memSpecView">
<property name="uniformRowHeights">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabCustomizePlot">
<attribute name="title">
<string>Customize Plot</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="customizePlotDescription">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;To customize the displayed rows double click or drag and drop items from the upper list to the lower list.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QTreeView" name="availableTreeView">
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragOnly</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="expandsOnDoubleClick">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QTreeView" name="selectedTreeView">
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragDrop</enum>
</property>
<property name="defaultDropAction">
<enum>Qt::MoveAction</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="expandsOnDoubleClick">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabComments">
<attribute name="title">
<string>Comments</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QTableView" name="commentView">
<property name="editTriggers">
<set>QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="gridStyle">
<enum>Qt::NoPen</enum>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabLatencyAnalysis">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Ignored">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<attribute name="title">
<string>Latency Analysis</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<layout class="QVBoxLayout" name="latencyLayout">
<item>
<widget class="QPushButton" name="startLatencyAnalysis">
<property name="text">
<string>Start Analysis</string>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="latencyAnalysisProgressBar">
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QwtPlot" name="latencyPlot">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>200</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QTreeView" name="latencyTreeView">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabPowerAnalysis">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Ignored">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="accessibleName">
<string/>
</property>
<attribute name="title">
<string>Power and Bandwidth Analysis</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
<item row="2" column="0">
<layout class="QVBoxLayout" name="powerLayout">
<item>
<widget class="QPushButton" name="startPowerAnalysis">
<property name="text">
<string>Start Analysis</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="powerBox">
<property name="title">
<string>Power:</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QwtPlot" name="powerPlot"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="bandwidthBox">
<property name="title">
<string>Bandwidth:</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QwtPlot" name="bandwidthPlot"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="bufferBox">
<property name="title">
<string>Buffer Analysis:</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QwtPlot" name="bufferPlot"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabDepInfos">
<attribute name="title">
<string>Dependency Information</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_depInfos">
<item>
<widget class="QLabel" name="depInfoLabel">
<property name="text">
<string>To display timing dependencies between transaction phases, select the respective phases and press &quot;Calculate Dependencies&quot;. The dependencies can now be displayed in the trace view using the context menu.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QTreeView" name="depInfosView">
<property name="uniformRowHeights">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="depTabPossiblePhases"/>
</item>
<item>
<widget class="QPushButton" name="calculateDependencies">
<property name="text">
<string>Calculate Dependencies</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QwtPlot</class>
<extends>QFrame</extends>
<header>qwt_plot.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>TracePlot</class>
<extends>QListView</extends>
<header>presentation/traceplot.h</header>
</customwidget>
<customwidget>
<class>TraceScroller</class>
<extends>QListView</extends>
<header>presentation/tracescroller.h</header>
</customwidget>
<customwidget>
<class>SelectedTransactionTreeWidget</class>
<extends>QTreeWidget</extends>
<header>presentation/selectedtransactiontreewidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>