Merge branch 'development' into cmake/linux_fix_warn_unused

Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>

# Conflicts:
#	Code/Legacy/CrySystem/Log.cpp
#	Code/Tools/Standalone/Source/Driller/Annotations/AnnotationHeaderView.cpp
#	Code/Tools/Standalone/Source/Driller/AreaChart.cpp
#	Code/Tools/Standalone/Source/Driller/AreaChart.hxx
#	Code/Tools/Standalone/Source/Driller/ChannelDataView.cpp
#	Code/Tools/Standalone/Source/Driller/DrillerCaptureWindow.cpp
#	Code/Tools/Standalone/Source/Driller/Profiler/ProfilerDataView.cpp
This commit is contained in:
Esteban Papp
2021-08-25 11:47:19 -07:00
400 changed files with 1886 additions and 46899 deletions
@@ -25,7 +25,6 @@
#include <AzCore/std/string/conversions.h>
#include <AzCore/std/string/regex.h>
#include <AzCore/Serialization/DataPatch.h>
#include <AzCore/Debug/FrameProfilerComponent.h>
#include <AzCore/NativeUI/NativeUISystemComponent.h>
#include <AzCore/Module/ModuleManagerBus.h>
#include <AzCore/Interface/Interface.h>
@@ -60,7 +59,6 @@
#include <AzFramework/StreamingInstall/StreamingInstall.h>
#include <AzFramework/TargetManagement/TargetManagementComponent.h>
#include <AzFramework/Viewport/CameraState.h>
#include <AzFramework/Driller/RemoteDrillerInterface.h>
#include <AzFramework/Metrics/MetricsPlainTextNameRegistration.h>
#include <AzFramework/Terrain/TerrainDataRequestBus.h>
#include <AzFramework/Viewport/ScreenGeometry.h>
@@ -296,7 +294,6 @@ namespace AzFramework
azrtti_typeid<AZ::JobManagerComponent>(),
azrtti_typeid<AZ::AssetManagerComponent>(),
azrtti_typeid<AZ::UserSettingsComponent>(),
azrtti_typeid<AZ::Debug::FrameProfilerComponent>(),
azrtti_typeid<AZ::SliceComponent>(),
azrtti_typeid<AZ::SliceSystemComponent>(),
@@ -312,7 +309,6 @@ namespace AzFramework
#endif
azrtti_typeid<AzFramework::AssetSystem::AssetSystemComponent>(),
azrtti_typeid<AzFramework::InputSystemComponent>(),
azrtti_typeid<AzFramework::DrillerNetworkAgentComponent>(),
#if !defined(AZCORE_EXCLUDE_LUA)
azrtti_typeid<AZ::ScriptSystemComponent>(),
@@ -374,7 +370,6 @@ namespace AzFramework
azrtti_typeid<AzFramework::RenderGeometry::GameIntersectorComponent>(),
azrtti_typeid<AzFramework::AssetSystem::AssetSystemComponent>(),
azrtti_typeid<AzFramework::InputSystemComponent>(),
azrtti_typeid<AzFramework::DrillerNetworkAgentComponent>(),
azrtti_typeid<AzFramework::StreamingInstall::StreamingInstallSystemComponent>(),
azrtti_typeid<AzFramework::SpawnableSystemComponent>(),
AZ::Uuid("{624a7be2-3c7e-4119-aee2-1db2bdb6cc89}"), // ScriptDebugAgent
@@ -191,3 +191,5 @@ namespace AzFramework
};
} // namespace AzFramework
AZ_DECLARE_BUDGET(AzFramework);
@@ -14,7 +14,6 @@
#include <AzFramework/Components/TransformComponent.h>
#include <AzFramework/Components/NonUniformScaleComponent.h>
#include <AzFramework/Components/AzFrameworkConfigurationSystemComponent.h>
#include <AzFramework/Driller/RemoteDrillerInterface.h>
#include <AzFramework/Entity/GameEntityContextComponent.h>
#include <AzFramework/FileTag/FileTagComponent.h>
#include <AzFramework/Input/System/InputSystemComponent.h>
@@ -27,6 +26,8 @@
#include <AzFramework/TargetManagement/TargetManagementComponent.h>
#include <AzFramework/Visibility/OctreeSystemComponent.h>
AZ_DEFINE_BUDGET(AzFramework);
namespace AzFramework
{
AzFrameworkModule::AzFrameworkModule()
@@ -46,7 +47,6 @@ namespace AzFramework
AzFramework::CreateScriptDebugAgentFactory(),
AzFramework::AssetSystem::AssetSystemComponent::CreateDescriptor(),
AzFramework::InputSystemComponent::CreateDescriptor(),
AzFramework::DrillerNetworkAgentComponent::CreateDescriptor(),
#if !defined(AZCORE_EXCLUDE_LUA)
AzFramework::ScriptComponent::CreateDescriptor(),
@@ -1,197 +0,0 @@
/*
* 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 <AzFramework/Driller/DrillToFileComponent.h>
#include <AzCore/Driller/Driller.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/IO/FileIO.h>
namespace AzFramework
{
void DrillToFileComponent::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<DrillToFileComponent, AZ::Component>()
;
if (serialize->FindClassData(DrillerInfo::RTTI_Type()) == nullptr)
{
serialize->Class<DrillerInfo>()
->Field("Id", &DrillerInfo::m_id)
->Field("GroupName", &DrillerInfo::m_groupName)
->Field("Name", &DrillerInfo::m_name)
->Field("Description", &DrillerInfo::m_description);
}
}
}
void DrillToFileComponent::Activate()
{
m_drillerSession = nullptr;
DrillerConsoleCommandBus::Handler::BusConnect();
}
void DrillToFileComponent::Deactivate()
{
DrillerConsoleCommandBus::Handler::BusDisconnect();
StopDrillerSession(reinterpret_cast<AZ::u64>(this));
}
void DrillToFileComponent::WriteBinary(const void* data, unsigned int dataSize)
{
if (dataSize > 0)
{
m_frameBuffer.insert(m_frameBuffer.end(), reinterpret_cast<const AZ::u8*>(data), reinterpret_cast<const AZ::u8*>(data) + dataSize);
}
}
void DrillToFileComponent::OnEndOfFrame()
{
AZStd::lock_guard<AZStd::mutex> lock(m_writerMutex);
m_writeQueue.push_back();
m_writeQueue.back().swap(m_frameBuffer);
m_signal.notify_all();
}
void DrillToFileComponent::EnumerateAvailableDrillers()
{
DrillerInfoListType availableDrillers;
AZ::Debug::DrillerManager* mgr = NULL;
EBUS_EVENT_RESULT(mgr, AZ::ComponentApplicationBus, GetDrillerManager);
if (mgr)
{
for (int i = 0; i < mgr->GetNumDrillers(); ++i)
{
AZ::Debug::Driller* driller = mgr->GetDriller(i);
AZ_Assert(driller, "DrillerManager returned a NULL driller. This is not legal!");
availableDrillers.push_back();
availableDrillers.back().m_id = driller->GetId();
availableDrillers.back().m_groupName = driller->GroupName();
availableDrillers.back().m_name = driller->GetName();
availableDrillers.back().m_description = driller->GetDescription();
}
}
EBUS_EVENT(DrillerConsoleEventBus, OnDrillersEnumerated, availableDrillers);
}
void DrillToFileComponent::StartDrillerSession(const AZ::Debug::DrillerManager::DrillerListType& requestedDrillers, AZ::u64 sessionId)
{
if (!m_drillerSession)
{
AZ_Assert(m_writeQueue.empty(), "write queue is not empty!");
m_sessionId = sessionId;
AZ::Debug::DrillerManager* mgr = nullptr;
EBUS_EVENT_RESULT(mgr, AZ::ComponentApplicationBus, GetDrillerManager);
if (mgr)
{
SetStringPool(&m_stringPool);;
m_drillerSession = mgr->Start(*this, requestedDrillers);
AZStd::unique_lock<AZStd::mutex> signalLock(m_writerMutex);
m_isWriterEnabled = true;
AZStd::thread_desc td;
td.m_name = "DrillToFileComponent Writer Thread";
m_writerThread = AZStd::thread(AZStd::bind(&DrillToFileComponent::AsyncWritePump, this), &td);
m_signal.wait(signalLock);
EBUS_EVENT(DrillerConsoleEventBus, OnDrillerSessionStarted, sessionId);
}
}
}
void DrillToFileComponent::StopDrillerSession(AZ::u64 sessionId)
{
if (sessionId == m_sessionId)
{
if (m_drillerSession)
{
AZ::Debug::DrillerManager* mgr = NULL;
EBUS_EVENT_RESULT(mgr, AZ::ComponentApplicationBus, GetDrillerManager);
if (mgr)
{
mgr->Stop(m_drillerSession);
}
m_drillerSession = nullptr;
EBUS_EVENT(DrillerConsoleEventBus, OnDrillerSessionStopped, reinterpret_cast<AZ::u64>(this));
}
m_isWriterEnabled = false;
if (m_writerThread.joinable())
{
m_writerMutex.lock();
m_signal.notify_all();
m_writerMutex.unlock();
m_writerThread.join();
}
SetStringPool(nullptr);
m_stringPool.Reset();
m_frameBuffer.clear(); // there may be pending data but we don't want to write it because it's an incomplete frame.
}
}
void DrillToFileComponent::AsyncWritePump()
{
AZStd::unique_lock<AZStd::mutex> signalLock(m_writerMutex);
AZStd::basic_string<char, AZStd::char_traits<char>, AZ::OSStdAllocator> drillerOutputPath;
// Try the log path first
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
if (fileIO)
{
const char* logLocation = fileIO->GetAlias("@log@");
if (logLocation)
{
drillerOutputPath = logLocation;
drillerOutputPath.append("/");
}
}
// Try the executable path
if (drillerOutputPath.empty())
{
EBUS_EVENT_RESULT(drillerOutputPath, AZ::ComponentApplicationBus, GetExecutableFolder);
drillerOutputPath.append("/");
}
drillerOutputPath.append("drillerdata.drl");
AZ::IO::SystemFile output;
output.Open(drillerOutputPath.c_str(), AZ::IO::SystemFile::SF_OPEN_CREATE | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY);
AZ_Assert(output.IsOpen(), "Failed to open driller output file!");
m_signal.notify_all();
while (true)
{
while (!m_writeQueue.empty())
{
AZStd::vector<AZ::u8, AZ::OSStdAllocator> outBuffer;
outBuffer.swap(m_writeQueue.front());
m_writeQueue.pop_front();
signalLock.unlock();
output.Write(outBuffer.data(), outBuffer.size());
output.Flush();
signalLock.lock();
}
if (!m_isWriterEnabled)
{
break;
}
m_signal.wait(signalLock);
}
output.Close();
}
} // namespace AzFramework
@@ -1,74 +0,0 @@
/*
* 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
*
*/
#pragma once
#include <AzFramework/Driller/DrillerConsoleAPI.h>
#include <AzCore/Driller/Driller.h>
#include <AzCore/Driller/DefaultStringPool.h>
#include <AzCore/Component/Component.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/containers/deque.h>
#include <AzCore/std/parallel/condition_variable.h>
//#define ENABLE_COMPRESSION_FOR_REMOTE_DRILLER
namespace AZ
{
struct ClassDataReflection;
}
namespace AzFramework
{
/**
* Runs on the machine being drilled and is responsible for communications
* with the DrillerNetworkConsole running on the tool side as well as
* creating DrillerNetSessionStreams for each driller session being started.
*/
class DrillToFileComponent
: public AZ::Component
, public AZ::Debug::DrillerOutputStream
, public DrillerConsoleCommandBus::Handler
{
public:
AZ_COMPONENT(DrillToFileComponent, "{42BAA25D-7CEB-4A37-8BD4-4A1FE2253894}")
//////////////////////////////////////////////////////////////////////////
// AZ::Component
static void Reflect(AZ::ReflectContext* context);
void Activate() override;
void Deactivate() override;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// DrillerOutputStream
void WriteBinary(const void* data, unsigned int dataSize) override;
void OnEndOfFrame() override;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// DrillerConsoleCommandBus
void EnumerateAvailableDrillers() override;
void StartDrillerSession(const AZ::Debug::DrillerManager::DrillerListType& requestedDrillers, AZ::u64 sessionId) override;
void StopDrillerSession(AZ::u64 sessionId) override;
//////////////////////////////////////////////////////////////////////////
protected:
void AsyncWritePump();
AZ::u64 m_sessionId;
AZ::Debug::DrillerSession* m_drillerSession;
AZ::Debug::DrillerDefaultStringPool m_stringPool;
AZStd::vector<AZ::u8, AZ::OSStdAllocator> m_frameBuffer;
AZStd::deque<AZStd::vector<AZ::u8, AZ::OSStdAllocator>, AZ::OSStdAllocator> m_writeQueue;
AZStd::mutex m_writerMutex;
AZStd::condition_variable m_signal;
AZStd::thread m_writerThread;
bool m_isWriterEnabled;
};
} // namespace AzFramework
@@ -1,79 +0,0 @@
/*
* 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
*
*/
#pragma once
#include <AzCore/Driller/Driller.h>
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/EBus/EBus.h>
namespace AzFramework
{
/*
* Descriptors for drillers available on the target machine.
*/
struct DrillerInfo final
{
AZ_RTTI(DrillerInfo, "{197AC318-B65C-4B36-A109-BD25422BF7D0}");
AZ::u32 m_id;
AZStd::string m_groupName;
AZStd::string m_name;
AZStd::string m_description;
};
typedef AZStd::vector<DrillerInfo> DrillerInfoListType;
typedef AZStd::vector<AZ::u32> DrillerListType;
/**
* Driller clients interested in receiving notification events from the
* console should implement this interface.
*/
class DrillerConsoleEvents
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
typedef AZ::OSStdAllocator AllocatorType;
//////////////////////////////////////////////////////////////////////////
virtual ~DrillerConsoleEvents() {}
// A list of available drillers has been received from the target machine.
virtual void OnDrillersEnumerated(const DrillerInfoListType& availableDrillers) = 0;
virtual void OnDrillerSessionStarted(AZ::u64 sessionId) = 0;
virtual void OnDrillerSessionStopped(AZ::u64 sessionId) = 0;
};
typedef AZ::EBus<DrillerConsoleEvents> DrillerConsoleEventBus;
/**
* Commands can be sent to the driller through this interface.
*/
class DrillerConsoleCommands
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
typedef AZ::OSStdAllocator AllocatorType;
// there's only one driller console instance allowed
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
virtual ~DrillerConsoleCommands() {}
// Request an enumeration of available drillers from the target machine
virtual void EnumerateAvailableDrillers() = 0;
// Start a drilling session. This function is normally called internally by DrillerRemoteSession
virtual void StartDrillerSession(const AZ::Debug::DrillerManager::DrillerListType& requestedDrillers, AZ::u64 sessionId) = 0;
// Stop a drilling session. This function is normally called internally by DrillerRemoteSession
virtual void StopDrillerSession(AZ::u64 sessionId) = 0;
};
typedef AZ::EBus<DrillerConsoleCommands> DrillerConsoleCommandBus;
} // namespace AzFramework
@@ -1,740 +0,0 @@
/*
* 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 <AzFramework/Driller/RemoteDrillerInterface.h>
#include <AzCore/Component/Component.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Driller/Driller.h>
#include <AzCore/Driller/Stream.h>
#include <AzCore/Driller/DefaultStringPool.h>
#include <AzCore/std/containers/fixed_vector.h>
#include <AzCore/Math/Crc.h>
#include <AzCore/Component/TickBus.h>
namespace AzFramework
{
//---------------------------------------------------------------------
// TEMP FOR DEBUGGING ONLY!!!
//---------------------------------------------------------------------
class DebugDrillerRemoteSession
: public DrillerRemoteSession
{
public:
AZ_CLASS_ALLOCATOR(DebugDrillerRemoteSession, AZ::OSAllocator, 0);
DebugDrillerRemoteSession()
{
AZStd::string filename = AZStd::string::format("remotedrill_%llu", static_cast<AZ::u64>(reinterpret_cast<size_t>(static_cast<DrillerRemoteSession*>(this))));
m_file.Open(filename.c_str(), AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY | AZ::IO::SystemFile::SF_OPEN_CREATE);
}
~DebugDrillerRemoteSession()
{
m_file.Close();
}
virtual void ProcessIncomingDrillerData(const char* streamIdentifier, const void* data, size_t dataSize)
{
(void)streamIdentifier;
m_file.Write(data, dataSize);
}
virtual void OnDrillerConnectionLost()
{
delete this;
}
AZ::IO::SystemFile m_file;
};
//---------------------------------------------------------------------
/**
* These are the different synchronization messages that are used.
*/
namespace NetworkDrillerSyncMsgId
{
static const AZ::Crc32 NetDrillMsg_RequestDrillerEnum = AZ_CRC("NetDrillMsg_RequestEnum", 0x517cca25);
static const AZ::Crc32 NetDrillMsg_RequestStartSession = AZ_CRC("NetDrillMsg_RequestStartSession", 0x5238b5fe);
static const AZ::Crc32 NetDrillMsg_RequestStopSession = AZ_CRC("NetDrillMsg_RequestStopSession", 0x1abe6888);
static const AZ::Crc32 NetDrillMsg_DrillerEnum = AZ_CRC("NetDrillMsg_Enum", 0x3d0a0f76);
};
struct NetDrillerStartSessionRequest
: public TmMsg
{
AZ_CLASS_ALLOCATOR(NetDrillerStartSessionRequest, AZ::OSAllocator, 0);
AZ_RTTI(NetDrillerStartSessionRequest, "{FF899D61-A445-44B5-9B67-8319ACC8BB06}");
NetDrillerStartSessionRequest()
: TmMsg(NetworkDrillerSyncMsgId::NetDrillMsg_RequestStartSession) {}
// TODO: Replace this with the DrillerListType from driller.h
DrillerListType m_drillerIds;
AZ::u64 m_sessionId;
};
struct NetDrillerStopSessionRequest
: public TmMsg
{
AZ_CLASS_ALLOCATOR(NetDrillerStopSessionRequest, AZ::OSAllocator, 0);
AZ_RTTI(NetDrillerStopSessionRequest, "{BCC6524F-287F-48D2-A21A-029215DB24DD}");
NetDrillerStopSessionRequest(AZ::u64 sessionId = 0)
: TmMsg(NetworkDrillerSyncMsgId::NetDrillMsg_RequestStopSession)
, m_sessionId(sessionId) {}
AZ::u64 m_sessionId;
};
struct NetDrillerEnumeration
: public TmMsg
{
AZ_CLASS_ALLOCATOR(NetDrillerEnumeration, AZ::OSAllocator, 0);
AZ_RTTI(NetDrillerEnumeration, "{60E5BED2-F492-4A55-8EF6-2628CD390991}");
NetDrillerEnumeration()
: TmMsg(NetworkDrillerSyncMsgId::NetDrillMsg_DrillerEnum) {}
DrillerInfoListType m_enumeration;
};
//---------------------------------------------------------------------
// DrillerRemoteSession
//---------------------------------------------------------------------
DrillerRemoteSession::DrillerRemoteSession()
#ifdef ENABLE_COMPRESSION_FOR_REMOTE_DRILLER
: m_decompressor(&AZ::AllocatorInstance<AZ::OSAllocator>::Get())
#endif
{
}
//---------------------------------------------------------------------
DrillerRemoteSession::~DrillerRemoteSession()
{
}
//---------------------------------------------------------------------
void DrillerRemoteSession::StartDrilling(const DrillerListType& drillers, const char* captureFile)
{
if (captureFile)
{
m_captureFile.Open(captureFile, AZ::IO::SystemFile::SF_OPEN_CREATE | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY);
AZ_Warning("DrillerRemoteSession", m_captureFile.IsOpen(), "Failed to open %s. Driller data will not be saved.", captureFile);
}
#ifdef ENABLE_COMPRESSION_FOR_REMOTE_DRILLER
m_decompressor.StartDecompressor();
#endif
BusConnect(static_cast<AZ::u64>(reinterpret_cast<size_t>(this)));
EBUS_EVENT(DrillerNetworkConsoleCommandBus, StartRemoteDrillerSession, drillers, this);
}
//---------------------------------------------------------------------
void DrillerRemoteSession::StopDrilling()
{
EBUS_EVENT(DrillerNetworkConsoleCommandBus, StopRemoteDrillerSession, static_cast<AZ::u64>(reinterpret_cast<size_t>(this)));
BusDisconnect();
#ifdef ENABLE_COMPRESSION_FOR_REMOTE_DRILLER
if (m_decompressor.IsDecompressorStarted())
{
m_decompressor.StopDecompressor();
}
#endif
m_captureFile.Close();
}
//---------------------------------------------------------------------
void DrillerRemoteSession::LoadCaptureData(const char* fileName)
{
m_captureFile.Open(fileName, AZ::IO::SystemFile::SF_OPEN_READ_ONLY);
AZ_Warning("DrillerRemoteSession", m_captureFile.IsOpen(), "Failed to open %s. No driller data could be loaded.", fileName);
if (m_captureFile.IsOpen())
{
#ifdef ENABLE_COMPRESSION_FOR_REMOTE_DRILLER
m_decompressor.StartDecompressor();
#endif
AZ::IO::SystemFile::SizeType bytesRemaining = m_captureFile.Length();
AZ::IO::SystemFile::SizeType maxReadChunkSize = 1024 * 1024;
AZStd::vector<char> readBuffer;
readBuffer.resize_no_construct(static_cast<size_t>(maxReadChunkSize));
while (bytesRemaining > 0)
{
AZ::IO::SystemFile::SizeType bytesToRead = bytesRemaining < maxReadChunkSize ? bytesRemaining : maxReadChunkSize;
if (m_captureFile.Read(bytesToRead, readBuffer.data()) != bytesToRead)
{
AZ_Warning("DrillerRemoteSession", false, "Failed reading driller data. No more driller data can be read.");
break;
}
#ifdef ENABLE_COMPRESSION_FOR_REMOTE_DRILLER
Decompress(readBuffer.data(), static_cast<size_t>(bytesToRead));
ProcessIncomingDrillerData(fileName, m_uncompressedMsgBuffer.data(), m_uncompressedMsgBuffer.size());
#else
ProcessIncomingDrillerData(fileName, readBuffer.data(), readBuffer.size());
#endif
bytesRemaining -= bytesToRead;
}
#ifdef ENABLE_COMPRESSION_FOR_REMOTE_DRILLER
m_decompressor.StopDecompressor();
#endif
m_captureFile.Close();
}
}
//---------------------------------------------------------------------
void DrillerRemoteSession::OnReceivedMsg(TmMsgPtr msg)
{
AZ_Assert(msg->GetCustomBlob(), "Missing driller frame data!");
if (msg->GetCustomBlobSize() == 0)
{
return;
}
if (m_captureFile.IsOpen())
{
if (m_captureFile.Write(msg->GetCustomBlob(), msg->GetCustomBlobSize()) != msg->GetCustomBlobSize())
{
AZ_Warning("DrillerRemoteSession", false, "Failed writing capture data to %s, no more data will be written out.", m_captureFile.Name());
m_captureFile.Close();
}
}
#ifdef ENABLE_COMPRESSION_FOR_REMOTE_DRILLER
Decompress(msg->GetCustomBlob(), msg->GetCustomBlobSize());
ProcessIncomingDrillerData(m_captureFile.Name(),m_uncompressedMsgBuffer.data(), m_uncompressedMsgBuffer.size());
#else
ProcessIncomingDrillerData(m_captureFile.Name(),msg->GetCustomBlob(), msg->GetCustomBlobSize());
#endif
}
//---------------------------------------------------------------------
void DrillerRemoteSession::Decompress(const void* compressedBuffer, size_t compressedBufferSize)
{
m_uncompressedMsgBuffer.clear();
if (m_uncompressedMsgBuffer.capacity() < compressedBufferSize * 10)
{
m_uncompressedMsgBuffer.reserve(compressedBufferSize * 10);
}
#if defined(ENABLE_COMPRESSION_FOR_REMOTE_DRILLER)
unsigned int compressedBytesRemaining = static_cast<unsigned int>(compressedBufferSize);
unsigned int decompressedBytes = 0;
while (compressedBytesRemaining > 0)
{
unsigned int uncompressedBytes = c_decompressionBufferSize;
unsigned int bytesConsumed = m_decompressor.Decompress(reinterpret_cast<const char*>(compressedBuffer) + decompressedBytes, compressedBytesRemaining, m_decompressionBuffer, uncompressedBytes);
decompressedBytes += bytesConsumed;
compressedBytesRemaining -= bytesConsumed;
m_uncompressedMsgBuffer.insert(m_uncompressedMsgBuffer.end(), &m_decompressionBuffer[0], &m_decompressionBuffer[uncompressedBytes]);
}
#else
m_uncompressedMsgBuffer.insert(m_uncompressedMsgBuffer.end(), &((char*)compressedBuffer)[0], &((char*)compressedBuffer)[compressedBufferSize]);
#endif
}
//---------------------------------------------------------------------
//---------------------------------------------------------------------
// DrillerNetSessionStream
//---------------------------------------------------------------------
/**
* Represents a driller session on the target machine.
* It is responsible for listening for driller events and forwarding
* them to the console machine.
*/
class DrillerNetSessionStream
: public AZ::Debug::DrillerOutputStream
, AZ::SystemTickBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(DrillerNetSessionStream, AZ::OSAllocator, 0);
DrillerNetSessionStream(AZ::u64 sessionId);
~DrillerNetSessionStream();
//---------------------------------------------------------------------
// DrillerOutputStream
//---------------------------------------------------------------------
virtual void WriteBinary(const void* data, unsigned int dataSize);
virtual void OnEndOfFrame();
//---------------------------------------------------------------------
//---------------------------------------------------------------------
// AZ::SystemTickBus
//---------------------------------------------------------------------
void OnSystemTick() override;
//---------------------------------------------------------------------
static const size_t c_defaultUncompressedBufferSize = 256 * 1024;
static const size_t c_defaultCompressedBufferSize = 32 * 1024;
static const size_t c_bufferCount = 2;
AZ::Debug::DrillerSession* m_session;
AZ::u64 m_sessionId;
TargetInfo m_requestor;
size_t m_activeBuffer;
AZStd::vector<char, AZ::OSStdAllocator> m_uncompressedBuffer[c_bufferCount];
AZStd::vector<char, AZ::OSStdAllocator> m_compressedBuffer[c_bufferCount];
#ifdef ENABLE_COMPRESSION_FOR_REMOTE_DRILLER
// Compression
AZ::ZLib m_compressor;
AZStd::fixed_vector<char, c_defaultCompressedBufferSize> m_compressionBuffer;
#endif
// String Pooling
AZ::Debug::DrillerDefaultStringPool m_stringPool;
// TEMP Debug
//AZ::IO::SystemFile m_file;
};
DrillerNetSessionStream::DrillerNetSessionStream(AZ::u64 sessionId)
: m_session(NULL)
, m_sessionId(sessionId)
, m_activeBuffer(0)
#ifdef ENABLE_COMPRESSION_FOR_REMOTE_DRILLER
, m_compressor(&AZ::AllocatorInstance<AZ::OSAllocator>::Get())
#endif
{
for (size_t i = 0; i < c_bufferCount; ++i)
{
m_uncompressedBuffer[i].reserve(c_defaultUncompressedBufferSize);
m_compressedBuffer[i].reserve(c_defaultCompressedBufferSize);
}
#ifdef ENABLE_COMPRESSION_FOR_REMOTE_DRILLER
// Level 3 compression seems to give pretty good compression at decent speed.
// Speed is paramount for us because initial driller packets can be huge and
// we need to be able to compress the data within the driller report call
// without blocking for too long.
m_compressor.StartCompressor(3);
#endif
SetStringPool(&m_stringPool);
AZ::SystemTickBus::Handler::BusConnect();
}
//---------------------------------------------------------------------
DrillerNetSessionStream::~DrillerNetSessionStream()
{
#ifdef ENABLE_COMPRESSION_FOR_REMOTE_DRILLER
m_compressor.StopCompressor();
#endif
// Debug
//m_file.Close();
}
//---------------------------------------------------------------------
void DrillerNetSessionStream::WriteBinary(const void* data, unsigned int dataSize)
{
size_t activeBuffer = m_activeBuffer;
if (dataSize > 0)
{
#ifdef ENABLE_COMPRESSION_FOR_REMOTE_DRILLER
// Only do the compression when the buffer is full so we don't run the compression all the time
if (m_uncompressedBuffer[activeBuffer].size() + dataSize > c_defaultUncompressedBufferSize)
{
// compress
unsigned int curDataSize = static_cast<unsigned int>(m_uncompressedBuffer[activeBuffer].size());
unsigned int remaining = curDataSize;
while (remaining > 0)
{
unsigned int processedBytes = curDataSize - remaining;
unsigned int compressedBytes = m_compressor.Compress(m_uncompressedBuffer[activeBuffer].data() + processedBytes, remaining, m_compressionBuffer.data(), static_cast<unsigned int>(c_defaultCompressedBufferSize));
if (compressedBytes > 0)
{
m_compressedBuffer[activeBuffer].insert(m_compressedBuffer[activeBuffer].end(), m_compressionBuffer.data(), m_compressionBuffer.data() + compressedBytes);
}
}
m_uncompressedBuffer[activeBuffer].clear();
}
m_uncompressedBuffer[activeBuffer].insert(m_uncompressedBuffer[activeBuffer].end(), reinterpret_cast<const char*>(data), reinterpret_cast<const char*>(data) + dataSize);
#else
// Since we are not compressing, transfer the input directly into our compressed buffer
m_compressedBuffer[activeBuffer].insert(m_compressedBuffer[activeBuffer].end(), reinterpret_cast<const char*>(data), reinterpret_cast<const char*>(data) + dataSize);
#endif
}
}
//---------------------------------------------------------------------
void DrillerNetSessionStream::OnEndOfFrame()
{
size_t activeBuffer = m_activeBuffer;
#ifdef ENABLE_COMPRESSION_FOR_REMOTE_DRILLER
// Write whatever data has not yet been compressed and flush the compressor
unsigned int curDataSize = static_cast<unsigned int>(m_uncompressedBuffer[activeBuffer].size());
unsigned int remaining = curDataSize;
unsigned int compressedBytes = 0;
do
{
unsigned int processedBytes = curDataSize - remaining;
compressedBytes = m_compressor.Compress(m_uncompressedBuffer[activeBuffer].data() + processedBytes, remaining, m_compressionBuffer.data(), static_cast<unsigned int>(c_defaultCompressedBufferSize), AZ::ZLib::FT_SYNC_FLUSH);
if (compressedBytes > 0)
{
m_compressedBuffer[activeBuffer].insert(m_compressedBuffer[activeBuffer].end(), m_compressionBuffer.data(), m_compressionBuffer.data() + compressedBytes);
}
} while (compressedBytes > 0 || remaining > 0);
#endif
m_activeBuffer = (activeBuffer + 1) % 2; // switch buffers
}
//-------------------------------------------------------------------------
void DrillerNetSessionStream::OnSystemTick()
{
// The buffer index we want to send is the one we wrote to in the previous frame.
size_t bufferIndex = (m_activeBuffer + 1) % 2;
if (m_compressedBuffer[bufferIndex].empty())
{
return;
}
TmMsg msg(m_sessionId);
msg.AddCustomBlob(m_compressedBuffer[bufferIndex].data(), m_compressedBuffer[bufferIndex].size());
EBUS_EVENT(TargetManager::Bus, SendTmMessage, m_requestor, msg);
// Debug
//if (!m_file.IsOpen())
//{
// AZStd::string filename = AZStd::string::format("localdrill_%llu", m_sessionId);
// m_file.Open(filename.c_str(), AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY | AZ::IO::SystemFile::SF_OPEN_CREATE);
//}
//m_file.Write(msg.GetCustomBlob(), msg.GetCustomBlobSize());
// Reset buffers
m_uncompressedBuffer[bufferIndex].clear();
m_compressedBuffer[bufferIndex].clear();
// Buffers may grow during exceptional circumstances. Re-shrink them to their default sizes
// so we don't keep holding on to the memory.
m_uncompressedBuffer[bufferIndex].reserve(c_defaultUncompressedBufferSize);
m_compressedBuffer[bufferIndex].reserve(c_defaultCompressedBufferSize);
}
//---------------------------------------------------------------------
//---------------------------------------------------------------------
// DrillerNetworkAgent
//---------------------------------------------------------------------
void DrillerNetworkAgentComponent::Init()
{
m_cbDrillerEnumRequest = TmMsgCallback(AZStd::bind(&DrillerNetworkAgentComponent::OnRequestDrillerEnum, this, AZStd::placeholders::_1));
m_cbDrillerStartRequest = TmMsgCallback(AZStd::bind(&DrillerNetworkAgentComponent::OnRequestDrillerStart, this, AZStd::placeholders::_1));
m_cbDrillerStopRequest = TmMsgCallback(AZStd::bind(&DrillerNetworkAgentComponent::OnRequestDrillerStop, this, AZStd::placeholders::_1));
}
//---------------------------------------------------------------------
void DrillerNetworkAgentComponent::Activate()
{
m_cbDrillerEnumRequest.BusConnect(NetworkDrillerSyncMsgId::NetDrillMsg_RequestDrillerEnum);
m_cbDrillerStartRequest.BusConnect(NetworkDrillerSyncMsgId::NetDrillMsg_RequestStartSession);
m_cbDrillerStopRequest.BusConnect(NetworkDrillerSyncMsgId::NetDrillMsg_RequestStopSession);
TargetManagerClient::Bus::Handler::BusConnect();
}
//---------------------------------------------------------------------
void DrillerNetworkAgentComponent::Deactivate()
{
TargetManagerClient::Bus::Handler::BusDisconnect();
m_cbDrillerEnumRequest.BusDisconnect(NetworkDrillerSyncMsgId::NetDrillMsg_RequestDrillerEnum);
m_cbDrillerStartRequest.BusDisconnect(NetworkDrillerSyncMsgId::NetDrillMsg_RequestStartSession);
m_cbDrillerStopRequest.BusDisconnect(NetworkDrillerSyncMsgId::NetDrillMsg_RequestStopSession);
AZ::Debug::DrillerManager* mgr = NULL;
EBUS_EVENT_RESULT(mgr, AZ::ComponentApplicationBus, GetDrillerManager);
for (size_t i = 0; i < m_activeSessions.size(); ++i)
{
if (mgr)
{
mgr->Stop(m_activeSessions[i]->m_session);
}
delete m_activeSessions[i];
}
m_activeSessions.clear();
}
//---------------------------------------------------------------------
void DrillerNetworkAgentComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC("DrillerNetworkAgentService", 0xcd2ab821));
}
//---------------------------------------------------------------------
void DrillerNetworkAgentComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC("DrillerNetworkAgentService", 0xcd2ab821));
}
//---------------------------------------------------------------------
void DrillerNetworkAgentComponent::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<DrillerNetworkAgentComponent, AZ::Component>()
->Version(1)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<DrillerNetworkAgentComponent>(
"Driller Network Agent", "Runs on the machine being drilled and communicates with tools")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "Profiling")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b))
;
}
ReflectNetDrillerClasses(context);
}
}
//---------------------------------------------------------------------
void DrillerNetworkAgentComponent::TargetLeftNetwork(TargetInfo info)
{
AZ::Debug::DrillerManager* mgr = NULL;
EBUS_EVENT_RESULT(mgr, AZ::ComponentApplicationBus, GetDrillerManager);
for (AZStd::vector<DrillerNetSessionStream*>::iterator it = m_activeSessions.begin(); it != m_activeSessions.end(); )
{
if ((*it)->m_requestor.GetNetworkId() == info.GetNetworkId())
{
if (mgr)
{
mgr->Stop((*it)->m_session);
}
delete *it;
it = m_activeSessions.erase(it);
}
else
{
++it;
}
}
}
//---------------------------------------------------------------------
void DrillerNetworkAgentComponent::OnRequestDrillerEnum(TmMsgPtr msg)
{
AZ::Debug::DrillerManager* mgr = NULL;
EBUS_EVENT_RESULT(mgr, AZ::ComponentApplicationBus, GetDrillerManager);
if (!mgr)
{
return;
}
TargetInfo sendTo;
EBUS_EVENT_RESULT(sendTo, TargetManager::Bus, GetTargetInfo, msg->GetSenderTargetId());
NetDrillerEnumeration drillerEnum;
for (int i = 0; i < mgr->GetNumDrillers(); ++i)
{
AZ::Debug::Driller* driller = mgr->GetDriller(i);
AZ_Assert(driller, "DrillerManager returned a NULL driller. This is not legal!");
drillerEnum.m_enumeration.push_back();
drillerEnum.m_enumeration.back().m_id = driller->GetId();
drillerEnum.m_enumeration.back().m_groupName = driller->GroupName();
drillerEnum.m_enumeration.back().m_name = driller->GetName();
drillerEnum.m_enumeration.back().m_description = driller->GetDescription();
}
EBUS_EVENT(TargetManager::Bus, SendTmMessage, sendTo, drillerEnum);
}
//---------------------------------------------------------------------
void DrillerNetworkAgentComponent::OnRequestDrillerStart(TmMsgPtr msg)
{
AZ::Debug::DrillerManager* mgr = NULL;
EBUS_EVENT_RESULT(mgr, AZ::ComponentApplicationBus, GetDrillerManager);
if (!mgr)
{
return;
}
NetDrillerStartSessionRequest* request = azdynamic_cast<NetDrillerStartSessionRequest*>(msg.get());
AZ_Assert(request, "Not a NetDrillerStartSessionRequest msg!");
AZ::Debug::DrillerManager::DrillerListType drillers;
for (size_t i = 0; i < request->m_drillerIds.size(); ++i)
{
AZ::Debug::DrillerManager::DrillerInfo di;
di.id = request->m_drillerIds[i];
drillers.push_back(di);
}
DrillerNetSessionStream* session = aznew DrillerNetSessionStream(request->m_sessionId);
EBUS_EVENT_RESULT(session->m_requestor, TargetManager::Bus, GetTargetInfo, msg->GetSenderTargetId());
m_activeSessions.push_back(session);
session->m_session = mgr->Start(*session, drillers);
}
//---------------------------------------------------------------------
void DrillerNetworkAgentComponent::OnRequestDrillerStop(TmMsgPtr msg)
{
NetDrillerStopSessionRequest* request = azdynamic_cast<NetDrillerStopSessionRequest*>(msg.get());
for (AZStd::vector<DrillerNetSessionStream*>::iterator it = m_activeSessions.begin(); it != m_activeSessions.end(); ++it)
{
if ((*it)->m_sessionId == request->m_sessionId)
{
AZ::Debug::DrillerManager* mgr = NULL;
EBUS_EVENT_RESULT(mgr, AZ::ComponentApplicationBus, GetDrillerManager);
if (mgr)
{
mgr->Stop((*it)->m_session);
}
delete *it;
m_activeSessions.erase(it);
return;
}
}
}
//---------------------------------------------------------------------
//---------------------------------------------------------------------
// DrillerRemoteConsole
//---------------------------------------------------------------------
void DrillerNetworkConsoleComponent::Init()
{
m_cbDrillerEnum = TmMsgCallback(AZStd::bind(&DrillerNetworkConsoleComponent::OnReceivedDrillerEnum, this, AZStd::placeholders::_1));
}
//---------------------------------------------------------------------
void DrillerNetworkConsoleComponent::Activate()
{
m_cbDrillerEnum.BusConnect(NetworkDrillerSyncMsgId::NetDrillMsg_DrillerEnum);
DrillerNetworkConsoleCommandBus::Handler::BusConnect();
TargetManagerClient::Bus::Handler::BusConnect();
}
//---------------------------------------------------------------------
void DrillerNetworkConsoleComponent::Deactivate()
{
TargetManagerClient::Bus::Handler::BusDisconnect();
DrillerNetworkConsoleCommandBus::Handler::BusDisconnect();
m_cbDrillerEnum.BusDisconnect(NetworkDrillerSyncMsgId::NetDrillMsg_DrillerEnum);
for (size_t i = 0; i < m_activeSessions.size(); ++i)
{
EBUS_EVENT(TargetManager::Bus, SendTmMessage, m_curTarget, NetDrillerStopSessionRequest(static_cast<AZ::u64>(reinterpret_cast<size_t>(m_activeSessions[i]))));
m_activeSessions[i]->OnDrillerConnectionLost();
}
m_activeSessions.clear();
}
//---------------------------------------------------------------------
void DrillerNetworkConsoleComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC("DrillerNetworkConsoleService", 0x2286125d));
}
//---------------------------------------------------------------------
void DrillerNetworkConsoleComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC("DrillerNetworkConsoleService", 0x2286125d));
}
//---------------------------------------------------------------------
void DrillerNetworkConsoleComponent::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<DrillerNetworkConsoleComponent, AZ::Component>()
->Version(1)
;
if (AZ::EditContext* editContext = serialize->GetEditContext())
{
editContext->Class<DrillerNetworkConsoleComponent>(
"Driller Network Console", "Runs on the tool machine and is responsible for communications with the DrillerNetworkAgent")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "Profiling")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b))
;
}
ReflectNetDrillerClasses(context);
}
}
//---------------------------------------------------------------------
void DrillerNetworkConsoleComponent::EnumerateAvailableDrillers()
{
EBUS_EVENT(TargetManager::Bus, SendTmMessage, m_curTarget, TmMsg(NetworkDrillerSyncMsgId::NetDrillMsg_RequestDrillerEnum));
}
//---------------------------------------------------------------------
void DrillerNetworkConsoleComponent::StartRemoteDrillerSession(const DrillerListType& drillers, DrillerRemoteSession* handler)
{
NetDrillerStartSessionRequest request;
request.m_drillerIds = drillers;
request.m_sessionId = static_cast<AZ::u64>(reinterpret_cast<size_t>(handler));
m_activeSessions.push_back(handler);
EBUS_EVENT(TargetManager::Bus, SendTmMessage, m_curTarget, request);
}
//---------------------------------------------------------------------
void DrillerNetworkConsoleComponent::StopRemoteDrillerSession(AZ::u64 sessionId)
{
for (size_t i = 0; i < m_activeSessions.size(); ++i)
{
if (sessionId == static_cast<AZ::u64>(reinterpret_cast<size_t>(m_activeSessions[i])))
{
EBUS_EVENT(TargetManager::Bus, SendTmMessage, m_curTarget, NetDrillerStopSessionRequest(sessionId));
m_activeSessions[i] = m_activeSessions.back();
m_activeSessions.pop_back();
}
}
}
//---------------------------------------------------------------------
void DrillerNetworkConsoleComponent::DesiredTargetConnected(bool connected)
{
if (connected)
{
EBUS_EVENT_RESULT(m_curTarget, TargetManager::Bus, GetDesiredTarget);
EBUS_EVENT(DrillerNetworkConsoleCommandBus, EnumerateAvailableDrillers);
}
else
{
for (size_t i = 0; i < m_activeSessions.size(); ++i)
{
m_activeSessions[i]->OnDrillerConnectionLost();
}
m_activeSessions.clear();
EBUS_EVENT(DrillerNetworkConsoleEventBus, OnReceivedDrillerEnumeration, DrillerInfoListType());
}
}
//---------------------------------------------------------------------
void DrillerNetworkConsoleComponent::DesiredTargetChanged(AZ::u32 newTargetID, AZ::u32 oldTargetID)
{
(void)oldTargetID;
(void)newTargetID;
EBUS_EVENT(DrillerNetworkConsoleEventBus, OnReceivedDrillerEnumeration, DrillerInfoListType());
for (size_t i = 0; i < m_activeSessions.size(); ++i)
{
EBUS_EVENT(TargetManager::Bus, SendTmMessage, m_curTarget, NetDrillerStopSessionRequest(static_cast<AZ::u64>(reinterpret_cast<size_t>(m_activeSessions[i]))));
m_activeSessions[i]->OnDrillerConnectionLost();
}
m_activeSessions.clear();
}
//---------------------------------------------------------------------
void DrillerNetworkConsoleComponent::OnReceivedDrillerEnum(TmMsgPtr msg)
{
NetDrillerEnumeration* drillerEnum = azdynamic_cast<NetDrillerEnumeration*>(msg.get());
AZ_Assert(drillerEnum, "No NetDrillerEnumeration message!");
EBUS_EVENT(DrillerNetworkConsoleEventBus, OnReceivedDrillerEnumeration, drillerEnum->m_enumeration);
}
//---------------------------------------------------------------------
//---------------------------------------------------------------------
// ReflectNetDrillerClasses
//---------------------------------------------------------------------
void ReflectNetDrillerClasses(AZ::ReflectContext* context)
{
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
// Assume no one else will register our classes.
if (serialize->FindClassData(DrillerInfo::RTTI_Type()) == nullptr)
{
serialize->Class<DrillerInfo>()
->Field("Id", &DrillerInfo::m_id)
->Field("GroupName", &DrillerInfo::m_groupName)
->Field("Name", &DrillerInfo::m_name)
->Field("Description", &DrillerInfo::m_description);
serialize->Class<NetDrillerStartSessionRequest, TmMsg>()
->Field("DrillerIds", &NetDrillerStartSessionRequest::m_drillerIds)
->Field("SessionId", &NetDrillerStartSessionRequest::m_sessionId);
serialize->Class<NetDrillerStopSessionRequest, TmMsg>()
->Field("SessionId", &NetDrillerStopSessionRequest::m_sessionId);
serialize->Class<NetDrillerEnumeration, TmMsg>()
->Field("Enumeration", &NetDrillerEnumeration::m_enumeration);
}
}
}
//---------------------------------------------------------------------
} // namespace AzFramework
@@ -1,217 +0,0 @@
/*
* 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
*
*/
#ifndef AZFRAMEWORK_REMOTE_DRILLER_INTERFACE_H
#define AZFRAMEWORK_REMOTE_DRILLER_INTERFACE_H
#include <AzCore/Driller/Driller.h>
#include <AzCore/Compression/Compression.h>
#include <AzCore/Component/Component.h>
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzFramework/Driller/DrillerConsoleAPI.h>
#include <AzFramework/TargetManagement/TargetManagementAPI.h>
//#define ENABLE_COMPRESSION_FOR_REMOTE_DRILLER
namespace AZ
{
struct ClassDataReflection;
}
namespace AzFramework
{
/**
* Represents a remote driller session on the tool machine.
* It is responsible for receiving and processing remote driller data.
* Driller clients should derive from this class and implement the virtual interfaces.
*/
class DrillerRemoteSession
: public TmMsgBus::Handler
{
public:
DrillerRemoteSession();
~DrillerRemoteSession();
// Called when new driller data arrives
virtual void ProcessIncomingDrillerData(const char* streamIdentifier, const void* data, size_t dataSize) = 0;
// Called when the connection to the driller is lost. The session should be deleted in response to this message
virtual void OnDrillerConnectionLost() = 0;
// Start drilling the selected drillers as part of this session
void StartDrilling(const DrillerListType& drillers, const char* captureFile);
// Stop this drill session
void StopDrilling();
// Replay a previously captured driller session from file
void LoadCaptureData(const char* fileName);
protected:
//---------------------------------------------------------------------
// TmMsgBus
//---------------------------------------------------------------------
virtual void OnReceivedMsg(TmMsgPtr msg);
//---------------------------------------------------------------------
void Decompress(const void* compressedBuffer, size_t compressedBufferSize);
static const AZ::u32 c_decompressionBufferSize = 128 * 1024;
AZStd::vector<char> m_uncompressedMsgBuffer;
#ifdef ENABLE_COMPRESSION_FOR_REMOTE_DRILLER
AZ::ZLib m_decompressor;
char m_decompressionBuffer[c_decompressionBufferSize];
#endif
AZ::IO::SystemFile m_captureFile;
};
/**
* Driller clients interested in receiving notification events from the
* network console should implement this interface.
*/
class DrillerNetworkConsoleEvents
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
typedef AZ::OSStdAllocator AllocatorType;
//////////////////////////////////////////////////////////////////////////
virtual ~DrillerNetworkConsoleEvents() {}
// A list of available drillers has been received from the target machine.
virtual void OnReceivedDrillerEnumeration(const DrillerInfoListType& availableDrillers) = 0;
};
typedef AZ::EBus<DrillerNetworkConsoleEvents> DrillerNetworkConsoleEventBus;
/**
* The network driller console implements this interface.
* Commands can be sent to the network console through this interface.
*/
class DrillerNetworkConsoleCommands
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
typedef AZ::OSStdAllocator AllocatorType;
// there's only one driller console instance allowed
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
virtual ~DrillerNetworkConsoleCommands() {}
// Request an enumeration of available drillers from the target machine
virtual void EnumerateAvailableDrillers() = 0;
// Start a drilling session. This function is normally called internally by DrillerRemoteSession
virtual void StartRemoteDrillerSession(const DrillerListType& drillers, DrillerRemoteSession* handler) = 0;
// Stop a drilling session. This function is normally called internally by DrillerRemoteSession
virtual void StopRemoteDrillerSession(AZ::u64 sessionId) = 0;
};
typedef AZ::EBus<DrillerNetworkConsoleCommands> DrillerNetworkConsoleCommandBus;
class DrillerNetSessionStream;
/**
* Runs on the machine being drilled and is responsible for communications
* with the DrillerNetworkConsole running on the tool side as well as
* creating DrillerNetSessionStreams for each driller session being started.
*/
class DrillerNetworkAgentComponent
: public AZ::Component
, public TargetManagerClient::Bus::Handler
{
public:
AZ_COMPONENT(DrillerNetworkAgentComponent, "{B587A74D-6190-4149-91CB-0EA69936BD59}")
//////////////////////////////////////////////////////////////////////////
// AZ::Component
virtual void Init();
virtual void Activate();
virtual void Deactivate();
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
static void Reflect(AZ::ReflectContext* context);
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// TargetManagerClient
virtual void TargetLeftNetwork(TargetInfo info);
//////////////////////////////////////////////////////////////////////////
protected:
//////////////////////////////////////////////////////////////////////////
// TmMsg handlers
virtual void OnRequestDrillerEnum(TmMsgPtr msg);
virtual void OnRequestDrillerStart(TmMsgPtr msg);
virtual void OnRequestDrillerStop(TmMsgPtr msg);
//////////////////////////////////////////////////////////////////////////
TmMsgCallback m_cbDrillerEnumRequest;
TmMsgCallback m_cbDrillerStartRequest;
TmMsgCallback m_cbDrillerStopRequest;
AZStd::vector<DrillerNetSessionStream*> m_activeSessions;
};
/**
* Runs on the tool machine and is responsible for communications with the
* DrillerNetworkAgent.
*/
class DrillerNetworkConsoleComponent
: public AZ::Component
, public DrillerNetworkConsoleCommandBus::Handler
, public TargetManagerClient::Bus::Handler
{
public:
AZ_COMPONENT(DrillerNetworkConsoleComponent, "{78ACADA4-F2C7-4320-8E97-59DD8B9BE33A}")
//////////////////////////////////////////////////////////////////////////
// AZ::Component
virtual void Init();
virtual void Activate();
virtual void Deactivate();
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
static void Reflect(AZ::ReflectContext* context);
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// DrillerNetworkConsoleCommandBus
virtual void EnumerateAvailableDrillers();
virtual void StartRemoteDrillerSession(const DrillerListType& drillers, DrillerRemoteSession* handler);
virtual void StopRemoteDrillerSession(AZ::u64 sessionId);
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// TargetManagerClient
virtual void DesiredTargetConnected(bool connected);
virtual void DesiredTargetChanged(AZ::u32 newTargetID, AZ::u32 oldTargetID);
//////////////////////////////////////////////////////////////////////////
protected:
//////////////////////////////////////////////////////////////////////////
// TmMsg handlers
virtual void OnReceivedDrillerEnum(TmMsgPtr msg);
//////////////////////////////////////////////////////////////////////////
typedef AZStd::vector<DrillerRemoteSession*> ActiveSessionListType;
ActiveSessionListType m_activeSessions;
TargetInfo m_curTarget;
TmMsgCallback m_cbDrillerEnum;
};
void ReflectNetDrillerClasses(AZ::ReflectContext* context);
} // namespace AzFramework
#endif // AZFRAMEWORK_REMOTE_DRILLER_INTERFACE_H
#pragma once
@@ -16,11 +16,14 @@
#ifndef AZFRAMEWORK_ENTITYCONTEXTBUS_H
#define AZFRAMEWORK_ENTITYCONTEXTBUS_H
#include <AzCore/Debug/Budget.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/Math/Uuid.h>
#include <AzCore/Asset/AssetCommon.h>
#include <AzCore/Component/ComponentBus.h>
AZ_DECLARE_BUDGET(AzFramework);
namespace AZ
{
class Entity;
@@ -10,6 +10,7 @@
#include <AzCore/Asset/AssetCommon.h>
#include <AzCore/Component/EntityId.h>
#include <AzCore/Debug/Budget.h>
#include <AzCore/Serialization/ObjectStream.h>
#include <AzFramework/Entity/EntityOwnershipServiceBus.h>
@@ -18,6 +19,8 @@ namespace AZ
class Entity;
}
AZ_DECLARE_BUDGET(AzFramework);
namespace AzFramework
{
// Types
@@ -33,6 +33,8 @@ extern "C" {
# include <Lua/lauxlib.h>
}
AZ_DEFINE_BUDGET(Script);
namespace ScriptComponentCpp
{
template<typename T>
@@ -239,10 +239,11 @@ namespace AzFramework
}
else if (rootSpawnableKeyType == AZ::SettingsRegistryInterface::Type::NoType)
{
AZ_Warning(
// [LYN-4146] - temporarily disabled
/*AZ_Warning(
"Spawnables", false,
"No root spawnable assigned. The root spawnable can be assigned in the Settings Registry under the key '%s'.\n",
RootSpawnableRegistryKey);
RootSpawnableRegistryKey);*/
ReleaseRootSpawnable();
}
}
@@ -10,6 +10,7 @@
#define AZFRAMEWORK_TARGETMANAGEMENTAPI_H
#include <AzCore/base.h>
#include <AzCore/Debug/Budget.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/std/containers/deque.h>
@@ -21,6 +22,8 @@
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/Memory/OSAllocator.h>
AZ_DECLARE_BUDGET(AzFramework);
namespace AZ
{
class ReflectContext;
@@ -144,6 +144,7 @@ namespace AzFramework
if (const auto& cursor = AZStd::get_if<CursorEvent>(&event))
{
m_cursorState.SetCurrentPosition(cursor->m_position);
m_cursorState.SetCaptured(cursor->m_captured);
}
else if (const auto& horizontalMotion = AZStd::get_if<HorizontalMotionEvent>(&event))
{
@@ -790,17 +791,24 @@ namespace AzFramework
const auto* position = inputChannel.GetCustomData<AzFramework::InputChannel::PositionData2D>();
AZ_Assert(position, "Expected PositionData2D but found nullptr");
return CursorEvent{ ScreenPoint(
static_cast<int>(position->m_normalizedPosition.GetX() * windowSize.m_width),
static_cast<int>(position->m_normalizedPosition.GetY() * windowSize.m_height)) };
auto currentCursorState = AzFramework::SystemCursorState::Unknown;
AzFramework::InputSystemCursorRequestBus::EventResult(
currentCursorState, inputDeviceId, &AzFramework::InputSystemCursorRequestBus::Events::GetSystemCursorState);
const auto x = position->m_normalizedPosition.GetX() * aznumeric_cast<float>(windowSize.m_width);
const auto y = position->m_normalizedPosition.GetY() * aznumeric_cast<float>(windowSize.m_height);
return CursorEvent{ ScreenPoint(aznumeric_cast<int>(AZStd::lround(x)), aznumeric_cast<int>(AZStd::lround(y))),
currentCursorState == AzFramework::SystemCursorState::ConstrainedAndHidden };
}
else if (inputChannelId == InputDeviceMouse::Movement::X)
{
return HorizontalMotionEvent{ aznumeric_cast<int>(inputChannel.GetValue()) };
const auto x = inputChannel.GetValue();
return HorizontalMotionEvent{ aznumeric_cast<int>(AZStd::lround(x)) };
}
else if (inputChannelId == InputDeviceMouse::Movement::Y)
{
return VerticalMotionEvent{ aznumeric_cast<int>(inputChannel.GetValue()) };
const auto y = inputChannel.GetValue();
return VerticalMotionEvent{ aznumeric_cast<int>(AZStd::lround(y)) };
}
else if (inputChannelId == InputDeviceMouse::Movement::Z)
{
@@ -88,6 +88,7 @@ namespace AzFramework
struct CursorEvent
{
ScreenPoint m_position;
bool m_captured = false;
};
struct ScrollEvent
@@ -21,6 +21,8 @@ namespace AzFramework
[[nodiscard]] ScreenVector CursorDelta() const;
//! Call this in a 'handle event' call to update the most recent cursor position.
void SetCurrentPosition(const ScreenPoint& currentPosition);
//! Set whether the cursor is currently being constrained (and hidden).
void SetCaptured(bool captured);
//! Call this in an 'update' call to copy the current cursor position to the last
//! cursor position.
void Update();
@@ -28,8 +30,14 @@ namespace AzFramework
private:
AZStd::optional<ScreenPoint> m_lastCursorPosition;
AZStd::optional<ScreenPoint> m_currentCursorPosition;
bool m_captured = false;
};
inline void CursorState::SetCaptured(const bool captured)
{
m_captured = captured;
}
inline void CursorState::SetCurrentPosition(const ScreenPoint& currentPosition)
{
m_currentCursorPosition = currentPosition;
@@ -44,9 +52,16 @@ namespace AzFramework
inline void CursorState::Update()
{
if (m_currentCursorPosition.has_value())
if (!m_captured)
{
m_lastCursorPosition = m_currentCursorPosition;
if (m_currentCursorPosition.has_value())
{
m_lastCursorPosition = m_currentCursorPosition;
}
}
else
{
m_currentCursorPosition = m_lastCursorPosition;
}
}
} // namespace AzFramework
@@ -12,6 +12,8 @@
#include <AzFramework/Visibility/BoundsBus.h>
#include <cstring>
AZ_DECLARE_BUDGET(AzFramework);
namespace AzFramework
{
EntityVisibilityBoundsUnionSystem::EntityVisibilityBoundsUnionSystem()
@@ -123,11 +123,6 @@ set(FILES
Entity/SliceGameEntityOwnershipServiceBus.h
Entity/PrefabEntityOwnershipService.h
Entity/PrefabEntityOwnershipService.cpp
Driller/RemoteDrillerInterface.cpp
Driller/RemoteDrillerInterface.h
Driller/DrillerConsoleAPI.h
Driller/DrillToFileComponent.h
Driller/DrillToFileComponent.cpp
Components/ComponentAdapter.h
Components/ComponentAdapter.inl
Components/ComponentAdapterHelpers.h
@@ -38,7 +38,7 @@ TEST_F(PlatformHelperTest, SpecialAllFlag_PlatformId_Valid)
AzFramework::PlatformFlags platformFlags = AzFramework::PlatformFlags::Platform_ALL;
auto platforms = AzFramework::PlatformHelper::GetPlatformsInterpreted(platformFlags);
EXPECT_EQ(platforms.size(), AzFramework::NumPlatforms);
EXPECT_THAT(platforms, testing::UnorderedElementsAre("pc", "android", "ios", "mac", "provo", "salem", "jasper", "server"));
EXPECT_THAT(platforms, testing::UnorderedElementsAre("pc", "linux", "android", "ios", "mac", "provo", "salem", "jasper", "server"));
}
TEST_F(PlatformHelperTest, SpecialAllClientFlag_PlatformId_Valid)
@@ -46,7 +46,7 @@ TEST_F(PlatformHelperTest, SpecialAllClientFlag_PlatformId_Valid)
AzFramework::PlatformFlags platformFlags = AzFramework::PlatformFlags::Platform_ALL_CLIENT;
auto platforms = AzFramework::PlatformHelper::GetPlatformsInterpreted(platformFlags);
EXPECT_EQ(platforms.size(), AzFramework::NumClientPlatforms);
EXPECT_THAT(platforms, testing::UnorderedElementsAre("pc", "android", "ios", "mac", "provo", "salem", "jasper"));
EXPECT_THAT(platforms, testing::UnorderedElementsAre("pc", "linux", "android", "ios", "mac", "provo", "salem", "jasper"));
}
TEST_F(PlatformHelperTest, InvalidPlatformFlags_PlatformId_Empty)
@@ -102,11 +102,7 @@ TEST_F(PlatformHelperTest, AppendPlatformCodeNames_ByValidName_OK)
{
AZStd::fixed_vector<AZStd::string_view, AzFramework::MaxPlatformCodeNames> platformCodes;
AzFramework::PlatformHelper::AppendPlatformCodeNames(platformCodes, AzFramework::PlatformPC);
ASSERT_EQ(2, platformCodes.size());
AZStd::string windows = platformCodes[0];
AZStd::string linux = platformCodes[1];
EXPECT_STRCASEEQ(AzFramework::PlatformCodeNameWindows, windows.c_str());
EXPECT_STRCASEEQ(AzFramework::PlatformCodeNameLinux, linux.c_str());
EXPECT_THAT(platformCodes, testing::Pointwise(testing::Eq(), {AzFramework::PlatformCodeNameWindows}));
}
TEST_F(PlatformHelperTest, AppendPlatformCodeNames_ByInvalidName_OK)
@@ -122,11 +118,7 @@ TEST_F(PlatformHelperTest, AppendPlatformCodeNames_ByValidId_OK)
{
AZStd::fixed_vector<AZStd::string_view, AzFramework::MaxPlatformCodeNames> platformCodes;
AzFramework::PlatformHelper::AppendPlatformCodeNames(platformCodes, AzFramework::PlatformId::PC);
ASSERT_EQ(2, platformCodes.size());
AZStd::string windows = platformCodes[0];
AZStd::string linux = platformCodes[1];
EXPECT_STRCASEEQ(AzFramework::PlatformCodeNameWindows, windows.c_str());
EXPECT_STRCASEEQ(AzFramework::PlatformCodeNameLinux, linux.c_str());
EXPECT_THAT(platformCodes, testing::Pointwise(testing::Eq(), {AzFramework::PlatformCodeNameWindows}));
}
TEST_F(PlatformHelperTest, AppendPlatformCodeNames_ByInvalidId_OK)