You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/Tools/Standalone/Source/Driller/IO/StreamerDrillerDialog.cpp

1534 lines
57 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Woodpecker_precompiled.h"
#include "StreamerDrillerDialog.hxx"
#include <Woodpecker/Driller/IO/moc_StreamerDrillerDialog.cpp>
#include "StreamerDataAggregator.hxx"
#include "StreamerEvents.h"
#include <QtWidgets/QSizePolicy>
#include <AzToolsFramework/UI/UICore/QWidgetSavedState.h>
#include <AzCore/UserSettings/UserSettingsComponent.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <Woodpecker/Driller/Workspaces/Workspace.h>
#include <Woodpecker/Driller/IO/ui_StreamerDrillerDialog.h>
#include <QSortFilterProxyModel>
#include <QAction>
#include <QMenu>
#include <QClipboard>
namespace Driller
{
class StreamerDrillerDialogSavedState;
// NB: update StreamerDataView.hxx GetXxxxColumn() calls to return matching numbers to SDM_ enums
enum
{
SDM_NAME = 0,
SDM_DEBUG_NAME,
SDM_EVENT_TYPE,
SDM_OPERATION,
SDM_DELTA_TIME,
SDM_DATA_TRANSFER,
SDM_READ_SIZE,
SDM_OFFSET,
SDM_TOTAL
};
static const char* SDM_STRING[] = {
"Name",
"Debug Name",
"Event Type",
"Operation",
"uSec Used",
"Data Transfer",
"Read Size",
"Offset",
};
enum
{
VIEW_TYPE_THROUGHPUT = 0,
VIEW_TYPE_SEEKINFO
};
static const char* eventTypeToString[] =
{
"Show All Events",
"Device Mounted",
"Device UnMounted",
"Register Stream",
"UnRegister Stream",
"Cache Hit",
"Request Added",
"Request Canceled",
"Request Rescheduled",
"Request Completed",
"Operation Start",
"Operation Complete",
NULL
};
static const int eventTypeFromIndex[] = { -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
static const char* operationTypeToString[] =
{
"All Operations",
"Invalid",
"Read",
"Write",
"Compressor Read",
"Compressor Write",
NULL
};
static const int operationTypeFromIndex[] = { -1, 0, 1, 2, 3, 4 };
static const char* secondsToDisplayString[] =
{
"10 Seconds",
"15 Seconds",
"30 Seconds",
"60 Seconds",
NULL
};
static const int secondsFromIndex[] = { 10, 15, 30, 60, 0 };
static const char* tableLengthToDisplayString[] =
{
"All Events",
" 1K Events",
" 5K Events",
"10K Events",
"50K Events",
"Playback Start Relative",
NULL
};
static const int tableLengthFromIndex[] = { 0, 1000, 5000, 10000, 50000, -1, 0 };
static const char* chartTypeToDisplayString[] =
{
"Throughput",
"Seek Count",
NULL
};
static const int chartTypeFromIndex[] = { 0, 1 };
static const char* seekTypeToString[] =
{
"",
"Skip Position",
"Switch Streams",
NULL
};
class StreamerDrillerDialogLocal
: public AZ::UserSettings
{
public:
AZ_RTTI(StreamerDrillerDialogLocal, "{FBC1032F-A1DE-40CB-97E1-8C5014E31850}", AZ::UserSettings);
AZ_CLASS_ALLOCATOR(StreamerDrillerDialogLocal, AZ::SystemAllocator, 0);
AZStd::vector<AZ::u8> m_tableColumnStorage;
static void Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<StreamerDrillerDialogLocal>()
->Field("m_tableColumnStorage", &StreamerDrillerDialogLocal::m_tableColumnStorage)
->Version(1);
}
}
};
class StreamerDrillerDialogSavedState
: public AZ::UserSettings
{
public:
AZ_RTTI(StreamerDrillerDialogSavedState, "{F97F6145-10D6-4C7F-87DB-FD268EB0EF21}", AZ::UserSettings);
AZ_CLASS_ALLOCATOR(StreamerDrillerDialogSavedState, AZ::SystemAllocator, 0);
int m_viewType;
bool m_autoZoom;
float m_manualZoomMin; // if we're not automatically zooming, then we remember the prior zoom to re-apply it
float m_manualZoomMax;
int m_chartLengthInSeconds;
AZStd::string m_chartNameFilter;
int m_chartOperationFilter;
int m_chartEventFilter;
int m_tableEventLimiter;
FrameNumberType m_frameDeltaLock;
StreamerDrillerDialogSavedState()
{
m_viewType = VIEW_TYPE_THROUGHPUT;
m_autoZoom = true;
m_manualZoomMin = 2000000000.0f;
m_manualZoomMax = -2000000000.0f;
m_chartLengthInSeconds = 10;
// -1 := no filter and 0..n := filtered by type
m_chartOperationFilter = -1;
m_chartEventFilter = -1;
m_tableEventLimiter = 0;
m_frameDeltaLock = 0;
}
static void Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<StreamerDrillerDialogSavedState>()
->Field("m_viewType", &StreamerDrillerDialogSavedState::m_viewType)
->Field("m_autoZoom", &StreamerDrillerDialogSavedState::m_autoZoom)
->Field("m_manualZoomMin", &StreamerDrillerDialogSavedState::m_manualZoomMin)
->Field("m_manualZoomMax", &StreamerDrillerDialogSavedState::m_manualZoomMax)
->Field("m_chartLengthInSeconds", &StreamerDrillerDialogSavedState::m_chartLengthInSeconds)
->Field("m_chartNameFilter", &StreamerDrillerDialogSavedState::m_chartNameFilter)
->Field("m_chartOperationFilter", &StreamerDrillerDialogSavedState::m_chartOperationFilter)
->Field("m_chartEventFilter", &StreamerDrillerDialogSavedState::m_chartEventFilter)
->Field("m_tableEventLimiter", &StreamerDrillerDialogSavedState::m_tableEventLimiter)
->Field("m_frameDeltaLock", &StreamerDrillerDialogSavedState::m_frameDeltaLock)
->Version(8);
}
}
};
//////////////////////////////////////////////////////////////////////////
// Qt supports A "filter proxy model"
// you have a normal model
// and then you wrap that model in a filter proxy model.
// this allows you to filter the inner model and feed the outer (filtered) model to the view.
// this particular filter model lets you specify search criteria in the Window or the Message field
class StreamerFilterModel
: public QSortFilterProxyModel
{
public:
AZ_CLASS_ALLOCATOR(StreamerFilterModel, AZ::SystemAllocator, 0);
int m_nameColumn;
int m_eventColumn;
int m_operationColumn;
StreamerDataAggregator* m_dataSource;
QString m_currentNameFilter;
int m_currentEventFilter;
int m_currentOperationFilter;
FrameNumberType m_frameDeltaLock;
StreamerFilterModel(StreamerDataAggregator* dataSource, int nameColumn, int eventColumn, int operationColumn, QObject* pParent)
: QSortFilterProxyModel(pParent)
{
m_dataSource = dataSource;
m_nameColumn = nameColumn;
m_eventColumn = eventColumn;
m_operationColumn = operationColumn;
m_currentEventFilter = eventTypeFromIndex[0];
m_currentOperationFilter = operationTypeFromIndex[0];
m_frameDeltaLock = 0;
}
void InvalidateFilter()
{
invalidateFilter();
}
void SetDeltaLock(FrameNumberType lock)
{
m_frameDeltaLock = lock;
invalidateFilter();
}
void UpdateNameFilter(const QString& newFilter)
{
if (newFilter.compare(m_currentNameFilter) != 0)
{
if (m_nameColumn >= 0)
{
m_currentNameFilter = newFilter;
invalidateFilter();
}
}
}
void UpdateEventFilter(int newFilter)
{
if (newFilter != m_currentEventFilter)
{
if (m_eventColumn >= 0)
{
m_currentEventFilter = newFilter;
invalidateFilter();
}
}
}
void UpdateOperationFilter(int newFilter)
{
if (newFilter != m_currentOperationFilter)
{
if (m_operationColumn >= 0)
{
m_currentOperationFilter = newFilter;
invalidateFilter();
}
}
}
protected:
virtual bool filterAcceptsRow(int source_row, const QModelIndex& /*source parent*/) const
{
StreamerDrillerLogModel* ptrModel = static_cast<StreamerDrillerLogModel*>(sourceModel());
if (!ptrModel)
{
return true;
}
EventNumberType firstIndex = ptrModel->GetAggregator()->GetFirstIndexAtFrame(m_frameDeltaLock);
EventNumberType rowEventIndex = ptrModel->RowToGlobalEventIndex(source_row);
if (firstIndex == Driller::kInvalidEventIndex
|| rowEventIndex == Driller::kInvalidEventIndex
|| rowEventIndex < firstIndex)
{
return false;
}
AZ_Assert(rowEventIndex < static_cast<AZ::s64>(m_dataSource->GetEvents().size()), "EventIndex outside of Events vector size.");
auto pEvt = m_dataSource->GetEvents()[rowEventIndex];
if (m_currentNameFilter.size())
{
QString sourceName = ptrModel->data(source_row, m_nameColumn, Qt::DisplayRole).toString();
QString sourceDebugName = ptrModel->data(source_row, m_nameColumn + 1, Qt::DisplayRole).toString();
if (
(!sourceName.contains(m_currentNameFilter, Qt::CaseInsensitive))
&&
(!sourceDebugName.contains(m_currentNameFilter, Qt::CaseInsensitive))
)
{
return false;
}
}
if (m_currentEventFilter != eventTypeFromIndex[0])
{
if ((unsigned int)m_currentEventFilter != pEvt->GetEventType())
{
return false;
}
}
if (m_currentOperationFilter != operationTypeFromIndex[0])
{
if (pEvt->GetEventType() == Driller::Streamer::SET_OPERATION_COMPLETE)
{
auto completeOp = static_cast<StreamerOperationCompleteEvent*>(pEvt);
if (m_currentOperationFilter == completeOp->m_type)
{
return true;
}
}
return false;
}
return true;
}
};
//////////////////////////////////////////////////////////////////////////
StreamerAxisFormatter::StreamerAxisFormatter(QObject* pParent)
: QAbstractAxisFormatter(pParent)
{
m_dataType = DATA_TYPE_BYTES_PER_SECOND;
m_lastAxisValueForScaling = 1.0f;
}
QString StreamerAxisFormatter::formatMegabytes(float value)
{
// data is in Bytes per Second!
// so how big is the division size?
if (m_lastAxisValueForScaling > 499999.0f) // greater than half MB
{
return QObject::tr("%1Mb/s").arg(QString::number(value / 1000000.0f, 'f', 1));
}
else if (m_lastAxisValueForScaling > 1000.0f) // greater than one K
{
if (m_lastAxisValueForScaling > 1000.0f) // whole milliseconds
{
return QObject::tr("%1%2").arg(QString::number(value / 1000.0f, 'f', 0)).arg("Kb/s");
}
else
{
return QObject::tr("%1%2").arg(QString::number(value / 1000.0f, 'f', 1)).arg("Kb/s");
}
}
else if (m_lastAxisValueForScaling > 1.0f)
{
return QObject::tr("%1B/s").arg((int)value);
}
else
{
return QObject::tr("%1B/s").arg(QString::number((double)value, 'f', 2));
}
}
void StreamerAxisFormatter::SetDataType(int type)
{
m_dataType = type;
}
QString StreamerAxisFormatter::convertAxisValueToText(Charts::AxisType axis, float value, float /*minDisplayedValue*/, float /*maxDisplayedValue*/, float divisionSize)
{
if (axis == Charts::AxisType::Vertical)
{
m_lastAxisValueForScaling = divisionSize;
if (m_dataType == DATA_TYPE_BYTES_PER_SECOND)
{
return formatMegabytes(value);
}
else
{
return QObject::tr("%1%2").arg(QString::number(value, 'f', 0)).arg("/s");
}
}
else
{
return QString::number((int)value);
}
};
//////////////////////////////////////////////////////////////////////////
StreamerDrillerDialog::StreamerDrillerDialog(StreamerDataAggregator* aggregator, FrameNumberType atFrame, int profilerIndex)
: QDialog()
, m_aggregator(aggregator)
, m_frame(atFrame)
, m_viewIndex(profilerIndex)
, m_isDeltaLocked(false)
, frameModulo(10)
{
m_gui = azcreate(Ui::StreamerDrillerDialog, ());
m_gui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose, true);
setWindowFlags((this->windowFlags() | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint) & ~(Qt::WindowContextHelpButtonHint));
setWindowTitle(aggregator->GetDialogTitle());
show();
raise();
activateWindow();
setFocus();
m_axisFormatter = aznew StreamerAxisFormatter(this);
m_gui->widgetDataStrip->SetAxisTextFormatter(m_axisFormatter);
this->layout()->addWidget(m_gui->widgetTableView);
m_gui->widgetTableView->horizontalHeader()->setSectionsMovable(true);
m_gui->widgetTableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
m_gui->widgetTableView->horizontalHeader()->setStretchLastSection(false);
m_gui->widgetTableView->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
m_gui->widgetTableView->verticalHeader()->setStretchLastSection(false);
m_gui->widgetTableView->verticalHeader()->setSectionsMovable(false);
m_gui->widgetTableView->verticalHeader()->hide();
m_ptrOriginalModel = aznew StreamerDrillerLogModel(aggregator, this);
m_ptrFilter = aznew StreamerFilterModel(m_aggregator, m_gui->widgetTableView->GetNameColumn(), m_gui->widgetTableView->GetEventColumn(), m_gui->widgetTableView->GetOperationColumn(), this);
m_ptrFilter->setSourceModel(m_ptrOriginalModel);
m_gui->widgetTableView->setModel(m_ptrFilter);
// context menu
actionSelectAll = new QAction(tr("Select All"), this);
connect(actionSelectAll, SIGNAL(triggered()), this, SLOT(SelectAll()));
actionSelectNone = new QAction(tr("Select None"), this);
connect(actionSelectNone, SIGNAL(triggered()), this, SLOT(SelectNone()));
actionCopySelected = new QAction(tr("Copy Selected Row(s)"), this);
actionCopySelected->setShortcutContext(Qt::WidgetWithChildrenShortcut);
connect(actionCopySelected, SIGNAL(triggered()), this, SLOT(CopySelected()));
actionCopyAll = new QAction(tr("Copy All Rows"), this);
connect(actionCopyAll, SIGNAL(triggered()), this, SLOT(CopyAll()));
// context menu for the table
m_gui->widgetTableView->setContextMenuPolicy(Qt::ActionsContextMenu);
m_gui->widgetTableView->addAction(actionSelectAll);
m_gui->widgetTableView->addAction(actionSelectNone);
m_gui->widgetTableView->addAction(actionCopySelected);
m_gui->widgetTableView->addAction(actionCopyAll);
connect(aggregator, SIGNAL(destroyed(QObject*)), this, SLOT(OnDataDestroyed()));
connect(m_ptrFilter, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)), m_gui->widgetTableView, SLOT(rowsAboutToBeInserted()));
connect(m_ptrFilter, SIGNAL(rowsInserted(const QModelIndex &, int, int)), m_gui->widgetTableView, SLOT(rowsInserted()));
connect(m_gui->nameFilter, SIGNAL(textChanged(const QString &)), this, SLOT(onTextChangeWindowFilter(const QString&)));
connect(m_ptrFilter, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(UpdateSummary()));
connect(m_ptrFilter, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(UpdateSummary()));
connect(m_ptrFilter, SIGNAL(modelReset()), this, SLOT(UpdateSummary()));
connect(m_ptrOriginalModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(UpdateSummary()));
connect(m_ptrOriginalModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(UpdateSummary()));
connect(m_ptrOriginalModel, SIGNAL(modelReset()), this, SLOT(UpdateSummary()));
connect(m_gui->checkBoxAutoZoom, SIGNAL(toggled(bool)), this, SLOT(OnAutoZoomChange(bool)));
{
QMenu* eventMenu = new QMenu(this);
for (int i = 0; eventTypeToString[i]; ++i)
{
eventMenu->addAction(CreateEventFilterAction(eventTypeToString[i], eventTypeFromIndex[i]));
}
m_gui->eventTypeFilterButton->setText(eventTypeToString[0]);
m_gui->eventTypeFilterButton->setMenu(eventMenu);
}
{
QMenu* operationMenu = new QMenu(this);
for (int i = 0; operationTypeToString[i]; ++i)
{
operationMenu->addAction(CreateOperationFilterAction(operationTypeToString[i], operationTypeFromIndex[i]));
}
m_gui->operationTypeFilterButton->setText(operationTypeToString[0]);
m_gui->operationTypeFilterButton->setMenu(operationMenu);
}
{
QMenu* secondsMenu = new QMenu(this);
for (int i = 0; secondsToDisplayString[i]; ++i)
{
secondsMenu->addAction(CreateSecondsMenuAction(secondsToDisplayString[i], secondsFromIndex[i]));
}
m_gui->chartLengthButton->setText(secondsToDisplayString[0]);
m_gui->chartLengthButton->setMenu(secondsMenu);
}
{
QMenu* chartTypeMenu = new QMenu(this);
for (int i = 0; chartTypeToDisplayString[i]; ++i)
{
chartTypeMenu->addAction(CreateChartTypeMenuAction(chartTypeToDisplayString[i], chartTypeFromIndex[i]));
}
m_gui->chartTypeButton->setText(chartTypeToDisplayString[0]);
m_gui->chartTypeButton->setMenu(chartTypeMenu);
}
{
QMenu* tableLengthMenu = new QMenu(this);
for (int i = 0; tableLengthToDisplayString[i]; ++i)
{
tableLengthMenu->addAction(CreateTableLengthMenuAction(tableLengthToDisplayString[i], i));
}
m_gui->tableLengthButton->setText(tableLengthToDisplayString[0]);
m_gui->tableLengthButton->setMenu(tableLengthMenu);
}
DrillerMainWindowMessages::Handler::BusConnect(m_aggregator->GetIdentity());
DrillerEventWindowMessages::Handler::BusConnect(m_aggregator->GetIdentity());
AZStd::string windowStateStr = AZStd::string::format("STREAMER DATA VIEW WINDOW STATE %i", m_viewIndex);
m_windowStateCRC = AZ::Crc32(windowStateStr.c_str());
AZStd::intrusive_ptr<AzToolsFramework::QWidgetSavedState> windowState = AZ::UserSettings::Find<AzToolsFramework::QWidgetSavedState>(m_windowStateCRC, AZ::UserSettings::CT_GLOBAL);
if (windowState)
{
windowState->RestoreGeometry(this);
}
AZStd::string tableStateStr = AZStd::string::format("STREAMER TABLE VIEW STATE %i", m_viewIndex);
m_tableStateCRC = AZ::Crc32(tableStateStr.c_str());
auto tableState = AZ::UserSettings::Find<StreamerDrillerDialogLocal>(m_tableStateCRC, AZ::UserSettings::CT_GLOBAL);
if (tableState)
{
QByteArray treeData((const char*)tableState->m_tableColumnStorage.data(), (int)tableState->m_tableColumnStorage.size());
m_gui->widgetTableView->horizontalHeader()->restoreState(treeData);
}
AZStd::string dataViewStateStr = AZStd::string::format("STREAMER DATA VIEW STATE %i", m_viewIndex);
m_dataViewStateCRC = AZ::Crc32(dataViewStateStr.c_str());
m_persistentState = AZ::UserSettings::CreateFind<StreamerDrillerDialogSavedState>(m_dataViewStateCRC, AZ::UserSettings::CT_GLOBAL);
ApplyPersistentState();
FrameChanged(atFrame);
}
StreamerDrillerDialog::~StreamerDrillerDialog()
{
SaveOnExit();
azdestroy(m_gui);
}
QAction* StreamerDrillerDialog::CreateSecondsMenuAction(QString qs, int seconds)
{
QAction* act = new QAction(qs, this);
act->setObjectName(qs);
act->setProperty("Seconds", seconds);
connect(act, SIGNAL(triggered()), this, SLOT(OnSecondsMenu()));
return act;
}
QAction* StreamerDrillerDialog::CreateTableLengthMenuAction(QString qs, int limit)
{
QAction* act = new QAction(qs, this);
act->setObjectName(qs);
act->setProperty("Limit", limit);
connect(act, SIGNAL(triggered()), this, SLOT(OnTableLengthMenu()));
return act;
}
QAction* StreamerDrillerDialog::CreateChartTypeMenuAction(QString qs, int dataType)
{
QAction* act = new QAction(qs, this);
act->setObjectName(qs);
act->setProperty("DataType", dataType);
connect(act, SIGNAL(triggered()), this, SLOT(OnDataTypeMenu()));
return act;
}
QAction* StreamerDrillerDialog::CreateEventFilterAction(QString qs, int eventType)
{
QAction* act = new QAction(qs, this);
act->setObjectName(qs);
act->setProperty("EventType", eventType);
connect(act, SIGNAL(triggered()), this, SLOT(OnEventFilterMenu()));
return act;
}
QAction* StreamerDrillerDialog::CreateOperationFilterAction(QString qs, int operationType)
{
QAction* act = new QAction(qs, this);
act->setObjectName(qs);
act->setProperty("OperationType", operationType);
connect(act, SIGNAL(triggered()), this, SLOT(OnOperationFilterMenu()));
return act;
}
void StreamerDrillerDialog::SaveOnExit()
{
auto tableState = AZ::UserSettings::CreateFind<StreamerDrillerDialogLocal>(m_tableStateCRC, AZ::UserSettings::CT_GLOBAL);
if (tableState)
{
if (m_gui->widgetTableView && m_gui->widgetTableView->horizontalHeader())
{
QByteArray qba = m_gui->widgetTableView->horizontalHeader()->saveState();
tableState->m_tableColumnStorage.assign((AZ::u8*)qba.begin(), (AZ::u8*)qba.end());
}
}
auto pState = AZ::UserSettings::CreateFind<AzToolsFramework::QWidgetSavedState>(m_windowStateCRC, AZ::UserSettings::CT_GLOBAL);
if (m_persistentState)
{
pState->CaptureGeometry(this);
}
}
void StreamerDrillerDialog::hideEvent(QHideEvent* evt)
{
QDialog::hideEvent(evt);
}
void StreamerDrillerDialog::closeEvent(QCloseEvent* evt)
{
QDialog::closeEvent(evt);
}
void StreamerDrillerDialog::OnDataDestroyed()
{
deleteLater();
}
void StreamerDrillerDialog::onTextChangeWindowFilter(const QString& newText)
{
m_ptrFilter->UpdateNameFilter(newText);
m_persistentState->m_chartNameFilter = newText.toUtf8().data();
}
void StreamerDrillerDialog::OnEventFilterMenu()
{
QAction* qa = qobject_cast<QAction*>(sender());
if (qa)
{
m_gui->eventTypeFilterButton->setText(qa->objectName());
int eventType = qa->property("EventType").toInt();
m_ptrFilter->UpdateEventFilter(eventType);
m_persistentState->m_chartEventFilter = eventType;
}
}
void StreamerDrillerDialog::OnOperationFilterMenu()
{
QAction* qa = qobject_cast<QAction*>(sender());
if (qa)
{
m_gui->operationTypeFilterButton->setText(qa->objectName());
int operationType = qa->property("OperationType").toInt();
m_ptrFilter->UpdateOperationFilter(operationType);
m_persistentState->m_chartOperationFilter = operationType;
}
}
void StreamerDrillerDialog::OnSecondsMenu()
{
QAction* qa = qobject_cast<QAction*>(sender());
if (qa)
{
m_gui->chartLengthButton->setText(qa->objectName());
int seconds = qa->property("Seconds").toInt();
SetChartLength(seconds);
}
}
void StreamerDrillerDialog::OnTableLengthMenu()
{
QAction* qa = qobject_cast<QAction*>(sender());
if (qa)
{
int limit = qa->property("Limit").toInt();
OnTableLengthMenu(limit);
}
}
void StreamerDrillerDialog::OnTableLengthMenu(int limit)
{
if (tableLengthFromIndex[limit] >= 0)
{
m_gui->tableLengthButton->setText(tableLengthToDisplayString[limit]);
m_persistentState->m_tableEventLimiter = limit;
m_isDeltaLocked = false;
SetTableLengthLimit(tableLengthFromIndex[limit]);
m_ptrFilter->SetDeltaLock(0);
}
else
{
m_gui->tableLengthButton->setText(QString("Delta:%1").arg(m_frame));
m_isDeltaLocked = true;
m_ptrFilter->SetDeltaLock(m_persistentState->m_frameDeltaLock);
}
BuildChart(m_frame, m_persistentState->m_viewType, m_persistentState->m_chartLengthInSeconds);
}
void StreamerDrillerDialog::OnDataTypeMenu()
{
QAction* qa = qobject_cast<QAction*>(sender());
if (qa)
{
OnDataTypeMenu(qa->property("DataType").toInt());
}
}
void StreamerDrillerDialog::OnDataTypeMenu(int type)
{
m_gui->chartTypeButton->setText(chartTypeToDisplayString[type]);
m_persistentState->m_viewType = type;
SetChartType(type);
m_axisFormatter->SetDataType(type);
}
void StreamerDrillerDialog::OnAutoZoomChange(bool newValue)
{
if (!newValue)
{
m_persistentState->m_autoZoom = false;
m_gui->widgetDataStrip->GetWindowRange(Charts::AxisType::Vertical, m_persistentState->m_manualZoomMin, m_persistentState->m_manualZoomMax);
}
else
{
m_persistentState->m_autoZoom = true;
m_persistentState->m_manualZoomMin = 2000000000.0f;
m_persistentState->m_manualZoomMax = -2000000000.0f;
}
BuildChart(m_frame, m_persistentState->m_viewType, m_persistentState->m_chartLengthInSeconds);
}
void StreamerDrillerDialog::SetChartLength(int newLength)
{
m_persistentState->m_chartLengthInSeconds = newLength;
BuildChart(m_frame, m_persistentState->m_viewType, newLength);
}
void StreamerDrillerDialog::SetChartType(int newType)
{
BuildChart(m_frame, newType, m_persistentState->m_chartLengthInSeconds);
}
void StreamerDrillerDialog::SetTableLengthLimit(int limit)
{
m_ptrOriginalModel->SetLengthLimit(limit);
m_ptrFilter->InvalidateFilter();
}
int StreamerDrillerDialog::GetViewType()
{
return m_persistentState->m_viewType;
}
// Backing code to the context menu
void StreamerDrillerDialog::SelectAll()
{
m_gui->widgetTableView->selectAll();
}
void StreamerDrillerDialog::SelectNone()
{
m_gui->widgetTableView->clearSelection();
}
QString StreamerDrillerDialog::ConvertRowToText(const QModelIndex& row)
{
auto pModel = m_ptrFilter;
if (!pModel)
{
return QString();
}
int columnCount = pModel->columnCount();
QString finalString = "";
QModelIndex sourceRow = m_ptrFilter->mapToSource(row);
for (int column = 0; column < columnCount; ++column)
{
QString displayString = m_ptrOriginalModel->data(sourceRow.row(), column, Qt::DisplayRole).toString();
if ((column != 0) && (finalString.length() > 0))
{
finalString += "; ";
}
if (displayString.length())
{
finalString += displayString.toUtf8().data();
}
else
{
// must enforce some length even on empty strings in the table
// so that comma-delimiters output properly
finalString += " ";
}
}
finalString += "\n";
return finalString;
}
void StreamerDrillerDialog::CopySelected()
{
auto pModel = m_ptrFilter;
if (!pModel)
{
return;
}
AZStd::string accumulator;
QItemSelectionModel* selectionModel = m_gui->widgetTableView->selectionModel();
QModelIndexList indices = selectionModel->selectedRows();
for (QModelIndexList::iterator iter = indices.begin(); iter != indices.end(); ++iter)
{
QString res = this->ConvertRowToText(*iter);
accumulator += res.toUtf8().data();
}
if (accumulator.size())
{
QClipboard* clipboard = QApplication::clipboard();
if (clipboard)
{
clipboard->setText(accumulator.c_str());
}
}
}
void StreamerDrillerDialog::CopyAll()
{
auto pModel = m_ptrFilter;
if (!pModel)
{
return;
}
QString finalString = "";
int numRows = pModel->rowCount();
for (int rowIdx = 0; rowIdx < numRows; ++rowIdx)
{
QModelIndex idx = pModel->index(rowIdx, 0);
finalString += this->ConvertRowToText(idx);
}
QClipboard* clipboard = QApplication::clipboard();
if (clipboard)
{
clipboard->setText(finalString);
}
}
void StreamerDrillerDialog::ApplyPersistentState()
{
onTextChangeWindowFilter(m_persistentState->m_chartNameFilter.c_str());
OnDataTypeMenu(m_persistentState->m_viewType);
m_gui->tableLengthButton->setText(tableLengthToDisplayString[m_persistentState->m_tableEventLimiter]);
SetTableLengthLimit(tableLengthFromIndex[m_persistentState->m_tableEventLimiter]);
if (m_isDeltaLocked)
{
m_gui->tableLengthButton->setText(QString("Delta:%1").arg(m_persistentState->m_frameDeltaLock));
m_ptrFilter->SetDeltaLock(m_persistentState->m_frameDeltaLock);
}
else
{
m_ptrFilter->SetDeltaLock(0);
}
m_gui->checkBoxAutoZoom->setChecked(m_persistentState->m_autoZoom);
OnAutoZoomChange(m_persistentState->m_autoZoom);
for (int i = 0; secondsFromIndex[i]; ++i)
{
if (m_persistentState->m_chartLengthInSeconds == secondsFromIndex[i])
{
m_gui->chartLengthButton->setText(secondsToDisplayString[i]);
break;
}
}
BuildChart(m_frame, m_persistentState->m_viewType, m_persistentState->m_chartLengthInSeconds); // full seconds, 60 frames per entry on the chart, modulo even seconds
UpdateSummary();
}
void StreamerDrillerDialog::ApplySettingsFromWorkspace(WorkspaceSettingsProvider* provider)
{
AZStd::string workspaceStateStr = AZStd::string::format("STREAMER DATA VIEW WORKSPACE STATE %i", m_viewIndex);
AZ::u32 workspaceStateCRC = AZ::Crc32(workspaceStateStr.c_str());
StreamerDrillerDialogSavedState* workspace = provider->FindSetting<StreamerDrillerDialogSavedState>(workspaceStateCRC);
if (workspace)
{
*m_persistentState = *workspace;
}
}
void StreamerDrillerDialog::ActivateWorkspaceSettings(WorkspaceSettingsProvider*)
{
ApplyPersistentState();
}
void StreamerDrillerDialog::FrameChanged(FrameNumberType frame)
{
m_frame = frame;
BuildChart(m_frame, m_persistentState->m_viewType, m_persistentState->m_chartLengthInSeconds); // full seconds, 60 frames per entry on the chart, modulo even seconds
}
void StreamerDrillerDialog::PlaybackLoopBeginChanged(FrameNumberType frame)
{
m_persistentState->m_frameDeltaLock = frame;
FrameNumberType lockedFrame = m_isDeltaLocked ? m_persistentState->m_frameDeltaLock : 0;
m_ptrFilter->SetDeltaLock(lockedFrame);
BuildChart(m_frame, m_persistentState->m_viewType, m_persistentState->m_chartLengthInSeconds); // full seconds, 60 frames per entry on the chart, modulo even seconds
}
void StreamerDrillerDialog::BuildChart(FrameNumberType atFrame, int viewType, int howFar)
{
BuildAllLabels(atFrame, viewType);
FrameNumberType lockedFrame = m_isDeltaLocked ? m_persistentState->m_frameDeltaLock : 0;
const char* vAxisLabel[] = {"Transfer", "Seek"};
m_gui->widgetDataStrip->Reset();
FrameNumberType flooredFrame = (atFrame + frameModulo - 1) / frameModulo;
float calculatedFrame = (float)(flooredFrame - howFar >= 0 ? flooredFrame - howFar : 0);
m_gui->widgetDataStrip->AddAxis("Time", calculatedFrame, (float)calculatedFrame + howFar, true, true);
m_gui->widgetDataStrip->AddAxis(vAxisLabel[viewType], m_persistentState->m_manualZoomMin, m_persistentState->m_manualZoomMax, false, false);
int channelID = m_gui->widgetDataStrip->AddChannel("ThroughputOrSeeks");
m_gui->widgetDataStrip->SetChannelStyle(channelID, StripChart::Channel::STYLE_CONNECTED_LINE);
m_gui->widgetDataStrip->SetChannelColor(channelID, Qt::green);
FrameNumberType currentFrame = atFrame - (atFrame % frameModulo) - 1;
float accumulator = 0;
while (howFar > 0 && currentFrame >= (lockedFrame - frameModulo))
{
FrameNumberType displayFrame = currentFrame;
float thisSecond = 0.0f;
if (viewType == VIEW_TYPE_THROUGHPUT)
{
while ((currentFrame % frameModulo) && (currentFrame >= 0))
{
thisSecond += m_aggregator->ThroughputAtFrame(currentFrame);
accumulator += m_aggregator->ThroughputAtFrame(currentFrame);
--currentFrame;
}
;
thisSecond += m_aggregator->ThroughputAtFrame(currentFrame);
accumulator += m_aggregator->ThroughputAtFrame(currentFrame);
}
else if (viewType == VIEW_TYPE_SEEKINFO)
{
while ((currentFrame % frameModulo) && (currentFrame >= 0))
{
thisSecond += m_aggregator->SeeksAtFrame(currentFrame);
accumulator += m_aggregator->SeeksAtFrame(currentFrame);
--currentFrame;
}
;
thisSecond += m_aggregator->SeeksAtFrame(currentFrame);
accumulator += m_aggregator->SeeksAtFrame(currentFrame);
}
m_gui->widgetDataStrip->AddData(channelID, displayFrame / frameModulo, (float)displayFrame / (float)frameModulo, thisSecond * (60.0f / (float)frameModulo));
--currentFrame;
--howFar;
}
if (m_persistentState->m_autoZoom)
{
m_gui->widgetDataStrip->ZoomExtents(Charts::AxisType::Vertical);
}
else
{
m_gui->widgetDataStrip->ZoomManual(Charts::AxisType::Vertical, m_persistentState->m_manualZoomMin, m_persistentState->m_manualZoomMax);
}
}
void StreamerDrillerDialog::BuildAllLabels(FrameNumberType atFrame, int viewType)
{
FrameNumberType currentFrame = atFrame;
float accumulateDelta = 0;
FrameNumberType lockedFrame = m_isDeltaLocked ? m_persistentState->m_frameDeltaLock : 0;
while (currentFrame >= lockedFrame)
{
if (viewType == VIEW_TYPE_THROUGHPUT)
{
accumulateDelta += m_aggregator->ThroughputAtFrame(currentFrame);
}
else if (viewType == VIEW_TYPE_SEEKINFO)
{
accumulateDelta += m_aggregator->SeeksAtFrame(currentFrame);
}
--currentFrame;
}
QString deltaString = UpdateDeltaLabel(accumulateDelta);
float accumulateTime = float(atFrame - lockedFrame + 1) / 60.0f;
QString timeString = QString("T=%1s").arg(QString::number(accumulateTime, 'f', 1));
float accumulateAverage = 0.0f;
if (atFrame >= lockedFrame)
{
if (viewType == VIEW_TYPE_THROUGHPUT)
{
accumulateAverage = m_aggregator->ThroughputAtFrame(atFrame);
}
else if (viewType == VIEW_TYPE_SEEKINFO)
{
accumulateAverage = m_aggregator->SeeksAtFrame(atFrame);
}
}
QString averageString = UpdateAverageLabel(accumulateAverage);
QString eventsString = UpdateSummary();
QString finalString = eventsString + QString(" ") + deltaString + QString(" ") + averageString + QString(" ") + timeString;
m_gui->summaryLabel->setText(finalString);
m_gui->summaryLabel->update();
}
QString StreamerDrillerDialog::UpdateSummary()
{
int filterRows = m_ptrFilter->rowCount();
int originalRows = m_ptrOriginalModel->rowCount();
return QString("[%1 / %2]").arg(filterRows).arg(originalRows);
}
QString StreamerDrillerDialog::UpdateDeltaLabel(float accumulator)
{
if (m_persistentState->m_viewType == VIEW_TYPE_THROUGHPUT)
{
QString formattedBytes = FormatMegabytes(accumulator);
return QString("Data=%1").arg(formattedBytes);
}
else
{
return QString("Seek=%1").arg(QString::number(accumulator, 'f', 0));
}
}
QString StreamerDrillerDialog::UpdateAverageLabel(float accumulator)
{
if (m_persistentState->m_viewType == VIEW_TYPE_THROUGHPUT)
{
QString formattedBytes = FormatMegabytes(accumulator);
return QString("Now=%1").arg(formattedBytes);
}
else
{
return QString("Seek=%1").arg(QString::number(accumulator, 'f', 0));
}
}
QString StreamerDrillerDialog::FormatMegabytes(float value)
{
// data is in Bytes
// so how big is the division size?
if (value > 499999.0f) // greater than half MB
{
return QObject::tr("%1Mb").arg(QString::number(value / 1000000.0f, 'f', 1));
}
else if (value > 1000.0f) // greater than one K
{
if (value > 1000.0f) // whole milliseconds
{
return QObject::tr("%1%2").arg(QString::number(value / 1000.0f, 'f', 0)).arg("Kb");
}
else
{
return QObject::tr("%1%2").arg(QString::number(value / 1000.0f, 'f', 1)).arg("Kb");
}
}
else if (value > 1.0f)
{
return QObject::tr("%1B").arg((int)value);
}
else
{
return QObject::tr("%1B").arg(QString::number((double)value, 'f', 2));
}
}
void StreamerDrillerDialog::EventFocusChanged(EventNumberType /*eventIdx*/)
{
}
void StreamerDrillerDialog::SaveSettingsToWorkspace(WorkspaceSettingsProvider* provider)
{
AZStd::string workspaceStateStr = AZStd::string::format("STREAMER DATA VIEW WORKSPACE STATE %i", m_viewIndex);
AZ::u32 workspaceStateCRC = AZ::Crc32(workspaceStateStr.c_str());
{
StreamerDrillerDialogSavedState* workspace = provider->CreateSetting<StreamerDrillerDialogSavedState>(workspaceStateCRC);
if (workspace)
{
*workspace = *m_persistentState;
}
}
}
void StreamerDrillerDialog::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
StreamerDrillerDialogSavedState::Reflect(context);
StreamerDrillerDialogLocal::Reflect(context);
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// StreamerDrillerLogModel
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
StreamerDrillerLogModel::StreamerDrillerLogModel(StreamerDataAggregator* data, QObject* pParent)
: QAbstractTableModel(pParent)
, m_data(data)
, m_lastShownEvent(-1)
, m_lengthLimit(0)
{
connect(data, SIGNAL(OnDataCurrentEventChanged()), this, SLOT(OnDataCurrentEventChanged()));
connect(data, SIGNAL(OnDataAddEvent()), this, SLOT(OnDataAddEvent()));
m_lastShownEvent = m_data->GetCurrentEvent();
}
StreamerDrillerLogModel::~StreamerDrillerLogModel()
{
}
void StreamerDrillerLogModel::OnDataCurrentEventChanged()
{
// real source data changes operate in real space, not the window of the length limited
int limitStore = m_lengthLimit;
SetLengthLimit(0);
AZ::s64 currentEvent = m_data->GetCurrentEvent();
// NOTE: we add +1 to all events, because we are EXECUTING the current event (so it must be shown)
if (m_lastShownEvent > currentEvent)
{
// remove rows
beginRemoveRows(QModelIndex(), (int)currentEvent + 1, (int)m_lastShownEvent);
endRemoveRows();
}
else if (m_lastShownEvent < currentEvent)
{
// add rows
beginInsertRows(QModelIndex(), (int)m_lastShownEvent + 1, (int)currentEvent);
endInsertRows();
}
m_lastShownEvent = currentEvent;
SetLengthLimit(limitStore);
}
void StreamerDrillerLogModel::OnDataAddEvent()
{
}
void StreamerDrillerLogModel::SetLengthLimit(int limit)
{
beginResetModel();
m_lengthLimit = limit;
endResetModel();
}
int StreamerDrillerLogModel::rowCount(const QModelIndex&) const
{
AZ::s64 currentEvent = m_data->GetCurrentEvent();
if (m_lengthLimit && (m_lengthLimit < (currentEvent + 1)))
{
return m_lengthLimit;
}
return (int)currentEvent + 1;
}
int StreamerDrillerLogModel::columnCount(const QModelIndex&) const
{
return SDM_TOTAL;
}
Qt::ItemFlags StreamerDrillerLogModel::flags(const QModelIndex& index) const
{
if (!index.isValid())
{
return Qt::ItemIsEnabled;
}
return QAbstractItemModel::flags(index);
}
QVariant StreamerDrillerLogModel::headerData (int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole)
{
if (orientation == Qt::Horizontal)
{
return QVariant(SDM_STRING[section]);
}
// purposefully ignoring the ::Vertical orientation as part of an optimiztion
}
return QVariant();
}
EventNumberType StreamerDrillerLogModel::RowToGlobalEventIndex(int row)
{
EventNumberType currentEvent = m_data->GetCurrentEvent();
if (m_lengthLimit && (m_lengthLimit < (currentEvent + 1)))
{
row = row + (int)currentEvent - m_lengthLimit + 1;
}
return row;
}
QVariant StreamerDrillerLogModel::data(const QModelIndex& index, int role) const
{
return data(index.row(), index.column(), role);
}
QVariant StreamerDrillerLogModel::data(int row, int column, int role) const
{
AZ::s64 currentEvent = m_data->GetCurrentEvent();
if (m_lengthLimit && (m_lengthLimit < (currentEvent + 1)))
{
row = row + (int)currentEvent - m_lengthLimit + 1;
}
return data(m_data->GetEvents()[row], row, column, role);
}
QVariant StreamerDrillerLogModel::data(DrillerEvent* event, int row, int column, int role) const
{
using namespace AZ::Debug;
const bool dummyCompressedFlag = false; // placeholder until set from stream info
if (role == Qt::DisplayRole)
{
// COLUMN -------------------------------------------------------------
if (column == SDM_NAME)
{
switch (event->GetEventType())
{
case Driller::Streamer::SET_DEVICE_MOUNTED:
{
return QVariant(QString(static_cast<StreamerMountDeviceEvent*>(event)->m_deviceData.m_name));
break;
}
case Driller::Streamer::SET_DEVICE_UNMOUNTED:
{
return QVariant(QString(static_cast<StreamerUnmountDeviceEvent*>(event)->m_unmountedDeviceData->m_name));
break;
}
case Driller::Streamer::SET_REGISTER_STREAM:
{
return QVariant(QString(static_cast<StreamerRegisterStreamEvent*>(event)->m_streamData.m_name));
break;
}
case Driller::Streamer::SET_UNREGISTER_STREAM:
{
auto depEvt = static_cast<StreamerUnregisterStreamEvent*>(event);
if (depEvt && depEvt->m_removedStreamData)
{
return QVariant(QString(depEvt->m_removedStreamData->m_name));
}
return QVariant(QString(m_data->GetFilenameFromStreamId(row, depEvt->m_streamId)));
break;
}
case Driller::Streamer::SET_ADD_REQUEST:
{
auto depEvt = static_cast<StreamerAddRequestEvent*>(event);
return QVariant(QString(m_data->GetFilenameFromStreamId(row, depEvt->m_requestData.m_streamId)));
break;
}
case Driller::Streamer::SET_CANCEL_REQUEST:
{
return QVariant(QString(m_data->GetFilenameFromStreamId(row, static_cast<StreamerCancelRequestEvent*>(event)->m_cancelledRequestData->m_streamId)));
break;
}
case Driller::Streamer::SET_RESCHEDULE_REQUEST:
{
return QVariant(QString(m_data->GetFilenameFromStreamId(row, static_cast<StreamerRescheduleRequestEvent*>(event)->m_rescheduledRequestData->m_streamId)));
break;
}
case Driller::Streamer::SET_COMPLETE_REQUEST:
{
auto depEvt = static_cast<StreamerCompleteRequestEvent*>(event);
return QVariant(QString(m_data->GetFilenameFromStreamId(row, depEvt->m_removedRequest->m_streamId)));
break;
}
case Driller::Streamer::SET_OPERATION_START:
{
auto depEvt = static_cast<StreamerOperationStartEvent*>(event);
return QVariant(QString("%1").arg(m_data->GetFilenameFromStreamId(row, depEvt->m_streamId)));
break;
}
case Driller::Streamer::SET_OPERATION_COMPLETE:
{
auto depEvt = static_cast<StreamerOperationCompleteEvent*>(event);
return QVariant(QString("%1").arg(m_data->GetFilenameFromStreamId(row, depEvt->m_streamId)));
break;
}
}
}
// COLUMN -------------------------------------------------------------
if (column == SDM_DEBUG_NAME)
{
switch (event->GetEventType())
{
case Driller::Streamer::SET_ADD_REQUEST:
{
auto depEvt = static_cast<StreamerAddRequestEvent*>(event);
if (depEvt->m_requestData.m_debugName)
{
return QVariant(QString(depEvt->m_requestData.m_debugName));
}
break;
}
case Driller::Streamer::SET_CANCEL_REQUEST:
{
return QVariant(QString(static_cast<StreamerCancelRequestEvent*>(event)->m_cancelledRequestData->m_debugName));
break;
}
case Driller::Streamer::SET_RESCHEDULE_REQUEST:
{
return QVariant(QString(static_cast<StreamerRescheduleRequestEvent*>(event)->m_rescheduledRequestData->m_debugName));
break;
}
case Driller::Streamer::SET_COMPLETE_REQUEST:
{
auto depEvt = static_cast<StreamerCompleteRequestEvent*>(event);
if (depEvt->m_removedRequest->m_debugName)
{
return QVariant(QString(depEvt->m_removedRequest->m_debugName));
}
break;
}
case Driller::Streamer::SET_OPERATION_START:
{
auto depEvt = static_cast<StreamerOperationStartEvent*>(event);
return QVariant(QString("%1").arg(m_data->GetDebugNameFromStreamId(row, depEvt->m_streamId)));
break;
}
case Driller::Streamer::SET_OPERATION_COMPLETE:
{
auto depEvt = static_cast<StreamerOperationCompleteEvent*>(event);
return QVariant(QString("%1").arg(m_data->GetDebugNameFromStreamId(row, depEvt->m_streamId)));
break;
}
}
}
// COLUMN -------------------------------------------------------------
else if (column == SDM_EVENT_TYPE)
{
return QVariant(QString(eventTypeToString[ event->GetEventType() + 1 ]));
}
// COLUMN -------------------------------------------------------------
else if (column == SDM_OPERATION)
{
switch (event->GetEventType())
{
case Driller::Streamer::SET_OPERATION_COMPLETE:
{
return QVariant(QString(operationTypeToString[ static_cast<StreamerOperationCompleteEvent*>(event)->m_type + 1 ]));
break;
}
}
}
// COLUMN -------------------------------------------------------------
else if (column == SDM_DELTA_TIME)
{
switch (event->GetEventType())
{
case Driller::Streamer::SET_OPERATION_START:
{
auto depEvt = static_cast<StreamerOperationStartEvent*>(event);
StreamerDataAggregator::SeekEventType seekType = m_data->GetSeekType(depEvt->GetGlobalEventId());
QString seekNotice = seekTypeToString[seekType];
return QVariant(QString("%1").arg(seekNotice));
break;
}
case Driller::Streamer::SET_ADD_REQUEST:
{
// this is a delta between this new request and a previous completion
// useful to determine slack time in incoming request sequences
auto depEvt = static_cast<StreamerAddRequestEvent*>(event);
int backtrackRow = row - 1;
while (backtrackRow >= 0)
{
DrillerEvent* pastEvent = m_data->GetEvents()[backtrackRow];
if (pastEvent->GetEventType() == Driller::Streamer::SET_COMPLETE_REQUEST)
{
auto olderRequest = static_cast<StreamerCompleteRequestEvent*>(pastEvent);
return QVariant(QString("%L1").arg(depEvt->m_timeStamp - olderRequest->m_timeStamp));
}
--backtrackRow;
}
break;
}
case Driller::Streamer::SET_COMPLETE_REQUEST:
{
auto thisEvent = static_cast<StreamerCompleteRequestEvent*>(event);
int backtrackRow = row - 1;
while (backtrackRow >= 0)
{
DrillerEvent* pastEvent = m_data->GetEvents()[backtrackRow];
if (pastEvent->GetEventType() == Driller::Streamer::SET_ADD_REQUEST)
{
auto originalRequest = static_cast<StreamerAddRequestEvent*>(pastEvent);
if (thisEvent->m_requestId == originalRequest->m_requestData.m_id)
{
return QVariant(QString("%L1").arg(thisEvent->m_timeStamp - originalRequest->m_timeStamp));
}
}
--backtrackRow;
}
break;
}
case Driller::Streamer::SET_OPERATION_COMPLETE:
{
auto thisEvent = static_cast<StreamerOperationCompleteEvent*>(event);
int backtrackRow = row - 1;
while (backtrackRow >= 0)
{
DrillerEvent* pastEvent = m_data->GetEvents()[backtrackRow];
if (pastEvent->GetEventType() == Driller::Streamer::SET_OPERATION_START)
{
auto originalOperation = static_cast<StreamerOperationStartEvent*>(pastEvent);
if (thisEvent->m_streamId == originalOperation->m_streamId)
{
return QVariant(QString("%L1").arg(thisEvent->m_timeStamp - originalOperation->m_timeStamp));
}
}
--backtrackRow;
}
break;
}
}
}
// COLUMN -------------------------------------------------------------
else if (column == SDM_DATA_TRANSFER)
{
switch (event->GetEventType())
{
case Driller::Streamer::SET_OPERATION_COMPLETE:
{
auto socEvent = static_cast<StreamerOperationCompleteEvent*>(event);
if (dummyCompressedFlag)
{
if (static_cast<StreamerDataAggregator::TransferEventType>(socEvent->m_type) == StreamerDataAggregator::TRANSFER_EVENT_COMPRESSOR_READ || static_cast<StreamerDataAggregator::TransferEventType>(socEvent->m_type) == StreamerDataAggregator::TRANSFER_EVENT_COMPRESSOR_WRITE)
{
return QVariant(QString("%1").arg(socEvent->m_bytesTransferred));
}
}
else
{
return QVariant(QString("%1").arg(socEvent->m_bytesTransferred));
}
break;
}
}
}
// COLUMN -------------------------------------------------------------
else if (column == SDM_READ_SIZE)
{
switch (event->GetEventType())
{
case Driller::Streamer::SET_ADD_REQUEST:
{
return QVariant(QString("%1").arg(static_cast<StreamerAddRequestEvent*>(event)->m_requestData.m_size));
break;
}
case Driller::Streamer::SET_COMPLETE_REQUEST:
{
return QVariant(QString("%1").arg(static_cast<StreamerCompleteRequestEvent*>(event)->m_removedRequest->m_size));
break;
}
}
}
else if (column == SDM_OFFSET)
{
switch (event->GetEventType())
{
case Driller::Streamer::SET_ADD_REQUEST:
{
StreamerAddRequestEvent* actualData = static_cast<StreamerAddRequestEvent*>(event);
return QVariant(QString::number(actualData->m_requestData.m_offset));
}
break;
case Driller::Streamer::SET_OPERATION_START:
{
StreamerOperationStartEvent* actualData = static_cast<StreamerOperationStartEvent*>(event);
return QVariant(QString::number(actualData->m_operation.m_offset));
}
break;
}
}
}
return QVariant();
}
}