Debug overlay for kpbs per entity works
Signed-off-by: AMZN-Olex <5432499+AMZN-Olex@users.noreply.github.com>
This commit is contained in:
@@ -24,5 +24,6 @@ namespace MultiplayerDiagnostics
|
||||
virtual void RecordPropertySent(Multiplayer::NetComponentId netComponentId, Multiplayer::PropertyIndex propertyId, uint32_t totalBytes) = 0;
|
||||
virtual void RecordPropertyReceived(Multiplayer::NetComponentId netComponentId, Multiplayer::PropertyIndex propertyId, uint32_t totalBytes) = 0;
|
||||
virtual void RecordRpcSent(Multiplayer::NetComponentId netComponentId, Multiplayer::RpcIndex rpcId, uint32_t totalBytes) = 0;
|
||||
virtual void RecordRpcReceived(Multiplayer::NetComponentId netComponentId, Multiplayer::RpcIndex rpcId, uint32_t totalBytes) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -19,6 +19,21 @@
|
||||
|
||||
#pragma optimize("", off)
|
||||
|
||||
AZ_CVAR(bool, net_DebugNetworkEntity_Bandwidth, true, nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
"If true, prints debug text over entities that use a considerable amount of network traffic");
|
||||
|
||||
AZ_CVAR(float, net_DebugNetworkEntity_ShowAboveKbps, 1.f, nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
"Prints bandwidth on network entities with higher kpbs than this value");
|
||||
|
||||
AZ_CVAR(float, net_DebugNetworkEntity_WarnAboveKbps, 10.f, nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
"Prints bandwidth on network entities with higher kpbs than this value");
|
||||
|
||||
AZ_CVAR(AZ::Color, net_DebugNetworkEntity_WarningColor, AZ::Colors::Red, nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
"If true, prints debug text over entities that use a considerable amount of network traffic");
|
||||
|
||||
AZ_CVAR(AZ::Color, net_DebugNetworkEntity_BelowWarningColor, AZ::Colors::Grey, nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
"If true, prints debug text over entities that use a considerable amount of network traffic");
|
||||
|
||||
namespace MultiplayerDiagnostics
|
||||
{
|
||||
#if defined(IMGUI_ENABLED)
|
||||
@@ -114,6 +129,17 @@ namespace MultiplayerDiagnostics
|
||||
}
|
||||
#endif
|
||||
|
||||
MultiplayerDebugPerEntityReporter::MultiplayerDebugPerEntityReporter()
|
||||
: m_updateDebugOverlay([this]() { UpdateDebugOverlay(); }, AZ::Name("UpdateDebugPerEntityOverlay"))
|
||||
{
|
||||
m_updateDebugOverlay.Enqueue(AZ::TimeMs{ 0 }, true);
|
||||
}
|
||||
|
||||
MultiplayerDebugPerEntityReporter::~MultiplayerDebugPerEntityReporter()
|
||||
{
|
||||
m_updateDebugOverlay.RemoveFromQueue();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void MultiplayerDebugPerEntityReporter::OnImGuiUpdate()
|
||||
{
|
||||
@@ -121,17 +147,6 @@ namespace MultiplayerDiagnostics
|
||||
static ImGuiTextFilter filter;
|
||||
filter.Draw();
|
||||
|
||||
char status[100] = {};
|
||||
|
||||
struct NetworkEntityTraffic
|
||||
{
|
||||
const char* m_name = nullptr;
|
||||
float m_up = 0.f;
|
||||
float m_down = 0.f;
|
||||
};
|
||||
|
||||
AZStd::fixed_unordered_map<AZ::EntityId, NetworkEntityTraffic, 5, 10> networkEntitiesTraffic;
|
||||
|
||||
if (ImGui::CollapsingHeader("Receiving Entities"))
|
||||
{
|
||||
for (AZStd::pair<AZ::EntityId, EntityReporter>& entityPair : m_receivingEntityReports)
|
||||
@@ -147,9 +162,6 @@ namespace MultiplayerDiagnostics
|
||||
DisplayReplicatedStateReport(entityPair.second.GetComponentReports(), m_replicatedStateKbpsWarn, m_replicatedStateMaxSizeWarn);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
networkEntitiesTraffic[entityPair.first].m_name = entityPair.second.GetEntityName();
|
||||
networkEntitiesTraffic[entityPair.first].m_down = entityPair.second.GetKbitsPerSecond();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,27 +181,8 @@ namespace MultiplayerDiagnostics
|
||||
DisplayReplicatedStateReport(entityPair.second.GetComponentReports(), m_replicatedStateKbpsWarn, m_replicatedStateMaxSizeWarn);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
networkEntitiesTraffic[entityPair.first].m_name = entityPair.second.GetEntityName();
|
||||
networkEntitiesTraffic[entityPair.first].m_up = entityPair.second.GetKbitsPerSecond();
|
||||
}
|
||||
}
|
||||
|
||||
constexpr float trafficThreshold = 0.1f;
|
||||
for (AZStd::pair<AZ::EntityId, NetworkEntityTraffic>& networkEntity : networkEntitiesTraffic)
|
||||
{
|
||||
if (networkEntity.second.m_down < trafficThreshold && networkEntity.second.m_up < trafficThreshold)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
azsprintf(status, "%s - %.0f down / %0.f up (kbps)", networkEntity.second.m_name, networkEntity.second.m_down, networkEntity.second.m_up);
|
||||
AZ::Vector3 entityPosition = AZ::Vector3::CreateZero();
|
||||
constexpr bool centerText = true;
|
||||
AZ::TransformBus::EventResult(entityPosition, networkEntity.first, &AZ::TransformBus::Events::GetWorldTranslation);
|
||||
AzFramework::DebugDisplayRequestBus::Broadcast(&AzFramework::DebugDisplayRequestBus::Events::DrawTextLabel,
|
||||
entityPosition, 1.0f, status, centerText, 0, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -271,4 +264,85 @@ namespace MultiplayerDiagnostics
|
||||
componentRegistry->GetComponentRpcName(netComponentId, rpcId), totalBytes);
|
||||
}
|
||||
}
|
||||
|
||||
void MultiplayerDebugPerEntityReporter::RecordRpcReceived(
|
||||
Multiplayer::NetComponentId netComponentId,
|
||||
Multiplayer::RpcIndex rpcId,
|
||||
uint32_t totalBytes)
|
||||
{
|
||||
if (const Multiplayer::MultiplayerComponentRegistry* componentRegistry = Multiplayer::GetMultiplayerComponentRegistry())
|
||||
{
|
||||
m_currentReceivingEntityReport.ReportField(static_cast<AZ::u32>(netComponentId),
|
||||
componentRegistry->GetComponentName(netComponentId),
|
||||
componentRegistry->GetComponentRpcName(netComponentId, rpcId), totalBytes);
|
||||
}
|
||||
}
|
||||
|
||||
void MultiplayerDebugPerEntityReporter::UpdateDebugOverlay()
|
||||
{
|
||||
if (net_DebugNetworkEntity_Bandwidth)
|
||||
{
|
||||
m_networkEntitiesTraffic.clear();
|
||||
|
||||
for (AZStd::pair<AZ::EntityId, EntityReporter>& entityPair : m_receivingEntityReports)
|
||||
{
|
||||
m_networkEntitiesTraffic[entityPair.first].m_name = entityPair.second.GetEntityName();
|
||||
m_networkEntitiesTraffic[entityPair.first].m_down = entityPair.second.GetKbitsPerSecond();
|
||||
}
|
||||
|
||||
for (AZStd::pair<AZ::EntityId, EntityReporter>& entityPair : m_sendingEntityReports)
|
||||
{
|
||||
m_networkEntitiesTraffic[entityPair.first].m_name = entityPair.second.GetEntityName();
|
||||
m_networkEntitiesTraffic[entityPair.first].m_up = entityPair.second.GetKbitsPerSecond();
|
||||
}
|
||||
|
||||
//get debug display interface for the viewport
|
||||
if (m_debugDisplay == nullptr)
|
||||
{
|
||||
AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus;
|
||||
AzFramework::DebugDisplayRequestBus::Bind(debugDisplayBus, AzFramework::g_defaultSceneEntityDebugDisplayId);
|
||||
m_debugDisplay = AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus);
|
||||
}
|
||||
|
||||
const AZ::u32 stateBefore = m_debugDisplay->GetState();
|
||||
|
||||
for (AZStd::pair<AZ::EntityId, NetworkEntityTraffic>& networkEntity : m_networkEntitiesTraffic)
|
||||
{
|
||||
if (networkEntity.second.m_down < net_DebugNetworkEntity_ShowAboveKbps && networkEntity.second.m_up < net_DebugNetworkEntity_ShowAboveKbps)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (networkEntity.second.m_down > net_DebugNetworkEntity_WarnAboveKbps || networkEntity.second.m_up > net_DebugNetworkEntity_WarnAboveKbps)
|
||||
{
|
||||
m_debugDisplay->SetColor(net_DebugNetworkEntity_WarningColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_debugDisplay->SetColor(net_DebugNetworkEntity_BelowWarningColor);
|
||||
}
|
||||
|
||||
if (networkEntity.second.m_down > net_DebugNetworkEntity_ShowAboveKbps && networkEntity.second.m_up > net_DebugNetworkEntity_ShowAboveKbps)
|
||||
{
|
||||
azsprintf(m_statusBuffer, "[%s] %.0f down / %0.f up (kbps)", networkEntity.second.m_name,
|
||||
networkEntity.second.m_down, networkEntity.second.m_up);
|
||||
}
|
||||
else if (networkEntity.second.m_down > net_DebugNetworkEntity_ShowAboveKbps)
|
||||
{
|
||||
azsprintf(m_statusBuffer, "[%s] %.0f down (kbps)", networkEntity.second.m_name, networkEntity.second.m_down);
|
||||
}
|
||||
else
|
||||
{
|
||||
azsprintf(m_statusBuffer, "[%s] %.0f up (kbps)", networkEntity.second.m_name, networkEntity.second.m_up);
|
||||
}
|
||||
|
||||
AZ::Vector3 entityPosition = AZ::Vector3::CreateZero();
|
||||
constexpr bool centerText = true;
|
||||
AZ::TransformBus::EventResult(entityPosition, networkEntity.first, &AZ::TransformBus::Events::GetWorldTranslation);
|
||||
m_debugDisplay->DrawTextLabel(entityPosition, 1.0f, m_statusBuffer, centerText, 0, 0);
|
||||
}
|
||||
|
||||
m_debugDisplay->SetState(stateBefore);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,10 @@
|
||||
#include "MultiplayerDebugByteReporter.h"
|
||||
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/EBus/ScheduledEvent.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <Debug/MultiplayerDebugPerEntityInterface.h>
|
||||
#include <GridMate/Drillers/CarrierDriller.h>
|
||||
#include <Multiplayer/MultiplayerTypes.h>
|
||||
@@ -24,8 +27,8 @@ namespace MultiplayerDiagnostics
|
||||
: public AZ::Interface<MultiplayerIPerEntityStats>::Registrar
|
||||
{
|
||||
public:
|
||||
MultiplayerDebugPerEntityReporter() = default;
|
||||
~MultiplayerDebugPerEntityReporter() override = default;
|
||||
MultiplayerDebugPerEntityReporter();
|
||||
~MultiplayerDebugPerEntityReporter() override;
|
||||
|
||||
// main update loop
|
||||
void OnImGuiUpdate();
|
||||
@@ -38,10 +41,15 @@ namespace MultiplayerDiagnostics
|
||||
void RecordPropertySent(Multiplayer::NetComponentId netComponentId, Multiplayer::PropertyIndex propertyId, uint32_t totalBytes) override;
|
||||
void RecordPropertyReceived(Multiplayer::NetComponentId netComponentId, Multiplayer::PropertyIndex propertyId, uint32_t totalBytes) override;
|
||||
void RecordRpcSent(Multiplayer::NetComponentId netComponentId, Multiplayer::RpcIndex rpcId, uint32_t totalBytes) override;
|
||||
void RecordRpcReceived(Multiplayer::NetComponentId netComponentId, Multiplayer::RpcIndex rpcId, uint32_t totalBytes) override;
|
||||
// }@
|
||||
|
||||
void UpdateDebugOverlay();
|
||||
|
||||
private:
|
||||
|
||||
AZ::ScheduledEvent m_updateDebugOverlay;
|
||||
|
||||
AZStd::map<AZ::EntityId, EntityReporter> m_sendingEntityReports{};
|
||||
EntityReporter m_currentSendingEntityReport;
|
||||
|
||||
@@ -50,5 +58,18 @@ namespace MultiplayerDiagnostics
|
||||
|
||||
float m_replicatedStateKbpsWarn = 10.f;
|
||||
float m_replicatedStateMaxSizeWarn = 30.f;
|
||||
|
||||
char m_statusBuffer[100] = {};
|
||||
|
||||
struct NetworkEntityTraffic
|
||||
{
|
||||
const char* m_name = nullptr;
|
||||
float m_up = 0.f;
|
||||
float m_down = 0.f;
|
||||
};
|
||||
|
||||
AZStd::fixed_unordered_map<AZ::EntityId, NetworkEntityTraffic, 5, 10> m_networkEntitiesTraffic;
|
||||
|
||||
AzFramework::DebugDisplayRequests* m_debugDisplay = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#include <AzNetworking/Framework/INetworkInterface.h>
|
||||
#include <Multiplayer/IMultiplayer.h>
|
||||
|
||||
#pragma optimize("", off)
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
void MultiplayerDebugSystemComponent::Reflect(AZ::ReflectContext* context)
|
||||
@@ -329,7 +327,8 @@ namespace Multiplayer
|
||||
|
||||
if (m_displayPerEntityStats)
|
||||
{
|
||||
if (ImGui::Begin("Multiplayer Per Entity Analytics", &m_displayPerEntityStats, ImGuiWindowFlags_None))
|
||||
//ImGui::SetNextWindowSize({500, 400});
|
||||
if (ImGui::Begin("Multiplayer Per Entity Stats", &m_displayPerEntityStats, ImGuiWindowFlags_AlwaysAutoResize))
|
||||
{
|
||||
if (m_reporter)
|
||||
{
|
||||
|
||||
@@ -101,6 +101,11 @@ namespace Multiplayer
|
||||
|
||||
void MultiplayerStats::RecordRpcReceived(NetComponentId netComponentId, RpcIndex rpcId, uint32_t totalBytes)
|
||||
{
|
||||
if (auto* perEntityStats = AZ::Interface<MultiplayerDiagnostics::MultiplayerIPerEntityStats>::Get())
|
||||
{
|
||||
perEntityStats->RecordRpcReceived(netComponentId, rpcId, totalBytes);
|
||||
}
|
||||
|
||||
const uint16_t netComponentIndex = aznumeric_cast<uint16_t>(netComponentId);
|
||||
const uint16_t rpcIndex = aznumeric_cast<uint16_t>(rpcId);
|
||||
m_componentStats[netComponentIndex].m_rpcsRecv[rpcIndex].m_totalCalls++;
|
||||
|
||||
Reference in New Issue
Block a user