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.
398 lines
13 KiB
C++
398 lines
13 KiB
C++
/*
|
|
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*
|
|
*/
|
|
|
|
#include <AzCore/Math/MathUtils.h>
|
|
|
|
#include "ReplicaBandwidthChartData.h"
|
|
|
|
namespace Driller
|
|
{
|
|
////////////////////
|
|
// GraphPlotHelper
|
|
////////////////////
|
|
|
|
GraphPlotHelper::GraphPlotHelper(const QColor& displayColor)
|
|
: m_color(displayColor)
|
|
, m_channelId(StripChart::DataStrip::s_invalidChannelId)
|
|
, m_zeroOutLine(false)
|
|
, m_initializeLine(false)
|
|
, m_lastHorizontalValue(0.0f)
|
|
{
|
|
}
|
|
|
|
void GraphPlotHelper::Reset()
|
|
{
|
|
m_initializeLine = true;
|
|
m_zeroOutLine = false;
|
|
m_channelId = StripChart::DataStrip::s_invalidChannelId;
|
|
m_lastHorizontalValue = 0.0f;
|
|
}
|
|
|
|
bool GraphPlotHelper::IsSetup() const
|
|
{
|
|
return m_channelId != StripChart::DataStrip::s_invalidChannelId;
|
|
}
|
|
|
|
void GraphPlotHelper::SetupPlotHelper(StripChart::DataStrip* chart, const char* channelName, float startValue)
|
|
{
|
|
if (chart == nullptr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
AZ_Assert(m_channelId == StripChart::DataStrip::s_invalidChannelId, "Double registering the GraphPlotHelper");
|
|
|
|
m_channelId = chart->AddChannel(channelName);
|
|
chart->SetChannelStyle(m_channelId, StripChart::Channel::STYLE_CONNECTED_LINE);
|
|
chart->SetChannelColor(m_channelId, m_color);
|
|
|
|
m_lastHorizontalValue = startValue;
|
|
}
|
|
|
|
void GraphPlotHelper::PlotData(StripChart::DataStrip* chart, float tickSize, float horizontalValue, float verticalValue, bool forceDraw)
|
|
{
|
|
if (chart == nullptr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!IsSetup())
|
|
{
|
|
SetupPlotHelper(chart, "<unknown>", horizontalValue);
|
|
}
|
|
|
|
bool hasData = !AZ::IsClose(verticalValue, 0.0f, 0.001f);
|
|
|
|
float stepDifference = horizontalValue - m_lastHorizontalValue;
|
|
|
|
if (m_zeroOutLine || hasData || forceDraw || m_initializeLine)
|
|
{
|
|
if (!hasData)
|
|
{
|
|
if (m_zeroOutLine)
|
|
{
|
|
chart->AddData(m_channelId, 0, m_lastHorizontalValue + tickSize, 0.0f);
|
|
}
|
|
else if (m_initializeLine)
|
|
{
|
|
chart->AddData(m_channelId, 0, m_lastHorizontalValue, 0.0f);
|
|
}
|
|
}
|
|
|
|
if (stepDifference > tickSize + 0.001f)
|
|
{
|
|
chart->AddData(m_channelId, 0, horizontalValue - tickSize, 0.0f);
|
|
}
|
|
|
|
m_initializeLine = false;
|
|
m_zeroOutLine = hasData;
|
|
m_lastHorizontalValue = horizontalValue;
|
|
|
|
chart->AddData(m_channelId, 0, horizontalValue, verticalValue);
|
|
}
|
|
}
|
|
|
|
void GraphPlotHelper::PlotBatchedData(StripChart::DataStrip* chart, float tickSize, float horizontalValue, float verticalValue, bool forceDraw)
|
|
{
|
|
bool hasData = !AZ::IsClose(verticalValue, 0.0f, 0.001f);
|
|
|
|
float stepDifference = horizontalValue - m_lastHorizontalValue;
|
|
|
|
if (m_zeroOutLine || hasData || forceDraw || m_initializeLine)
|
|
{
|
|
if (!hasData)
|
|
{
|
|
if (m_zeroOutLine)
|
|
{
|
|
chart->AddBatchedData(m_channelId, 0, m_lastHorizontalValue + tickSize, 0.0f);
|
|
}
|
|
else if (m_initializeLine)
|
|
{
|
|
chart->AddBatchedData(m_channelId, 0, m_lastHorizontalValue, 0.0f);
|
|
}
|
|
}
|
|
|
|
if (stepDifference > tickSize + 0.001f)
|
|
{
|
|
chart->AddBatchedData(m_channelId, 0, horizontalValue - tickSize, 0.0f);
|
|
}
|
|
|
|
m_initializeLine = false;
|
|
m_zeroOutLine = hasData;
|
|
m_lastHorizontalValue = horizontalValue;
|
|
|
|
chart->AddBatchedData(m_channelId, 0, horizontalValue, verticalValue);
|
|
}
|
|
}
|
|
|
|
void GraphPlotHelper::SetHighlight(StripChart::DataStrip* chart, bool highlight)
|
|
{
|
|
if (chart == nullptr || m_channelId == StripChart::DataStrip::s_invalidChannelId)
|
|
{
|
|
return;
|
|
}
|
|
|
|
chart->SetChannelHighlight(m_channelId, highlight);
|
|
}
|
|
|
|
void GraphPlotHelper::ZeroOutLine(float lastHorizontalValue, float tickSize, StripChart::DataStrip* chart)
|
|
{
|
|
if (m_zeroOutLine && !AZ::IsClose(lastHorizontalValue, m_lastHorizontalValue, 0.001f))
|
|
{
|
|
chart->AddData(m_channelId, 0, m_lastHorizontalValue + tickSize, 0.0f);
|
|
}
|
|
}
|
|
|
|
////////////////////////
|
|
// AreaGraphPlotHelper
|
|
////////////////////////
|
|
|
|
AreaGraphPlotHelper::AreaGraphPlotHelper(const QColor& displayColor)
|
|
: m_color(displayColor)
|
|
, m_areaChart(nullptr)
|
|
, m_seriesId(AreaChart::AreaChart::k_invalidSeriesId)
|
|
{
|
|
}
|
|
|
|
bool AreaGraphPlotHelper::IsSetup() const
|
|
{
|
|
return m_areaChart != nullptr && m_seriesId != AreaChart::AreaChart::k_invalidSeriesId;
|
|
}
|
|
|
|
void AreaGraphPlotHelper::Reset()
|
|
{
|
|
m_areaChart = nullptr;
|
|
m_seriesId = AreaChart::AreaChart::k_invalidSeriesId;
|
|
}
|
|
|
|
void AreaGraphPlotHelper::SetupPlotHelper(AreaChart::AreaChart* chart, const char* channelName, size_t seriesSize)
|
|
{
|
|
AZ_Error("AreaGraphPlotHelper", !IsSetup(), "Plot Helper is already setup.");
|
|
if (IsSetup())
|
|
{
|
|
Reset();
|
|
}
|
|
|
|
QString name(channelName);
|
|
|
|
m_areaChart = chart;
|
|
m_seriesId = m_areaChart->CreateSeries(name, m_color,seriesSize);
|
|
}
|
|
|
|
void AreaGraphPlotHelper::PlotData(int position, unsigned int value)
|
|
{
|
|
if (IsSetup())
|
|
{
|
|
m_areaChart->AddPoint(m_seriesId, position, value);
|
|
}
|
|
}
|
|
|
|
void AreaGraphPlotHelper::PlotBatchedData(int position, unsigned int value)
|
|
{
|
|
m_areaChart->AddPoint(m_seriesId, position, value);
|
|
}
|
|
|
|
void AreaGraphPlotHelper::SetHighlighted(bool highlighted)
|
|
{
|
|
if (IsSetup())
|
|
{
|
|
m_areaChart->SetSeriesHighlight(m_seriesId, highlighted);
|
|
}
|
|
}
|
|
|
|
void AreaGraphPlotHelper::SetEnabled(bool enabled)
|
|
{
|
|
if (IsSetup())
|
|
{
|
|
m_areaChart->SetSeriesEnabled(m_seriesId, enabled);
|
|
}
|
|
}
|
|
|
|
bool AreaGraphPlotHelper::IsSeries(size_t seriesId) const
|
|
{
|
|
if (m_seriesId == AreaChart::AreaChart::k_invalidSeriesId)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return m_seriesId == seriesId;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////
|
|
// BandwidthUsageAggregator
|
|
//////////////////////////////
|
|
|
|
BandwidthUsageAggregator::BandwidthUsageAggregator()
|
|
: m_bytesSent(0)
|
|
, m_bytesReceived(0)
|
|
{
|
|
}
|
|
|
|
void BandwidthUsageAggregator::Reset()
|
|
{
|
|
m_bytesSent = 0;
|
|
m_bytesReceived = 0;
|
|
}
|
|
|
|
////////////////////////////
|
|
// BandwidthUsageContainer
|
|
////////////////////////////
|
|
|
|
BandwidthUsageContainer::BandwidthUsageContainer()
|
|
{
|
|
m_dataTypeAggregationMap.insert(DataTypeAggreationMap::value_type(BandwidthUsage::DataType::DATA_SET, UsageAggregationMap()));
|
|
m_dataTypeAggregationMap.insert(DataTypeAggreationMap::value_type(BandwidthUsage::DataType::REMOTE_PROCEDURE_CALL, UsageAggregationMap()));
|
|
}
|
|
|
|
BandwidthUsageContainer::~BandwidthUsageContainer()
|
|
{
|
|
}
|
|
|
|
void BandwidthUsageContainer::ProcessChunkEvent(const ReplicaChunkEvent* chunkEvent)
|
|
{
|
|
BandwidthUsage* bandwidthUsage = nullptr;
|
|
|
|
if (azrtti_istypeof<const ReplicaChunkDataSetEvent*>(chunkEvent))
|
|
{
|
|
const ReplicaChunkDataSetEvent* dataSetEvent = static_cast<const ReplicaChunkDataSetEvent*>(chunkEvent);
|
|
|
|
size_t index = dataSetEvent->GetIndex();
|
|
|
|
UsageAggregationMap& dataSetAggregationMap = m_dataTypeAggregationMap[BandwidthUsage::DataType::DATA_SET];
|
|
|
|
UsageAggregationMap::iterator usageIter = dataSetAggregationMap.find(index);
|
|
|
|
if (usageIter == dataSetAggregationMap.end())
|
|
{
|
|
BandwidthUsage usage;
|
|
|
|
usage.m_dataType = BandwidthUsage::DataType::DATA_SET;
|
|
usage.m_identifier = dataSetEvent->GetDataSetName();
|
|
usage.m_index = dataSetEvent->GetIndex();
|
|
|
|
usageIter = dataSetAggregationMap.insert(UsageAggregationMap::value_type(index, usage)).first;
|
|
}
|
|
|
|
bandwidthUsage = (&usageIter->second);
|
|
|
|
if (azrtti_istypeof<const ReplicaChunkSentDataSetEvent*>(dataSetEvent))
|
|
{
|
|
m_totalUsageAggregator.m_bytesSent += dataSetEvent->GetUsageBytes();
|
|
bandwidthUsage->m_usageAggregator.m_bytesSent += dataSetEvent->GetUsageBytes();
|
|
OnProcessSentDataSet(static_cast<const ReplicaChunkSentDataSetEvent*>(dataSetEvent));
|
|
}
|
|
else if (azrtti_istypeof<const ReplicaChunkReceivedDataSetEvent*>(dataSetEvent))
|
|
{
|
|
m_totalUsageAggregator.m_bytesReceived += dataSetEvent->GetUsageBytes();
|
|
bandwidthUsage->m_usageAggregator.m_bytesReceived += dataSetEvent->GetUsageBytes();
|
|
OnProcessReceivedDataSet(static_cast<const ReplicaChunkReceivedDataSetEvent*>(dataSetEvent));
|
|
}
|
|
else
|
|
{
|
|
AZ_Error("Standalone Tools", false, "Unknown event type in BadnwidthUsageContainer::ProcessChunkEvent.");
|
|
}
|
|
}
|
|
else if (azrtti_istypeof<const ReplicaChunkRPCEvent>(chunkEvent))
|
|
{
|
|
const ReplicaChunkRPCEvent* rpcEvent = static_cast<const ReplicaChunkRPCEvent*>(chunkEvent);
|
|
|
|
size_t index = rpcEvent->GetIndex();
|
|
|
|
UsageAggregationMap& rpcUsageAggregationMap = m_dataTypeAggregationMap[BandwidthUsage::DataType::REMOTE_PROCEDURE_CALL];
|
|
|
|
UsageAggregationMap::iterator usageIter = rpcUsageAggregationMap.find(index);
|
|
|
|
if (usageIter == rpcUsageAggregationMap.end())
|
|
{
|
|
BandwidthUsage usage;
|
|
|
|
usage.m_dataType = BandwidthUsage::DataType::REMOTE_PROCEDURE_CALL;
|
|
usage.m_identifier = rpcEvent->GetRPCName();
|
|
usage.m_index = rpcEvent->GetIndex();
|
|
|
|
usageIter = rpcUsageAggregationMap.insert(UsageAggregationMap::value_type(index, usage)).first;
|
|
}
|
|
|
|
bandwidthUsage = (&usageIter->second);
|
|
|
|
if (azrtti_istypeof<const ReplicaChunkSentRPCEvent*>(rpcEvent))
|
|
{
|
|
m_totalUsageAggregator.m_bytesSent += rpcEvent->GetUsageBytes();
|
|
bandwidthUsage->m_usageAggregator.m_bytesSent += rpcEvent->GetUsageBytes();
|
|
OnProcessSentRPC(static_cast<const ReplicaChunkSentRPCEvent*>(rpcEvent));
|
|
}
|
|
else if (azrtti_istypeof<const ReplicaChunkReceivedRPCEvent*>(rpcEvent))
|
|
{
|
|
m_totalUsageAggregator.m_bytesReceived += rpcEvent->GetUsageBytes();
|
|
bandwidthUsage->m_usageAggregator.m_bytesReceived += rpcEvent->GetUsageBytes();
|
|
OnProcessReceivedRPC(static_cast<const ReplicaChunkReceivedRPCEvent*>(rpcEvent));
|
|
}
|
|
else
|
|
{
|
|
AZ_Error("Standalone Tools", false, "Unknown event type in BadnwidthUsageContainer::ProcessChunkEvent.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AZ_Error("Standalone Tools", false, "Unknown event type in BadnwidthUsageContainer::ProcessChunkEvent.");
|
|
}
|
|
}
|
|
|
|
size_t BandwidthUsageContainer::GetTotalBytesSent() const
|
|
{
|
|
return m_totalUsageAggregator.m_bytesSent;
|
|
}
|
|
|
|
size_t BandwidthUsageContainer::GetTotalBytesReceived() const
|
|
{
|
|
return m_totalUsageAggregator.m_bytesReceived;
|
|
}
|
|
|
|
size_t BandwidthUsageContainer::GetTotalBandwidthUsage() const
|
|
{
|
|
return GetTotalBytesSent() + GetTotalBytesReceived();
|
|
}
|
|
|
|
const BandwidthUsageContainer::UsageAggregationMap& BandwidthUsageContainer::GetDataTypeUsageAggregation(BandwidthUsage::DataType dataType) const
|
|
{
|
|
static UsageAggregationMap s_emptyMap;
|
|
|
|
DataTypeAggreationMap::const_iterator dataTypeIterator = m_dataTypeAggregationMap.find(dataType);
|
|
|
|
AZ_Error("Standalone Tools", dataTypeIterator != m_dataTypeAggregationMap.end(), "Use of Unknown DataType inside of GetDataTypeUsageAggreation");
|
|
if (dataTypeIterator != m_dataTypeAggregationMap.end())
|
|
{
|
|
return dataTypeIterator->second;
|
|
}
|
|
|
|
return s_emptyMap;
|
|
}
|
|
|
|
void BandwidthUsageContainer::OnProcessSentDataSet(const ReplicaChunkSentDataSetEvent* sentData)
|
|
{
|
|
(void)sentData;
|
|
}
|
|
|
|
void BandwidthUsageContainer::OnProcessReceivedDataSet(const ReplicaChunkReceivedDataSetEvent* receivedData)
|
|
{
|
|
(void)receivedData;
|
|
}
|
|
|
|
void BandwidthUsageContainer::OnProcessSentRPC(const ReplicaChunkSentRPCEvent* sentData)
|
|
{
|
|
(void)sentData;
|
|
}
|
|
|
|
void BandwidthUsageContainer::OnProcessReceivedRPC(const ReplicaChunkReceivedRPCEvent* receivedData)
|
|
{
|
|
(void)receivedData;
|
|
}
|
|
}
|