Initial Imgui debug display for stats, some hookup between entity replication and the spawnable code to make testing possible

main
karlberg 5 years ago
parent a59e212134
commit 4e75a099b8

@ -18,16 +18,16 @@ ly_add_target(
INCLUDE_DIRECTORIES
PRIVATE
${pal_source_dir}
Source
AZ::AzNetworking
Source
.
PUBLIC
Include
BUILD_DEPENDENCIES
PUBLIC
AZ::AzCore
AZ::AzFramework
AZ::AzNetworking
Gem::CertificateManager
3rdParty::AWSNativeSDK::Core
AUTOGEN_RULES
*.AutoPackets.xml,AutoPackets_Header.jinja,$path/$fileprefix.AutoPackets.h
*.AutoPackets.xml,AutoPackets_Inline.jinja,$path/$fileprefix.AutoPackets.inl
@ -49,6 +49,8 @@ ly_add_target(
PRIVATE
Source
.
PUBLIC
Include
BUILD_DEPENDENCIES
PRIVATE
Gem::Multiplayer.Static
@ -56,7 +58,6 @@ ly_add_target(
Gem::CertificateManager
)
if (PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_target(
NAME Multiplayer.Tools MODULE
@ -77,10 +78,7 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS)
)
endif()
################################################################################
# Tests
################################################################################
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
if (PAL_TRAIT_BUILD_TESTS_SUPPORTED)
ly_add_target(
NAME Multiplayer.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
NAMESPACE Gem
@ -92,6 +90,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
${pal_source_dir}
Source
.
PUBLIC
Include
BUILD_DEPENDENCIES
PRIVATE
AZ::AzTest
@ -101,3 +101,25 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
NAME Gem::Multiplayer.Tests
)
endif()
ly_add_target(
NAME Multiplayer.Imgui ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
FILES_CMAKE
multiplayer_imgui_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
Source
.
PUBLIC
Include
BUILD_DEPENDENCIES
PRIVATE
AZ::AzCore
AZ::AtomCore
AZ::AzFramework
AZ::AzNetworking
Gem::Atom_Feature_Common.Static
Gem::Multiplayer.Static
Gem::ImGui.Static
)

@ -1168,6 +1168,12 @@ namespace {{ Component.attrib['Namespace'] }}
void {{ ComponentBaseName }}::Init()
{
if (m_netBindComponent == nullptr)
{
AZLOG_ERROR("NetBindComponent is null, ensure NetworkAttach is called prior to activating a networked entity");
return;
}
{{ DefineComponentServiceProxyGrabs(Component, ClassType, ComponentName)|indent(8) }}
{% if ComponentDerived %}
OnInit();

@ -0,0 +1,36 @@
/*
* 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 <Source/Multiplayer_precompiled.h>
#include <Source/Imgui/MultiplayerImguiModule.h>
#include <Source/Imgui/MultiplayerImguiSystemComponent.h>
namespace Multiplayer
{
MultiplayerImguiModule::MultiplayerImguiModule()
: AZ::Module()
{
m_descriptors.insert(m_descriptors.end(), {
MultiplayerImguiSystemComponent::CreateDescriptor(),
});
}
AZ::ComponentTypeList MultiplayerImguiModule::GetRequiredSystemComponents() const
{
return AZ::ComponentTypeList
{
azrtti_typeid<MultiplayerImguiSystemComponent>(),
};
}
}
AZ_DECLARE_MODULE_CLASS(Gem_Multiplayer_Imgui, Multiplayer::MultiplayerImguiModule);

@ -0,0 +1,31 @@
/*
* 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.
*
*/
#pragma once
#include <AzCore/Module/Module.h>
namespace Multiplayer
{
class MultiplayerImguiModule
: public AZ::Module
{
public:
AZ_RTTI(MultiplayerImguiModule, "{9E1460FA-4513-4B5E-86B4-9DD8ADEFA714}", AZ::Module);
AZ_CLASS_ALLOCATOR(MultiplayerImguiModule, AZ::SystemAllocator, 0);
MultiplayerImguiModule();
~MultiplayerImguiModule() override = default;
AZ::ComponentTypeList GetRequiredSystemComponents() const override;
};
}

@ -0,0 +1,123 @@
/*
* 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 <Source/Imgui/MultiplayerImguiSystemComponent.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Interface/Interface.h>
#include <Include/IMultiplayer.h>
namespace Multiplayer
{
void MultiplayerImguiSystemComponent::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<MultiplayerImguiSystemComponent, AZ::Component>()
->Version(1);
}
}
void MultiplayerImguiSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC_CE("MultiplayerImguiSystemComponent"));
}
void MultiplayerImguiSystemComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required)
{
;
}
void MultiplayerImguiSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatbile)
{
incompatbile.push_back(AZ_CRC_CE("MultiplayerImguiSystemComponent"));
}
void MultiplayerImguiSystemComponent::Activate()
{
#ifdef IMGUI_ENABLED
ImGui::ImGuiUpdateListenerBus::Handler::BusConnect();
#endif
}
void MultiplayerImguiSystemComponent::Deactivate()
{
#ifdef IMGUI_ENABLED
ImGui::ImGuiUpdateListenerBus::Handler::BusDisconnect();
#endif
}
#ifdef IMGUI_ENABLED
void MultiplayerImguiSystemComponent::OnImGuiMainMenuUpdate()
{
if (ImGui::BeginMenu("Multiplayer"))
{
//{
// static int lossPercent{ 0 };
// lossPercent = static_cast<int>(net_UdpDebugLossPercent);
// if (ImGui::SliderInt("UDP Loss Percent", &lossPercent, 0, 100))
// {
// net_UdpDebugLossPercent = lossPercent;
// m_ClientAgent.UpdateConnectionCvars(net_UdpDebugLossPercent);
// }
//}
//
//{
// static int latency{ 0 };
// latency = static_cast<int>(net_UdpDebugLatencyMs);
// if (ImGui::SliderInt("UDP Latency Ms", &latency, 0, 3000))
// {
// net_UdpDebugLatencyMs = latency;
// m_ClientAgent.UpdateConnectionCvars(net_UdpDebugLatencyMs);
// }
//}
//
//{
// static int variance{ 0 };
// variance = static_cast<int>(net_UdpDebugVarianceMs);
// if (ImGui::SliderInt("UDP Variance Ms", &variance, 0, 1000))
// {
// net_UdpDebugVarianceMs = variance;
// m_ClientAgent.UpdateConnectionCvars(net_UdpDebugVarianceMs);
// }
//}
ImGui::Checkbox("Multiplayer Stats", &m_displayStats);
ImGui::EndMenu();
}
}
void MultiplayerImguiSystemComponent::OnImGuiUpdate()
{
if (m_displayStats)
{
if (ImGui::Begin("Multiplayer Stats", &m_displayStats, ImGuiWindowFlags_HorizontalScrollbar))
{
IMultiplayer* multiplayer = AZ::Interface<IMultiplayer>::Get();
Multiplayer::MultiplayerStats& stats = multiplayer->GetStats();
ImGui::Text("Multiplayer operating in %s mode", GetEnumString(multiplayer->GetAgentType()));
ImGui::Text("Total networked entities: %llu", aznumeric_cast<AZ::u64>(stats.m_entityCount));
ImGui::Text("Total client connections: %llu", aznumeric_cast<AZ::u64>(stats.m_clientConnectionCount));
ImGui::Text("Total server connections: %llu", aznumeric_cast<AZ::u64>(stats.m_serverConnectionCount));
ImGui::Text("Total property updates sent: %llu", aznumeric_cast<AZ::u64>(stats.m_propertyUpdatesSent));
ImGui::Text("Total property updates sent bytes: %llu", aznumeric_cast<AZ::u64>(stats.m_propertyUpdatesSentBytes));
ImGui::Text("Total property updates received: %llu", aznumeric_cast<AZ::u64>(stats.m_propertyUpdatesRecv));
ImGui::Text("Total property updates received bytes: %llu", aznumeric_cast<AZ::u64>(stats.m_propertyUpdatesRecvBytes));
ImGui::Text("Total RPCs sent: %llu", aznumeric_cast<AZ::u64>(stats.m_rpcsSent));
ImGui::Text("Total RPCs sent bytes: %llu", aznumeric_cast<AZ::u64>(stats.m_rpcsSentBytes));
ImGui::Text("Total RPCs received: %llu", aznumeric_cast<AZ::u64>(stats.m_rpcsRecv));
ImGui::Text("Total RPCs received bytes: %llu", aznumeric_cast<AZ::u64>(stats.m_rpcsRecvBytes));
}
ImGui::End();
}
}
#endif
}

@ -0,0 +1,56 @@
/*
* 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.
*
*/
#pragma once
#include <AzCore/Component/Component.h>
#ifdef IMGUI_ENABLED
# include <imgui/imgui.h>
# include <ImGuiBus.h>
#endif
namespace Multiplayer
{
class MultiplayerImguiSystemComponent final
: public AZ::Component
#ifdef IMGUI_ENABLED
, public ImGui::ImGuiUpdateListenerBus::Handler
#endif
{
public:
AZ_COMPONENT(MultiplayerImguiSystemComponent, "{060BF3F1-0BFE-4FCE-9C3C-EE991F0DA581}");
static void Reflect(AZ::ReflectContext* context);
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatbile);
~MultiplayerImguiSystemComponent() override = default;
//! AZ::Component overrides
//! @{
void Activate() override;
void Deactivate() override;
//! @}
#ifdef IMGUI_ENABLED
//! ImGui::ImGuiUpdateListenerBus overrides
//! @{
void OnImGuiMainMenuUpdate() override;
void OnImGuiUpdate() override;
//! @}
#endif
private:
bool m_displayStats = false;
};
}

@ -133,23 +133,33 @@ namespace Multiplayer
// Let the network system know the frame is done and we can collect dirty bits
m_networkEntityManager.NotifyEntitiesDirtied();
MultiplayerStats& stats = GetStats();
stats.m_entityCount = GetNetworkEntityManager()->GetEntityCount();
stats.m_serverConnectionCount = 0;
stats.m_clientConnectionCount = 0;
// Send out the game state update to all connections
{
auto sendNetworkUpdates = [serverGameTimeMs](IConnection& connection)
auto sendNetworkUpdates = [serverGameTimeMs, &stats](IConnection& connection)
{
if (connection.GetUserData() != nullptr)
{
IConnectionData* connectionData = reinterpret_cast<IConnectionData*>(connection.GetUserData());
connectionData->Update(serverGameTimeMs);
if (connectionData->GetConnectionDataType() == ConnectionDataType::ServerToClient)
{
stats.m_clientConnectionCount++;
}
else
{
stats.m_serverConnectionCount++;
}
}
};
m_networkInterface->GetConnectionSet().VisitConnections(sendNetworkUpdates);
}
MultiplayerStats& stats = GetStats();
stats.m_entityCount = GetNetworkEntityManager()->GetEntityCount();
MultiplayerPackets::SyncConsole packet;
AZ::ThreadSafeDeque<AZStd::string>::DequeType cvarUpdates;
m_cvarCommands.Swap(cvarUpdates);

@ -62,4 +62,4 @@ namespace Multiplayer
}
} // namespace Multiplayer
AZ_DECLARE_MODULE_CLASS(Gem_Multiplayer2_Tools, Multiplayer::MultiplayerToolsModule);
AZ_DECLARE_MODULE_CLASS(Gem_Multiplayer_Tools, Multiplayer::MultiplayerToolsModule);

@ -9,7 +9,7 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma optimize("", off)
#include <Source/NetworkEntity/EntityReplication/EntityReplicationManager.h>
#include <Source/NetworkEntity/EntityReplication/EntityReplicator.h>
#include <Source/NetworkEntity/EntityReplication/PropertyPublisher.h>
@ -18,6 +18,7 @@
#include <Source/EntityDomains/IEntityDomain.h>
#include <Source/NetworkEntity/NetworkEntityUpdateMessage.h>
#include <Source/NetworkEntity/NetworkEntityRpcMessage.h>
#include <Source/NetworkEntity/INetworkEntityManager.h>
#include <Source/Components/NetBindComponent.h>
#include <Source/AutoGen/Multiplayer.AutoPackets.h>
#include <AzNetworking/ConnectionLayer/IConnection.h>
@ -30,7 +31,6 @@
#include <AzCore/Console/IConsole.h>
#include <AzCore/Console/ILogger.h>
#include <AzCore/Math/Transform.h>
#include <Include/INetworkEntityManager.h>
namespace Multiplayer
{

@ -39,12 +39,6 @@ namespace Multiplayer
{
AZ::Interface<INetworkEntityManager>::Register(this);
AzFramework::RootSpawnableNotificationBus::Handler::BusConnect();
if (AZ::Interface<AZ::ComponentApplicationRequests>::Get() != nullptr)
{
// Null guard needed for unit tests
AZ::Interface<AZ::ComponentApplicationRequests>::Get()->RegisterEntityAddedEventHandler(m_entityAddedEventHandler);
AZ::Interface<AZ::ComponentApplicationRequests>::Get()->RegisterEntityRemovedEventHandler(m_entityRemovedEventHandler);
}
}
NetworkEntityManager::~NetworkEntityManager()
@ -58,6 +52,12 @@ namespace Multiplayer
m_hostId = hostId;
m_entityDomain = AZStd::move(entityDomain);
m_updateEntityDomainEvent.Enqueue(net_EntityDomainUpdateMs, true);
if (AZ::Interface<AZ::ComponentApplicationRequests>::Get() != nullptr)
{
// Null guard needed for unit tests
AZ::Interface<AZ::ComponentApplicationRequests>::Get()->RegisterEntityAddedEventHandler(m_entityAddedEventHandler);
AZ::Interface<AZ::ComponentApplicationRequests>::Get()->RegisterEntityRemovedEventHandler(m_entityRemovedEventHandler);
}
}
NetworkEntityTracker* NetworkEntityManager::GetNetworkEntityTracker()

@ -26,6 +26,10 @@ namespace Multiplayer
}
}
NetworkSpawnableHolderComponent::NetworkSpawnableHolderComponent()
{
}
void NetworkSpawnableHolderComponent::Activate()
{
}
@ -43,9 +47,4 @@ namespace Multiplayer
{
return m_networkSpawnableAsset;
}
NetworkSpawnableHolderComponent::NetworkSpawnableHolderComponent()
{
}
}

@ -0,0 +1,19 @@
#
# 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.
#
set(FILES
Source/Multiplayer_precompiled.cpp
Source/Multiplayer_precompiled.h
Source/Imgui/MultiplayerImguiModule.cpp
Source/Imgui/MultiplayerImguiModule.h
Source/Imgui/MultiplayerImguiSystemComponent.cpp
Source/Imgui/MultiplayerImguiSystemComponent.h
)
Loading…
Cancel
Save