Merging from development

Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
Esteban Papp
2021-12-07 12:35:41 -08:00
parent b1eeebb6b6
commit cd5306febf
334 changed files with 9946 additions and 3757 deletions
@@ -6,7 +6,6 @@
*
*/
#include <AzCore/Asset/AssetManagerBus.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Component/NamedEntityId.h>
@@ -14,6 +13,7 @@
#include <AzCore/Script/ScriptSystemBus.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/IdUtils.h>
#include <AzCore/Serialization/Json/RegistrationContext.h>
#include <AzCore/Serialization/Utils.h>
#include <AzFramework/Asset/AssetSystemBus.h>
#include <AzFramework/StringFunc/StringFunc.h>
@@ -21,23 +21,27 @@
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <Core/ScriptCanvasBus.h>
#include <Editor/Assets/ScriptCanvasAssetTrackerBus.h>
#include <LyViewPaneNames.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
#include <ScriptCanvas/Bus/RequestBus.h>
#include <ScriptCanvas/Components/EditorGraph.h>
#include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
#include <ScriptCanvas/Components/EditorScriptCanvasComponent.h>
#include <ScriptCanvas/Components/EditorScriptCanvasComponentSerializer.h>
#include <ScriptCanvas/Components/EditorUtils.h>
#include <ScriptCanvas/Core/Node.h>
#include <ScriptCanvas/PerformanceStatisticsBus.h>
namespace EditorScriptCanvasComponentCpp
{
enum Version
{
PrefabIntegration = 10,
InternalDev,
AddSourceHandle,
// add description above
Current
};
@@ -128,7 +132,7 @@ namespace ScriptCanvasEditor
}
ScriptCanvasBuilder::BuildVariableOverrides overrides;
overrides.m_source = AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>(assetHolder.GetAssetId(), assetHolder.GetAssetType(), assetHolder.GetAssetHint());;
overrides.m_source = SourceHandle(nullptr, assetHolder.GetAssetId().m_guid, {});
for (auto& variable : editableData.GetVariables())
{
@@ -142,6 +146,25 @@ namespace ScriptCanvasEditor
}
}
if (rootElement.GetVersion() < EditorScriptCanvasComponentCpp::Version::AddSourceHandle)
{
ScriptCanvasAssetHolder assetHolder;
if (!rootElement.FindSubElementAndGetData(AZ_CRC_CE("m_assetHolder"), assetHolder))
{
AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: could not retrieve old 'm_assetHolder'");
return false;
}
auto assetId = assetHolder.GetAssetId();
auto path = assetHolder.GetAssetHint();
if (!rootElement.AddElementWithData(serializeContext, "runtimeDataOverrides", SourceHandle(nullptr, assetId.m_guid, path)))
{
AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: failed to add 'sourceHandle'");
return false;
}
}
return true;
}
@@ -153,9 +176,9 @@ namespace ScriptCanvasEditor
serializeContext->Class<EditorScriptCanvasComponent, EditorComponentBase>()
->Version(EditorScriptCanvasComponentCpp::Version::Current, &EditorScriptCanvasComponentVersionConverter)
->Field("m_name", &EditorScriptCanvasComponent::m_name)
->Field("m_assetHolder", &EditorScriptCanvasComponent::m_scriptCanvasAssetHolder)
->Field("runtimeDataIsValid", &EditorScriptCanvasComponent::m_runtimeDataIsValid)
->Field("runtimeDataOverrides", &EditorScriptCanvasComponent::m_variableOverrides)
->Field("sourceHandle", &EditorScriptCanvasComponent::m_sourceHandle)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
@@ -171,29 +194,34 @@ namespace ScriptCanvasEditor
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("UI", 0x27ff46b0))
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Level", 0x9aeacc13))
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/scripting/script-canvas/")
->DataElement(AZ::Edit::UIHandlers::Default, &EditorScriptCanvasComponent::m_scriptCanvasAssetHolder, "Script Canvas Asset", "Script Canvas asset associated with this component")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->DataElement(AZ::Edit::UIHandlers::Default, &EditorScriptCanvasComponent::m_sourceHandle, "Script Canvas Source File", "Script Canvas source file associated with this component")
->Attribute("BrowseIcon", ":/stylesheet/img/UI20/browse-edit-select-files.svg")
->Attribute("EditButton", "")
->Attribute("EditDescription", "Open in Script Canvas Editor")
->Attribute("EditCallback", &EditorScriptCanvasComponent::OpenEditor)
->Attribute(AZ::Edit::Attributes::AssetPickerTitle, "Script Canvas")
->Attribute(AZ::Edit::Attributes::SourceAssetFilterPattern, "*.scriptcanvas")
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorScriptCanvasComponent::OnFileSelectionChanged)
->DataElement(AZ::Edit::UIHandlers::Default, &EditorScriptCanvasComponent::m_variableOverrides, "Properties", "Script Canvas Graph Properties")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
;
}
}
if (AZ::JsonRegistrationContext* jsonContext = azrtti_cast<AZ::JsonRegistrationContext*>(context))
{
jsonContext->Serializer<AZ::EditorScriptCanvasComponentSerializer>()->HandlesType<EditorScriptCanvasComponent>();
}
}
EditorScriptCanvasComponent::EditorScriptCanvasComponent()
: EditorScriptCanvasComponent(AZ::Data::Asset<ScriptCanvasAsset>())
: EditorScriptCanvasComponent(SourceHandle())
{
}
EditorScriptCanvasComponent::EditorScriptCanvasComponent(AZ::Data::Asset<ScriptCanvasAsset> asset)
: m_scriptCanvasAssetHolder()
EditorScriptCanvasComponent::EditorScriptCanvasComponent(const SourceHandle& sourceHandle)
: m_sourceHandle(sourceHandle)
{
if (asset.GetId().IsValid())
{
m_scriptCanvasAssetHolder.SetAsset(asset.GetId());
}
m_scriptCanvasAssetHolder.SetScriptChangedCB([this](AZ::Data::AssetId assetId) { OnScriptCanvasAssetChanged(assetId); });
}
EditorScriptCanvasComponent::~EditorScriptCanvasComponent()
@@ -209,50 +237,34 @@ namespace ScriptCanvasEditor
void EditorScriptCanvasComponent::UpdateName()
{
AZ::Data::AssetId assetId = m_scriptCanvasAssetHolder.GetAssetId();
if (assetId.IsValid())
SetName(m_sourceHandle.Path().Filename().Native());
}
void EditorScriptCanvasComponent::OpenEditor(const AZ::Data::AssetId&, const AZ::Data::AssetType&)
{
AzToolsFramework::OpenViewPane(LyViewPane::ScriptCanvas);
AZ::Outcome<int, AZStd::string> openOutcome = AZ::Failure(AZStd::string());
if (m_sourceHandle.IsDescriptionValid())
{
// Pathname from the asset doesn't seem to return a value unless the asset has been loaded up once(which isn't done until we try to show it).
// Using the Job system to determine the asset name instead.
AZ::Outcome<AzToolsFramework::AssetSystem::JobInfoContainer> jobOutcome = AZ::Failure();
AzToolsFramework::AssetSystemJobRequestBus::BroadcastResult(jobOutcome, &AzToolsFramework::AssetSystemJobRequestBus::Events::GetAssetJobsInfoByAssetID, assetId, false, false);
AZStd::string assetPath;
AZStd::string assetName;
if (jobOutcome.IsSuccess())
GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset, m_sourceHandle, Tracker::ScriptCanvasFileState::UNMODIFIED, -1);
if (!openOutcome)
{
AzToolsFramework::AssetSystem::JobInfoContainer& jobs = jobOutcome.GetValue();
// Get the asset relative path
if (!jobs.empty())
{
assetPath = jobs[0].m_sourceFile;
}
// Get the asset file name
assetName = assetPath;
if (!assetPath.empty())
{
AzFramework::StringFunc::Path::GetFileName(assetPath.c_str(), assetName);
SetName(assetName);
}
AZ_Warning("Script Canvas", openOutcome, "%s", openOutcome.GetError().data());
}
}
}
void EditorScriptCanvasComponent::OpenEditor()
{
m_scriptCanvasAssetHolder.OpenEditor();
}
void EditorScriptCanvasComponent::CloseGraph()
{
AZ::Data::AssetId assetId = m_scriptCanvasAssetHolder.GetAssetId();
if (assetId.IsValid())
else if (GetEntityId().IsValid())
{
GeneralRequestBus::Broadcast(&GeneralRequests::CloseScriptCanvasAsset, assetId);
AzToolsFramework::EntityIdList selectedEntityIds;
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(selectedEntityIds, &AzToolsFramework::ToolsApplicationRequests::GetSelectedEntities);
// Going to bypass the multiple selected entities flow for right now.
if (selectedEntityIds.size() == 1)
{
GeneralRequestBus::Broadcast(&GeneralRequests::CreateScriptCanvasAssetFor, AZStd::make_pair(GetEntityId(), GetId()));
}
}
}
@@ -261,7 +273,11 @@ namespace ScriptCanvasEditor
EditorComponentBase::Init();
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusConnect();
m_scriptCanvasAssetHolder.Init(GetEntityId(), GetId());
}
void EditorScriptCanvasComponent::InitializeSource(const SourceHandle& sourceHandle)
{
m_sourceHandle = sourceHandle;
}
//=========================================================================
@@ -269,6 +285,8 @@ namespace ScriptCanvasEditor
{
EditorComponentBase::Activate();
AzToolsFramework::AssetSystemBus::Handler::BusConnect();
AZ::EntityId entityId = GetEntityId();
EditorContextMenuRequestBus::Handler::BusConnect(entityId);
@@ -277,19 +295,13 @@ namespace ScriptCanvasEditor
EditorScriptCanvasComponentLoggingBus::Handler::BusConnect(entityId);
EditorLoggingComponentNotificationBus::Broadcast(&EditorLoggingComponentNotifications::OnEditorScriptCanvasComponentActivated, GetNamedEntityId(), GetGraphIdentifier());
AZ::Data::AssetId fileAssetId = m_scriptCanvasAssetHolder.GetAssetId();
if (fileAssetId.IsValid())
{
AssetTrackerNotificationBus::Handler::BusConnect(fileAssetId);
AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent);
}
AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent);
}
//=========================================================================
void EditorScriptCanvasComponent::Deactivate()
{
AssetTrackerNotificationBus::Handler::BusDisconnect();
AzToolsFramework::AssetSystemBus::Handler::BusDisconnect();
EditorScriptCanvasComponentLoggingBus::Handler::BusDisconnect();
EditorLoggingComponentNotificationBus::Broadcast(&EditorLoggingComponentNotifications::OnEditorScriptCanvasComponentDeactivated, GetNamedEntityId(), GetGraphIdentifier());
@@ -306,7 +318,7 @@ namespace ScriptCanvasEditor
m_runtimeDataIsValid = false;
auto assetTreeOutcome = LoadEditorAssetTree(m_scriptCanvasAssetHolder.GetAssetId(), m_scriptCanvasAssetHolder.GetAssetHint());
auto assetTreeOutcome = LoadEditorAssetTree(m_sourceHandle);
if (!assetTreeOutcome.IsSuccess())
{
AZ_Warning("ScriptCanvas", false, "EditorScriptCanvasComponent::BuildGameEntityData failed: %s", assetTreeOutcome.GetError().c_str());
@@ -344,7 +356,8 @@ namespace ScriptCanvasEditor
if (!m_runtimeDataIsValid)
{
AZ_Error("ScriptCanvasBuilder", false, "Runtime information did not build for ScriptCanvas Component using asset: %s", m_scriptCanvasAssetHolder.GetAssetId().ToString<AZStd::string>().c_str());
AZ_Error("ScriptCanvasBuilder", false, "Runtime information did not build for ScriptCanvas Component using asset: %s"
, m_sourceHandle.ToString().c_str());
return;
}
@@ -352,123 +365,66 @@ namespace ScriptCanvasEditor
runtimeComponent->TakeRuntimeDataOverrides(ConvertToRuntime(m_variableOverrides));
}
void EditorScriptCanvasComponent::OnCatalogAssetAdded(const AZ::Data::AssetId& assetId)
{
if (m_removedCatalogId == assetId)
{
if (!m_scriptCanvasAssetHolder.GetAssetId().IsValid())
{
SetPrimaryAsset(assetId);
m_removedCatalogId.SetInvalid();
}
}
}
void EditorScriptCanvasComponent::OnCatalogAssetRemoved(const AZ::Data::AssetId& removedAssetId, const AZ::Data::AssetInfo& /*assetInfo*/)
{
AZ::Data::AssetId assetId = m_scriptCanvasAssetHolder.GetAssetId();
if (assetId == removedAssetId)
{
m_removedCatalogId = assetId;
SetPrimaryAsset({});
}
}
void EditorScriptCanvasComponent::SetPrimaryAsset(const AZ::Data::AssetId& assetId)
{
m_scriptCanvasAssetHolder.ClearAsset();
m_sourceHandle = SourceHandle(nullptr, assetId.m_guid, {});
if (assetId.IsValid())
auto completeAsset = CompleteDescription(m_sourceHandle);
if (completeAsset)
{
ScriptCanvasMemoryAsset::pointer memoryAsset;
AssetTrackerRequestBus::BroadcastResult(memoryAsset, &AssetTrackerRequests::GetAsset, assetId);
if (memoryAsset)
{
m_scriptCanvasAssetHolder.SetAsset(memoryAsset->GetFileAssetId());
OnScriptCanvasAssetChanged(memoryAsset->GetFileAssetId());
SetName(memoryAsset->GetTabName());
}
else
{
auto scriptCanvasAsset = AZ::Data::AssetManager::Instance().FindAsset(assetId, AZ::Data::AssetLoadBehavior::Default);
if (scriptCanvasAsset)
{
m_scriptCanvasAssetHolder.SetAsset(assetId);
}
}
m_sourceHandle = *completeAsset;
}
OnScriptCanvasAssetChanged(SourceChangeDescription::SelectionChanged);
SetName(m_sourceHandle.Path().Filename().Native());
AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_AttributesAndValues);
}
AZ::Data::AssetId EditorScriptCanvasComponent::GetAssetId() const
{
return m_scriptCanvasAssetHolder.GetAssetId();
return m_sourceHandle.Id();
}
AZ::EntityId EditorScriptCanvasComponent::GetGraphEntityId() const
AZ::u32 EditorScriptCanvasComponent::OnFileSelectionChanged()
{
AZ::EntityId scriptCanvasEntityId;
AZ::Data::AssetId assetId = m_scriptCanvasAssetHolder.GetAssetId();
if (assetId.IsValid())
{
AssetTrackerRequestBus::BroadcastResult(scriptCanvasEntityId, &AssetTrackerRequests::GetScriptCanvasId, assetId);
}
return scriptCanvasEntityId;
m_sourceHandle = SourceHandle(nullptr, m_sourceHandle.Path());
CompleteDescriptionInPlace(m_sourceHandle);
m_previousHandle = {};
m_removedHandle = {};
OnScriptCanvasAssetChanged(SourceChangeDescription::SelectionChanged);
return AZ::Edit::PropertyRefreshLevels::EntireTree;
}
void EditorScriptCanvasComponent::OnAssetReady(const ScriptCanvasMemoryAsset::pointer asset)
void EditorScriptCanvasComponent::OnScriptCanvasAssetChanged(SourceChangeDescription changeDescription)
{
OnScriptCanvasAssetReady(asset);
}
void EditorScriptCanvasComponent::OnAssetSaved(const ScriptCanvasMemoryAsset::pointer asset, bool isSuccessful)
{
if (isSuccessful)
{
OnScriptCanvasAssetReady(asset);
}
}
void EditorScriptCanvasComponent::OnAssetReloaded(const ScriptCanvasMemoryAsset::pointer asset)
{
OnScriptCanvasAssetReady(asset);
}
void EditorScriptCanvasComponent::OnScriptCanvasAssetChanged(AZ::Data::AssetId assetId)
{
AssetTrackerNotificationBus::Handler::BusDisconnect();
ScriptCanvas::GraphIdentifier newIdentifier = GetGraphIdentifier();
newIdentifier.m_assetId = assetId;
newIdentifier.m_assetId = m_sourceHandle.Id();
ScriptCanvas::GraphIdentifier oldIdentifier = GetGraphIdentifier();
oldIdentifier.m_assetId = m_previousAssetId;
oldIdentifier.m_assetId = m_previousHandle.Id();
EditorLoggingComponentNotificationBus::Broadcast(&EditorLoggingComponentNotifications::OnAssetSwitched, GetNamedEntityId(), newIdentifier, oldIdentifier);
m_previousAssetId = m_scriptCanvasAssetHolder.GetAssetId();
m_previousHandle = m_sourceHandle.Describe();
// Only clear our variables when we are given a new asset id
// or when the asset was explicitly set to empty.
//
// i.e. do not clear variables when we lose the catalog asset.
if ((assetId.IsValid() && assetId != m_removedCatalogId)
|| (!assetId.IsValid() && !m_removedCatalogId.IsValid()))
if (changeDescription == SourceChangeDescription::SelectionChanged)
{
ClearVariables();
}
if (assetId.IsValid())
if (m_sourceHandle.IsDescriptionValid())
{
AssetTrackerNotificationBus::Handler::BusConnect(assetId);
ScriptCanvasMemoryAsset::pointer memoryAsset;
AssetTrackerRequestBus::BroadcastResult(memoryAsset, &AssetTrackerRequests::GetAsset, assetId);
if (memoryAsset && memoryAsset->GetAsset().GetStatus() == AZ::Data::AssetData::AssetStatus::Ready)
if (!m_sourceHandle.Get())
{
OnScriptCanvasAssetReady(memoryAsset);
if (auto loaded = LoadFromFile(m_sourceHandle.Path().c_str()); loaded.IsSuccess())
{
m_sourceHandle = SourceHandle(loaded.TakeValue(), m_sourceHandle.Id(), m_sourceHandle.Path().c_str());
}
}
if (m_sourceHandle.Get())
{
UpdatePropertyDisplay(m_sourceHandle);
}
}
@@ -485,35 +441,66 @@ namespace ScriptCanvasEditor
AZ::ScriptSystemRequestBus::Broadcast(&AZ::ScriptSystemRequests::GarbageCollect);
}
void EditorScriptCanvasComponent::SetAssetId(const AZ::Data::AssetId& assetId)
void EditorScriptCanvasComponent::SetAssetId(const SourceHandle& assetId)
{
if (m_scriptCanvasAssetHolder.GetAssetId() != assetId)
if (m_sourceHandle.Describe() != assetId.Describe())
{
// Invalidate the previously removed catalog id if we are setting a new asset id
m_removedCatalogId.SetInvalid();
SetPrimaryAsset(assetId);
m_removedHandle = {};
SetPrimaryAsset(assetId.Id());
}
}
void EditorScriptCanvasComponent::SourceFileChanged([[maybe_unused]] AZStd::string relativePath
, [[maybe_unused]] AZStd::string scanFolder, [[maybe_unused]] AZ::Uuid fileAssetId)
{
if (fileAssetId == m_sourceHandle.Id())
{
if (auto handle = CompleteDescription(SourceHandle(nullptr, fileAssetId, {})))
{
m_sourceHandle = *handle;
// consider queueing on tick bus
OnScriptCanvasAssetChanged(SourceChangeDescription::Modified);
}
}
}
void EditorScriptCanvasComponent::SourceFileRemoved([[maybe_unused]] AZStd::string relativePath
, [[maybe_unused]] AZStd::string scanFolder, [[maybe_unused]] AZ::Uuid fileAssetId)
{
if (fileAssetId == m_sourceHandle.Id())
{
m_removedHandle = m_sourceHandle;
OnScriptCanvasAssetChanged(SourceChangeDescription::Removed);
}
}
void EditorScriptCanvasComponent::SourceFileFailed([[maybe_unused]] AZStd::string relativePath
, [[maybe_unused]] AZStd::string scanFolder, [[maybe_unused]] AZ::Uuid fileAssetId)
{
if (fileAssetId == m_sourceHandle.Id())
{
m_removedHandle = m_sourceHandle;
OnScriptCanvasAssetChanged(SourceChangeDescription::Error);
}
}
bool EditorScriptCanvasComponent::HasAssetId() const
{
return m_scriptCanvasAssetHolder.GetAssetId().IsValid();
return !m_sourceHandle.Id().IsNull();
}
ScriptCanvas::GraphIdentifier EditorScriptCanvasComponent::GetGraphIdentifier() const
{
// For now we don't want to deal with disambiguating duplicates of the same script running on one entity.
// Should that change we need to add the component id back into this.
return ScriptCanvas::GraphIdentifier(m_scriptCanvasAssetHolder.GetAssetId(), 0);
return ScriptCanvas::GraphIdentifier(m_sourceHandle.Id(), 0);
}
void EditorScriptCanvasComponent::OnScriptCanvasAssetReady(const ScriptCanvasMemoryAsset::pointer memoryAsset)
void EditorScriptCanvasComponent::UpdatePropertyDisplay(const SourceHandle& sourceHandle)
{
if (memoryAsset->GetFileAssetId() == m_scriptCanvasAssetHolder.GetAssetId())
if (sourceHandle.IsGraphValid())
{
auto assetData = memoryAsset->GetAsset();
[[maybe_unused]] AZ::Entity* scriptCanvasEntity = assetData->GetScriptCanvasEntity();
AZ_Assert(scriptCanvasEntity, "This graph must have a valid entity");
BuildGameEntityData();
UpdateName();
AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent);