Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
@@ -0,0 +1,396 @@
/*
* 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 "precompiled.h"
#include <AzCore/std/containers/vector.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <Editor/View/Widgets/LoggingPanel/LiveWindowSession/LiveLoggingDataAggregator.h>
#include <ScriptCanvas/Debugger/API.h>
#include <ScriptCanvas/Asset/ExecutionLogAssetBus.h>
namespace ScriptCanvasEditor
{
//////////////////////////////
// LiveLoggingDataAggregator
//////////////////////////////
LiveLoggingDataAggregator::LiveLoggingDataAggregator()
: m_captureType(CaptureType::Editor)
, m_isCapturingData(false)
, m_ignoreRegistrations(false)
{
ScriptCanvas::Debugger::ClientUINotificationBus::Handler::BusConnect();
OnCurrentTargetChanged();
}
LiveLoggingDataAggregator::~LiveLoggingDataAggregator()
{
}
void LiveLoggingDataAggregator::OnCurrentTargetChanged()
{
ResetData();
bool isConnected = false;
ScriptCanvas::Debugger::ClientRequestsBus::BroadcastResult(isConnected, &ScriptCanvas::Debugger::ClientRequests::HasValidConnection);
if (isConnected)
{
EditorLoggingComponentNotificationBus::Handler::BusDisconnect();
if (!ScriptCanvas::Debugger::ServiceNotificationsBus::Handler::BusIsConnected())
{
ScriptCanvas::Debugger::ServiceNotificationsBus::Handler::BusConnect();
}
bool isSelf = false;
ScriptCanvas::Debugger::ClientRequestsBus::BroadcastResult(isSelf, &ScriptCanvas::Debugger::ClientRequests::IsConnectedToSelf);
if (!isSelf)
{
m_captureType = CaptureType::External;
m_staticRegistrations.clear();
}
}
else
{
if (!EditorLoggingComponentNotificationBus::Handler::BusIsConnected())
{
EditorLoggingComponentNotificationBus::Handler::BusConnect();
}
ScriptCanvas::Debugger::ServiceNotificationsBus::Handler::BusDisconnect();
m_captureType = CaptureType::Editor;
SetupEditorEntities();
}
}
bool LiveLoggingDataAggregator::CanCaptureData() const
{
return true;
}
bool LiveLoggingDataAggregator::IsCapturingData() const
{
return m_isCapturingData;
}
void LiveLoggingDataAggregator::OnEditorScriptCanvasComponentActivated(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
if (graphIdentifier.m_assetId.IsValid())
{
RegisterScriptCanvas(namedEntityId, graphIdentifier);
}
}
void LiveLoggingDataAggregator::OnEditorScriptCanvasComponentDeactivated(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
UnregisterScriptCanvas(namedEntityId, graphIdentifier);
}
void LiveLoggingDataAggregator::OnAssetSwitched(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& newGraphIdentifier, const ScriptCanvas::GraphIdentifier& oldGraphIdentifier)
{
if (newGraphIdentifier == oldGraphIdentifier)
{
return;
}
if (newGraphIdentifier.m_assetId.IsValid())
{
RegisterScriptCanvas(namedEntityId, newGraphIdentifier);
}
UnregisterScriptCanvas(namedEntityId, oldGraphIdentifier);
RemoveStaticRegistration(namedEntityId, oldGraphIdentifier);
}
void LiveLoggingDataAggregator::Connected([[maybe_unused]] const ScriptCanvas::Debugger::Target& target)
{
AZStd::lock(m_notificationMutex);
SetupExternalEntities();
}
void LiveLoggingDataAggregator::GraphActivated(const ScriptCanvas::GraphActivation& activationSignal)
{
AZStd::lock(m_notificationMutex);
RegisterScriptCanvas(activationSignal.m_runtimeEntity, activationSignal.m_graphIdentifier);
RegisterEntityName(activationSignal.m_runtimeEntity, activationSignal.m_runtimeEntity.GetName());
LoggingDataNotificationBus::Event(GetDataId(), &LoggingDataNotifications::OnEnabledStateChanged, activationSignal.m_entityIsObserved, activationSignal.m_runtimeEntity, activationSignal.m_graphIdentifier);
}
void LiveLoggingDataAggregator::GraphDeactivated(const ScriptCanvas::GraphDeactivation& deactivationSignal)
{
AZStd::lock(m_notificationMutex);
UnregisterScriptCanvas(deactivationSignal.m_runtimeEntity, deactivationSignal.m_graphIdentifier);
}
void LiveLoggingDataAggregator::NodeStateChanged(const ScriptCanvas::NodeStateChange& nodeStateChangeSignal)
{
AZStd::lock(m_notificationMutex);
ProcessNodeStateChanged(nodeStateChangeSignal);
}
void LiveLoggingDataAggregator::SignaledInput(const ScriptCanvas::InputSignal& inputSignal)
{
AZStd::lock(m_notificationMutex);
ProcessInputSignal(inputSignal);
}
void LiveLoggingDataAggregator::SignaledOutput(const ScriptCanvas::OutputSignal& outputSignal)
{
AZStd::lock(m_notificationMutex);
ProcessOutputSignal(outputSignal);
}
void LiveLoggingDataAggregator::SignaledDataOutput(const ScriptCanvas::OutputDataSignal& outputDataSignal)
{
AZStd::lock(m_notificationMutex);
ProcessOutputDataSignal(outputDataSignal);
}
void LiveLoggingDataAggregator::AnnotateNode(const ScriptCanvas::AnnotateNodeSignal& annotateNode)
{
AZStd::lock(m_notificationMutex);
ProcessAnnotateNode(annotateNode);
}
void LiveLoggingDataAggregator::VariableChanged(const ScriptCanvas::VariableChange& variableChangeSignal)
{
AZStd::lock(m_notificationMutex);
ProcessVariableChangedSignal(variableChangeSignal);
}
void LiveLoggingDataAggregator::GetActiveEntitiesResult(const ScriptCanvas::ActiveEntityStatusMap& activeEntities)
{
AZStd::lock(m_notificationMutex);
m_ignoreRegistrations = true;
for (const auto& activeEntityPair : activeEntities)
{
const AZ::NamedEntityId& namedEntityId = activeEntityPair.first;
RegisterEntityName(namedEntityId, namedEntityId.GetName());
const auto& activeEntityStatus = activeEntityPair.second;
for (const auto& activeGraphStatus : activeEntityStatus.m_activeGraphs)
{
RegisterScriptCanvas(namedEntityId, activeGraphStatus.first);
LoggingDataNotificationBus::Event(GetDataId(), &LoggingDataNotifications::OnEnabledStateChanged, activeGraphStatus.second.m_isObserved, namedEntityId, activeGraphStatus.first);
}
}
m_ignoreRegistrations = false;
}
const AZStd::unordered_multimap<AZ::NamedEntityId, ScriptCanvas::GraphIdentifier>& LiveLoggingDataAggregator::GetStaticRegistrations() const
{
return m_staticRegistrations;
}
void LiveLoggingDataAggregator::OnRegistrationEnabled(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
if (m_ignoreRegistrations)
{
return;
}
if (IsCapturingData() || m_captureType == External)
{
if (graphIdentifier.m_componentId == k_dynamicallySpawnedControllerId)
{
ScriptCanvas::Debugger::ClientUIRequestBus::Broadcast(&ScriptCanvas::Debugger::ClientUIRequests::AddGraphLoggingTarget, graphIdentifier.m_assetId);
}
else
{
ScriptCanvas::Debugger::ClientUIRequestBus::Broadcast(&ScriptCanvas::Debugger::ClientUIRequests::AddEntityLoggingTarget, namedEntityId, graphIdentifier);
bool gotResult = false;
AZ::EntityId editorId;
AzToolsFramework::EditorEntityContextRequestBus::BroadcastResult(gotResult, &AzToolsFramework::EditorEntityContextRequests::MapRuntimeIdToEditorId, namedEntityId, editorId);
if (gotResult)
{
AZ::NamedEntityId namedEditorId(editorId, namedEntityId.GetName());
AddStaticRegistration(namedEditorId, graphIdentifier);
}
}
return;
}
AddStaticRegistration(namedEntityId, graphIdentifier);
}
void LiveLoggingDataAggregator::OnRegistrationDisabled(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
if (m_ignoreRegistrations)
{
return;
}
if (IsCapturingData() || m_captureType == External)
{
if (graphIdentifier.m_componentId == k_dynamicallySpawnedControllerId)
{
ScriptCanvas::Debugger::ClientUIRequestBus::Broadcast(&ScriptCanvas::Debugger::ClientUIRequests::RemoveGraphLoggingTarget, graphIdentifier.m_assetId);
}
else
{
ScriptCanvas::Debugger::ClientUIRequestBus::Broadcast(&ScriptCanvas::Debugger::ClientUIRequests::RemoveEntityLoggingTarget, namedEntityId, graphIdentifier);
if (m_captureType == Editor)
{
bool gotResult = false;
AZ::EntityId editorId;
AzToolsFramework::EditorEntityContextRequestBus::BroadcastResult(gotResult, &AzToolsFramework::EditorEntityContextRequests::MapRuntimeIdToEditorId, namedEntityId, editorId);
if (gotResult)
{
AZ::NamedEntityId namedEditorId(editorId, namedEntityId.GetName());
RemoveStaticRegistration(namedEditorId, graphIdentifier);
}
}
}
return;
}
RemoveStaticRegistration(namedEntityId, graphIdentifier);
}
void LiveLoggingDataAggregator::AddStaticRegistration(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
if (graphIdentifier.m_componentId == k_dynamicallySpawnedControllerId
|| m_captureType != Editor)
{
return;
}
bool registerEvent = true;
auto mapRange = m_staticRegistrations.equal_range(namedEntityId);
for (auto mapIter = mapRange.first; mapIter != mapRange.second; ++mapIter)
{
if (mapIter->second == graphIdentifier)
{
registerEvent = false;
break;
}
}
if (registerEvent)
{
m_staticRegistrations.insert(AZStd::make_pair(namedEntityId, graphIdentifier));
}
}
void LiveLoggingDataAggregator::RemoveStaticRegistration(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier)
{
if (graphIdentifier.m_componentId == k_dynamicallySpawnedControllerId
|| m_captureType != Editor)
{
return;
}
auto mapRange = m_staticRegistrations.equal_range(namedEntityId);
for (auto mapIter = mapRange.first; mapIter != mapRange.second; ++mapIter)
{
if (mapIter->second == graphIdentifier)
{
m_staticRegistrations.erase(mapIter);
break;
}
}
}
void LiveLoggingDataAggregator::SetupEditorEntities()
{
m_ignoreRegistrations = true;
EditorScriptCanvasComponentLoggingBus::EnumerateHandlers([this](EditorScriptCanvasComponentLogging* loggingComponent)
{
ScriptCanvas::GraphIdentifier graphIdentifier = loggingComponent->GetGraphIdentifier();
if (graphIdentifier.m_assetId.IsValid())
{
RegisterScriptCanvas(loggingComponent->FindNamedEntityId(), graphIdentifier);
}
return true;
});
for (const auto& mapPair : m_staticRegistrations)
{
LoggingDataNotificationBus::Event(GetDataId(), &LoggingDataNotifications::OnEnabledStateChanged, true, mapPair.first, mapPair.second);
}
m_ignoreRegistrations = false;
}
void LiveLoggingDataAggregator::SetupExternalEntities()
{
ScriptCanvas::Debugger::ClientRequestsBus::Broadcast(&ScriptCanvas::Debugger::ClientRequests::GetActiveEntities);
}
void LiveLoggingDataAggregator::StartCaptureData()
{
AZStd::lock(m_notificationMutex);
m_isCapturingData = true;
ResetLog();
ScriptCanvas::Debugger::ServiceNotificationsBus::Handler::BusConnect();
}
void LiveLoggingDataAggregator::StopCaptureData()
{
AZStd::lock(m_notificationMutex);
m_isCapturingData = false;
ResetData();
const AZStd::string name = AZStd::string::format("ScriptCanvasLog_%s", AZStd::to_string(AZStd::GetTimeUTCMilliSecond()).data());
ScriptCanvas::ExecutionLogAssetEBus::Broadcast(&ScriptCanvas::ExecutionLogAssetBus::SaveToRelativePath, name);
if (m_captureType == CaptureType::Editor)
{
bool isDesiredTargetConnected = false;
AzFramework::TargetManager::Bus::BroadcastResult(isDesiredTargetConnected, &AzFramework::TargetManager::IsDesiredTargetOnline);
if (isDesiredTargetConnected)
{
SetupExternalEntities();
}
else
{
SetupEditorEntities();
}
}
else
{
SetupExternalEntities();
}
ScriptCanvas::ExecutionLogAssetEBus::Broadcast(&ScriptCanvas::ExecutionLogAssetBus::ClearLog);
ScriptCanvas::Debugger::ServiceNotificationsBus::Handler::BusDisconnect();
}
}
@@ -0,0 +1,99 @@
/*
* 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 <AzFramework/TargetManagement/TargetManagementAPI.h>
#include <Editor/Include/ScriptCanvas/Bus/EditorScriptCanvasBus.h>
#include <Editor/View/Widgets/LoggingPanel/LoggingDataAggregator.h>
#include <ScriptCanvas/Debugger/Bus.h>
#include <ScriptCanvas/Debugger/Logger.h>
namespace ScriptCanvasEditor
{
class LiveLoggingDataAggregator
: public LoggingDataAggregator
, public EditorLoggingComponentNotificationBus::Handler
, public ScriptCanvas::Debugger::ServiceNotificationsBus::Handler
, public ScriptCanvas::Debugger::ClientUINotificationBus::Handler
{
enum CaptureType
{
Editor,
External
};
public:
AZ_CLASS_ALLOCATOR(LiveLoggingDataAggregator, AZ::SystemAllocator, 0);
LiveLoggingDataAggregator();
~LiveLoggingDataAggregator();
// ClientUINotificationBus
void OnCurrentTargetChanged() override;
////
bool CanCaptureData() const;
bool IsCapturingData() const;
void StartCaptureData();
void StopCaptureData();
// EditorLoggingComponentNotifications
void OnEditorScriptCanvasComponentActivated(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier) override;
void OnEditorScriptCanvasComponentDeactivated(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier) override;
void OnAssetSwitched(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& newAssetId, const ScriptCanvas::GraphIdentifier& oldAssetId) override;
////
// ServiceNotifications
//// Logging Notifications
void Connected(const ScriptCanvas::Debugger::Target& target) override;
void GraphActivated(const ScriptCanvas::GraphActivation& activatedSignal) override;
void GraphDeactivated(const ScriptCanvas::GraphDeactivation& deactivatedSignal) override;
void NodeStateChanged(const ScriptCanvas::NodeStateChange& stateChange) override;
void SignaledInput(const ScriptCanvas::InputSignal& inputSignal) override;
void SignaledOutput(const ScriptCanvas::OutputSignal& outputSignal) override;
void SignaledDataOutput(const ScriptCanvas::OutputDataSignal&) override;
void AnnotateNode(const ScriptCanvas::AnnotateNodeSignal& annotateNode) override;
void VariableChanged(const ScriptCanvas::VariableChange& variableChanged) override;
//// Result Methods
void GetActiveEntitiesResult(const ScriptCanvas::ActiveEntityStatusMap& activeEntityMap) override;
////
const AZStd::unordered_multimap<AZ::NamedEntityId, ScriptCanvas::GraphIdentifier>& GetStaticRegistrations() const;
protected:
void OnRegistrationEnabled(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier) override;
void OnRegistrationDisabled(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier) override;
private:
void AddStaticRegistration(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier);
void RemoveStaticRegistration(const AZ::NamedEntityId& namedEntityId, const ScriptCanvas::GraphIdentifier& graphIdentifier);
void SetupEditorEntities();
void SetupExternalEntities();
CaptureType m_captureType;
bool m_isCapturingData;
bool m_ignoreRegistrations;
AZStd::recursive_mutex m_notificationMutex;
ScriptCanvas::Debugger::Logger m_logger;
AZStd::unordered_multimap<AZ::NamedEntityId, ScriptCanvas::GraphIdentifier> m_staticRegistrations;
};
}
@@ -0,0 +1,549 @@
/*
* 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 "precompiled.h"
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <EditorCoreAPI.h>
#include <IEditor.h>
#include <Editor/View/Widgets/LoggingPanel/LiveWindowSession/LiveLoggingWindowSession.h>
namespace ScriptCanvasEditor
{
///////////////////////
// TargetManagerModel
///////////////////////
TargetManagerModel::TargetManagerModel()
{
AzFramework::TargetInfo editorTargetInfo(0, "Editor");
m_targetInfo.push_back(editorTargetInfo);
AzFramework::TargetManager::Bus::BroadcastResult(m_selfInfo, &AzFramework::TargetManager::GetMyTargetInfo);
ScrapeTargetInfo();
}
int TargetManagerModel::rowCount([[maybe_unused]] const QModelIndex& parent) const
{
return static_cast<int>(m_targetInfo.size());
}
QVariant TargetManagerModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid())
{
return QVariant();
}
switch (role)
{
case Qt::DisplayRole:
{
const AzFramework::TargetInfo& targetInfo = m_targetInfo[index.row()];
if (index.row() > 0)
{
return QString("%1 (%2)").arg(targetInfo.GetDisplayName(), QString::number(targetInfo.GetPersistentId(), 16));
}
else
{
return QString(targetInfo.GetDisplayName());
}
}
break;
default:
break;
}
return QVariant();
}
void TargetManagerModel::TargetJoinedNetwork(AzFramework::TargetInfo info)
{
if (!info.IsIdentityEqualTo(m_selfInfo))
{
int element = GetRowForTarget(info.GetPersistentId());
if (element < 0)
{
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_targetInfo.push_back(info);
endInsertRows();
}
}
else
{
ScrapeTargetInfo();
}
}
void TargetManagerModel::TargetLeftNetwork(AzFramework::TargetInfo info)
{
int element = GetRowForTarget(info.GetPersistentId());
// 0 is reserved for our fake Editor one.
// And we don't want to remove it.
if (element > 0)
{
beginRemoveRows(QModelIndex(), element, element);
m_targetInfo.erase(m_targetInfo.begin() + element);
endRemoveRows();
}
}
AzFramework::TargetInfo TargetManagerModel::FindTargetInfoForRow(int row)
{
if (row < 0 && row >= m_targetInfo.size())
{
return AzFramework::TargetInfo();
}
return m_targetInfo[row];
}
int TargetManagerModel::GetRowForTarget(AZ::u32 targetId)
{
for (size_t i = 0; i < m_targetInfo.size(); ++i)
{
if (m_targetInfo[i].GetPersistentId() == targetId)
{
return static_cast<int>(i);
}
}
return -1;
}
void TargetManagerModel::ScrapeTargetInfo()
{
AzFramework::TargetContainer targets;
AzFramework::TargetManager::Bus::Broadcast(&AzFramework::TargetManager::EnumTargetInfos, targets);
for (const auto& targetPair : targets)
{
if (!targetPair.second.IsIdentityEqualTo(m_selfInfo))
{
m_targetInfo.push_back(targetPair.second);
}
}
}
////////////////////////////
// LiveLoggingUserSettings
////////////////////////////
AZStd::intrusive_ptr<LiveLoggingUserSettings> LiveLoggingUserSettings::FindSettingsInstance()
{
return AZ::UserSettings::CreateFind<LiveLoggingUserSettings>(AZ_CRC("ScriptCanvas::LiveLoggingUserSettings", 0xc79efe7b), AZ::UserSettings::CT_LOCAL);
}
void LiveLoggingUserSettings::Reflect(AZ::ReflectContext* reflectContext)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext);
if (serializeContext)
{
serializeContext->Class<LiveLoggingUserSettings>()
->Version(1)
->Field("AutoCapturing", &LiveLoggingUserSettings::m_isAutoCaptureEnabled)
->Field("LiveUpdating", &LiveLoggingUserSettings::m_enableLiveUpdates)
;
}
}
void LiveLoggingUserSettings::SetAutoCaptureEnabled(bool enabled)
{
m_isAutoCaptureEnabled = enabled;
}
bool LiveLoggingUserSettings::IsAutoCaptureEnabled() const
{
return m_isAutoCaptureEnabled;
}
void LiveLoggingUserSettings::SetLiveUpdates(bool enabled)
{
m_enableLiveUpdates = enabled;
}
bool LiveLoggingUserSettings::IsLiveUpdating() const
{
return m_enableLiveUpdates;
}
/////////////////////////////
// LiveLoggingWindowSession
/////////////////////////////
LiveLoggingWindowSession::LiveLoggingWindowSession(QWidget* parent)
: LoggingWindowSession(parent)
, m_startedSession(false)
, m_encodeStaticEntities(false)
, m_isCapturing(false)
{
AzFramework::TargetManagerClient::Bus::Handler::BusConnect();
m_targetManagerModel = aznew TargetManagerModel();
{
QSignalBlocker signalBlocker(m_ui->targetSelector);
m_ui->targetSelector->setModel(m_targetManagerModel);
}
AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusConnect();
ScriptCanvas::Debugger::ServiceNotificationsBus::Handler::BusConnect();
SetDataId(m_liveDataAggregator.GetDataId());
RegisterTreeRoot(m_liveDataAggregator.GetTreeRoot());
m_userSettings = LiveLoggingUserSettings::FindSettingsInstance();
if (!m_userSettings->IsLiveUpdating())
{
m_liveDataAggregator.GetTreeRoot()->SetUpdatePolicy(DebugLogRootItem::UpdatePolicy::SingleTime);
}
else
{
m_liveDataAggregator.GetTreeRoot()->SetUpdatePolicy(DebugLogRootItem::UpdatePolicy::RealTime);
}
// Despite being apart of the base menu for now, the LiveLoggingWindow is the only one that needs to utilize these buttons.
// Going to control them from here.
m_ui->liveUpdatesToggle->setChecked(m_userSettings->IsLiveUpdating());
QObject::connect(m_ui->liveUpdatesToggle, &QToolButton::toggled, this, &LiveLoggingWindowSession::OnLiveUpdateToggled);
m_ui->autoCaptureToggle->setChecked(m_userSettings->IsAutoCaptureEnabled());
QObject::connect(m_ui->autoCaptureToggle, &QToolButton::toggled, this, &LiveLoggingWindowSession::OnAutoCaptureToggled);
}
LiveLoggingWindowSession::~LiveLoggingWindowSession()
{
AzFramework::TargetManagerClient::Bus::Handler::BusDisconnect();
AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusDisconnect();
ScriptCanvas::Debugger::ServiceNotificationsBus::Handler::BusDisconnect();
}
void LiveLoggingWindowSession::DesiredTargetChanged(AZ::u32 newId, [[maybe_unused]] AZ::u32 oldId)
{
{
QSignalBlocker signalBlocker(m_ui->targetSelector);
int row = m_targetManagerModel->GetRowForTarget(newId);
if (row < 0)
{
m_ui->targetSelector->setCurrentIndex(0);
}
else
{
m_ui->targetSelector->setCurrentIndex(row);
}
}
}
void LiveLoggingWindowSession::DesiredTargetConnected(bool connected)
{
{
QSignalBlocker signalBlocker(m_ui->targetSelector);
bool useFallback = !connected;
if (connected)
{
AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusDisconnect();
AzFramework::TargetInfo desiredInfo;
AzFramework::TargetManager::Bus::BroadcastResult(desiredInfo, &AzFramework::TargetManager::GetDesiredTarget);
if (desiredInfo.IsValid() && !desiredInfo.IsSelf())
{
int index = m_targetManagerModel->GetRowForTarget(desiredInfo.GetPersistentId());
if (index > 0)
{
m_ui->targetSelector->setCurrentIndex(index);
}
}
else
{
useFallback = true;
}
}
else if (m_isCapturing)
{
SetIsCapturing(false);
}
if (useFallback)
{
if (!AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusIsConnected())
{
AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusConnect();
}
m_ui->targetSelector->setCurrentIndex(0);
}
}
}
void LiveLoggingWindowSession::TargetJoinedNetwork(AzFramework::TargetInfo info)
{
{
QSignalBlocker signalBlocker(m_ui->targetSelector);
m_targetManagerModel->TargetJoinedNetwork(info);
}
}
void LiveLoggingWindowSession::TargetLeftNetwork(AzFramework::TargetInfo info)
{
{
QSignalBlocker signalBlocker(m_ui->targetSelector);
m_targetManagerModel->TargetLeftNetwork(info);
}
}
void LiveLoggingWindowSession::OnStartPlayInEditorBegin()
{
if (isVisible())
{
m_encodeStaticEntities = true;
ScriptCanvas::Debugger::ClientUIRequestBus::Broadcast(&ScriptCanvas::Debugger::ClientUIRequests::StartEditorSession);
if ((m_userSettings->IsAutoCaptureEnabled()) || m_startedSession)
{
SetIsCapturing(true);
}
}
}
void LiveLoggingWindowSession::OnStopPlayInEditor()
{
if (isVisible())
{
SetIsCapturing(false);
m_startedSession = false;
ScriptCanvas::Debugger::ClientUIRequestBus::Broadcast(&ScriptCanvas::Debugger::ClientUIRequests::StopEditorSession);
m_encodeStaticEntities = false;
}
}
void LiveLoggingWindowSession::Connected([[maybe_unused]] const ScriptCanvas::Debugger::Target& target)
{
if (m_userSettings->IsAutoCaptureEnabled() && isVisible())
{
SetIsCapturing(true);
}
}
void LiveLoggingWindowSession::OnCaptureButtonPressed()
{
bool isSelfTarget = false;
ScriptCanvas::Debugger::ClientRequestsBus::BroadcastResult(isSelfTarget, &ScriptCanvas::Debugger::ClientRequests::IsConnectedToSelf);
if (isSelfTarget)
{
if (!m_startedSession)
{
bool isRunningGame = false;
AzToolsFramework::EditorEntityContextRequestBus::BroadcastResult(isRunningGame, &AzToolsFramework::EditorEntityContextRequests::IsEditorRunningGame);
if (!isRunningGame)
{
m_startedSession = true;
GetIEditor()->SetInGameMode(true);
return;
}
}
else
{
GetIEditor()->SetInGameMode(false);
return;
}
}
SetIsCapturing(!m_isCapturing);
}
void LiveLoggingWindowSession::OnPlaybackButtonPressed()
{
// Nothing to do in the LiveLoggingWindowSession
}
void LiveLoggingWindowSession::OnOptionsButtonPressed()
{
QPoint point = QCursor::pos();
QMenu optionsMenu;
QAction* autoCaptureAction = optionsMenu.addAction("Auto Capture");
autoCaptureAction->setCheckable(true);
autoCaptureAction->setChecked(m_userSettings->IsAutoCaptureEnabled());
QObject::connect(autoCaptureAction, &QAction::toggled, this, &LiveLoggingWindowSession::OnAutoCaptureToggled);
QAction* liveUpdateAction = optionsMenu.addAction("Live Updates");
liveUpdateAction->setCheckable(true);
liveUpdateAction->setChecked(m_userSettings->IsLiveUpdating());
QObject::connect(liveUpdateAction, &QAction::toggled, this, &LiveLoggingWindowSession::OnLiveUpdateToggled);
optionsMenu.exec(point);
}
void LiveLoggingWindowSession::OnTargetChanged(int index)
{
// Special case out the editor
if (index == 0)
{
AzFramework::TargetManager::Bus::Broadcast(&AzFramework::TargetManager::SetDesiredTarget, 0);
}
else
{
AzFramework::TargetInfo info = m_targetManagerModel->FindTargetInfoForRow(index);
if (info.IsValid())
{
AzFramework::TargetManager::Bus::Broadcast(&AzFramework::TargetManager::SetDesiredTarget, info.GetNetworkId());
}
}
}
void LiveLoggingWindowSession::OnAutoCaptureToggled(bool checked)
{
m_userSettings->SetAutoCaptureEnabled(checked);
}
void LiveLoggingWindowSession::OnLiveUpdateToggled(bool checked)
{
m_userSettings->SetLiveUpdates(checked);
if (!m_userSettings->IsLiveUpdating())
{
m_liveDataAggregator.GetTreeRoot()->SetUpdatePolicy(DebugLogRootItem::UpdatePolicy::SingleTime);
}
else
{
// If we enable this we want to update the current display.
m_liveDataAggregator.GetTreeRoot()->RedoLayout();
m_liveDataAggregator.GetTreeRoot()->SetUpdatePolicy(DebugLogRootItem::UpdatePolicy::RealTime);
}
}
void LiveLoggingWindowSession::StartDataCapture()
{
ScriptCanvas::Debugger::ScriptTarget captureInfo;
ConfigureScriptTarget(captureInfo);
m_liveDataAggregator.StartCaptureData();
m_ui->captureButton->setIcon(QIcon(":/ScriptCanvasEditorResources/Resources/capture_live.png"));
ScriptCanvas::Debugger::ClientUIRequestBus::Broadcast(&ScriptCanvas::Debugger::ClientUIRequests::StartLogging, captureInfo);
}
void LiveLoggingWindowSession::StopDataCapture()
{
m_liveDataAggregator.StopCaptureData();
m_ui->captureButton->setIcon(QIcon(":/ScriptCanvasEditorResources/Resources/capture_offline.png"));
ScriptCanvas::Debugger::ClientUIRequestBus::Broadcast(&ScriptCanvas::Debugger::ClientUIRequests::StopLogging);
if (!m_userSettings->IsLiveUpdating())
{
m_liveDataAggregator.GetTreeRoot()->RedoLayout();
}
}
void LiveLoggingWindowSession::ConfigureScriptTarget(ScriptCanvas::Debugger::ScriptTarget& captureInfo)
{
if (m_encodeStaticEntities)
{
const auto& staticRegistrations = m_liveDataAggregator.GetStaticRegistrations();
for (const auto& registrationPair : staticRegistrations)
{
bool gotResult = false;
AZ::EntityId runtimeId;
AzToolsFramework::EditorEntityContextRequestBus::BroadcastResult(gotResult, &AzToolsFramework::EditorEntityContextRequests::MapEditorIdToRuntimeId, registrationPair.first, runtimeId);
if (runtimeId.IsValid())
{
auto entityIter = captureInfo.m_entities.find(runtimeId);
if (entityIter == captureInfo.m_entities.end())
{
auto insertResult = captureInfo.m_entities.insert(AZStd::make_pair(runtimeId, AZStd::unordered_set< ScriptCanvas::GraphIdentifier >()));
entityIter = insertResult.first;
}
entityIter->second.insert(registrationPair.second);
m_liveDataAggregator.RegisterEntityName(runtimeId, registrationPair.first.GetName());
}
else
{
auto insertResult = captureInfo.m_staticEntities.insert(registrationPair.first);
insertResult.first->second.insert(registrationPair.second);
}
}
}
const LoggingEntityMap& registrationMap = m_liveDataAggregator.GetLoggingEntityMap();
for (const auto& registrationPair : registrationMap)
{
auto entityIter = captureInfo.m_entities.find(registrationPair.first);
if (entityIter == captureInfo.m_entities.end())
{
auto insertResult = captureInfo.m_entities.insert(AZStd::make_pair(registrationPair.first, AZStd::unordered_set< ScriptCanvas::GraphIdentifier >()));
entityIter = insertResult.first;
}
entityIter->second.insert(registrationPair.second);
}
const LoggingAssetSet& registrationSet = m_liveDataAggregator.GetLoggingAssetSet();
for (const auto& graphIdentifier : registrationSet)
{
captureInfo.m_graphs.insert(graphIdentifier.m_assetId);
}
}
void LiveLoggingWindowSession::SetIsCapturing(bool isCapturing)
{
if (isCapturing != m_isCapturing)
{
m_isCapturing = isCapturing;
if (m_isCapturing)
{
StartDataCapture();
}
else
{
StopDataCapture();
}
}
}
#include <Editor/View/Widgets/LoggingPanel/LiveWindowSession/moc_LiveLoggingWindowSession.cpp>
}
@@ -0,0 +1,143 @@
/*
* 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
#if !defined(Q_MOC_RUN)
#include <QAbstractListModel>
#include <AzCore/UserSettings/UserSettings.h>
#include <AzFramework/TargetManagement/TargetManagementAPI.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <Editor/View/Widgets/LoggingPanel/LoggingWindowSession.h>
#include <Editor/View/Widgets/LoggingPanel/LiveWindowSession/LiveLoggingDataAggregator.h>
#endif
namespace ScriptCanvasEditor
{
class TargetManagerModel
: public QAbstractListModel
{
public:
AZ_CLASS_ALLOCATOR(TargetManagerModel, AZ::SystemAllocator, 0);
TargetManagerModel();
// QAbstarctItemModel
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
////
void TargetJoinedNetwork(AzFramework::TargetInfo info);
void TargetLeftNetwork(AzFramework::TargetInfo info);
AzFramework::TargetInfo FindTargetInfoForRow(int row);
int GetRowForTarget(AZ::u32 targetId);
private:
void ScrapeTargetInfo();
AzFramework::TargetInfo m_selfInfo;
AZStd::vector< AzFramework::TargetInfo > m_targetInfo;
};
class LiveLoggingUserSettings
: public AZ::UserSettings
{
public:
static AZStd::intrusive_ptr<LiveLoggingUserSettings> FindSettingsInstance();
AZ_RTTI(LiveLoggingUserSettings, "{2E32C949-5766-480D-B569-781BE9166B2E}", AZ::UserSettings);
AZ_CLASS_ALLOCATOR(LiveLoggingUserSettings, AZ::SystemAllocator, 0);
static void Reflect(AZ::ReflectContext* reflectContext);
LiveLoggingUserSettings() = default;
void SetAutoCaptureEnabled(bool enabled);
bool IsAutoCaptureEnabled() const;
void SetLiveUpdates(bool enabled);
bool IsLiveUpdating() const;
private:
bool m_isAutoCaptureEnabled = true;
bool m_enableLiveUpdates = true;
};
class LiveLoggingWindowSession
: public LoggingWindowSession
, public AzFramework::TargetManagerClient::Bus::Handler
, public AzToolsFramework::EditorEntityContextNotificationBus::Handler
, public ScriptCanvas::Debugger::ServiceNotificationsBus::Handler
{
Q_OBJECT
public:
AZ_CLASS_ALLOCATOR(LiveLoggingWindowSession, AZ::SystemAllocator, 0);
LiveLoggingWindowSession(QWidget* parent = nullptr);
~LiveLoggingWindowSession() override;
// AzFramework::TargetManagerClient
void DesiredTargetChanged(AZ::u32 newId, AZ::u32 oldId) override;
void DesiredTargetConnected(bool connected) override;
void TargetJoinedNetwork(AzFramework::TargetInfo info) override;
void TargetLeftNetwork(AzFramework::TargetInfo info) override;
////
// AzToolsFramework::EditorEntityContextNotificationBus::Handler
void OnStartPlayInEditorBegin();
void OnStopPlayInEditor();
////
// ScriptCavnas::Debugger::ServiceNotificationsBus
void Connected(const ScriptCanvas::Debugger::Target& target) override;
////
protected:
void OnCaptureButtonPressed() override;
void OnPlaybackButtonPressed() override;
void OnOptionsButtonPressed() override;
void OnTargetChanged(int currentIndex) override;
private:
void OnAutoCaptureToggled(bool checked);
void OnLiveUpdateToggled(bool checked);
void StartDataCapture();
void StopDataCapture();
void ConfigureScriptTarget(ScriptCanvas::Debugger::ScriptTarget& captureInfo);
void SetIsCapturing(bool isCapturing);
TargetManagerModel* m_targetManagerModel;
bool m_startedSession;
bool m_encodeStaticEntities;
bool m_isCapturing;
LiveLoggingDataAggregator m_liveDataAggregator;
ScriptCanvas::Debugger::Target m_targetConfiguration;
AZStd::intrusive_ptr<LiveLoggingUserSettings> m_userSettings;
};
}