Apply reviewer suggestions

Signed-off-by: Nemerle <nemerle5+git@gmail.com>
This commit is contained in:
Nemerle
2021-12-17 16:02:33 +01:00
449 changed files with 11205 additions and 5685 deletions
@@ -22,8 +22,7 @@
// Undo this
AZ_PUSH_DISABLE_WARNING(4251 4800 4244, "-Wunknown-warning-option")
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Components/EditorGraph.h>
#include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
AZ_POP_DISABLE_WARNING
@@ -85,10 +84,7 @@ namespace ScriptCanvasEditor
static bool HandlesSource(const AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry* entry)
{
AZStd::string_view targetExtension = entry->GetExtension();
ScriptCanvasAsset::Description description;
AZStd::string_view scriptCanvasFileFilter = description.GetFileFilterImpl();
AZStd::string_view scriptCanvasFileFilter = SourceDescription::GetFileFilter();
if (AZStd::wildcard_match(scriptCanvasFileFilter.data(), targetExtension.data()))
{
return true;
@@ -132,7 +128,7 @@ namespace ScriptCanvasEditor
// and then a lambda which will be activated if the user chooses to open it with your opener:
openers.push_back({ "ScriptCanvas_Editor_Asset_Edit", "Script Canvas Editor..."
, QIcon(ScriptCanvasAssetDescription().GetIconPathImpl()),
, QIcon(ScriptCanvasEditor::SourceDescription::GetIconPath()),
[](const char*, const AZ::Uuid& scSourceUuid)
{
AzToolsFramework::OpenViewPane(LyViewPane::ScriptCanvas);
@@ -17,8 +17,6 @@
namespace ScriptCanvasEditor
{
class ScriptCanvasAsset;
class EditorAssetSystemComponent
: public AZ::Component
, public EditorAssetConversionBus::Handler
@@ -6,15 +6,15 @@
*
*/
#include <AzCore/Asset/AssetSerializer.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <Builder/ScriptCanvasBuilder.h>
#include <Builder/ScriptCanvasBuilderWorker.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
#include <ScriptCanvas/Components/EditorDeprecationData.h>
#include <ScriptCanvas/Components/EditorGraph.h>
#include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
#include <ScriptCanvas/Grammar/AbstractCodeModel.h>
#include <AzCore/Asset/AssetSerializer.h>
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
#include <ScriptCanvas/Components/EditorGraph.h>
namespace BuildVariableOverridesCpp
{
@@ -41,7 +41,7 @@ namespace BuildVariableOverridesCpp
}
auto& sourceElement = rootElement.GetSubElement(sourceIndex);
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> asset;
AZ::Data::Asset<ScriptCanvasEditor::Deprecated::ScriptCanvasAsset> asset;
if (!sourceElement.GetData(asset))
{
AZ_Error("ScriptCanvas", false, "BuildVariableOverrides coversion failed: could not retrieve 'source' data");
@@ -15,7 +15,6 @@
namespace ScriptCanvasEditor
{
class ScriptCanvasAsset;
class EditorAssetTree;
}
@@ -14,8 +14,7 @@
#include <Builder/ScriptCanvasBuilderWorker.h>
#include <ScriptCanvas/Asset/RuntimeAssetHandler.h>
#include <ScriptCanvas/Asset/SubgraphInterfaceAssetHandler.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Utils/BehaviorContextUtils.h>
namespace ScriptCanvasBuilder
@@ -97,8 +96,6 @@ namespace ScriptCanvasBuilder
builderDescriptor.m_productsToKeepOnFailure[s_scriptCanvasProcessJobKey] = { AZ_CRC("SubgraphInterface", 0xdfe6dc72) };
m_scriptCanvasBuilder.BusConnect(builderDescriptor.m_busId);
AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBus::Handler::RegisterBuilderInformation, builderDescriptor);
AzToolsFramework::ToolsAssetSystemBus::Broadcast(&AzToolsFramework::ToolsAssetSystemRequests::RegisterSourceAssetType, azrtti_typeid<ScriptCanvasEditor::ScriptCanvasAsset>(), ScriptCanvasEditor::ScriptCanvasAsset::Description::GetFileFilter<ScriptCanvasEditor::ScriptCanvasAsset>());
}
m_sharedHandlers = HandleAssetTypes();
@@ -110,7 +107,6 @@ namespace ScriptCanvasBuilder
{
// Finish all queued work
AZ::Data::AssetBus::ExecuteQueuedEvents();
AzToolsFramework::ToolsAssetSystemBus::Broadcast(&AzToolsFramework::ToolsAssetSystemRequests::UnregisterSourceAssetType, azrtti_typeid<ScriptCanvasEditor::ScriptCanvasAsset>());
m_scriptCanvasBuilder.BusDisconnect();
m_sharedHandlers.DeleteOwnedHandlers();
}
@@ -18,7 +18,6 @@
#include <Builder/ScriptCanvasBuilderWorker.h>
#include <ScriptCanvas/Asset/RuntimeAssetHandler.h>
#include <ScriptCanvas/Asset/SubgraphInterfaceAssetHandler.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
#include <ScriptCanvas/Components/EditorGraph.h>
#include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
@@ -45,10 +44,8 @@ namespace ScriptCanvasBuilder
AzFramework::StringFunc::Path::ConstructFull(request.m_watchFolder.data(), request.m_sourceFile.data(), fullPath, false);
AzFramework::StringFunc::Path::Normalize(fullPath);
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> asset;
const ScriptCanvasEditor::Graph* sourceGraph = nullptr;
const ScriptCanvas::GraphData* graphData = nullptr;
ScriptCanvasEditor::SourceHandle sourceHandle;
auto sourceOutcome = ScriptCanvasEditor::LoadFromFile(fullPath);
@@ -58,7 +55,14 @@ namespace ScriptCanvasBuilder
sourceGraph = sourceHandle.Get();
graphData = sourceGraph->GetGraphDataConst();
}
else
{
AZ_TracePrintf(s_scriptCanvasBuilder, "Failed to load the file: %s", fullPath.c_str());
response.m_result = AssetBuilderSDK::CreateJobsResultCode::Failed;
}
// in terms of job creation, assert on anything but smooth sailing from this point
AZ_Assert(sourceGraph, "Graph component is missing from entity.");
AZ_Assert(graphData, "GraphData is missing from entity");
@@ -36,7 +36,6 @@ namespace ScriptCanvas
namespace ScriptCanvasEditor
{
class Graph;
class ScriptCanvasAsset;
class SourceHandle;
}
@@ -132,8 +131,6 @@ namespace ScriptCanvasBuilder
int GetBuilderVersion();
AZ::Outcome<AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>, AZStd::string> LoadEditorAsset(AZStd::string_view graphPath, AZ::Data::AssetId assetId, AZ::Data::AssetFilterCB assetFilterCB = {});
AZ::Outcome<ScriptCanvas::Grammar::AbstractCodeModelConstPtr, AZStd::string> ParseGraph(AZ::Entity& buildEntity, AZStd::string_view graphPath);
AZ::Outcome<void, AZStd::string> ProcessTranslationJob(ProcessTranslationJobInput& input);
@@ -20,7 +20,6 @@
#include <ScriptCanvas/Asset/SubgraphInterfaceAssetHandler.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Asset/RuntimeAssetHandler.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Components/EditorGraph.h>
#include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
#include <ScriptCanvas/Core/Connection.h>
@@ -386,45 +385,6 @@ namespace ScriptCanvasBuilder
;
}
AZ::Outcome < AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>, AZStd::string> LoadEditorAsset(AZStd::string_view filePath, AZ::Data::AssetId assetId, AZ::Data::AssetFilterCB assetFilterCB)
{
AZStd::shared_ptr<AZ::Data::AssetDataStream> assetDataStream = AZStd::make_shared<AZ::Data::AssetDataStream>();
// Read the asset into a memory buffer, then hand ownership of the buffer to assetDataStream
{
AZ::IO::FileIOStream stream(filePath.data(), AZ::IO::OpenMode::ModeRead);
if (!AZ::IO::RetryOpenStream(stream))
{
AZ_Warning(s_scriptCanvasBuilder, false, "CreateJobs for \"%s\" failed because the source file could not be opened.", filePath.data());
AZ::Failure(AZStd::string::format("Failed to load ScriptCavas asset: %s", filePath.data()));
}
AZStd::vector<AZ::u8> fileBuffer(stream.GetLength());
size_t bytesRead = stream.Read(fileBuffer.size(), fileBuffer.data());
if (bytesRead != stream.GetLength())
{
AZ_Warning(s_scriptCanvasBuilder, false, "CreateJobs for \"%s\" failed because the source file could not be read.", filePath.data());
AZ::Failure(AZStd::string::format("Failed to load ScriptCavas asset: %s", filePath.data()));
}
assetDataStream->Open(AZStd::move(fileBuffer));
}
ScriptCanvasEditor::ScriptCanvasAssetHandler editorAssetHandler;
AZ::SerializeContext* context{};
AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> asset;
asset.Create(assetId);
if (editorAssetHandler.LoadAssetData(asset, assetDataStream, assetFilterCB) != AZ::Data::AssetHandler::LoadResult::LoadComplete)
{
return AZ::Failure(AZStd::string::format("Failed to load ScriptCavas asset: %s", filePath.data()));
}
return AZ::Success(asset);
}
ScriptCanvasEditor::Graph* PrepareSourceGraph(AZ::Entity* const buildEntity)
{
auto sourceGraph = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvasEditor::Graph>(buildEntity);
@@ -1,126 +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 <AzCore/Asset/AssetManagerBus.h>
#include <AzCore/Serialization/Utils.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Bus/ScriptCanvasBus.h>
#include <ScriptCanvas/Core/ScriptCanvasBus.h>
#include <ScriptCanvas/Components/EditorGraph.h>
#include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
namespace ScriptCanvas
{
ScriptCanvasData::ScriptCanvasData(ScriptCanvasData&& other)
: m_scriptCanvasEntity(AZStd::move(other.m_scriptCanvasEntity))
{
}
ScriptCanvasData& ScriptCanvasData::operator=(ScriptCanvasData&& other)
{
m_scriptCanvasEntity = AZStd::move(other.m_scriptCanvasEntity);
return *this;
}
static bool ScriptCanvasDataVersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& rootDataElementNode)
{
if (rootDataElementNode.GetVersion() == 0)
{
int scriptCanvasEntityIndex = rootDataElementNode.FindElement(AZ_CRC("m_scriptCanvas", 0xfcd20d85));
if (scriptCanvasEntityIndex == -1)
{
AZ_Error("Script Canvas", false, "Version Converter failed, The Script Canvas Entity is missing");
return false;
}
auto scComponentElements = AZ::Utils::FindDescendantElements(context, rootDataElementNode, AZStd::vector<AZ::Crc32>{AZ_CRC("m_scriptCanvas", 0xfcd20d85),
AZ_CRC("element", 0x41405e39), AZ_CRC("Components", 0xee48f5fd)});
if (!scComponentElements.empty())
{
scComponentElements.front()->AddElementWithData(context, "element", ScriptCanvasEditor::EditorGraphVariableManagerComponent());
}
}
if (rootDataElementNode.GetVersion() < 4)
{
auto scEntityElements = AZ::Utils::FindDescendantElements(context, rootDataElementNode,
AZStd::vector<AZ::Crc32>{AZ_CRC("m_scriptCanvas", 0xfcd20d85), AZ_CRC("element", 0x41405e39)});
if (scEntityElements.empty())
{
AZ_Error("Script Canvas", false, "Version Converter failed, The Script Canvas Entity is missing");
return false;
}
auto& scEntityDataElement = *scEntityElements.front();
AZ::Entity scEntity;
if (!scEntityDataElement.GetData(scEntity))
{
AZ_Error("Script Canvas", false, "Unable to retrieve entity data from the Data Element");
return false;
}
auto graph = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::Graph>(&scEntity);
if (!graph)
{
AZ_Error("Script Canvas", false, "Script Canvas graph component could not be found on Script Canvas Entity for ScriptCanvasData version %u", rootDataElementNode.GetVersion());
return false;
}
auto variableManager = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::GraphVariableManagerComponent>(&scEntity);
if (!variableManager)
{
AZ_Error("Script Canvas", false, "Script Canvas variable manager component could not be found on Script Canvas Entity for ScriptCanvasData version %u", rootDataElementNode.GetVersion());
return false;
}
variableManager->ConfigureScriptCanvasId(graph->GetScriptCanvasId());
if (!scEntityDataElement.SetData(context, scEntity))
{
AZ_Error("Script Canvas", false, "Failed to set converted Script Canvas Entity back on data element node when transitioning from version %u to version 4", rootDataElementNode.GetVersion());
return false;
}
}
return true;
}
void ScriptCanvasData::Reflect(AZ::ReflectContext* reflectContext)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
{
serializeContext->Class<ScriptCanvasData>()
->Version(4, &ScriptCanvasDataVersionConverter)
->Field("m_scriptCanvas", &ScriptCanvasData::m_scriptCanvasEntity)
;
}
}
}
namespace ScriptCanvasEditor
{
ScriptCanvas::Graph* ScriptCanvasAsset::GetScriptCanvasGraph() const
{
return AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::Graph>(m_data->m_scriptCanvasEntity.get());
}
ScriptCanvas::ScriptCanvasData& ScriptCanvasAsset::GetScriptCanvasData()
{
AZ_Assert(m_data != nullptr, "ScriptCanvasData not initialized, it must be created on construction");
return *m_data;
}
const ScriptCanvas::ScriptCanvasData& ScriptCanvasAsset::GetScriptCanvasData() const
{
AZ_Assert(m_data != nullptr, "ScriptCanvasData not initialized, it must be created on construction");
return *m_data;
}
}
@@ -1,289 +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 <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/IO/GenericStreams.h>
#include <AzCore/Serialization/Json/JsonSerialization.h>
#include <AzCore/Serialization/Json/JsonSerializationResult.h>
#include <AzCore/Serialization/Json/JsonUtils.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/Utils.h>
#include <AzCore/std/string/string_view.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <Core/ScriptCanvasBus.h>
#include <GraphCanvas/GraphCanvasBus.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
#include <ScriptCanvas/Bus/ScriptCanvasBus.h>
#include <ScriptCanvas/Components/EditorGraph.h>
#include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
#include <ScriptCanvas/Components/EditorScriptCanvasComponent.h>
#include <ScriptCanvas/Core/SerializationListener.h>
namespace ScriptCanvasAssetHandlerCpp
{
using namespace ScriptCanvas;
void CollectNodes(const GraphData::NodeContainer& container, SerializationListeners& listeners)
{
for (auto& nodeEntity : container)
{
if (nodeEntity)
{
if (auto listener = azrtti_cast<SerializationListener*>(AZ::EntityUtils::FindFirstDerivedComponent<Node>(nodeEntity)))
{
listeners.push_back(listener);
}
}
}
}
}
namespace ScriptCanvasEditor
{
ScriptCanvasAssetHandler::ScriptCanvasAssetHandler(AZ::SerializeContext* context)
{
SetSerializeContext(context);
AZ::AssetTypeInfoBus::MultiHandler::BusConnect(GetAssetType());
}
ScriptCanvasAssetHandler::~ScriptCanvasAssetHandler()
{
AZ::AssetTypeInfoBus::MultiHandler::BusDisconnect();
}
AZ::Data::AssetPtr ScriptCanvasAssetHandler::CreateAsset(const AZ::Data::AssetId& id, const AZ::Data::AssetType& type)
{
(void)type;
auto assetData = aznew ScriptCanvasAsset(id);
AZ::Entity* scriptCanvasEntity = aznew AZ::Entity("Script Canvas Graph");
SystemRequestBus::Broadcast(&SystemRequests::CreateEditorComponentsOnEntity, scriptCanvasEntity, azrtti_typeid<ScriptCanvas::RuntimeAsset>());
assetData->SetScriptCanvasEntity(scriptCanvasEntity);
return assetData;
}
// Override the stream info to force source assets to load into the Editor instead of cached, processed assets.
void ScriptCanvasAssetHandler::GetCustomAssetStreamInfoForLoad(AZ::Data::AssetStreamInfo& streamInfo)
{
//ScriptCanvas files are source assets and should be placed in a source asset directory
const char* assetPath = streamInfo.m_streamName.c_str();
if (AzFramework::StringFunc::Path::IsRelative(assetPath))
{
AZStd::string watchFolder;
bool sourceInfoFound{};
AZ::Data::AssetInfo assetInfo;
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, assetPath, assetInfo, watchFolder);
if (sourceInfoFound)
{
AzFramework::StringFunc::Path::Join(watchFolder.data(), assetInfo.m_relativePath.data(), streamInfo.m_streamName);
}
}
}
AZ::Data::AssetHandler::LoadResult ScriptCanvasAssetHandler::LoadAssetData
( const AZ::Data::Asset<AZ::Data::AssetData>& assetTarget
, AZStd::shared_ptr<AZ::Data::AssetDataStream> streamSource
, [[maybe_unused]] const AZ::Data::AssetFilterCB& assetLoadFilterCB)
{
namespace JSRU = AZ::JsonSerializationUtils;
using namespace ScriptCanvas;
auto* scriptCanvasAssetTarget = assetTarget.GetAs<ScriptCanvasAsset>();
AZ_Assert(scriptCanvasAssetTarget, "This should be a ScriptCanvasAsset, as this is the only type we process!");
if (m_serializeContext
&& streamSource
&& scriptCanvasAssetTarget)
{
streamSource->Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN);
auto& scriptCanvasDataTarget = scriptCanvasAssetTarget->GetScriptCanvasData();
AZStd::vector<char> byteBuffer;
byteBuffer.resize_no_construct(streamSource->GetLength());
// this duplicate stream is to allow for trying again if the JSON read fails
AZ::IO::ByteContainerStream<decltype(byteBuffer)> byteStreamSource(&byteBuffer);
const size_t bytesRead = streamSource->Read(byteBuffer.size(), byteBuffer.data());
scriptCanvasDataTarget.m_scriptCanvasEntity.reset(nullptr);
if (bytesRead == streamSource->GetLength())
{
byteStreamSource.Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN);
AZ::JsonDeserializerSettings settings;
settings.m_serializeContext = m_serializeContext;
settings.m_metadata.Create<SerializationListeners>();
// attempt JSON deserialization...
auto jsonResult = LoadDataFromJson
( scriptCanvasDataTarget
, AZStd::string_view{ byteBuffer.begin(), byteBuffer.size() }
, *m_serializeContext);
if (jsonResult.IsSuccess())
{
return AZ::Data::AssetHandler::LoadResult::LoadComplete;
}
#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)////
else
{
// ...if there is a failure, check if it is saved in the old format
byteStreamSource.Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN);
// tolerate unknown classes in the editor. Let the asset processor warn about bad nodes...
if (AZ::Utils::LoadObjectFromStreamInPlace
( byteStreamSource
, scriptCanvasDataTarget
, m_serializeContext
, AZ::ObjectStream::FilterDescriptor(assetLoadFilterCB, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES)))
{
AZ_Warning
( "ScriptCanvas"
, false
, "ScriptCanvasAssetHandler::LoadAssetData failed to load graph data from JSON, %s, consider converting to JSON"
" by opening it and saving it, or running the graph update tool from the editor0"
, jsonResult.GetError().c_str());
return AZ::Data::AssetHandler::LoadResult::LoadComplete;
}
}
#else
else
{
AZ_Warning
( "ScriptCanvas"
, false
, "ScriptCanvasAssetHandler::LoadAssetData failed to load graph data from JSON %s"
, jsonResult.GetError().c_str()");
}
#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)
}
}
return AZ::Data::AssetHandler::LoadResult::Error;
}
bool ScriptCanvasAssetHandler::SaveAssetData(const AZ::Data::Asset<AZ::Data::AssetData>& asset, AZ::IO::GenericStream* stream)
{
return SaveAssetData(asset.GetAs<ScriptCanvasAsset>(), stream);
}
bool ScriptCanvasAssetHandler::SaveAssetData(const ScriptCanvasAsset* assetData, AZ::IO::GenericStream* stream)
{
return SaveAssetData(assetData, stream, AZ::DataStream::ST_XML);
}
bool ScriptCanvasAssetHandler::SaveAssetData
( const ScriptCanvasAsset* assetData
, AZ::IO::GenericStream* stream
, [[maybe_unused]] AZ::DataStream::StreamType streamType)
{
// #sc_editor_asset delete usage of this, and route to ScriptCanvasEditor::SaveToStream
namespace JSRU = AZ::JsonSerializationUtils;
using namespace ScriptCanvas;
if (m_serializeContext
&& stream
&& assetData
&& assetData->GetScriptCanvasGraph()
&& assetData->GetScriptCanvasGraph()->GetGraphData())
{
auto graphData = assetData->GetScriptCanvasGraph()->GetGraphData();
AZ::JsonSerializerSettings settings;
settings.m_metadata.Create<SerializationListeners>();
auto listeners = settings.m_metadata.Find<SerializationListeners>();
AZ_Assert(listeners, "Failed to create SerializationListeners");
ScriptCanvasAssetHandlerCpp::CollectNodes(graphData->m_nodes, *listeners);
settings.m_keepDefaults = false;
settings.m_serializeContext = m_serializeContext;
for (auto listener : *listeners)
{
listener->OnSerialize();
}
return JSRU::SaveObjectToStream<ScriptCanvasData>(&assetData->GetScriptCanvasData(), *stream, nullptr, &settings).IsSuccess();
}
else
{
AZ_Error("ScriptCanvas", false, "Saving ScriptCavas assets in the handler requires a valid IO stream, "
"asset pointer, and serialize context");
return false;
}
}
void ScriptCanvasAssetHandler::DestroyAsset(AZ::Data::AssetPtr ptr)
{
delete ptr;
}
AZ::SerializeContext* ScriptCanvasAssetHandler::GetSerializeContext() const
{
return m_serializeContext;
}
void ScriptCanvasAssetHandler::SetSerializeContext(AZ::SerializeContext* context)
{
m_serializeContext = context;
if (m_serializeContext == nullptr)
{
// use the default app serialize context
EBUS_EVENT_RESULT(m_serializeContext, AZ::ComponentApplicationBus, GetSerializeContext);
if (!m_serializeContext)
{
AZ_Error("Script Canvas", false, "ScriptCanvasAssetHandler: No serialize context provided! "
"We will not be able to process Graph Asset type");
}
}
}
void ScriptCanvasAssetHandler::GetHandledAssetTypes(AZStd::vector<AZ::Data::AssetType>& assetTypes)
{
assetTypes.push_back(GetAssetType());
}
AZ::Data::AssetType ScriptCanvasAssetHandler::GetAssetType() const
{
return ScriptCanvasAssetHandler::GetAssetTypeStatic();
}
const char* ScriptCanvasAssetHandler::GetAssetTypeDisplayName() const
{
return "Script Canvas";
}
AZ::Data::AssetType ScriptCanvasAssetHandler::GetAssetTypeStatic()
{
return azrtti_typeid<ScriptCanvasAsset>();
}
void ScriptCanvasAssetHandler::GetAssetTypeExtensions(AZStd::vector<AZStd::string>& extensions)
{
ScriptCanvasAsset::Description description;
extensions.push_back(description.GetExtensionImpl());
}
AZ::Uuid ScriptCanvasAssetHandler::GetComponentTypeId() const
{
return azrtti_typeid<EditorScriptCanvasComponent>();
}
const char* ScriptCanvasAssetHandler::GetGroup() const
{
return ScriptCanvas::AssetDescription::GetGroup<ScriptCanvasEditor::ScriptCanvasAsset>();
}
const char* ScriptCanvasAssetHandler::GetBrowserIcon() const
{
return ScriptCanvas::AssetDescription::GetIconPath<ScriptCanvasEditor::ScriptCanvasAsset>();
}
}
@@ -8,7 +8,7 @@
#include <Editor/Assets/ScriptCanvasAssetHelpers.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
namespace ScriptCanvasEditor
@@ -150,11 +150,7 @@ namespace ScriptCanvasEditor
bool IsValidSourceFile(const AZStd::string& filePath, [[maybe_unused]] ScriptCanvas::ScriptCanvasId scriptCanvasId)
{
ScriptCanvasAssetDescription assetDescription;
return AZ::StringFunc::EndsWith(filePath, assetDescription.GetExtensionImpl(), false);
{
return true;
}
return AZ::StringFunc::EndsWith(filePath, ScriptCanvasEditor::SourceDescription::GetFileExtension(), false);
}
}
}
@@ -1,207 +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 <LyViewPaneNames.h>
#include <Editor/Assets/ScriptCanvasAssetHolder.h>
#include <ScriptCanvas/Asset/AssetRegistry.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
#include <ScriptCanvas/Bus/ScriptCanvasBus.h>
#include <ScriptCanvas/Core/ScriptCanvasBus.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Serialization/IdUtils.h>
#include <AzCore/Asset/AssetManager.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <Editor/Assets/ScriptCanvasAssetTrackerBus.h>
#include <Editor/Assets/ScriptCanvasAssetTracker.h>
#include <Editor/Assets/ScriptCanvasAssetTrackerDefinitions.h>
namespace ScriptCanvasEditor
{
//=========================================================================
void ScriptCanvasAssetHolder::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<ScriptCanvasAssetHolder>()
->Version(1)
->Field("m_asset", &ScriptCanvasAssetHolder::m_scriptCanvasAsset)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<ScriptCanvasAssetHolder>("Script Canvas", "Script Canvas Asset Holder")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->DataElement(AZ::Edit::UIHandlers::Default, &ScriptCanvasAssetHolder::m_scriptCanvasAsset, "Script Canvas Asset", "Script Canvas asset associated with this component")
->Attribute(AZ::Edit::Attributes::ChangeNotify, &ScriptCanvasAssetHolder::OnScriptChanged)
->Attribute("BrowseIcon", ":/stylesheet/img/UI20/browse-edit-select-files.svg")
->Attribute("EditButton", "")
->Attribute("EditDescription", "Open in Script Canvas Editor")
->Attribute("EditCallback", &ScriptCanvasAssetHolder::LaunchScriptCanvasEditor)
->Attribute(AZ::Edit::Attributes::ShowProductAssetFileName, false)
;
}
}
}
ScriptCanvasAssetHolder::~ScriptCanvasAssetHolder()
{
}
void ScriptCanvasAssetHolder::Init(AZ::EntityId ownerId, AZ::ComponentId componentId)
{
m_ownerId = AZStd::make_pair(ownerId, componentId);
if (!m_scriptCanvasAsset || !m_scriptCanvasAsset.IsReady())
{
AssetTrackerNotificationBus::Handler::BusConnect(m_scriptCanvasAsset.GetId());
Callbacks::OnAssetReadyCallback onAssetReady = [](ScriptCanvasMemoryAsset& asset)
{
AssetHelpers::DumpAssetInfo(asset.GetFileAssetId(), "ScriptCanvasAssetHolder::Init");
};
AssetTrackerRequestBus::Broadcast(&AssetTrackerRequests::Load, m_scriptCanvasAsset.GetId(), azrtti_typeid<ScriptCanvasAsset>(), onAssetReady);
}
}
void ScriptCanvasAssetHolder::LaunchScriptCanvasEditor(const AZ::Data::AssetId&, const AZ::Data::AssetType&) const
{
OpenEditor();
}
void ScriptCanvasAssetHolder::OpenEditor() const
{
}
ScriptCanvas::ScriptCanvasId ScriptCanvasAssetHolder::GetScriptCanvasId() const
{
ScriptCanvas::ScriptCanvasId graphId;
if (m_scriptCanvasAsset.IsReady())
{
ScriptCanvas::SystemRequestBus::BroadcastResult(graphId, &ScriptCanvas::SystemRequests::FindScriptCanvasId, m_scriptCanvasAsset.Get()->GetScriptCanvasEntity());
}
return graphId;
}
void ScriptCanvasAssetHolder::SetScriptChangedCB(const ScriptChangedCB& scriptChangedCB)
{
m_scriptNotifyCallback = scriptChangedCB;
}
void ScriptCanvasAssetHolder::Load(AZ::Data::AssetId fileAssetId)
{
m_scriptCanvasAsset = AZ::Data::AssetManager::Instance().FindAsset(fileAssetId, AZ::Data::AssetLoadBehavior::Default);
if (!m_scriptCanvasAsset || !m_scriptCanvasAsset.IsReady())
{
m_scriptCanvasAsset = AZ::Data::AssetManager::Instance().GetAsset(fileAssetId, azrtti_typeid<ScriptCanvasAsset>(), AZ::Data::AssetLoadBehavior::Default);
m_triggeredLoad = true;
AZ::Data::AssetBus::Handler::BusDisconnect();
AZ::Data::AssetBus::Handler::BusConnect(fileAssetId);
}
else if (m_memoryScriptCanvasAsset.Get() == nullptr)
{
m_triggeredLoad = false;
LoadMemoryAsset(fileAssetId);
}
}
void ScriptCanvasAssetHolder::LoadMemoryAsset(AZ::Data::AssetId fileAssetId)
{
Callbacks::OnAssetReadyCallback onAssetReady = [this](ScriptCanvasMemoryAsset& asset)
{
m_memoryScriptCanvasAsset = asset.GetAsset();
AssetHelpers::DumpAssetInfo(asset.GetFileAssetId(), "ScriptCanvasAssetHolder::Load onAssetReady");
};
AssetTrackerRequestBus::Broadcast(&AssetTrackerRequests::Load, fileAssetId, azrtti_typeid<ScriptCanvasAsset>(), onAssetReady);
}
void ScriptCanvasAssetHolder::OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
AZ::Data::AssetBus::Handler::BusDisconnect();
LoadMemoryAsset(asset.GetId());
}
AZ::u32 ScriptCanvasAssetHolder::OnScriptChanged()
{
AssetTrackerNotificationBus::Handler::BusDisconnect();
if (m_scriptCanvasAsset.GetId().IsValid())
{
AssetTrackerNotificationBus::Handler::BusConnect(m_scriptCanvasAsset.GetId());
Load(m_scriptCanvasAsset.GetId());
}
else
{
m_scriptCanvasAsset = {};
m_memoryScriptCanvasAsset = {};
}
if (m_scriptNotifyCallback)
{
m_scriptNotifyCallback(m_scriptCanvasAsset.GetId());
}
return AZ::Edit::PropertyRefreshLevels::EntireTree;
}
void ScriptCanvasAssetHolder::OnAssetReady(const ScriptCanvasMemoryAsset::pointer asset)
{
if (asset->GetFileAssetId() == m_scriptCanvasAsset.GetId())
{
AssetTrackerNotificationBus::Handler::BusDisconnect(m_scriptCanvasAsset.GetId());
m_scriptCanvasAsset = AZ::Data::AssetManager::Instance().FindAsset(asset->GetFileAssetId(), AZ::Data::AssetLoadBehavior::Default);
m_memoryScriptCanvasAsset = asset->GetAsset();
if (m_triggeredLoad && m_scriptNotifyCallback)
{
m_triggeredLoad = false;
m_scriptNotifyCallback(m_scriptCanvasAsset.GetId());
}
}
}
void ScriptCanvasAssetHolder::SetAsset(AZ::Data::AssetId fileAssetId)
{
AZ::Data::AssetBus::Handler::BusDisconnect();
AssetTrackerNotificationBus::Handler::BusDisconnect();
Load(fileAssetId);
if (m_scriptCanvasAsset)
{
AssetTrackerNotificationBus::Handler::BusConnect(m_scriptCanvasAsset.GetId());
}
}
const AZ::Data::AssetType& ScriptCanvasAssetHolder::GetAssetType() const
{
return m_scriptCanvasAsset.GetType();
}
void ScriptCanvasAssetHolder::ClearAsset()
{
m_scriptCanvasAsset = {};
m_memoryScriptCanvasAsset = {};
}
AZ::Data::AssetId ScriptCanvasAssetHolder::GetAssetId() const
{
return m_scriptCanvasAsset.GetId();
}
}
@@ -1,99 +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/Component/EntityId.h>
#include <AzCore/Asset/AssetCommon.h>
#include <Editor/Assets/ScriptCanvasAssetTrackerBus.h>
#include <ScriptCanvas/Bus/RequestBus.h>
#include <ScriptCanvas/Core/Core.h>
namespace ScriptCanvasEditor
{
class ScriptCanvasAsset;
/*! ScriptCanvasAssetHolder
Wraps a ScriptCanvasAsset reference and registers for the individual AssetBus events
for saving, loading and unloading the asset.
The ScriptCanvasAsset Holder contains functionality for activating the ScriptCanvasEntity stored on the reference asset
as well as attempting to open the ScriptCanvasAsset within the ScriptCanvas Editor.
It also provides the EditContext reflection for opening the asset in the ScriptCanvas Editor via a button
*/
class ScriptCanvasAssetHolder
: AssetTrackerNotificationBus::Handler
, AZ::Data::AssetBus::Handler
{
public:
AZ_RTTI(ScriptCanvasAssetHolder, "{3E80CEE3-2932-4DC1-AADF-398FDDC6DEFE}");
AZ_CLASS_ALLOCATOR(ScriptCanvasAssetHolder, AZ::SystemAllocator, 0);
using ScriptChangedCB = AZStd::function<void(AZ::Data::AssetId)>;
ScriptCanvasAssetHolder() = default;
~ScriptCanvasAssetHolder() override;
static void Reflect(AZ::ReflectContext* context);
void Init(AZ::EntityId ownerId = AZ::EntityId(), AZ::ComponentId componentId = AZ::ComponentId());
const AZ::Data::AssetType& GetAssetType() const;
void ClearAsset();
void SetAsset(AZ::Data::AssetId fileAssetId);
AZ::Data::AssetId GetAssetId() const;
ScriptCanvas::ScriptCanvasId GetScriptCanvasId() const;
void LaunchScriptCanvasEditor(const AZ::Data::AssetId&, const AZ::Data::AssetType&) const;
void OpenEditor() const;
void SetScriptChangedCB(const ScriptChangedCB&);
void Load(AZ::Data::AssetId fileAssetId);
void LoadMemoryAsset(AZ::Data::AssetId fileAssetId);
//! AZ::Data::AssetBus
void OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
////
const AZStd::string_view GetAssetHint() const
{
if (m_scriptCanvasAsset)
{
return m_scriptCanvasAsset.GetHint().c_str();
}
if (m_memoryScriptCanvasAsset)
{
return m_memoryScriptCanvasAsset.GetHint().c_str();
}
return "";
}
protected:
//=====================================================================
// AssetTrackerNotificationBus
void OnAssetReady(const ScriptCanvasMemoryAsset::pointer asset) override;
//=====================================================================
//! Reloads the Script From the AssetData if it has changed
AZ::u32 OnScriptChanged();
AZ::Data::Asset<ScriptCanvasAsset> m_scriptCanvasAsset;
AZ::Data::Asset<ScriptCanvasAsset> m_memoryScriptCanvasAsset;
TypeDefs::EntityComponentId m_ownerId; // Id of Entity which stores this AssetHolder object
ScriptChangedCB m_scriptNotifyCallback;
bool m_triggeredLoad = false;
};
}
@@ -1,441 +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 "ScriptCanvasAssetTracker.h"
#include <AzCore/IO/FileIO.h>
#include <AzCore/Component/TickBus.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserModel.h>
#include <AzToolsFramework/AssetBrowser/Entries/ProductAssetBrowserEntry.h>
#include <AzToolsFramework/SourceControl/SourceControlAPI.h>
#include <Editor/Assets/ScriptCanvasAssetHelpers.h>
#include <Editor/Assets/ScriptCanvasMemoryAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Core/ScriptCanvasBus.h>
#include <AzCore/std/smart_ptr/make_shared.h>
namespace ScriptCanvasEditor
{
/////////////////
// AssetTracker
/////////////////
AZ::Data::AssetId AssetTracker::Create(AZStd::string_view assetAbsolutePath, AZ::Data::AssetType assetType, Callbacks::OnAssetCreatedCallback onAssetCreatedCallback)
{
AZ::Data::AssetId newAssetId = AZ::Uuid::CreateRandom();
MemoryAssetMapIterator iterator = m_assetsInUse.emplace(newAssetId, AZStd::make_shared<ScriptCanvasMemoryAsset>());
ScriptCanvasMemoryAsset::pointer memoryAsset = iterator.first->second;
memoryAsset->Create(newAssetId, assetAbsolutePath, assetType, onAssetCreatedCallback);
return newAssetId;
}
bool AssetTracker::IsSaving(AZ::Data::AssetId assetId) const
{
assetId = CheckAssetId(assetId);
return m_savingAssets.find(assetId) != m_savingAssets.end();
}
void AssetTracker::Save(AZ::Data::AssetId assetId, Callbacks::OnSave onSaveCallback)
{
SaveAs(assetId, {}, onSaveCallback);
}
void AssetTracker::SaveAs(AZ::Data::AssetId /*assetId*/, const AZStd::string& /*path*/, Callbacks::OnSave /*onSaveCallback*/)
{
}
bool AssetTracker::Load(AZ::Data::AssetId fileAssetId, AZ::Data::AssetType assetType, Callbacks::OnAssetReadyCallback onAssetReadyCallback)
{
if (!fileAssetId.IsValid())
{
return false;
}
auto assetIter = m_assetsInUse.find(fileAssetId);
if (assetIter != m_assetsInUse.end())
{
if (!assetIter->second->IsSourceInError())
{
if (onAssetReadyCallback)
{
// The asset is already loaded and tracked
AZStd::invoke(onAssetReadyCallback, *m_assetsInUse[fileAssetId]);
AssetTrackerNotificationBus::Event(fileAssetId, &AssetTrackerNotifications::OnAssetReady, m_assetsInUse[fileAssetId]);
}
return true;
}
else
{
m_assetsInUse.erase(assetIter);
}
}
m_assetsInUse[fileAssetId] = AZStd::make_shared<ScriptCanvasMemoryAsset>();
m_onAssetReadyCallback = onAssetReadyCallback;
auto onReady = [this, fileAssetId](ScriptCanvasMemoryAsset& asset)
{
m_remappedAsset[asset.GetId()] = fileAssetId;
if (m_onAssetReadyCallback)
{
AZStd::invoke(m_onAssetReadyCallback, *m_assetsInUse[fileAssetId]);
}
};
// If we failed to load the asset, signal back as much
if (!m_assetsInUse[fileAssetId]->Load(fileAssetId, assetType, onReady))
{
m_assetsInUse.erase(fileAssetId);
return false;
}
return true;
}
void AssetTracker::Close(AZ::Data::AssetId assetId)
{
assetId = CheckAssetId(assetId);
if (m_assetsInUse.find(assetId) == m_assetsInUse.end())
{
return;
}
if (m_savingAssets.find(assetId) == m_savingAssets.end())
{
m_assetsInUse.erase(assetId);
}
else
{
m_queuedCloses.insert(assetId);
}
}
void AssetTracker::ClearView(AZ::Data::AssetId assetId)
{
assetId = CheckAssetId(assetId);
if (m_assetsInUse.find(assetId) != m_assetsInUse.end())
{
m_assetsInUse[assetId]->ClearView();
}
}
void AssetTracker::UntrackAsset(AZ::Data::AssetId assetId)
{
assetId = CheckAssetId(assetId);
m_assetsInUse.erase(assetId);
}
void AssetTracker::RefreshAll()
{
for (const auto& asset : m_assetsInUse)
{
auto id = asset.second->GetScriptCanvasId();
ScriptCanvasEditor::EditorGraphRequestBus::Event(id, &ScriptCanvasEditor::EditorGraphRequests::ClearGraphCanvasScene);
ScriptCanvasEditor::EditorGraphRequestBus::Event(id, &ScriptCanvasEditor::EditorGraphRequests::CreateGraphCanvasScene);
ScriptCanvasEditor::EditorGraphRequestBus::Event(id, &ScriptCanvasEditor::EditorGraphRequests::DisplayGraphCanvasScene);
}
}
void AssetTracker::CreateView(AZ::Data::AssetId assetId, QWidget* parent)
{
assetId = CheckAssetId(assetId);
if (m_assetsInUse.find(assetId) != m_assetsInUse.end())
{
m_assetsInUse[assetId]->CreateView(parent);
}
}
ScriptCanvasMemoryAsset::pointer AssetTracker::GetAsset(AZ::Data::AssetId assetId)
{
if (!assetId.IsValid())
{
return nullptr;
}
assetId = CheckAssetId(assetId);
if (m_assetsInUse.find(assetId) == m_assetsInUse.end())
{
auto asset = AZ::Data::AssetManager::Instance().FindAsset(assetId, AZ::Data::AssetLoadBehavior::Default);
if (asset)
{
auto insertResult = m_assetsInUse.emplace(AZStd::make_pair(assetId, AZStd::make_shared<ScriptCanvasMemoryAsset>()));
auto onReady = [this, assetId](ScriptCanvasMemoryAsset& asset)
{
m_remappedAsset[asset.GetId()] = assetId;
};
insertResult.first->second->Load(assetId, AZ::Data::AssetType::CreateNull(), onReady);
insertResult.first->second->ActivateAsset();
return insertResult.first->second;
}
// Handle the weird case of saving out a file you can't load because of pathing issues.
for (auto assetPair : m_assetsInUse)
{
if (assetPair.second->GetFileAssetId() == assetId)
{
return assetPair.second;
}
}
return nullptr;
}
if (m_assetsInUse.find(assetId) != m_assetsInUse.end())
{
return m_assetsInUse[assetId];
}
return nullptr;
}
AZ::Data::AssetId AssetTracker::GetAssetId(ScriptCanvas::ScriptCanvasId scriptCanvasSceneId)
{
for (const auto& asset : m_assetsInUse)
{
if (asset.second && asset.second->GetScriptCanvasId() == scriptCanvasSceneId)
{
AZ::Data::AssetId assetId = asset.second->GetAsset().GetId();
return assetId;
}
}
return {};
}
AZ::Data::AssetType AssetTracker::GetAssetType(ScriptCanvas::ScriptCanvasId scriptCanvasSceneId)
{
for (const auto& asset : m_assetsInUse)
{
if (asset.second && asset.second->GetScriptCanvasId() == scriptCanvasSceneId)
{
return asset.second->GetAssetType();
}
}
return AZ::Data::AssetType::CreateNull();
}
ScriptCanvas::ScriptCanvasId AssetTracker::GetScriptCanvasId(AZ::Data::AssetId assetId)
{
assetId = CheckAssetId(assetId);
if (m_assetsInUse.find(assetId) != m_assetsInUse.end())
{
return m_assetsInUse[assetId]->GetScriptCanvasId();
}
return ScriptCanvas::ScriptCanvasId();
}
AZ::EntityId AssetTracker::GetGraphCanvasId(AZ::EntityId scriptCanvasEntityId)
{
if (scriptCanvasEntityId.IsValid())
{
for (auto& asset : m_assetsInUse)
{
if (asset.second && asset.second->GetScriptCanvasId() == scriptCanvasEntityId)
{
return asset.second->GetGraphId();
}
}
}
return AZ::EntityId();
}
ScriptCanvas::ScriptCanvasId AssetTracker::GetScriptCanvasIdFromGraphId(AZ::EntityId graphId)
{
if (graphId.IsValid())
{
for (auto& asset : m_assetsInUse)
{
if (asset.second && asset.second->GetGraphId() == graphId)
{
return asset.second->GetScriptCanvasId();
}
}
}
return AZ::EntityId();
}
ScriptCanvas::ScriptCanvasId AssetTracker::GetGraphId(AZ::Data::AssetId assetId)
{
if (assetId.IsValid())
{
assetId = CheckAssetId(assetId);
auto assetIter = m_assetsInUse.find(assetId);
if (assetIter != m_assetsInUse.end())
{
return assetIter->second->GetGraphId();
}
}
return ScriptCanvas::ScriptCanvasId();
}
AZStd::string AssetTracker::GetTabName(AZ::Data::AssetId assetId)
{
assetId = CheckAssetId(assetId);
if (m_assetsInUse.find(assetId) != m_assetsInUse.end())
{
return m_assetsInUse[assetId]->GetTabName();
}
return {};
}
ScriptCanvasEditor::Tracker::ScriptCanvasFileState AssetTracker::GetFileState(AZ::Data::AssetId assetId)
{
assetId = CheckAssetId(assetId);
if (m_assetsInUse.find(assetId) != m_assetsInUse.end())
{
return m_assetsInUse[assetId]->GetFileState();
}
return Tracker::ScriptCanvasFileState::INVALID;
}
void AssetTracker::SignalSaveComplete(const AZ::Data::AssetId& fileAssetId)
{
size_t eraseCount = m_savingAssets.erase(fileAssetId);
if (eraseCount > 0)
{
if (m_queuedCloses.erase(fileAssetId) > 0)
{
Close(fileAssetId);
}
}
}
AZ::Data::AssetId AssetTracker::CheckAssetId(AZ::Data::AssetId assetId) const
{
auto remappedIter = m_remappedAsset.find(assetId);
if (remappedIter != m_remappedAsset.end())
{
assetId = remappedIter->second;
}
return assetId;
}
ScriptCanvasEditor::ScriptCanvasAssetHandler* AssetTracker::GetAssetHandlerForType(AZ::Data::AssetType assetType)
{
ScriptCanvasAssetHandler* assetHandler = nullptr;
AZ::EBusAggregateResults<AZ::Data::AssetHandler*> foundAssetHandlers;
ScriptCanvas::AssetRegistryRequestBus::BroadcastResult(foundAssetHandlers, &ScriptCanvas::AssetRegistryRequests::GetAssetHandler);
for (auto handler : foundAssetHandlers.values)
{
if (handler != nullptr)
{
ScriptCanvasAssetHandler* theHandler = azrtti_cast<ScriptCanvasAssetHandler*>(handler);
if (theHandler != nullptr && theHandler->GetAssetType() == assetType)
{
assetHandler = theHandler;
break;
}
}
}
AZ_Assert(assetHandler, "The specified asset type does not have a registered asset handler.");
return assetHandler;
}
void AssetTracker::UpdateFileState(AZ::Data::AssetId assetId, Tracker::ScriptCanvasFileState state)
{
assetId = CheckAssetId(assetId);
if (m_assetsInUse.find(assetId) != m_assetsInUse.end())
{
m_assetsInUse[assetId]->SetFileState(state);
}
}
AssetTrackerRequests::AssetList AssetTracker::GetUnsavedAssets()
{
auto pred = [](ScriptCanvasMemoryAsset::pointer asset)
{
auto fileState = asset->GetFileState();
if (fileState == Tracker::ScriptCanvasFileState::NEW || fileState == Tracker::ScriptCanvasFileState::MODIFIED)
{
return true;
}
return false;
};
return GetAssetsIf(pred);
}
AssetTrackerRequests::AssetList AssetTracker::GetAssets()
{
return GetAssetsIf([](ScriptCanvasMemoryAsset::pointer) { return true; });
}
AssetTrackerRequests::AssetList AssetTracker::GetAssetsIf(AZStd::function<bool(ScriptCanvasMemoryAsset::pointer asset)> pred)
{
AZStd::vector<ScriptCanvasMemoryAsset::pointer> unsavedAssets;
for (auto& assetIterator : m_assetsInUse)
{
auto testAsset = assetIterator.second;
if (AZStd::invoke(pred, testAsset) == true)
{
unsavedAssets.push_back(testAsset);
}
}
return unsavedAssets;
}
AZ::EntityId AssetTracker::GetSceneEntityIdFromEditorEntityId(AZ::Data::AssetId assetId, AZ::EntityId editorEntityId)
{
assetId = CheckAssetId(assetId);
if (m_assetsInUse.find(assetId) != m_assetsInUse.end())
{
return m_assetsInUse[assetId]->GetSceneEntityIdFromEditorEntityId(editorEntityId);
}
return AZ::EntityId();
}
AZ::EntityId AssetTracker::GetEditorEntityIdFromSceneEntityId(AZ::Data::AssetId assetId, AZ::EntityId sceneEntityId)
{
assetId = CheckAssetId(assetId);
if (m_assetsInUse.find(assetId) != m_assetsInUse.end())
{
return m_assetsInUse[assetId]->GetEditorEntityIdFromSceneEntityId(sceneEntityId);
}
return AZ::EntityId();
}
}
@@ -1,124 +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/std/containers/unordered_map.h>
#include <AzCore/std/string/string.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h>
#include <AzToolsFramework/AssetBrowser/Search/Filter.h>
#include <Editor/Assets/ScriptCanvasAssetTrackerBus.h>
#include <GraphCanvas/Editor/EditorTypes.h>
#include <ScriptCanvas/Bus/RequestBus.h>
namespace ScriptCanvasEditor
{
class ScriptCanvasMemoryAsset;
// This class tracks all things related to the assets that the Script Canvas editor
// has in play. It also provides helper functionality to quickly getting asset information
// from GraphCanvas
//
// The AssetTracker will be the ONLY allowed place to connect Script Canvas to the Asset System and any of its buses.
//
// The goal is to centralize all of the asset operations to a single place in order to simplify Script Canvas'
// interactions with the asset system as well as keeping any transient cache of information that is
// only important while Script Canvas graphs are open.
class AssetTracker
: AssetTrackerRequestBus::Handler
, Internal::MemoryAssetSystemNotificationBus::Handler
{
public:
AssetTracker() = default;
~AssetTracker() = default;
void Activate()
{
AssetTrackerRequestBus::Handler::BusConnect();
Internal::MemoryAssetSystemNotificationBus::Handler::BusConnect();
}
void Deactivate()
{
Internal::MemoryAssetSystemNotificationBus::Handler::BusDisconnect();
AssetTrackerRequestBus::Handler::BusDisconnect();
}
// AssetTrackerRequestBus
AZ::Data::AssetId Create(AZStd::string_view assetAbsolutePath, AZ::Data::AssetType assetType, Callbacks::OnAssetCreatedCallback onAssetCreatedCallback) override;
bool IsSaving(AZ::Data::AssetId assetId) const override;
void Save(AZ::Data::AssetId assetId, Callbacks::OnSave onSaveCallback) override;
void SaveAs(AZ::Data::AssetId assetId, const AZStd::string& path, Callbacks::OnSave onSaveCallback) override;
bool Load(AZ::Data::AssetId assetId, AZ::Data::AssetType assetType, Callbacks::OnAssetReadyCallback onAssetReadyCallback) override;
void Close(AZ::Data::AssetId assetId) override;
void CreateView(AZ::Data::AssetId assetId, QWidget* parent) override;
void ClearView(AZ::Data::AssetId assetId) override;
void UntrackAsset(AZ::Data::AssetId assetId) override;
void RefreshAll() override;
// Getters
// Given the assetId it returns a reference to the in-memory asset, returns false if the asset is not tracked
ScriptCanvasMemoryAsset::pointer GetAsset(AZ::Data::AssetId assetId) override;
// Given a ScriptCanvas EntityId it will lookup the AssetId
AZ::Data::AssetId GetAssetId(ScriptCanvas::ScriptCanvasId scriptCanvasSceneId) override;
// Given a ScriptCanvas EntityId it will lookup the asset's type
AZ::Data::AssetType GetAssetType(ScriptCanvas::ScriptCanvasId scriptCanvasSceneId) override;
// Retrieves the ScriptCanvasEntity for a given asset
ScriptCanvas::ScriptCanvasId GetScriptCanvasId(AZ::Data::AssetId assetId) override;
// Retrieves the Graph Canvas scene Id for a given asset
AZ::EntityId GetGraphCanvasId(AZ::EntityId scriptCanvasEntityId) override;
ScriptCanvas::ScriptCanvasId GetScriptCanvasIdFromGraphId(AZ::EntityId graphId) override;
ScriptCanvas::ScriptCanvasId GetGraphId(AZ::Data::AssetId assetId) override;
Tracker::ScriptCanvasFileState GetFileState(AZ::Data::AssetId assetId) override;
AZStd::string GetTabName(AZ::Data::AssetId assetId) override;
ScriptCanvasEditor::ScriptCanvasAssetHandler* GetAssetHandlerForType(AZ::Data::AssetType assetType) override;
void UpdateFileState(AZ::Data::AssetId assetId, Tracker::ScriptCanvasFileState state) override;
AssetTrackerRequests::AssetList GetUnsavedAssets() override;
AssetTrackerRequests::AssetList GetAssets() override;
AssetTrackerRequests::AssetList GetAssetsIf(AZStd::function<bool(ScriptCanvasMemoryAsset::pointer asset)> pred = []() { return true; }) override;
AZ::EntityId GetSceneEntityIdFromEditorEntityId(AZ::Data::AssetId assetId, AZ::EntityId editorEntityId) override;
AZ::EntityId GetEditorEntityIdFromSceneEntityId(AZ::Data::AssetId assetId, AZ::EntityId sceneEntityId) override;
//
private:
void SignalSaveComplete(const AZ::Data::AssetId& fileAssetId);
// Verifies if an asset Id has been remapped, this happens when we save a new graph because the AssetId will
// change on save, but there may be some UX elements still referring to the initial asset Id, this ensures
// we are getting the right key into m_assetsInUse
AZ::Data::AssetId CheckAssetId(AZ::Data::AssetId assetId) const;
// Map of all the currently tracked in-memory assets
using MemoryAssetMap = AZStd::unordered_map<AZ::Data::AssetId, ScriptCanvasMemoryAsset::pointer>;
using MemoryAssetMapIterator = AZStd::pair<AZStd::list_iterator<AZStd::pair<AZ::Data::AssetId, ScriptCanvasMemoryAsset::pointer>>, bool>;
AZStd::unordered_set<AZ::Data::AssetId> m_savingAssets;
AZStd::unordered_set<AZ::Data::AssetId> m_queuedCloses;
// Map of all assets being tracked
MemoryAssetMap m_assetsInUse;
// When a graph has been saved to file, its Id will change but it may still have external references with the old Id, this maps the file Id to the in-memory Id
AZStd::unordered_map<AZ::Data::AssetId, AZ::Data::AssetId> m_remappedAsset;
// Invoked when an asset is loaded from file and becomes ready
Callbacks::OnAssetReadyCallback m_onAssetReadyCallback;
};
}
@@ -1,159 +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/Asset/AssetManager.h>
#include <AzCore/Component/EntityId.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/containers/vector.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <Editor/Assets/ScriptCanvasAssetTrackerDefinitions.h>
#include <Editor/Assets/ScriptCanvasMemoryAsset.h>
#include <ScriptCanvas/Bus/RequestBus.h>
class QWidget;
namespace AZ
{
class EntityId;
}
namespace ScriptCanvas
{
class ScriptCanvasAssetBase;
}
namespace ScriptCanvasEditor
{
class ScriptCanvasAssetHandler;
class AssetTrackerRequests
: public AZ::EBusTraits
{
public:
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//! Callback used to know when a save operation failed or succeeded
using OnSave = AZStd::function<void(bool saveSuccess, AZ::Data::Asset<ScriptCanvas::ScriptCanvasAssetBase>)>;
//! Callback used when the asset has been loaded and is ready for use
using OnAssetReadyCallback = AZStd::function<void(ScriptCanvasMemoryAsset&)>;
//! Callback used when the asset is newly created
using OnAssetCreatedCallback = OnAssetReadyCallback;
// Operations
//! Creates a new Script Canvas asset and tracks it
virtual AZ::Data::AssetId Create([[maybe_unused]] AZStd::string_view assetAbsolutePath, [[maybe_unused]] AZ::Data::AssetType assetType, Callbacks::OnAssetCreatedCallback onAssetCreatedCallback) { return AZ::Data::AssetId(); }
//! Saves a Script Canvas asset to a new file, once the save is complete it will use the source Id (not the Id of the in-memory asset)
virtual void SaveAs([[maybe_unused]] AZ::Data::AssetId assetId, [[maybe_unused]] const AZStd::string& path, Callbacks::OnSave onSaveCallback) {}
//! Saves a previously loaded Script Canvas asset to file
virtual void Save([[maybe_unused]] AZ::Data::AssetId assetId, Callbacks::OnSave onSaveCallback) {}
//! Returns whether or not the specified asset is currently saving
virtual bool IsSaving([[maybe_unused]] AZ::Data::AssetId assetId) const { return false; }
//! Loads a Script Canvas graph
virtual bool Load([[maybe_unused]] AZ::Data::AssetId assetId, [[maybe_unused]] AZ::Data::AssetType assetType, Callbacks::OnAssetReadyCallback onAssetReadyCallback) { return false; }
//! Closes and unloads a Script Canvas graph from the tracker
virtual void Close([[maybe_unused]] AZ::Data::AssetId assetId) {}
//! Creates the asset's view
virtual void CreateView([[maybe_unused]] AZ::Data::AssetId assetId, [[maybe_unused]] QWidget* parent) {}
//! Releases the asset's view
virtual void ClearView([[maybe_unused]] AZ::Data::AssetId assetId) {}
//! Used to make sure assets that are unloaded also get removed from tracking
virtual void UntrackAsset([[maybe_unused]] AZ::Data::AssetId assetId) {}
//! Recreates the view for all tracked assets
virtual void RefreshAll() {}
using AssetList = AZStd::vector<ScriptCanvasMemoryAsset::pointer>;
// Accessors
virtual ScriptCanvasMemoryAsset::pointer GetAsset([[maybe_unused]] AZ::Data::AssetId assetId) { return nullptr; }
virtual ScriptCanvas::ScriptCanvasId GetScriptCanvasId([[maybe_unused]] AZ::Data::AssetId assetId) { return AZ::EntityId(); }
virtual ScriptCanvas::ScriptCanvasId GetScriptCanvasIdFromGraphId([[maybe_unused]] AZ::EntityId graphId) { return AZ::EntityId(); }
virtual ScriptCanvas::ScriptCanvasId GetGraphCanvasId(AZ::EntityId) { return AZ::EntityId(); }
virtual ScriptCanvas::ScriptCanvasId GetGraphId([[maybe_unused]] AZ::Data::AssetId assetId) { return ScriptCanvas::ScriptCanvasId(); }
virtual Tracker::ScriptCanvasFileState GetFileState([[maybe_unused]] AZ::Data::AssetId assetId) { return Tracker::ScriptCanvasFileState::INVALID; }
virtual AZ::Data::AssetId GetAssetId([[maybe_unused]] ScriptCanvas::ScriptCanvasId scriptCanvasSceneId) { return {}; }
virtual AZ::Data::AssetType GetAssetType([[maybe_unused]] ScriptCanvas::ScriptCanvasId scriptCanvasSceneId) { return {}; }
virtual AZStd::string GetTabName([[maybe_unused]] AZ::Data::AssetId assetId) { return {}; }
virtual AssetList GetUnsavedAssets() { return {}; }
virtual AssetList GetAssets() { return {}; }
virtual AssetList GetAssetsIf(AZStd::function<bool(ScriptCanvasMemoryAsset::pointer asset)>) { return {}; }
virtual AZ::EntityId GetSceneEntityIdFromEditorEntityId([[maybe_unused]] AZ::Data::AssetId assetId, [[maybe_unused]] AZ::EntityId editorEntityId) { return AZ::EntityId(); }
virtual AZ::EntityId GetEditorEntityIdFromSceneEntityId([[maybe_unused]] AZ::Data::AssetId assetId, [[maybe_unused]] AZ::EntityId sceneEntityId) { return AZ::EntityId(); }
// Setters / Updates
virtual void UpdateFileState([[maybe_unused]] AZ::Data::AssetId assetId, [[maybe_unused]] Tracker::ScriptCanvasFileState state) {}
// Helpers
virtual ScriptCanvasAssetHandler* GetAssetHandlerForType([[maybe_unused]] AZ::Data::AssetType assetType) { return nullptr; }
};
using AssetTrackerRequestBus = AZ::EBus<AssetTrackerRequests>;
//! These are the notifications sent by the AssetTracker only.
//! We use these to communicate the asset status, do not use the AssetBus directly, all Script Canvas
//! assets are managed by the AssetTracker
class AssetTrackerNotifications
: public AZ::EBusTraits
{
public:
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
using BusIdType = AZ::Data::AssetId;
// These will be forwarded as a result of the Asset System's events
// this is deliberate in order to keep the AssetTracker as the only
// place that interacts directly with the asset bus, but allowing
// other systems to know the status of tracked assets
virtual void OnAssetReady(const ScriptCanvasMemoryAsset::pointer asset) {}
virtual void OnAssetReloaded(const ScriptCanvasMemoryAsset::pointer asset) {}
virtual void OnAssetUnloaded([[maybe_unused]] const AZ::Data::AssetId assetId, [[maybe_unused]] const AZ::Data::AssetType assetType) {}
virtual void OnAssetSaved(const ScriptCanvasMemoryAsset::pointer asset, [[maybe_unused]] bool isSuccessful) {}
virtual void OnAssetError(const ScriptCanvasMemoryAsset::pointer asset) {}
};
using AssetTrackerNotificationBus = AZ::EBus<AssetTrackerNotifications>;
namespace Internal
{
class MemoryAssetSystemNotifications
: public AZ::EBusTraits
{
public:
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
virtual void OnAssetReady([[maybe_unused]] const ScriptCanvasMemoryAsset* asset) {}
virtual void OnAssetReloaded([[maybe_unused]] const ScriptCanvasMemoryAsset* asset) {}
virtual void OnAssetSaved([[maybe_unused]] const ScriptCanvasMemoryAsset* asset, [[maybe_unused]] bool isSuccessful) {}
virtual void OnAssetError([[maybe_unused]] const ScriptCanvasMemoryAsset* asset) {}
};
using MemoryAssetSystemNotificationBus = AZ::EBus<MemoryAssetSystemNotifications>;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
}
@@ -1,28 +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/std/function/function_base.h>
#include <ScriptCanvas/Asset/ScriptCanvasAssetBase.h>
namespace ScriptCanvasEditor
{
class ScriptCanvasMemoryAsset;
namespace Callbacks
{
//! Callback used to know when a save operation failed or succeeded
using OnSave = AZStd::function<void(bool saveSuccess, const SourceHandle& attempt, const SourceHandle& previous)>;
using OnAssetReadyCallback = AZStd::function<void(ScriptCanvasMemoryAsset&)>;
using OnAssetCreatedCallback = OnAssetReadyCallback;
}
}
@@ -1,687 +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 "ScriptCanvasMemoryAsset.h"
#include "ScriptCanvasUndoHelper.h"
#include <AzCore/IO/Streamer/StreamerContext.h>
#include <AzCore/IO/Streamer/FileRequest.h>
#include <AzCore/IO/IStreamer.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <Editor/Assets/ScriptCanvasAssetTrackerBus.h>
#include <ScriptCanvas/Asset/ScriptCanvasAssetBase.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Components/EditorGraph.h>
namespace ScriptCanvasEditor
{
ScriptCanvasMemoryAsset::ScriptCanvasMemoryAsset()
: m_sourceInError(false)
{
m_undoState = AZStd::make_unique<SceneUndoState>(this);
}
ScriptCanvasMemoryAsset::~ScriptCanvasMemoryAsset()
{
AssetTrackerRequestBus::Broadcast(&AssetTrackerRequests::UntrackAsset, m_inMemoryAssetId);
AssetHelpers::PrintInfo(AZStd::string::format("ScriptCanvasMemoryAsset went out of scope and has been released and untracked: %s", m_absolutePath.c_str()).c_str());
if (m_inMemoryAsset.IsReady() && !m_inMemoryAsset.Release())
{
// Something else is holding on to it
AZ_Assert(false, "Unable to release in memory asset");
}
}
const AZStd::string ScriptCanvasMemoryAsset::GetTabName() const
{
AZStd::string tabName;
AzFramework::StringFunc::Path::GetFileName(m_absolutePath.c_str(), tabName);
return tabName;
}
AZ::EntityId ScriptCanvasMemoryAsset::GetGraphId()
{
if (!m_graphId.IsValid())
{
EditorGraphRequestBus::EventResult(m_graphId, m_scriptCanvasId, &EditorGraphRequests::GetGraphCanvasGraphId);
}
return m_graphId;
}
Tracker::ScriptCanvasFileState ScriptCanvasMemoryAsset::GetFileState() const
{
if (m_sourceRemoved)
{
return Tracker::ScriptCanvasFileState::SOURCE_REMOVED;
}
else
{
return m_fileState;
}
}
void ScriptCanvasMemoryAsset::SetFileState(Tracker::ScriptCanvasFileState fileState)
{
m_fileState = fileState;
SignalFileStateChanged();
}
void ScriptCanvasMemoryAsset::CloneTo(ScriptCanvasMemoryAsset& memoryAsset)
{
if (m_assetType == azrtti_typeid<ScriptCanvasAsset>())
{
AZ::Data::Asset<ScriptCanvasAsset> newAsset = Clone<ScriptCanvasAsset>();
memoryAsset.m_inMemoryAsset = newAsset;
}
else
{
AZ_Assert(false, "Unsupported Script Canvas Asset Type");
}
memoryAsset.m_sourceAsset = m_sourceAsset;
}
void ScriptCanvasMemoryAsset::Create(AZ::Data::AssetId assetId, AZStd::string_view assetAbsolutePath, AZ::Data::AssetType assetType, Callbacks::OnAssetCreatedCallback onAssetCreatedCallback)
{
m_inMemoryAssetId = assetId;
m_absolutePath = assetAbsolutePath;
m_assetType = assetType;
m_fileState = Tracker::ScriptCanvasFileState::NEW;
ScriptCanvasAssetHandler* assetHandler = GetAssetHandlerForType(assetType);
AZ::Data::AssetPtr asset = nullptr;
if (assetType == azrtti_typeid<ScriptCanvasAsset>())
{
asset = assetHandler->CreateAsset(assetId, azrtti_typeid<ScriptCanvasAsset>());
}
m_inMemoryAsset = AZ::Data::Asset<AssetType>(asset, AZ::Data::AssetLoadBehavior::PreLoad);
ActivateAsset();
// For new assets, we directly set its status as "Ready" in order to make it usable.
ScriptCanvas::ScriptCanvasAssetBusRequestBus::Event(assetId, &ScriptCanvas::ScriptCanvasAssetBusRequests::SetAsNewAsset);
Internal::MemoryAssetSystemNotificationBus::Broadcast(&Internal::MemoryAssetSystemNotifications::OnAssetReady, this);
AssetHelpers::PrintInfo("Newly created Script Canvas asset is now tracked: %s", AssetHelpers::AssetIdToString(assetId).c_str());
if (onAssetCreatedCallback)
{
AZStd::invoke(onAssetCreatedCallback, *this);
}
}
void ScriptCanvasMemoryAsset::Save(Callbacks::OnSave onSaveCallback)
{
if (m_fileState == Tracker::ScriptCanvasFileState::UNMODIFIED)
{
// The file hasn't changed, don't save it
return;
}
SaveAs({}, onSaveCallback);
}
void ScriptCanvasMemoryAsset::SaveAs(const AZStd::string& path, Callbacks::OnSave onSaveCallback)
{
if (!path.empty())
{
m_saveAsPath = path;
}
else
{
m_saveAsPath = m_absolutePath;
}
AZ::Data::AssetStreamInfo streamInfo;
streamInfo.m_streamFlags = AZ::IO::OpenMode::ModeWrite;
streamInfo.m_streamName = m_saveAsPath;
if (!streamInfo.IsValid())
{
return;
}
bool sourceControlActive = false;
AzToolsFramework::SourceControlConnectionRequestBus::BroadcastResult(sourceControlActive, &AzToolsFramework::SourceControlConnectionRequests::IsActive);
// If Source Control is active then use it to check out the file before saving otherwise query the file info and save only if the file is not read-only
if (sourceControlActive)
{
AzToolsFramework::SourceControlCommandBus::Broadcast(&AzToolsFramework::SourceControlCommandBus::Events::RequestEdit,
streamInfo.m_streamName.c_str(),
true,
[this, streamInfo, onSaveCallback](bool success, AzToolsFramework::SourceControlFileInfo info) { FinalizeAssetSave(success, info, streamInfo, onSaveCallback); }
);
}
else
{
AzToolsFramework::SourceControlCommandBus::Broadcast(&AzToolsFramework::SourceControlCommandBus::Events::GetFileInfo,
streamInfo.m_streamName.c_str(),
[this, streamInfo, onSaveCallback](bool success, AzToolsFramework::SourceControlFileInfo info) { FinalizeAssetSave(success, info, streamInfo, onSaveCallback); }
);
}
}
void ScriptCanvasMemoryAsset::Set(AZ::Data::AssetId fileAssetId)
{
Callbacks::OnAssetReadyCallback onAssetReady = [](ScriptCanvasMemoryAsset&) {};
Load(fileAssetId, AZ::Data::AssetType::CreateNull(), onAssetReady);
ActivateAsset();
}
bool ScriptCanvasMemoryAsset::Load(AZ::Data::AssetId assetId, AZ::Data::AssetType assetType, Callbacks::OnAssetReadyCallback onAssetReadyCallback)
{
AZStd::string rootPath;
AZ::Data::AssetInfo assetInfo = AssetHelpers::GetAssetInfo(assetId, rootPath);
AzFramework::StringFunc::Path::Join(rootPath.c_str(), assetInfo.m_relativePath.c_str(), m_absolutePath);
if (assetInfo.m_assetType.IsNull())
{
// Try to find the asset type from the source file asset
assetInfo.m_assetType = AssetHelpers::GetAssetType(AZStd::string::format("%s/%s", rootPath.c_str(), assetInfo.m_relativePath.c_str()).c_str());
}
if (!assetType.IsNull() && assetInfo.m_assetType.IsNull())
{
assetInfo.m_assetType = assetType;
}
else
{
AZ_Assert(assetInfo.m_assetId.IsValid(), "Failed to get the asset info properly from the asset system");
}
SetFileAssetId(assetId);
auto asset = AZ::Data::AssetManager::Instance().FindAsset<ScriptCanvas::ScriptCanvasAssetBase>(assetId, AZ::Data::AssetLoadBehavior::PreLoad);
if (!asset || !asset.IsReady())
{
AZ::Data::AssetBus::MultiHandler::BusConnect(assetId);
}
if (assetInfo.m_assetType == azrtti_typeid<ScriptCanvasAsset>())
{
m_inMemoryAsset = AZ::Data::AssetManager::Instance().GetAsset<ScriptCanvasAsset>(assetId, AZ::Data::AssetLoadBehavior::Default);
}
if (m_inMemoryAsset)
{
m_inMemoryAsset.BlockUntilLoadComplete();
m_sourceAsset = m_inMemoryAsset;
m_assetType = m_inMemoryAsset->GetType();
AZ_Assert(m_inMemoryAsset.GetId() == assetId, "The asset IDs must match");
m_onAssetReadyCallback = onAssetReadyCallback;
if (m_inMemoryAsset.IsReady())
{
OnAssetReady(m_inMemoryAsset);
}
}
return !m_inMemoryAsset.IsError();
}
void ScriptCanvasMemoryAsset::ActivateAsset()
{
ScriptCanvas::ScriptCanvasAssetBase* assetData = m_inMemoryAsset.Get();
AZ_Assert(assetData, "ActivateAsset should have a valid asset of type %s", AssetHelpers::AssetIdToString(azrtti_typeid<ScriptCanvas::ScriptCanvasAssetBase>()).c_str());
if (assetData == nullptr)
{
return;
}
AZ::Entity* scriptCanvasEntity = assetData->GetScriptCanvasEntity();
AZ_Assert(scriptCanvasEntity, "ActivateAsset should have a valid ScriptCanvas Entity");
// Only activate the entity for assets that have been saved
if (scriptCanvasEntity->GetState() == AZ::Entity::State::Constructed)
{
scriptCanvasEntity->Init();
}
if (scriptCanvasEntity->GetState() == AZ::Entity::State::Init)
{
scriptCanvasEntity->Activate();
}
const AZStd::string& assetPath = m_absolutePath;
AZStd::string graphName;
AzFramework::StringFunc::Path::GetFileName(assetPath.c_str(), graphName);
if (!graphName.empty())
{
scriptCanvasEntity->SetName(graphName);
}
Graph* editorGraph = AZ::EntityUtils::FindFirstDerivedComponent<Graph>(scriptCanvasEntity);
AZ_Assert(editorGraph, "Script Canvas entity must have a Graph component");
if (editorGraph == nullptr)
{
return;
}
m_scriptCanvasId = editorGraph->GetScriptCanvasId();
EditorGraphNotificationBus::Handler::BusDisconnect();
EditorGraphNotificationBus::Handler::BusConnect(m_scriptCanvasId);
}
ScriptCanvasEditor::Widget::CanvasWidget* ScriptCanvasMemoryAsset::CreateView(QWidget* /*parent*/)
{
return nullptr;
}
void ScriptCanvasMemoryAsset::ClearView()
{
delete m_canvasWidget;
m_canvasWidget = nullptr;
}
void ScriptCanvasMemoryAsset::UndoStackChange()
{
OnUndoStackChanged();
}
bool ScriptCanvasMemoryAsset::IsSourceInError() const
{
return m_sourceInError;
}
void ScriptCanvasMemoryAsset::OnGraphCanvasSceneDisplayed()
{
// We need to wait until this event in order the get the m_graphId which represents the GraphCanvas scene Id
EditorGraphRequestBus::EventResult(m_graphId, m_scriptCanvasId, &EditorGraphRequests::GetGraphCanvasGraphId);
EditorGraphNotificationBus::Handler::BusDisconnect();
}
void ScriptCanvasMemoryAsset::OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
// If we've already cloned the memory asset, we don't want to do the start-up things again.
if (m_inMemoryAsset->GetId() == m_sourceAsset.GetId())
{
AZStd::string rootPath;
AZ::Data::AssetInfo assetInfo = AssetHelpers::GetAssetInfo(m_fileAssetId, rootPath);
AZStd::string absolutePath;
AzFramework::StringFunc::Path::Join(rootPath.c_str(), assetInfo.m_relativePath.c_str(), absolutePath);
m_absolutePath = absolutePath;
m_fileState = Tracker::ScriptCanvasFileState::UNMODIFIED;
m_assetType = asset.GetType();
// Keep the canonical asset's Id, we will need it when we want to save the asset back to file
SetFileAssetId(asset.GetId());
// The source file is ready, we need to make the an in-memory version of it.
AZ::Data::AssetId inMemoryAssetId = AZ::Uuid::CreateRandom();
m_sourceAsset = AZ::Data::AssetManager::Instance().FindAsset<ScriptCanvas::ScriptCanvasAssetBase>(m_fileAssetId, AZ::Data::AssetLoadBehavior::PreLoad);
m_inMemoryAsset = AZStd::move(CloneAssetData(inMemoryAssetId));
AZ_Assert(m_inMemoryAsset, "Asset should have been successfully cloned.");
AZ_Assert(m_inMemoryAsset.GetId() == inMemoryAssetId, "Asset Id should match to the newly created one");
m_inMemoryAssetId = m_inMemoryAsset.GetId();
ActivateAsset();
if (m_onAssetReadyCallback)
{
AZStd::invoke(m_onAssetReadyCallback, *this);
}
}
// Instead just update the source asset to the get the new asset to keep it in memory.
else
{
m_sourceAsset = AZ::Data::AssetManager::Instance().FindAsset<ScriptCanvas::ScriptCanvasAssetBase>(m_fileAssetId, AZ::Data::AssetLoadBehavior::PreLoad);
}
if (m_fileAssetId == asset.GetId())
{
Internal::MemoryAssetSystemNotificationBus::Broadcast(&Internal::MemoryAssetSystemNotifications::OnAssetReady, this);
}
}
void ScriptCanvasMemoryAsset::OnAssetReloaded(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
if (m_fileAssetId == asset.GetId())
{
m_sourceInError = false;
// Update our source asset information so we keep references alive.
m_sourceAsset = AZ::Data::AssetManager::Instance().FindAsset<ScriptCanvas::ScriptCanvasAssetBase>(m_fileAssetId, AZ::Data::AssetLoadBehavior::PreLoad);
// The source file was reloaded, but we have an in-memory version of it.
// We need to handle this.
}
else
{
Internal::MemoryAssetSystemNotificationBus::Broadcast(&Internal::MemoryAssetSystemNotifications::OnAssetReloaded, this);
}
}
void ScriptCanvasMemoryAsset::OnAssetError(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
if (m_fileAssetId == asset.GetId())
{
m_sourceInError = true;
if (m_onAssetReadyCallback)
{
AZStd::invoke(m_onAssetReadyCallback, *this);
}
}
else
{
Internal::MemoryAssetSystemNotificationBus::Broadcast(&Internal::MemoryAssetSystemNotifications::OnAssetError, this);
}
}
void ScriptCanvasMemoryAsset::OnAssetUnloaded(const AZ::Data::AssetId assetId, const AZ::Data::AssetType assetType)
{
if (m_fileAssetId == assetId)
{
AssetTrackerNotificationBus::Event(assetId, &AssetTrackerNotifications::OnAssetUnloaded, assetId, assetType);
}
}
void ScriptCanvasMemoryAsset::SourceFileChanged(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid sourceAssetId)
{
// This updates the asset Id with the canonical assetId on SourceFileChanged
// This occurs for new ScriptCanvas assets because before the SC asset is saved to disk, the asset database
// has no asset Id associated with it, so this uses the supplied source path to find the asset Id registered
AZStd::string fullPath;
AzFramework::StringFunc::Path::Join(scanFolder.data(), relativePath.data(), fullPath);
AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::NormalizePath, fullPath);
SavingComplete(fullPath, sourceAssetId);
}
void ScriptCanvasMemoryAsset::SourceFileRemoved(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid fileAssetId)
{
AZ_UNUSED(relativePath);
AZ_UNUSED(scanFolder);
if (m_fileAssetId == fileAssetId)
{
m_sourceRemoved = true;
SignalFileStateChanged();
}
}
void ScriptCanvasMemoryAsset::SourceFileFailed(AZStd::string /*relativePath*/, AZStd::string /*scanFolder*/, AZ::Uuid)
{
}
void ScriptCanvasMemoryAsset::SavingComplete(const AZStd::string& /*streamName*/, AZ::Uuid /*sourceAssetId*/)
{
}
void ScriptCanvasMemoryAsset::FinalizeAssetSave(bool, const AzToolsFramework::SourceControlFileInfo& fileInfo, const AZ::Data::AssetStreamInfo& saveInfo, Callbacks::OnSave onSaveCallback)
{
m_onSaveCallback = onSaveCallback;
AZStd::string normPath = saveInfo.m_streamName;
AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::NormalizePath, normPath);
m_pendingSave.emplace_back(normPath);
m_assetSaveFinalizer.Reset();
m_assetSaveFinalizer.Start(this, fileInfo, saveInfo, onSaveCallback, AssetSaveFinalizer::OnCompleteHandler([](AZ::Data::AssetId /*assetId*/)
{
}));
}
AZ::Data::Asset<AZ::Data::AssetData> ScriptCanvasMemoryAsset::CloneAssetData(AZ::Data::AssetId newAssetId)
{
if (m_assetType == azrtti_typeid<ScriptCanvasAsset>())
{
return CloneAssetData<ScriptCanvasAsset>(newAssetId);
}
AZ_Assert(false, "The provides asset type is not supported as a valid Script Canvas memory asset");
return AZ::Data::Asset<AZ::Data::AssetData>();
}
void ScriptCanvasMemoryAsset::OnUndoStackChanged()
{
UndoNotificationBus::Broadcast(&UndoNotifications::OnCanUndoChanged, m_undoState->m_undoStack->CanUndo());
UndoNotificationBus::Broadcast(&UndoNotifications::OnCanRedoChanged, m_undoState->m_undoStack->CanRedo());
}
void ScriptCanvasMemoryAsset::SetFileAssetId(const AZ::Data::AssetId& /*fileAssetId*/)
{
}
void ScriptCanvasMemoryAsset::SignalFileStateChanged()
{
}
AZStd::string ScriptCanvasMemoryAsset::MakeTemporaryFilePathForSave(AZStd::string_view targetFilename)
{
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
AZ_Assert(fileIO, "File IO is not initialized.");
AZStd::string tempFilename;
AzFramework::StringFunc::Path::GetFullFileName(targetFilename.data(), tempFilename);
AZStd::string tempPath = AZStd::string::format("@usercache@/scriptcanvas/%s.temp", tempFilename.data());
AZStd::array<char, AZ::IO::MaxPathLength> resolvedPath{};
fileIO->ResolvePath(tempPath.data(), resolvedPath.data(), resolvedPath.size());
return resolvedPath.data();
}
ScriptCanvasAssetHandler* ScriptCanvasMemoryAsset::GetAssetHandlerForType(AZ::Data::AssetType assetType)
{
ScriptCanvasAssetHandler* assetHandler = nullptr;
AZ::EBusAggregateResults<AZ::Data::AssetHandler*> foundAssetHandlers;
ScriptCanvas::AssetRegistryRequestBus::BroadcastResult(foundAssetHandlers, &ScriptCanvas::AssetRegistryRequests::GetAssetHandler);
for (auto handler : foundAssetHandlers.values)
{
if (handler != nullptr)
{
ScriptCanvasAssetHandler* theHandler = azrtti_cast<ScriptCanvasAssetHandler*>(handler);
if (theHandler != nullptr && theHandler->GetAssetType() == assetType)
{
assetHandler = theHandler;
break;
}
}
}
AZ_Assert(assetHandler, "The specified asset type does not have a registered asset handler.");
return assetHandler;
}
AZ::EntityId ScriptCanvasMemoryAsset::GetEditorEntityIdFromSceneEntityId(AZ::EntityId sceneEntityId)
{
if (m_editorEntityIdMap.find(sceneEntityId) != m_editorEntityIdMap.end())
{
return m_editorEntityIdMap[sceneEntityId];
}
return AZ::EntityId();
}
AZ::EntityId ScriptCanvasMemoryAsset::GetSceneEntityIdFromEditorEntityId(AZ::EntityId editorEntityId)
{
for (auto mapEntry : m_editorEntityIdMap)
{
if (mapEntry.second == editorEntityId)
{
return mapEntry.first;
}
}
return AZ::EntityId();
}
// AssetSaveFinalizer
//////////////////////////////////////
bool AssetSaveFinalizer::ValidateStatus(const AzToolsFramework::SourceControlFileInfo& /*fileInfo*/)
{
return true;
}
AssetSaveFinalizer::AssetSaveFinalizer()
: m_inMemoryAsset(nullptr)
, m_sourceAsset(nullptr)
, m_saving(false)
, m_fileAvailableForSave(false)
{
}
AssetSaveFinalizer::~AssetSaveFinalizer()
{
AZ::SystemTickBus::Handler::BusDisconnect();
}
void AssetSaveFinalizer::Start(ScriptCanvasMemoryAsset* sourceAsset, const AzToolsFramework::SourceControlFileInfo& fileInfo, const AZ::Data::AssetStreamInfo& saveInfo, Callbacks::OnSave onSaveCallback, OnCompleteHandler onComplete)
{
m_onCompleteHandler = onComplete;
m_onCompleteHandler.Connect(m_onComplete);
m_saveInfo = saveInfo;
m_onSave = onSaveCallback;
m_sourceAsset = sourceAsset;
m_inMemoryAsset = sourceAsset->GetAsset().Get();
m_assetType = sourceAsset->GetAssetType();
if (!ValidateStatus(fileInfo))
{
return;
}
auto streamer = AZ::Interface<AZ::IO::IStreamer>::Get();
AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(saveInfo.m_streamName.data());
streamer->SetRequestCompleteCallback(flushRequest, [this]([[maybe_unused]] AZ::IO::FileRequestHandle request)
{
m_fileAvailableForSave = true;
});
streamer->QueueRequest(flushRequest);
AZ::SystemTickBus::Handler::BusConnect();
m_saving = true;
}
AZStd::string AssetSaveFinalizer::MakeTemporaryFilePathForSave(AZStd::string_view targetFilename)
{
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
AZ_Assert(fileIO, "File IO is not initialized.");
AZStd::string tempFilename;
AzFramework::StringFunc::Path::GetFullFileName(targetFilename.data(), tempFilename);
AZStd::string tempPath = AZStd::string::format("@usercache@/scriptcanvas/%s.temp", tempFilename.data());
AZStd::array<char, AZ::IO::MaxPathLength> resolvedPath{};
fileIO->ResolvePath(tempPath.data(), resolvedPath.data(), resolvedPath.size());
return resolvedPath.data();
}
void AssetSaveFinalizer::OnSystemTick()
{
if (m_fileAvailableForSave)
{
AZ::SystemTickBus::Handler::BusDisconnect();
m_fileAvailableForSave = false;
const AZStd::string tempPath = MakeTemporaryFilePathForSave(m_saveInfo.m_streamName);
AZ::IO::FileIOStream stream(tempPath.data(), m_saveInfo.m_streamFlags);
if (stream.IsOpen())
{
ScriptCanvasAssetHandler* assetHandler = nullptr;
AssetTrackerRequestBus::BroadcastResult(assetHandler, &AssetTrackerRequests::GetAssetHandlerForType, m_assetType);
AZ_Assert(assetHandler, "An asset handler must be found");
bool savedSuccess;
{
AZ_PROFILE_SCOPE(ScriptCanvas, "ScriptCanvasAssetHandler::SaveAssetData");
ScriptCanvasMemoryAsset cloneAsset;
m_sourceAsset->CloneTo(cloneAsset);
savedSuccess = assetHandler->SaveAssetData(cloneAsset.GetAsset(), &stream);
}
stream.Close();
if (savedSuccess)
{
AZ_PROFILE_SCOPE(ScriptCanvas, "AssetTracker::SaveAssetPostSourceControl : TempToTargetFileReplacement");
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
const bool targetFileExists = fileIO->Exists(m_saveInfo.m_streamName.data());
bool removedTargetFile;
{
AZ_PROFILE_SCOPE(ScriptCanvas, "AssetTracker::SaveAssetPostSourceControl : TempToTargetFileReplacement : RemoveTarget");
removedTargetFile = fileIO->Remove(m_saveInfo.m_streamName.data());
}
if (targetFileExists && !removedTargetFile)
{
savedSuccess = false;
}
else
{
AZ_PROFILE_SCOPE(ScriptCanvas, "AssetTracker::SaveAssetPostSourceControl : TempToTargetFileReplacement : RenameTempFile");
AZ::IO::Result renameResult = fileIO->Rename(tempPath.data(), m_saveInfo.m_streamName.data());
if (!renameResult)
{
savedSuccess = false;
}
}
}
if (savedSuccess)
{
AZ_TracePrintf("Script Canvas", "Script Canvas successfully saved as Asset \"%s\"", m_saveInfo.m_streamName.data());
}
m_onComplete.Signal(m_sourceAsset->GetId());
}
Reset();
}
}
void AssetSaveFinalizer::Reset()
{
m_sourceAsset = nullptr;
m_fileAssetId = {};
m_onSave = nullptr;
m_saving = false;
m_inMemoryAsset = nullptr;
m_saveInfo = {};
}
}
@@ -1,344 +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/Component/TickBus.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/std/smart_ptr/enable_shared_from_this.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzToolsFramework/SourceControl/SourceControlAPI.h>
#include <Editor/Assets/ScriptCanvasAssetHelpers.h>
#include <Editor/Assets/ScriptCanvasAssetTrackerDefinitions.h>
#include <ScriptCanvas/Asset/ScriptCanvasAssetBase.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Bus/ScriptCanvasBus.h>
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
#include <Editor/View/Widgets/CanvasWidget.h>
#include <Editor/Undo/ScriptCanvasUndoManager.h>
#include <ScriptCanvas/Bus/RequestBus.h>
namespace ScriptCanvasEditor
{
class ScriptCanvasAssetHandler;
template <typename BaseAssetType>
class MemoryAsset
: protected AZ::Data::AssetBus::MultiHandler
, protected AzToolsFramework::AssetSystemBus::Handler
, public AzToolsFramework::UndoSystem::IUndoNotify
{
public:
MemoryAsset()
{
AzToolsFramework::AssetSystemBus::Handler::BusConnect();
}
~MemoryAsset()
{
AZ::Data::AssetBus::MultiHandler::BusDisconnect();
AzToolsFramework::AssetSystemBus::Handler::BusDisconnect();
}
using AssetType = BaseAssetType;
virtual void Create(AZ::Data::AssetId assetId, AZStd::string_view assetAbsolutePath, AZ::Data::AssetType assetType, Callbacks::OnAssetCreatedCallback onAssetCreatedCallback) = 0;
virtual void SaveAs(const AZStd::string& path, Callbacks::OnSave onSaveCallback) = 0;
virtual void Save(Callbacks::OnSave onSaveCallback) = 0;
virtual bool Load(AZ::Data::AssetId assetId, AZ::Data::AssetType assetType, Callbacks::OnAssetReadyCallback onAssetReadyCallback) = 0;
};
class UndoHelper;
// Saving an asset is an asynchronous process that requires several steps, this helper
// class ensures asset saving takes place correctly and reduces the complexity of
// ScriptCanvasMemoryAsset's saving requirements
class AssetSaveFinalizer
: AZ::SystemTickBus::Handler
{
public:
using OnCompleteEvent = AZ::Event<AZ::Data::AssetId>;
using OnCompleteHandler = AZ::Event<AZ::Data::AssetId>::Handler;
AssetSaveFinalizer();
~AssetSaveFinalizer();
void Start(ScriptCanvasMemoryAsset* sourceAsset, const AzToolsFramework::SourceControlFileInfo& fileInfo, const AZ::Data::AssetStreamInfo& saveInfo, Callbacks::OnSave onSaveCallback, OnCompleteHandler onComplete);
void Reset();
private:
// AZ::SystemTickBus::Handler ...
void OnSystemTick() override;
///
bool ValidateStatus(const AzToolsFramework::SourceControlFileInfo& fileInfo);
AZStd::string MakeTemporaryFilePathForSave(AZStd::string_view targetFilename);
OnCompleteHandler m_onCompleteHandler;
OnCompleteEvent m_onComplete;
Callbacks::OnSave m_onSave;
bool m_saving = false;
bool m_fileAvailableForSave = false;
AZ::Data::AssetPtr m_inMemoryAsset;
AZ::Data::AssetId m_fileAssetId;
AZ::Data::AssetStreamInfo m_saveInfo;
ScriptCanvasMemoryAsset* m_sourceAsset;
AZ::Data::AssetType m_assetType;
};
// Script Canvas primarily works with an in-memory copy of an asset.
// There are two situations, the first is, when a new asset is created and not yet saved.
// Once saved, we will create a new asset on file, however, and this is important
// once the file is saved to file, its asset ID will be changed, if the file is to remain
// open, we need to update the source AssetId to correspond to the file asset.
//
// The other is when an asset is loaded, we clone the asset from file and use an in-memory
// version of the asset until it is time to save, at that moment we need to save to the
// source file
class ScriptCanvasMemoryAsset
: public MemoryAsset<ScriptCanvas::ScriptCanvasAssetBase>
, public AZStd::enable_shared_from_this<ScriptCanvasMemoryAsset>
, EditorGraphNotificationBus::Handler
{
public:
ScriptCanvasMemoryAsset();
~ScriptCanvasMemoryAsset() override;
ScriptCanvasMemoryAsset(const ScriptCanvasMemoryAsset& rhs) = delete;
ScriptCanvasMemoryAsset& operator = (const ScriptCanvasMemoryAsset& rhs) = delete;
using pointer = AZStd::shared_ptr<ScriptCanvasMemoryAsset>;
void Create(AZ::Data::AssetId assetId, AZStd::string_view assetAbsolutePath, AZ::Data::AssetType assetType, Callbacks::OnAssetCreatedCallback onAssetCreatedCallback) override;
void SaveAs(const AZStd::string& path, Callbacks::OnSave onSaveCallback) override;
void Save(Callbacks::OnSave onSaveCallback) override;
bool Load(AZ::Data::AssetId assetId, AZ::Data::AssetType assetType, Callbacks::OnAssetReadyCallback onAssetReadyCallback) override;
void Set(AZ::Data::AssetId assetId);
const AZ::Data::AssetId& GetId() const { return m_inMemoryAssetId; }
const AZ::Data::AssetId& GetFileAssetId() const { return m_fileAssetId; }
const AZ::Data::AssetType GetAssetType() const { return m_assetType; }
AZ::Data::Asset<AssetType> GetAsset() { return m_inMemoryAsset; }
const AZ::Data::Asset<AssetType>& GetAsset() const { return m_inMemoryAsset; }
const AZStd::string GetTabName() const;
const AZStd::string& GetAbsolutePath() const { return m_absolutePath; }
AZ::EntityId GetScriptCanvasId() const { return m_scriptCanvasId; }
AZ::EntityId GetGraphId();
Tracker::ScriptCanvasFileState GetFileState() const;
void SetFileState(Tracker::ScriptCanvasFileState fileState);
void CloneTo(ScriptCanvasMemoryAsset& memoryAsset);
void ActivateAsset();
Widget::CanvasWidget* GetView() { return m_canvasWidget; }
Widget::CanvasWidget* CreateView(QWidget* parent);
void ClearView();
void UndoStackChange();
SceneUndoState* GetUndoState() { return m_undoState.get(); }
bool IsSourceInError() const;
void SavingComplete(const AZStd::string& fullPath, AZ::Uuid sourceAssetId);
AZ::Data::AssetId GetSourceUuid() const { return m_sourceUuid; }
private:
template <typename T>
auto Clone()
{
AZ::Data::AssetId assetId = AZ::Uuid::CreateRandom();
AZ::Data::Asset<T> newAsset = m_inMemoryAsset;
newAsset = { aznew T(assetId, AZ::Data::AssetData::AssetStatus::Ready), AZ::Data::AssetLoadBehavior::Default };
auto serializeContext = AZ::EntityUtils::GetApplicationSerializeContext();
serializeContext->CloneObjectInplace(newAsset.Get()->GetScriptCanvasData(), &m_inMemoryAsset.Get()->GetScriptCanvasData());
m_editorEntityIdMap.clear();
AZ::IdUtils::Remapper<AZ::EntityId>::GenerateNewIdsAndFixRefs(&newAsset.Get()->GetScriptCanvasData(), m_editorEntityIdMap, serializeContext);
return newAsset;
}
// EditorGraphNotificationBus
void OnGraphCanvasSceneDisplayed() override;
///
//! AZ::Data::AssetBus
void OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
void OnAssetReloaded(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
void OnAssetError(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
void OnAssetUnloaded(const AZ::Data::AssetId assetId, const AZ::Data::AssetType assetType) override;
///////////////////////
// AzToolsFramework::AssetSystemBus::Handler
void SourceFileChanged(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid fileAssetId) override;
void SourceFileRemoved(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid fileAssetId) override;
void SourceFileFailed(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid fileAssetId) override;
///
void FinalizeAssetSave(bool, const AzToolsFramework::SourceControlFileInfo& fileInfo, const AZ::Data::AssetStreamInfo& saveInfo, Callbacks::OnSave onSaveCallback);
template <typename T>
void StartAssetLoad(AZ::Data::AssetId assetId, AZ::Data::Asset<T>& asset)
{
asset = AZ::Data::AssetManager::Instance().GetAsset<T>(assetId, asset.GetAutoLoadBehavior());
}
template <typename AssetType>
AZ::Data::Asset<AZ::Data::AssetData> CloneAssetData(AZ::Data::AssetId newAssetId)
{
AssetType* assetData = aznew AssetType(newAssetId, AZ::Data::AssetData::AssetStatus::Ready);
auto& scriptCanvasData = assetData->GetScriptCanvasData();
// Clone asset data into SC Editor asset
auto serializeContext = AZ::EntityUtils::GetApplicationSerializeContext();
serializeContext->CloneObjectInplace(scriptCanvasData, &m_inMemoryAsset.Get()->GetScriptCanvasData());
m_editorEntityIdMap.clear();
AZ::IdUtils::Remapper<AZ::EntityId>::GenerateNewIdsAndFixRefs(&scriptCanvasData, m_editorEntityIdMap, serializeContext);
// Upon doing this move, the canonical asset will be unloaded
m_inMemoryAsset = { AZStd::move(assetData), AZ::Data::AssetLoadBehavior::Default };
return m_inMemoryAsset;
}
// Upon loading a graph, we clone the source data and we replace the loaded asset with
// a clone, this is to prevent modifications to the source data and it gives us some
// flexibility if we need to load the source asset again
AZ::Data::Asset<AZ::Data::AssetData> CloneAssetData(AZ::Data::AssetId newAssetId);
// IUndoNotify
void OnUndoStackChanged() override;
//
private:
void SetFileAssetId(const AZ::Data::AssetId& fileAssetId);
void SignalFileStateChanged();
AZStd::string MakeTemporaryFilePathForSave(AZStd::string_view targetFilename);
//! Finds the appropriate asset handler for the type of Script Canvas asset given
ScriptCanvasAssetHandler* GetAssetHandlerForType(AZ::Data::AssetType assetType);
//! The asset type, we need it to make sure we call the correct factory methods
AZ::Data::AssetType m_assetType;
//! The in-memory asset
AZ::Data::Asset<AssetType> m_inMemoryAsset;
AZ::Data::Asset<AssetType> m_sourceAsset;
//! Whether we are making a new asset or loading one, we should always have its absolute path
AZStd::string m_absolutePath;
AZStd::string m_saveAsPath;
//! The AssetId of the canonical asset on file, if the asset has never been saved to file, it is Invalid
AZ::Data::AssetId m_fileAssetId;
//! The AssetId that represents this asset, it will always be the in-memory asset Id and never the file asset Id
AZ::Data::AssetId m_inMemoryAssetId;
//! When a new asset is saved, we need to keep it's previous internal Ids in order for the front end to remap to the new Ids
using FormerGraphIdPair = AZStd::pair<AZ::EntityId /*scriptCanvasEntityId*/, AZ::EntityId /* graphId */>;
FormerGraphIdPair m_formerGraphIdPair;
//! The EntityId of the ScriptCanvasEntity owned by the ScriptCanvasAsset
ScriptCanvas::ScriptCanvasId m_scriptCanvasId;
//! The EntityId that represents the ScriptCanvas graph
AZ::EntityId m_graphId;
//! Gives the ability to provide a lambda invoked when the asset is ready
Callbacks::OnAssetReadyCallback m_onAssetReadyCallback;
//! The Save is officially complete after SourceFileChange is handled.
Callbacks::OnSave m_onSaveCallback;
bool m_sourceRemoved = false;
Tracker::ScriptCanvasFileState m_fileState = Tracker::ScriptCanvasFileState::INVALID;
//! We need to track the filename of the file being saved because we need to match it when we handle SourceFileChange (see SourceFileChange for details)
AZStd::vector<AZStd::string> m_pendingSave;
//! Each memory asset owns its view widget
Widget::CanvasWidget* m_canvasWidget = nullptr;
//! Utility cache of remapped entityIds
using EditorEntityIdMap = AZStd::unordered_map<AZ::EntityId, AZ::EntityId>;
//! Cached mapping of Scene Entity ID to Asset Id, used by the debugger
EditorEntityIdMap m_editorEntityIdMap;
//! Each asset keeps track of its undo state
AZStd::unique_ptr<SceneUndoState> m_undoState;
//! The undo helper is an object that implements the Undo behaviors
AZStd::unique_ptr<UndoHelper> m_undoHelper;
bool m_sourceInError;
AZ::Data::AssetId m_sourceUuid;
AssetSaveFinalizer m_assetSaveFinalizer;
public:
//! Given a scene EntityId, find the respective editor EntityId
AZ::EntityId GetEditorEntityIdFromSceneEntityId(AZ::EntityId sceneEntityId);
//! Given an editor EntityId, find the respective scene EntityId
AZ::EntityId GetSceneEntityIdFromEditorEntityId(AZ::EntityId editorEntityId);
//! When a new asset is saved, we need to keep it's previous internal Ids in order for the front end to remap to the new Ids
const FormerGraphIdPair& GetFormerGraphIds() const { return m_formerGraphIdPair; }
};
}
@@ -7,7 +7,6 @@
*/
#include "ScriptCanvasUndoHelper.h"
#include "ScriptCanvasMemoryAsset.h"
#include <Undo/ScriptCanvasGraphCommand.h>
#include <ScriptCanvas/Components/EditorGraph.h>
@@ -77,7 +77,6 @@ AZ_POP_DISABLE_WARNING
#include <Libraries/Core/EBusEventHandler.h>
#include <Libraries/Core/ReceiveScriptEvent.h>
#include <Libraries/Core/ScriptEventBase.h>
#include <ScriptCanvas/Assets/ScriptCanvasBaseAssetData.h>
#include <Libraries/Core/SendScriptEvent.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Core/Connection.h>
@@ -20,13 +20,13 @@
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#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/EditorDeprecationData.h>
#include <ScriptCanvas/Components/EditorGraph.h>
#include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
#include <ScriptCanvas/Components/EditorScriptCanvasComponent.h>
@@ -59,15 +59,15 @@ namespace ScriptCanvasEditor
}
auto assetElement = rootElement.GetSubElement(assetElementIndex);
AZ::Data::Asset<ScriptCanvasAsset> scriptCanvasAsset;
AZ::Data::Asset<Deprecated::ScriptCanvasAsset> scriptCanvasAsset;
if (!assetElement.GetData(scriptCanvasAsset))
{
AZ_Error("Script Canvas", false, "Unable to find Script Canvas Asset on a Version %u Editor ScriptCanvas Component", rootElement.GetVersion());
return false;
}
ScriptCanvasAssetHolder assetHolder;
assetHolder.SetAsset(scriptCanvasAsset.GetId());
Deprecated::ScriptCanvasAssetHolder assetHolder;
assetHolder.m_scriptCanvasAsset = scriptCanvasAsset;
if (!rootElement.AddElementWithData(serializeContext, "m_assetHolder", assetHolder))
{
@@ -115,7 +115,7 @@ namespace ScriptCanvasEditor
auto& scriptCanvasAssetHolderElement = rootElement.GetSubElement(scriptCanvasAssetHolderElementIndex);
ScriptCanvasAssetHolder assetHolder;
Deprecated::ScriptCanvasAssetHolder assetHolder;
if (!scriptCanvasAssetHolderElement.GetData(assetHolder))
{
AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: could not retrieve old 'm_assetHolder'");
@@ -131,7 +131,7 @@ namespace ScriptCanvasEditor
}
ScriptCanvasBuilder::BuildVariableOverrides overrides;
overrides.m_source = SourceHandle(nullptr, assetHolder.GetAssetId().m_guid, {});
overrides.m_source = SourceHandle(nullptr, assetHolder.m_scriptCanvasAsset.GetId().m_guid, {});
for (auto& variable : editableData.GetVariables())
{
@@ -145,19 +145,22 @@ namespace ScriptCanvasEditor
}
}
if (rootElement.GetVersion() < EditorScriptCanvasComponentCpp::Version::AddSourceHandle)
auto scriptCanvasAssetHolderElementIndex = rootElement.FindElement(AZ_CRC_CE("m_assetHolder"));
if (scriptCanvasAssetHolderElementIndex != -1)
{
ScriptCanvasAssetHolder assetHolder;
if (!rootElement.FindSubElementAndGetData(AZ_CRC_CE("m_assetHolder"), assetHolder))
auto& scriptCanvasAssetHolderElement = rootElement.GetSubElement(scriptCanvasAssetHolderElementIndex);
Deprecated::ScriptCanvasAssetHolder assetHolder;
if (!scriptCanvasAssetHolderElement.GetData(assetHolder))
{
AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: could not retrieve old 'm_assetHolder'");
return false;
}
auto assetId = assetHolder.GetAssetId();
auto path = assetHolder.GetAssetHint();
auto assetId = assetHolder.m_scriptCanvasAsset.GetId();
auto path = assetHolder.m_scriptCanvasAsset.GetHint();
if (!rootElement.AddElementWithData(serializeContext, "runtimeDataOverrides", SourceHandle(nullptr, assetId.m_guid, path)))
if (!rootElement.AddElementWithData(serializeContext, "sourceHandle", SourceHandle(nullptr, assetId.m_guid, path)))
{
AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: failed to add 'sourceHandle'");
return false;
@@ -188,7 +191,6 @@ namespace ScriptCanvasEditor
->Attribute(AZ::Edit::Attributes::Icon, "Icons/ScriptCanvas/ScriptCanvas.svg")
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/ScriptCanvas/Viewport/ScriptCanvas.svg")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->Attribute(AZ::Edit::Attributes::PrimaryAssetType, ScriptCanvasAssetHandler::GetAssetTypeStatic())
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c))
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("UI", 0x27ff46b0))
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Level", 0x9aeacc13))
@@ -16,7 +16,7 @@
#include <Editor/Framework/ScriptCanvasReporter.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Asset/RuntimeAssetHandler.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Execution/ExecutionState.h>
#include <ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.h>
#include <ScriptCanvas/Execution/RuntimeComponent.h>
@@ -149,36 +149,33 @@ namespace ScriptCanvasEditor
}
}
AZ_INLINE void RunEditorAsset(AZ::Data::Asset<AZ::Data::AssetData> asset, Reporter& reporter, ScriptCanvas::ExecutionMode mode)
AZ_INLINE void RunEditorAsset(SourceHandle asset, Reporter& reporter, ScriptCanvas::ExecutionMode mode)
{
if (asset.IsReady())
AZ::Data::AssetId assetId = asset.Id();
AZ::Data::AssetId runtimeAssetId(assetId.m_guid, AZ_CRC("RuntimeData", 0x163310ae));
AZ::Data::Asset<ScriptCanvas::RuntimeAsset> runtimeAsset;
if (!runtimeAsset.Create(runtimeAssetId, true))
{
AZ::Data::AssetId assetId = asset.GetId();
AZ::Data::AssetId runtimeAssetId(assetId.m_guid, AZ_CRC("RuntimeData", 0x163310ae));
AZ::Data::Asset<ScriptCanvas::RuntimeAsset> runtimeAsset;
if (!runtimeAsset.Create(runtimeAssetId, true))
{
return;
}
reporter.SetExecutionMode(mode);
LoadTestGraphResult loadResult;
loadResult.m_editorAsset = SourceHandle(nullptr, assetId.m_guid, asset.GetHint());
AZ::EntityId scriptCanvasId;
loadResult.m_entity = AZStd::make_unique<AZ::Entity>("Loaded test graph");
loadResult.m_runtimeAsset = runtimeAsset;
RunGraphSpec runGraphSpec;
runGraphSpec.dirPath = "";
runGraphSpec.graphPath = asset.GetHint().c_str();
runGraphSpec.runSpec.duration.m_spec = eDuration::Ticks;
runGraphSpec.runSpec.duration.m_ticks = 10;
runGraphSpec.runSpec.execution = mode;
runGraphSpec.runSpec.release = true;
runGraphSpec.runSpec.debug = runGraphSpec.runSpec.traced = false;
RunGraphImplementation(runGraphSpec, loadResult, reporter);
return;
}
reporter.SetExecutionMode(mode);
LoadTestGraphResult loadResult;
loadResult.m_editorAsset = SourceHandle(nullptr, assetId.m_guid, asset.Path());
AZ::EntityId scriptCanvasId;
loadResult.m_entity = AZStd::make_unique<AZ::Entity>("Loaded test graph");
loadResult.m_runtimeAsset = runtimeAsset;
RunGraphSpec runGraphSpec;
runGraphSpec.dirPath = "";
runGraphSpec.graphPath = asset.Path().c_str();
runGraphSpec.runSpec.duration.m_spec = eDuration::Ticks;
runGraphSpec.runSpec.duration.m_ticks = 10;
runGraphSpec.runSpec.execution = mode;
runGraphSpec.runSpec.release = true;
runGraphSpec.runSpec.debug = runGraphSpec.runSpec.traced = false;
RunGraphImplementation(runGraphSpec, loadResult, reporter);
}
AZ_INLINE void RunGraphImplementation(const RunGraphSpec& runGraphSpec, Reporter& reporter)
@@ -42,8 +42,6 @@ namespace ScriptCanvas
namespace ScriptCanvasEditor
{
class ScriptCanvasAsset;
struct LoadTestGraphResult
{
AZStd::unique_ptr<AZ::Entity> m_entity;
@@ -219,7 +219,7 @@ namespace ScriptCanvasEditor
if (scriptCanvasSlot && scriptCanvasSlot->IsVisible())
{
int& index = (scriptCanvasSlot->IsData() && scriptCanvasSlot->IsOutput()) ? paramIndex : outputIndex;
int& index = (scriptCanvasSlot->IsData() && scriptCanvasSlot->IsOutput()) ? outputIndex : paramIndex;
auto graphCanvasSlotId = Nodes::DisplayScriptCanvasSlot(GetEntityId(), (*scriptCanvasSlot), index);
@@ -14,7 +14,6 @@
#include <GraphCanvas/Components/Slots/SlotBus.h>
#include <GraphCanvas/Components/Nodes/NodeTitleBus.h>
#include <Editor/Assets/ScriptCanvasAssetHelpers.h>
#include <Editor/Translation/TranslationHelper.h>
#include <Editor/Include/ScriptCanvas/Bus/EditorScriptCanvasBus.h>
@@ -89,16 +88,9 @@ namespace ScriptCanvasEditor
bool FunctionNodeDescriptorComponent::OnMouseDoubleClick(const QGraphicsSceneMouseEvent*)
{
AZ::Data::AssetInfo assetInfo = AssetHelpers::GetSourceInfoByProductId(m_assetId, azrtti_typeid< ScriptCanvas::SubgraphInterfaceAsset>());
if (!assetInfo.m_assetId.IsValid())
{
return false;
}
AZ::Outcome<int, AZStd::string> openOutcome = AZ::Failure(AZStd::string());
GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset
, SourceHandle( nullptr, assetInfo.m_assetId.m_guid, {} ), Tracker::ScriptCanvasFileState::UNMODIFIED, -1);
, SourceHandle( nullptr, m_assetId.m_guid, {} ), Tracker::ScriptCanvasFileState::UNMODIFIED, -1);
return openOutcome.IsSuccess();
}
@@ -1,88 +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/Asset/AssetCommon.h>
#include <ScriptCanvas/Asset/AssetDescription.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetBus.h>
#include <ScriptCanvas/Assets/ScriptCanvasBaseAssetData.h>
#include <ScriptCanvas/Asset/ScriptCanvasAssetBase.h>
namespace AZ
{
class Entity;
}
namespace ScriptCanvas
{
class Graph;
}
namespace ScriptCanvasEditor
{
class Graph;
class ScriptCanvasAsset;
class ScriptCanvasAssetDescription : public ScriptCanvas::AssetDescription
{
public:
AZ_TYPE_INFO(ScriptCanvasAssetDescription, "{3678E33E-521B-4CAC-9DC1-42566AC71249}");
ScriptCanvasAssetDescription()
: ScriptCanvas::AssetDescription(
azrtti_typeid<ScriptCanvasAsset>(),
"Script Canvas",
"Script Canvas Graph Asset",
"@projectroot@/scriptcanvas",
".scriptcanvas",
"Script Canvas",
"Untitled-%i",
"Script Canvas Files (*.scriptcanvas)",
"Script Canvas",
"Script Canvas",
"Icons/ScriptCanvas/Viewport/ScriptCanvas.png",
AZ::Color(0.321f, 0.302f, 0.164f, 1.0f),
true
)
{}
};
class ScriptCanvasAsset
: public ScriptCanvas::ScriptCanvasAssetBase
{
public:
AZ_RTTI(ScriptCanvasAsset, "{FA10C3DA-0717-4B72-8944-CD67D13DFA2B}", ScriptCanvas::ScriptCanvasAssetBase);
AZ_CLASS_ALLOCATOR(ScriptCanvasAsset, AZ::SystemAllocator, 0);
ScriptCanvasAsset(const AZ::Data::AssetId& assetId = AZ::Data::AssetId(AZ::Uuid::CreateRandom()),
AZ::Data::AssetData::AssetStatus status = AZ::Data::AssetData::AssetStatus::NotLoaded)
: ScriptCanvas::ScriptCanvasAssetBase(assetId, status)
{
m_data = aznew ScriptCanvas::ScriptCanvasData();
}
~ScriptCanvasAsset() override
{
}
ScriptCanvas::AssetDescription GetAssetDescription() const override
{
return ScriptCanvasAssetDescription();
}
ScriptCanvas::Graph* GetScriptCanvasGraph() const;
using Description = ScriptCanvasAssetDescription;
ScriptCanvas::ScriptCanvasData& GetScriptCanvasData() override;
const ScriptCanvas::ScriptCanvasData& GetScriptCanvasData() const override;
};
}
@@ -1,31 +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
namespace ScriptCanvas
{
class ScriptCanvasAssetBusRequests : public AZ::EBusTraits
{
public:
using BusIdType = AZ::Data::AssetId;
using MutexType = AZStd::recursive_mutex;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
virtual void SetAsNewAsset() = 0;
};
using ScriptCanvasAssetBusRequestBus = AZ::EBus<ScriptCanvasAssetBusRequests>;
}
@@ -1,81 +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/Asset/AssetManager.h>
#include <AzCore/Asset/AssetTypeInfoBus.h>
#include <AzCore/Serialization/ObjectStream.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
namespace AZ
{
class SerializeContext;
}
namespace ScriptCanvasEditor
{
/**
* Manages editor Script Canvas graph assets.
*/
class ScriptCanvasAssetHandler
: public AZ::Data::AssetHandler
, protected AZ::AssetTypeInfoBus::MultiHandler
{
public:
AZ_CLASS_ALLOCATOR(ScriptCanvasAssetHandler, AZ::SystemAllocator, 0);
AZ_RTTI(ScriptCanvasAssetHandler, "{098B86B2-2527-4155-84C9-A698A0D20068}", AZ::Data::AssetHandler);
ScriptCanvasAssetHandler(AZ::SerializeContext* context = nullptr);
~ScriptCanvasAssetHandler();
// Called by the asset database to create a new asset.
AZ::Data::AssetPtr CreateAsset(const AZ::Data::AssetId& id, const AZ::Data::AssetType& type) override;
// Override the stream info to force source assets to load into the Editor instead of cached, processed assets.
void GetCustomAssetStreamInfoForLoad(AZ::Data::AssetStreamInfo& streamInfo) override;
// Called by the asset database to perform actual asset load.
AZ::Data::AssetHandler::LoadResult LoadAssetData(
const AZ::Data::Asset<AZ::Data::AssetData>& asset,
AZStd::shared_ptr<AZ::Data::AssetDataStream> stream,
const AZ::Data::AssetFilterCB& assetLoadFilterCB) override;
// Called by the asset database to perform actual asset save. Returns true if successful otherwise false (default - as we don't require support save).
bool SaveAssetData(const AZ::Data::Asset<AZ::Data::AssetData>& asset, AZ::IO::GenericStream* stream) override;
bool SaveAssetData(const ScriptCanvasAsset* assetData, AZ::IO::GenericStream* stream);
bool SaveAssetData(const ScriptCanvasAsset* assetData, AZ::IO::GenericStream* stream, AZ::DataStream::StreamType streamType);
// Called by the asset database when an asset should be deleted.
void DestroyAsset(AZ::Data::AssetPtr ptr) override;
// Called by asset database on registration.
void GetHandledAssetTypes(AZStd::vector<AZ::Data::AssetType>& assetTypes) override;
// Provides editor with information about script canvas graph assets.
AZ::Data::AssetType GetAssetType() const override;
const char* GetAssetTypeDisplayName() const override;
void GetAssetTypeExtensions(AZStd::vector<AZStd::string>& extensions) override;
AZ::Uuid GetComponentTypeId() const override;
AZ::SerializeContext* GetSerializeContext() const;
void SetSerializeContext(AZ::SerializeContext* context);
static AZ::Data::AssetType GetAssetTypeStatic();
// protected AZ::AssetTypeInfoBus::MultiHandler...
const char* GetGroup() const override;
const char* GetBrowserIcon() const override;
protected:
AZ::SerializeContext* m_serializeContext;
};
}
@@ -1,14 +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
namespace ScriptCanvasEditor
{
}
@@ -1,10 +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 <ScriptCanvas/Assets/ScriptCanvasBaseAssetData.h>
@@ -1,17 +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 <ScriptCanvas/Variable/VariableData.h>
#include <ScriptCanvas/Core/GraphData.h>
namespace ScriptCanvas
{
}
@@ -11,7 +11,7 @@
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/Asset/AssetTypeInfoBus.h>
#include <AzCore/Serialization/ObjectStream.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Core/Core.h>
namespace AZ
{
@@ -20,7 +20,6 @@
#include <GraphCanvas/Editor/EditorTypes.h>
#include <GraphCanvas/Types/EntitySaveData.h>
#include <Editor/Include/ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <Editor/Include/ScriptCanvas/Bus/NodeIdPair.h>
#include <ScriptCanvas/Core/ExecutionNotificationsBus.h>
#include <ScriptCanvas/Variable/VariableCore.h>
@@ -37,11 +37,6 @@ namespace GraphCanvas
class NodePaletteDockWidget;
}
namespace ScriptCanvas
{
class ScriptCanvasAssetBase;
}
namespace ScriptCanvasEditor
{
struct CategoryInformation;
@@ -23,7 +23,7 @@ namespace ScriptCanvasEditor
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
virtual Reporter RunGraph(AZStd::string_view path, ScriptCanvas::ExecutionMode mode) = 0;
virtual Reporter RunAssetGraph(AZ::Data::Asset<AZ::Data::AssetData>, ScriptCanvas::ExecutionMode mode) = 0;
virtual Reporter RunAssetGraph(SourceHandle source, ScriptCanvas::ExecutionMode mode) = 0;
};
using ScriptCanvasExecutionBus = AZ::EBus<ScriptCanvasExecutionRequests>;
@@ -0,0 +1,30 @@
/*
* 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 <ScriptCanvas/Components/EditorDeprecationData.h>
#include <AzCore/RTTI/ReflectContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Asset/AssetSerializer.h>
namespace ScriptCanvasEditor
{
namespace Deprecated
{
void ScriptCanvasAssetHolder::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<ScriptCanvasAssetHolder>()
->Version(1)
->Field("m_asset", &ScriptCanvasAssetHolder::m_scriptCanvasAsset)
;
}
}
}
}
@@ -0,0 +1,46 @@
/*
* 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/Component/EntityId.h>
#include <AzCore/Asset/AssetCommon.h>
#include <ScriptCanvas/Core/Core.h>
#include <AzCore/Asset/AssetCommon.h>
namespace ScriptCanvasEditor
{
namespace Deprecated
{
// only used as a pass-through to loading a guid / hint during version conversion
class ScriptCanvasAsset
: public AZ::Data::AssetData
{
public:
AZ_TYPE_INFO(ScriptCanvasAsset, "{FA10C3DA-0717-4B72-8944-CD67D13DFA2B}");
AZ_CLASS_ALLOCATOR(ScriptCanvasAsset, AZ::SystemAllocator, 0);
ScriptCanvasAsset() = default;
};
// only used as a pass-through to loading a guid / hint during version conversion
class ScriptCanvasAssetHolder
{
public:
AZ_TYPE_INFO(ScriptCanvasAssetHolder, "{3E80CEE3-2932-4DC1-AADF-398FDDC6DEFE}");
AZ_CLASS_ALLOCATOR(ScriptCanvasAssetHolder, AZ::SystemAllocator, 0);
static void Reflect(AZ::ReflectContext* context);
AZ::Data::Asset<ScriptCanvasAsset> m_scriptCanvasAsset;
ScriptCanvasAssetHolder() = default;
};
}
}
@@ -13,8 +13,6 @@
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
#include <Builder/ScriptCanvasBuilder.h>
#include <Editor/Assets/ScriptCanvasAssetHolder.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
#include <ScriptCanvas/Components/EditorScriptCanvasComponentSerializer.h>
#include <ScriptCanvas/Execution/RuntimeComponent.h>
@@ -23,14 +21,8 @@
namespace ScriptCanvasEditor
{
/*! EditorScriptCanvasComponent
The user facing Editor Component for interfacing with ScriptCanvas
It connects to the AssetCatalogEventBus in order to remove the ScriptCanvasAssetHolder asset reference
when the asset is removed from the file system. The reason the ScriptCanvasAssetHolder holder does not
remove the asset reference itself is because the ScriptCanvasEditor MainWindow has a ScriptCanvasAssetHolder
which it uses to maintain the asset data in memory. Therefore removing an open ScriptCanvasAsset from the file system
will remove the reference from the EditorScriptCanvasComponent, but not the reference from the MainWindow allowing the
ScriptCanvas graph to still be modified while open
Finally per graph instance variables values are stored on the EditorScriptCanvasComponent and injected into the runtime ScriptCanvas component in BuildGameEntity
The user facing Editor Component for interfacing with ScriptCanvas.
Per graph instance variables values are stored here and injected into the runtime ScriptCanvas component in BuildGameEntity.
*/
class EditorScriptCanvasComponent
: public AzToolsFramework::Components::EditorComponentBase
@@ -90,13 +82,6 @@ namespace ScriptCanvasEditor
AZ::Data::AssetId GetAssetId() const override;
//=====================================================================
//=====================================================================
// EditorEntityContextNotificationBus
protected:
enum class SourceChangeDescription : AZ::u8
{
@@ -6,26 +6,102 @@
*
*/
#include <Editor/ReflectComponent.h>
#include <AssetBuilderSDK/AssetBuilderSDK.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <Editor/Assets/ScriptCanvasAssetHolder.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <Editor/Include/ScriptCanvas/Components/EditorGraph.h>
#include <Editor/ReflectComponent.h>
#include <Editor/View/Dialogs/SettingsDialog.h>
#include <Editor/View/Widgets/LoggingPanel/LiveWindowSession/LiveLoggingWindowSession.h>
#include <Editor/View/Widgets/NodePalette/CreateNodeMimeEvent.h>
#include <Editor/View/Widgets/NodePalette/ScriptEventsNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/NodePalette/EBusNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/NodePalette/FunctionNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/NodePalette/GeneralNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/NodePalette/ScriptEventsNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/NodePalette/SpecializedNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/NodePalette/VariableNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/NodePalette/FunctionNodePaletteTreeItemTypes.h>
#include <ScriptCanvas/Bus/UndoBus.h>
#include <ScriptCanvas/Components/EditorDeprecationData.h>
#include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
#include <ScriptCanvas/Variable/GraphVariableManagerComponent.h>
namespace CoreCpp
{
static bool ScriptCanvasDataVersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& rootDataElementNode)
{
if (rootDataElementNode.GetVersion() == 0)
{
int scriptCanvasEntityIndex = rootDataElementNode.FindElement(AZ_CRC("m_scriptCanvas", 0xfcd20d85));
if (scriptCanvasEntityIndex == -1)
{
AZ_Error("Script Canvas", false, "Version Converter failed, The Script Canvas Entity is missing");
return false;
}
auto scComponentElements = AZ::Utils::FindDescendantElements(context, rootDataElementNode, AZStd::vector<AZ::Crc32>{AZ_CRC("m_scriptCanvas", 0xfcd20d85),
AZ_CRC("element", 0x41405e39), AZ_CRC("Components", 0xee48f5fd)});
if (!scComponentElements.empty())
{
scComponentElements.front()->AddElementWithData(context, "element", ScriptCanvasEditor::EditorGraphVariableManagerComponent());
}
}
if (rootDataElementNode.GetVersion() < 4)
{
auto scEntityElements = AZ::Utils::FindDescendantElements(context, rootDataElementNode,
AZStd::vector<AZ::Crc32>{AZ_CRC("m_scriptCanvas", 0xfcd20d85), AZ_CRC("element", 0x41405e39)});
if (scEntityElements.empty())
{
AZ_Error("Script Canvas", false, "Version Converter failed, The Script Canvas Entity is missing");
return false;
}
auto& scEntityDataElement = *scEntityElements.front();
AZ::Entity scEntity;
if (!scEntityDataElement.GetData(scEntity))
{
AZ_Error("Script Canvas", false, "Unable to retrieve entity data from the Data Element");
return false;
}
auto graph = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::Graph>(&scEntity);
if (!graph)
{
AZ_Error("Script Canvas", false, "Script Canvas graph component could not be found on Script Canvas Entity for ScriptCanvasData version %u", rootDataElementNode.GetVersion());
return false;
}
auto variableManager = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::GraphVariableManagerComponent>(&scEntity);
if (!variableManager)
{
AZ_Error("Script Canvas", false, "Script Canvas variable manager component could not be found on Script Canvas Entity for ScriptCanvasData version %u", rootDataElementNode.GetVersion());
return false;
}
variableManager->ConfigureScriptCanvasId(graph->GetScriptCanvasId());
if (!scEntityDataElement.SetData(context, scEntity))
{
AZ_Error("Script Canvas", false, "Failed to set converted Script Canvas Entity back on data element node when transitioning from version %u to version 4", rootDataElementNode.GetVersion());
return false;
}
}
return true;
}
}
namespace ScriptCanvas
{
void ScriptCanvasData::Reflect(AZ::ReflectContext* reflectContext)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
{
serializeContext->Class<ScriptCanvasData>()
->Version(4, &CoreCpp::ScriptCanvasDataVersionConverter)
->Field("m_scriptCanvas", &ScriptCanvasData::m_scriptCanvasEntity)
;
}
}
}
namespace ScriptCanvasEditor
{
@@ -33,7 +109,7 @@ namespace ScriptCanvasEditor
{
SourceHandle::Reflect(context);
ScriptCanvas::ScriptCanvasData::Reflect(context);
ScriptCanvasAssetHolder::Reflect(context);
Deprecated::ScriptCanvasAssetHolder::Reflect(context);
EditorSettings::EditorWorkspace::Reflect(context);
EditorSettings::ScriptCanvasEditorSettings::Reflect(context);
LiveLoggingUserSettings::Reflect(context);
+1 -1
View File
@@ -13,7 +13,7 @@
#include "Settings.h"
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Data/Data.h>
#include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
@@ -37,6 +37,8 @@
#include <ScriptCanvas/PerformanceStatisticsBus.h>
#include <ScriptCanvas/Variable/VariableCore.h>
#include <ScriptCanvas/View/EditCtrls/GenericLineEditCtrl.h>
#include <Editor/Assets/ScriptCanvasAssetHelpers.h>
namespace ScriptCanvasEditor
{
@@ -109,7 +111,6 @@ namespace ScriptCanvasEditor
void SystemComponent::Activate()
{
m_assetTracker.Activate();
AZ::JobManagerDesc jobDesc;
for (size_t i = 0; i < cs_jobThreads; ++i)
{
@@ -165,7 +166,6 @@ namespace ScriptCanvasEditor
m_jobContext.reset();
m_jobManager.reset();
m_assetTracker.Deactivate();
}
void SystemComponent::AddAsyncJob(AZStd::function<void()>&& jobFunc)
@@ -316,8 +316,8 @@ namespace ScriptCanvasEditor
using namespace AzToolsFramework::AssetBrowser;
bool isScriptCanvasAsset = false;
ScriptCanvasAssetDescription scriptCanvasAssetDescription;
if (AZStd::wildcard_match(AZStd::string::format("*%s", scriptCanvasAssetDescription.GetExtensionImpl()).c_str(), fullSourceFileName))
if (AZStd::wildcard_match(ScriptCanvasEditor::SourceDescription::GetFileExtension(), fullSourceFileName))
{
isScriptCanvasAsset = true;
}
@@ -339,7 +339,7 @@ namespace ScriptCanvasEditor
}
};
openers.push_back({ "O3DE_ScriptCanvasEditor", "Open In Script Canvas Editor...", QIcon(ScriptCanvasAssetDescription().GetIconPathImpl()), scriptCanvasEditorCallback });
openers.push_back({ "O3DE_ScriptCanvasEditor", "Open In Script Canvas Editor...", QIcon(ScriptCanvasEditor::SourceDescription::GetIconPath()), scriptCanvasEditorCallback });
}
}
@@ -394,7 +394,7 @@ namespace ScriptCanvasEditor
return ScriptCanvasEditor::RunGraph(runGraphSpec).front();
}
Reporter SystemComponent::RunAssetGraph(AZ::Data::Asset<AZ::Data::AssetData> asset, ScriptCanvas::ExecutionMode mode)
Reporter SystemComponent::RunAssetGraph(SourceHandle asset, ScriptCanvas::ExecutionMode mode)
{
Reporter reporter;
RunEditorAsset(asset, reporter, mode);
@@ -19,7 +19,6 @@
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/Editor/EditorContextMenuBus.h>
#include <Core/GraphBus.h>
#include <Editor/Assets/ScriptCanvasAssetTracker.h>
#include <Editor/View/Windows/Tools/UpgradeTool/Model.h>
#include <ScriptCanvas/Bus/ScriptCanvasBus.h>
#include <ScriptCanvas/Bus/ScriptCanvasExecutionBus.h>
@@ -79,7 +78,7 @@ namespace ScriptCanvasEditor
////////////////////////////////////////////////////////////////////////
// ScriptCanvasExecutionBus::Handler...
Reporter RunAssetGraph(AZ::Data::Asset<AZ::Data::AssetData>, ScriptCanvas::ExecutionMode mode) override;
Reporter RunAssetGraph(SourceHandle source, ScriptCanvas::ExecutionMode mode) override;
Reporter RunGraph(AZStd::string_view path, ScriptCanvas::ExecutionMode mode) override;
////////////////////////////////////////////////////////////////////////
@@ -118,8 +117,6 @@ namespace ScriptCanvasEditor
AZStd::unordered_set<ScriptCanvas::Data::Type> m_creatableTypes;
AssetTracker m_assetTracker;
AZStd::vector<AZ::Data::AssetId> m_assetsThatNeedManualUpgrade;
bool m_isUpgrading = false;
@@ -19,7 +19,6 @@
#include <Editor/Undo/ScriptCanvasGraphCommand.h>
#include <Editor/Include/ScriptCanvas/Bus/EditorScriptCanvasBus.h>
#include <Editor/Assets/ScriptCanvasAssetTrackerBus.h>
namespace ScriptCanvasEditor
{
@@ -30,8 +30,6 @@ namespace ScriptCanvasEditor
using GraphItemCommandNotificationBus = AZ::EBus<GraphItemCommandNotifications>;
class ScriptCanvasMemoryAsset;
// This command is the base URSequencePoint command from which all Script Canvas undo/redo commands derive
class GraphItemCommand
: public AzToolsFramework::UndoSystem::URSequencePoint
@@ -78,7 +78,7 @@ namespace ScriptCanvasEditor
if (!tabDataVariant.value<GraphTabMetadata>().m_canvasWidget)
{
CanvasWidget* canvasWidget = new CanvasWidget(tabDataVariant.value<GraphTabMetadata>().m_assetId, this);
canvasWidget->SetDefaultBorderColor(ScriptCanvasAssetDescription().GetDisplayColorImpl());
canvasWidget->SetDefaultBorderColor(ScriptCanvasEditor::SourceDescription::GetDisplayColor());
GraphTabMetadata replacement = tabDataVariant.value<GraphTabMetadata>();
replacement.m_canvasWidget = canvasWidget;
tabDataVariant.setValue(replacement);
@@ -147,11 +147,11 @@ namespace ScriptCanvasEditor
{
if (!SelectTab(assetId))
{
QIcon tabIcon = QIcon(ScriptCanvasAssetDescription().GetIconPathImpl());
QIcon tabIcon = QIcon(ScriptCanvasEditor::SourceDescription::GetIconPath());
tabIndex = qobject_cast<AzQtComponents::TabWidget*>(parent())->insertTab(tabIndex, new QWidget(), tabIcon, "");
GraphTabMetadata metaData;
CanvasWidget* canvasWidget = new CanvasWidget(assetId, this);
canvasWidget->SetDefaultBorderColor(ScriptCanvasAssetDescription().GetDisplayColorImpl());
canvasWidget->SetDefaultBorderColor(SourceDescription::GetDisplayColor());
metaData.m_canvasWidget = canvasWidget;
metaData.m_assetId = assetId;
metaData.m_fileState = fileState;
@@ -17,7 +17,6 @@
#include <AzCore/Asset/AssetCommon.h>
#include <ScriptCanvas/Core/Core.h>
#include <Editor/Assets/ScriptCanvasAssetTracker.h>
#include <ScriptCanvas/Bus/RequestBus.h>
#endif
@@ -9,11 +9,9 @@
#include <AzCore/Asset/AssetManagerBus.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserModel.h>
#include <Editor/View/Widgets/LoggingPanel/PivotTree/GraphPivotTree/GraphPivotTree.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <AzToolsFramework/AssetBrowser/Entries/ProductAssetBrowserEntry.h>
#include <Editor/View/Widgets/LoggingPanel/PivotTree/GraphPivotTree/GraphPivotTree.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
namespace ScriptCanvasEditor
{
@@ -355,7 +353,7 @@ namespace ScriptCanvasEditor
m_assetModel = new AzToolsFramework::AssetBrowser::AssetBrowserFilterModel();
AzToolsFramework::AssetBrowser::AssetGroupFilter* assetFilter = new AzToolsFramework::AssetBrowser::AssetGroupFilter();
assetFilter->SetAssetGroup(ScriptCanvasEditor::ScriptCanvasAsset::Description::GetGroup(azrtti_typeid<ScriptCanvasAsset>()));
assetFilter->SetAssetGroup(ScriptCanvasEditor::SourceDescription::GetGroup());
assetFilter->SetFilterPropagation(AzToolsFramework::AssetBrowser::AssetBrowserEntryFilter::PropagateDirection::Down);
@@ -530,7 +528,7 @@ namespace ScriptCanvasEditor
{
const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry* productEntry = azrtti_cast<const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry*>(entry);
if (productEntry->GetAssetType() == azrtti_typeid<ScriptCanvasEditor::ScriptCanvasAsset>())
if (productEntry->GetAssetType() == azrtti_typeid<ScriptCanvas::SubgraphInterfaceAsset>())
{
auto mapIter = m_graphTreeItemMapping.find(productEntry->GetAssetId());
@@ -556,7 +554,7 @@ namespace ScriptCanvasEditor
{
const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry* productEntry = static_cast<const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry*>(entry);
if (productEntry->GetAssetType() == azrtti_typeid<ScriptCanvasEditor::ScriptCanvasAsset>())
if (productEntry->GetAssetType() == azrtti_typeid<ScriptCanvas::SubgraphInterfaceAsset>())
{
OnEntityGraphRegistered(AZ::NamedEntityId(), ScriptCanvas::GraphIdentifier(productEntry->GetAssetId(), k_dynamicallySpawnedControllerId));
}
@@ -17,7 +17,7 @@
#include <ScriptCanvas/Bus/NodeIdPair.h>
#include <ScriptCanvas/Bus/RequestBus.h>
#include <Editor/View/Widgets/NodePalette/CreateNodeMimeEvent.h>
#include <ScriptCanvas/Core/SubgraphInterface.h>
#include <ScriptCanvas/GraphCanvas/NodeDescriptorBus.h>
namespace AZ
@@ -16,7 +16,6 @@
#include <Editor/View/Widgets/NodePalette/NodePaletteModel.h>
#include <Editor/Assets/ScriptCanvasAssetHelpers.h>
#include <Editor/Include/ScriptCanvas/Bus/RequestBus.h>
#include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
#include <Editor/Nodes/NodeUtils.h>
@@ -462,31 +462,32 @@ namespace ScriptCanvasEditor
return;
}
AZStd::string rootPath, absolutePath;
AZ::Data::AssetInfo assetInfo = AssetHelpers::GetAssetInfo(assetId, rootPath);
AzFramework::StringFunc::Path::Join(rootPath.c_str(), assetInfo.m_relativePath.c_str(), absolutePath);
AZStd::string normPath = absolutePath;
AzFramework::StringFunc::Path::Normalize(normPath);
AZStd::string watchFolder;
bool sourceInfoFound{};
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, normPath.c_str(), assetInfo, watchFolder);
if (!sourceInfoFound)
{
return;
}
CreateFunctionPaletteItem(asset, assetInfo);
treePaletteIter = m_globalFunctionTreeItems.find(asset->GetId());
if (treePaletteIter != m_globalFunctionTreeItems.end())
{
treePaletteIter->second->ClearError();
}
m_monitoredAssets.emplace(asset->GetId(), asset);
}
else
@@ -10,11 +10,10 @@
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <Editor/Assets/ScriptCanvasAssetTrackerBus.h>
#include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
#include <Editor/View/Widgets/StatisticsDialog/NodeUsageTreeItem.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Components/EditorGraph.h>
namespace ScriptCanvasEditor
@@ -136,8 +135,6 @@ namespace ScriptCanvasEditor
void ScriptCanvasAssetNodeUsageTreeItem::SetAssetId(const AZ::Data::AssetId& assetId, AZ::Data::AssetType assetType)
{
// If we are setting up a new assetId, we wantt o register for the bus.
// Otherwise we just want to reload the asset to scrape some data from it.
if (m_assetId != assetId)
{
if (AZ::Data::AssetBus::Handler::BusIsConnected())
@@ -151,9 +148,6 @@ namespace ScriptCanvasEditor
}
m_assetType = assetType;
auto onAssetReady = [](ScriptCanvasMemoryAsset&) {};
AssetTrackerRequestBus::Broadcast(&AssetTrackerRequests::Load, m_assetId, m_assetType, onAssetReady);
}
const AZ::Data::AssetId& ScriptCanvasAssetNodeUsageTreeItem::GetAssetId() const
@@ -188,6 +182,7 @@ namespace ScriptCanvasEditor
return nodeIter->second;
}
/*
void ScriptCanvasAssetNodeUsageTreeItem::OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
ProcessAsset(asset);
@@ -206,7 +201,8 @@ namespace ScriptCanvasEditor
ProcessAsset(asset);
}
void ScriptCanvasAssetNodeUsageTreeItem::ProcessAsset(const AZ::Data::Asset<ScriptCanvas::ScriptCanvasAssetBase>& scriptCanvasAsset)
// #sc_editor_asset_redux fix graph use statistics
void ScriptCanvasAssetNodeUsageTreeItem::ProcessAsset(const AZ::Data::Asset<LegacyScriptCanvasBaseAsset>& scriptCanvasAsset)
{
if (scriptCanvasAsset.IsReady())
{
@@ -228,6 +224,7 @@ namespace ScriptCanvasEditor
}
}
}
*/
///////////////////////////////////////////
// ScriptCanvasAssetNodeUsageTreeItemRoot
@@ -15,7 +15,7 @@
#include <GraphCanvas/Widgets/NodePalette/TreeItems/IconDecoratedNodePaletteTreeItem.h>
#include <Editor/View/Widgets/NodePalette/NodePaletteModel.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Components/EditorUtils.h>
namespace ScriptCanvasEditor
@@ -94,15 +94,16 @@ namespace ScriptCanvasEditor
void SetActiveNodeType(const ScriptCanvas::NodeTypeIdentifier& nodeTypeIdentifier);
int GetNodeCount() const;
private:
// AZ::Data::AssetBus::Handler
/*
void OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
void OnAssetSaved(AZ::Data::Asset<AZ::Data::AssetData> asset, bool isSuccessful) override;
void OnAssetReloaded(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
*/
////
private:
void ProcessAsset(const AZ::Data::Asset<ScriptCanvas::ScriptCanvasAssetBase>& scriptCanvasAsset);
// void ProcessAsset(const AZ::Data::Asset<LegacyScriptCanvasBaseAsset>& scriptCanvasAsset);
QString m_name;
QIcon m_icon;
@@ -15,7 +15,7 @@
#include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Bus/RequestBus.h>
namespace
@@ -176,14 +176,15 @@ namespace ScriptCanvasEditor
{
}
void StatisticsDialog::OnCatalogAssetChanged(const AZ::Data::AssetId& assetId)
void StatisticsDialog::OnCatalogAssetChanged(const AZ::Data::AssetId& /*assetId*/)
{
AZ::Data::AssetInfo assetInfo;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetInfo, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetInfoById, assetId);
if (assetInfo.m_assetType == azrtti_typeid<ScriptCanvasAsset>())
{
m_scriptCanvasAssetTreeRoot->RegisterAsset(assetId, assetInfo.m_assetType);
}
// #sc_editor_asset_redux cut or update
// AZ::Data::AssetInfo assetInfo;
// AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetInfo, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetInfoById, assetId);
// if (assetInfo.m_assetType == azrtti_typeid<OldAssetType())
// {
// m_scriptCanvasAssetTreeRoot->RegisterAsset(assetId, assetInfo.m_assetType);
// }
}
void StatisticsDialog::OnCatalogAssetAdded(const AZ::Data::AssetId& assetId)
@@ -191,14 +192,16 @@ namespace ScriptCanvasEditor
OnCatalogAssetChanged(assetId);
}
void StatisticsDialog::OnCatalogAssetRemoved(const AZ::Data::AssetId& assetId, const AZ::Data::AssetInfo& /*assetInfo*/)
void StatisticsDialog::OnCatalogAssetRemoved(const AZ::Data::AssetId& /*assetId*/, const AZ::Data::AssetInfo& /*assetInfo*/)
{
AZ::Data::AssetInfo assetInfo;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetInfo, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetInfoById, assetId);
if (assetInfo.m_assetType == azrtti_typeid<ScriptCanvasAsset>())
{
m_scriptCanvasAssetTreeRoot->RemoveAsset(assetId);
}
// #sc_editor_asset_redux cut or update
// AZ::Data::AssetInfo assetInfo;
// AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetInfo, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetInfoById, assetId);
// if (assetInfo.m_assetType == azrtti_typeid<OldAssetType>())
// {
// m_scriptCanvasAssetTreeRoot->RemoveAsset(assetId);
// }
}
void StatisticsDialog::OnAssetModelRepopulated()
@@ -432,22 +435,23 @@ namespace ScriptCanvasEditor
}
}
void StatisticsDialog::ProcessAsset(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry)
void StatisticsDialog::ProcessAsset([[maybe_unused]] const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry)
{
if (entry)
{
if (entry->GetEntryType() == AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Product)
{
const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry* productEntry = static_cast<const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry*>(entry);
if (productEntry->GetAssetType() == azrtti_typeid<ScriptCanvasAsset>())
{
const AZ::Data::AssetId& assetId = productEntry->GetAssetId();
m_scriptCanvasAssetTreeRoot->RegisterAsset(assetId, productEntry->GetAssetType());
}
}
}
// #sc_editor_asset_redux cut or update
// if (entry)
// {
// if (entry->GetEntryType() == AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Product)
// {
// const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry* productEntry = static_cast<const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry*>(entry);
//
// if (productEntry->GetAssetType() == azrtti_typeid<OldAssetType>())
// {
// const AZ::Data::AssetId& assetId = productEntry->GetAssetId();
//
// m_scriptCanvasAssetTreeRoot->RegisterAsset(assetId, productEntry->GetAssetType());
// }
// }
// }
}
#include <Editor/View/Widgets/StatisticsDialog/moc_ScriptCanvasStatisticsDialog.cpp>
@@ -26,7 +26,7 @@
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/Asset/AssetManager.h>
#include <Editor/Assets/ScriptCanvasAssetHelpers.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
@@ -35,7 +35,6 @@
#include <Editor/QtMetaTypes.h>
#include <Editor/Settings.h>
#include <Editor/Assets/ScriptCanvasAssetHelpers.h>
#include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
#include <Editor/Include/ScriptCanvas/GraphCanvas/NodeDescriptorBus.h>
#include <Editor/Model/UnitTestBrowserFilterModel.h>
@@ -47,13 +46,12 @@
#include <Data/Data.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Bus/ScriptCanvasExecutionBus.h>
#include <ScriptCanvas/Bus/UnitTestVerificationBus.h>
#include <ScriptCanvas/Data/DataRegistry.h>
#include <ScriptCanvas/GraphCanvas/NodeDescriptorBus.h>
#include <ScriptCanvas/Components/EditorUtils.h>
#include <LyViewPaneNames.h>
namespace ScriptCanvasEditor
@@ -522,16 +520,9 @@ namespace ScriptCanvasEditor
continue;
}
AZ::Data::AssetInfo assetInfo;
if (AssetHelpers::GetAssetInfo(sourceBrowserEntry->GetFullPath(), assetInfo))
{
auto asset = AZ::Data::AssetManager::Instance().GetAsset(assetInfo.m_assetId, azrtti_typeid<ScriptCanvasAsset>(), AZ::Data::AssetLoadBehavior::PreLoad);
asset.BlockUntilLoadComplete();
if (asset.IsReady())
{
RunTestGraph(asset, mode);
}
}
ScriptCanvasEditor::SourceHandle source(nullptr, scriptUuid, "");
ScriptCanvasEditor::CompleteDescriptionInPlace(source);
RunTestGraph(source, mode);
}
}
}
@@ -580,19 +571,19 @@ namespace ScriptCanvasEditor
m_testMetrics[interpretedMode].Clear();
}
void UnitTestDockWidget::RunTestGraph(AZ::Data::Asset<AZ::Data::AssetData> asset, ScriptCanvas::ExecutionMode mode)
void UnitTestDockWidget::RunTestGraph(SourceHandle asset, ScriptCanvas::ExecutionMode mode)
{
Reporter reporter;
UnitTestWidgetNotificationBus::Broadcast(&UnitTestWidgetNotifications::OnTestStart, asset.GetId().m_guid);
UnitTestWidgetNotificationBus::Broadcast(&UnitTestWidgetNotifications::OnTestStart, asset.Id());
ScriptCanvasExecutionBus::BroadcastResult(reporter, &ScriptCanvasExecutionRequests::RunAssetGraph, asset, mode);
UnitTestResult testResult;
UnitTestVerificationBus::BroadcastResult(testResult, &UnitTestVerificationRequests::Verify, reporter);
UnitTestWidgetNotificationBus::Broadcast(&UnitTestWidgetNotifications::OnTestResult, asset.GetId().m_guid, testResult);
UnitTestWidgetNotificationBus::Broadcast(&UnitTestWidgetNotifications::OnTestResult, asset.Id(), testResult);
m_pendingTests.Add(asset.GetId(), mode);
m_pendingTests.Add(asset, mode);
++m_testMetrics[static_cast<int>(mode)].m_graphsTested;
@@ -612,7 +603,7 @@ namespace ScriptCanvasEditor
++m_testMetrics[static_cast<int>(mode)].m_compilationFailures;
}
m_pendingTests.Complete(asset.GetId(), mode);
m_pendingTests.Complete(asset, mode);
}
void UnitTestDockWidget::OnSystemTick()
@@ -623,14 +614,14 @@ namespace ScriptCanvasEditor
}
}
void UnitTestDockWidget::PendingTests::Add(AZ::Data::AssetId assetId, ExecutionMode mode)
void UnitTestDockWidget::PendingTests::Add(ScriptCanvasEditor::SourceHandle assetId, ExecutionMode mode)
{
m_pendingTests.push_back(AZStd::make_pair(assetId, mode));
}
void UnitTestDockWidget::PendingTests::Complete(AZ::Data::AssetId assetId, ExecutionMode mode)
void UnitTestDockWidget::PendingTests::Complete(ScriptCanvasEditor::SourceHandle assetId, ExecutionMode mode)
{
AZStd::erase_if(m_pendingTests, [assetId, mode](const AZStd::pair<AZ::Data::AssetId, ExecutionMode>& pending)
AZStd::erase_if(m_pendingTests, [assetId, mode](const AZStd::pair<ScriptCanvasEditor::SourceHandle, ExecutionMode>& pending)
{
return (assetId == pending.first && mode == pending.second);
});
@@ -162,7 +162,7 @@ namespace ScriptCanvasEditor
void OpenTestResults(AZ::Uuid sourceUuid, AZStd::string_view sourceDisplayName);
void RunTests(const AZStd::vector<AZ::Uuid>& scriptUuids);
void RunTestGraph(AZ::Data::Asset<AZ::Data::AssetData>, ScriptCanvas::ExecutionMode);
void RunTestGraph(SourceHandle sourceHandle, ScriptCanvas::ExecutionMode);
void OnTestsComplete();
@@ -184,15 +184,15 @@ namespace ScriptCanvasEditor
{
public:
void Add(AZ::Data::AssetId assetId, ExecutionMode mode);
void Add(ScriptCanvasEditor::SourceHandle assetId, ExecutionMode mode);
void Complete(AZ::Data::AssetId assetId, ExecutionMode mode);
void Complete(ScriptCanvasEditor::SourceHandle assetId, ExecutionMode mode);
bool IsFinished() const;
private:
AZStd::vector<AZStd::pair<AZ::Data::AssetId, ExecutionMode>> m_pendingTests;
AZStd::vector<AZStd::pair<SourceHandle, ExecutionMode>> m_pendingTests;
};
PendingTests m_pendingTests;
@@ -33,7 +33,7 @@
#include <Editor/QtMetaTypes.h>
#include <ScriptCanvas/Data/DataRegistry.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <AzCore/Asset/AssetManagerBus.h>
#include <AzCore/Asset/AssetManager.h>
@@ -716,7 +716,6 @@ namespace ScriptCanvasEditor
void GraphVariablesModel::SetActiveScene(const ScriptCanvas::ScriptCanvasId& scriptCanvasId)
{
ScriptCanvas::GraphVariableManagerNotificationBus::Handler::BusDisconnect();
m_assetType = azrtti_typeid<ScriptCanvasAsset>();
m_scriptCanvasId = scriptCanvasId;
if (m_scriptCanvasId.IsValid())
@@ -919,11 +918,6 @@ namespace ScriptCanvasEditor
return -1;
}
bool GraphVariablesModel::IsFunction()const
{
return m_assetType == azrtti_typeid<ScriptCanvas::SubgraphInterfaceAsset>();
}
////////////////////////////////////////////
// GraphVariablesModelSortFilterProxyModel
////////////////////////////////////////////
@@ -106,8 +106,6 @@ namespace ScriptCanvasEditor
void PopulateSceneVariables();
AZ::Data::AssetType m_assetType;
AZStd::vector<ScriptCanvas::GraphScopedVariableId> m_variableIds;
ScriptCanvas::ScriptCanvasId m_scriptCanvasId;
};
@@ -37,7 +37,6 @@
#include <Data/Data.h>
#include <Editor/Assets/ScriptCanvasAssetTrackerBus.h>
#include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
#include <Editor/QtMetaTypes.h>
#include <Editor/Settings.h>
@@ -37,7 +37,6 @@
#include <Data/Data.h>
#include <Editor/Assets/ScriptCanvasAssetTrackerBus.h>
#include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
#include <Editor/QtMetaTypes.h>
#include <Editor/Settings.h>
@@ -96,8 +96,7 @@
#include <ScriptCanvas/Core/ScriptCanvasBus.h>
#include <ScriptCanvas/Core/Graph.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Libraries/Core/FunctionDefinitionNode.h>
#include <GraphCanvas/GraphCanvasBus.h>
@@ -145,12 +144,9 @@
////
#include <Editor/Assets/ScriptCanvasAssetHelpers.h>
#include <Editor/Assets/ScriptCanvasAssetTracker.h>
#include <Editor/Assets/ScriptCanvasAssetTrackerDefinitions.h>
#include <ScriptCanvas/Asset/AssetDescription.h>
#include <ScriptCanvas/Components/EditorScriptCanvasComponent.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <Editor/QtMetaTypes.h>
#include <GraphCanvas/Components/SceneBus.h>
@@ -358,21 +354,6 @@ namespace ScriptCanvasEditor
}
}
void Workspace::OnAssetReady(const ScriptCanvasMemoryAsset::pointer memoryAsset)
{
// open the file in the main window
// const ScriptCanvasEditor::SourceHandle& fileAssetId = memoryAsset->GetFileAssetId();
//
// if (AssetTrackerNotificationBus::MultiHandler::BusIsConnectedId(fileAssetId))
// {
// AssetTrackerNotificationBus::MultiHandler::BusDisconnect(fileAssetId);
//
// m_mainWindow->OpenScriptCanvasAsset(*memoryAsset);
//
// SignalAssetComplete(fileAssetId);
// }
}
void Workspace::SignalAssetComplete(const ScriptCanvasEditor::SourceHandle& /*fileAssetId*/)
{
// When we are done loading all assets we can safely set the focus to the recorded asset
@@ -453,7 +434,7 @@ namespace ScriptCanvasEditor
m_scriptCanvasAssetModel = new ScriptCanvasAssetBrowserModel(this);
AzToolsFramework::AssetBrowser::AssetGroupFilter* scriptCanvasAssetFilter = new AzToolsFramework::AssetBrowser::AssetGroupFilter();
scriptCanvasAssetFilter->SetAssetGroup(ScriptCanvasAsset::Description::GetGroup(azrtti_typeid<ScriptCanvasAsset>()));
scriptCanvasAssetFilter->SetAssetGroup(ScriptCanvas::SubgraphInterfaceAssetDescription().GetGroupImpl());
scriptCanvasAssetFilter->SetFilterPropagation(AzToolsFramework::AssetBrowser::AssetBrowserEntryFilter::PropagateDirection::Down);
m_scriptCanvasAssetModel->setSourceModel(assetBrowserModel);
@@ -791,11 +772,7 @@ namespace ScriptCanvasEditor
// View menu
connect(ui->action_ViewNodePalette, &QAction::triggered, this, &MainWindow::OnViewNodePalette);
// Disabling the Minimap since it does not play nicely with the Qt caching solution
// And causing some weird visual issues.
connect(ui->action_ViewMiniMap, &QAction::triggered, this, &MainWindow::OnViewMiniMap);
ui->action_ViewMiniMap->setVisible(false);
connect(ui->action_ViewProperties, &QAction::triggered, this, &MainWindow::OnViewProperties);
connect(ui->action_ViewBookmarks, &QAction::triggered, this, &MainWindow::OnBookmarks);
@@ -1501,17 +1478,17 @@ namespace ScriptCanvasEditor
for (;;)
{
ScriptCanvasAssetDescription description;
AZStd::string newAssetName = AZStd::string::format(description.GetAssetNamePatternImpl(), ++scriptCanvasEditorDefaultNewNameCount);
AZStd::string newAssetName = AZStd::string::format(SourceDescription::GetAssetNamePattern()
, ++scriptCanvasEditorDefaultNewNameCount);
AZStd::array<char, AZ::IO::MaxPathLength> assetRootArray;
if (!AZ::IO::FileIOBase::GetInstance()->ResolvePath(description.GetSuggestedSavePathImpl()
if (!AZ::IO::FileIOBase::GetInstance()->ResolvePath(SourceDescription::GetSuggestedSavePath()
, assetRootArray.data(), assetRootArray.size()))
{
AZ_ErrorOnce("Script Canvas", false, "Unable to resolve @projectroot@ path");
}
AzFramework::StringFunc::Path::Join(assetRootArray.data(), (newAssetName + description.GetExtensionImpl()).data(), assetPath);
AzFramework::StringFunc::Path::Join(assetRootArray.data(), (newAssetName + SourceDescription::GetFileExtension()).data(), assetPath);
AZ::Data::AssetInfo assetInfo;
if (!AssetHelpers::GetAssetInfo(assetPath, assetInfo))
@@ -1639,7 +1616,6 @@ namespace ScriptCanvasEditor
}
PrepareAssetForSave(inMemoryAssetId);
ScriptCanvasAssetDescription assetDescription;
AZStd::string suggestedFilename;
AZStd::string suggestedFileFilter;
@@ -1648,16 +1624,16 @@ namespace ScriptCanvasEditor
if (save == Save::InPlace)
{
isValidFileName = true;
suggestedFileFilter = ScriptCanvasAssetDescription().GetExtensionImpl();
suggestedFileFilter = SourceDescription::GetFileExtension();
suggestedFilename = inMemoryAssetId.Path().c_str();
}
else
{
suggestedFileFilter = ScriptCanvasAssetDescription().GetExtensionImpl();
suggestedFileFilter = SourceDescription::GetFileExtension();
if (inMemoryAssetId.Path().empty())
{
suggestedFilename = ScriptCanvasAssetDescription().GetSuggestedSavePathImpl();
suggestedFilename = SourceDescription::GetSuggestedSavePath();
}
else
{
@@ -1679,9 +1655,9 @@ namespace ScriptCanvasEditor
{
AZStd::string filePath = selectedFile.toUtf8().data();
if (!AZ::StringFunc::EndsWith(filePath, assetDescription.GetExtensionImpl(), false))
if (!AZ::StringFunc::EndsWith(filePath, SourceDescription::GetFileExtension(), false))
{
filePath += assetDescription.GetExtensionImpl();
filePath += SourceDescription::GetFileExtension();
}
AZStd::string fileName;
@@ -1713,9 +1689,9 @@ namespace ScriptCanvasEditor
AZStd::string internalStringFile = selectedFile.toUtf8().data();
if (!AZ::StringFunc::EndsWith(internalStringFile, assetDescription.GetExtensionImpl(), false))
if (!AZ::StringFunc::EndsWith(internalStringFile, SourceDescription::GetFileExtension(), false))
{
internalStringFile += assetDescription.GetExtensionImpl();
internalStringFile += SourceDescription::GetFileExtension();
}
if (!AssetHelpers::IsValidSourceFile(internalStringFile, GetActiveScriptCanvasId()))
@@ -2758,14 +2734,12 @@ namespace ScriptCanvasEditor
m_logPanel->hide();
}
/* Disable Mini-map until we fix rendering performance
if (m_minimap)
{
addDockWidget(Qt::LeftDockWidgetArea, m_minimap);
m_minimap->setFloating(false);
m_minimap->hide();
m_minimap->show();
}
*/
if (m_nodePalette)
{
@@ -2809,14 +2783,12 @@ namespace ScriptCanvasEditor
m_bookmarkDockWidget->hide();
}
/* Disable mini-map until we fix rendering performance
if (m_minimap)
{
addDockWidget(Qt::RightDockWidgetArea, m_minimap);
m_minimap->setFloating(false);
m_minimap->hide();
m_minimap->show();
}
*/
resizeDocks(
{ m_nodePalette, m_propertyGrid },
@@ -3513,19 +3485,23 @@ namespace ScriptCanvasEditor
return findChild<QObject*>(elementName);
}
AZ::EntityId MainWindow::FindEditorNodeIdByAssetNodeId(const ScriptCanvasEditor::SourceHandle& assetId, AZ::EntityId assetNodeId) const
AZ::EntityId MainWindow::FindEditorNodeIdByAssetNodeId([[maybe_unused]] const ScriptCanvasEditor::SourceHandle& assetId
, [[maybe_unused]] AZ::EntityId assetNodeId) const
{
AZ::EntityId editorEntityId;
AssetTrackerRequestBus::BroadcastResult
( editorEntityId, &AssetTrackerRequests::GetEditorEntityIdFromSceneEntityId, assetId.Id(), assetNodeId);
AZ::EntityId editorEntityId{};
// AssetTrackerRequestBus::BroadcastResult
// ( editorEntityId, &AssetTrackerRequests::GetEditorEntityIdFromSceneEntityId, assetId.Id(), assetNodeId);
// #sc_editor_asset_redux fix logger
return editorEntityId;
}
AZ::EntityId MainWindow::FindAssetNodeIdByEditorNodeId(const ScriptCanvasEditor::SourceHandle& assetId, AZ::EntityId editorNodeId) const
AZ::EntityId MainWindow::FindAssetNodeIdByEditorNodeId([[maybe_unused]] const ScriptCanvasEditor::SourceHandle& assetId
, [[maybe_unused]] AZ::EntityId editorNodeId) const
{
AZ::EntityId sceneEntityId;
AssetTrackerRequestBus::BroadcastResult
( sceneEntityId, &AssetTrackerRequests::GetSceneEntityIdFromEditorEntityId, assetId.Id(), editorNodeId);
AZ::EntityId sceneEntityId{};
// AssetTrackerRequestBus::BroadcastResult
// ( sceneEntityId, &AssetTrackerRequests::GetSceneEntityIdFromEditorEntityId, assetId.Id(), editorNodeId);
// #sc_editor_asset_redux fix logger
return sceneEntityId;
}
@@ -43,11 +43,11 @@
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
#include <ScriptCanvas/Core/ScriptCanvasBus.h>
#include <ScriptCanvas/Debugger/ClientTransceiver.h>
#include <Editor/Assets/ScriptCanvasAssetHolder.h>
#include <Editor/Undo/ScriptCanvasGraphCommand.h>
#include <Editor/Utilities/RecentFiles.h>
#include <Editor/View/Dialogs/SettingsDialog.h>
#include <Editor/View/Widgets/NodePalette/NodePaletteModel.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <Editor/View/Widgets/AssetGraphSceneDataBus.h>
@@ -56,13 +56,9 @@
#if SCRIPTCANVAS_EDITOR
#include <Include/EditorCoreAPI.h>
#endif
#endif//#if SCRIPTCANVAS_EDITOR
#include <Editor/Assets/ScriptCanvasAssetTrackerBus.h>
#include <Editor/Assets/ScriptCanvasAssetTrackerDefinitions.h>
#include <ScriptCanvas/Asset/ScriptCanvasAssetBase.h>
#endif
#endif//#if !defined(Q_MOC_RUN)
namespace GraphCanvas
{
@@ -90,7 +86,6 @@ namespace AzQtComponents
class QDir;
class QFile;
class QProgressDialog;
namespace ScriptCanvas { class ScriptCanvasAssetBase; }
namespace ScriptCanvasEditor
{
@@ -155,7 +150,6 @@ namespace ScriptCanvasEditor
//! Manages the Save/Restore operations of the user's last opened and focused graphs
class Workspace
: AssetTrackerNotificationBus::MultiHandler
{
public:
@@ -174,7 +168,6 @@ namespace ScriptCanvasEditor
private:
void OnAssetReady(const ScriptCanvasMemoryAsset::pointer asset) override;
void SignalAssetComplete(const ScriptCanvasEditor::SourceHandle& fileAssetId);
ScriptCanvasEditor::SourceHandle GetSourceAssetId(const ScriptCanvasEditor::SourceHandle& memoryAssetId) const;
@@ -329,7 +322,6 @@ namespace ScriptCanvasEditor
bool OnFileSaveAs();
bool OnFileSaveCaller(){return OnFileSave();};
bool OnFileSaveAsCaller(){return OnFileSaveAs();};
bool SaveAssetImpl_OLD(const ScriptCanvasEditor::SourceHandle& assetId, const Callbacks::OnSave& saveCB);
enum class Save
{
InPlace,
@@ -438,7 +430,6 @@ namespace ScriptCanvasEditor
AZ::Outcome<int, AZStd::string> CreateScriptCanvasAsset(AZStd::string_view assetPath, int tabIndex = -1);
//! Removes the assetId -> ScriptCanvasAsset mapping and disconnects from the asset tracker
void RemoveScriptCanvasAsset(const ScriptCanvasEditor::SourceHandle& assetId);
void OnChangeActiveGraphTab(ScriptCanvasEditor::SourceHandle) override;
@@ -29,7 +29,6 @@
#include <Editor/Settings.h>
#include <Editor/View/Windows/Tools/UpgradeTool/Controller.h>
#include <Editor/View/Windows/Tools/UpgradeTool/LogTraits.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
#include <ScriptCanvas/Components/EditorGraph.h>
@@ -16,7 +16,6 @@
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/SourceControl/SourceControlAPI.h>
#include <Editor/View/Windows/Tools/UpgradeTool/FileSaver.h>
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
namespace ScriptCanvasEditor
@@ -8,11 +8,10 @@
#include <AzCore/Asset/AssetManagerBus.h>
#include <CryCommon/CrySystemBus.h>
#include <Editor/Assets/ScriptCanvasAssetHelpers.h>
#include <Editor/View/Windows/Tools/UpgradeTool/Model.h>
#include <IConsole.h>
#include <ISystem.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
namespace ModifierCpp
{
@@ -10,7 +10,7 @@
#include <Editor/View/Windows/Tools/UpgradeTool/LogTraits.h>
#include <Editor/View/Windows/Tools/UpgradeTool/Modifier.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
#include <ScriptCanvas/Core/Graph.h>
@@ -6,13 +6,13 @@
*
*/
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserModel.h>
#include <Editor/View/Windows/Tools/UpgradeTool/LogTraits.h>
#include <Editor/View/Windows/Tools/UpgradeTool/Scanner.h>
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
namespace ScannerCpp
@@ -24,7 +24,6 @@
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/SourceControl/SourceControlAPI.h>
#include <Editor/Assets/ScriptCanvasAssetHelpers.h>
#include <Editor/Settings.h>
#include <Editor/View/Windows/Tools/UpgradeTool/ModelTraits.h>
#include <Editor/View/Windows/Tools/UpgradeTool/UpgradeHelper.h>
@@ -529,7 +529,10 @@
<property name="text">
<string>Test Manager</string>
</property>
<property name="shortcut">
<property name="enabled">
<bool>false</bool>
</property>
<property name="shortcut">
<string>Ctrl+Shift+T</string>
</property>
<property name="autoRepeat">
@@ -1,89 +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/std/smart_ptr/enable_shared_from_this.h>
#include <AzCore/Asset/AssetCommon.h>
#include <Editor/Include/ScriptCanvas/Assets/ScriptCanvasAssetBus.h>
#include <Editor/Include/ScriptCanvas/Assets/ScriptCanvasBaseAssetData.h>
#include <ScriptCanvas/Asset/AssetDescription.h>
namespace ScriptCanvas
{
class ScriptCanvasAssetBase
: public AZ::Data::AssetData
, public AZStd::enable_shared_from_this<ScriptCanvasAssetBase>
, ScriptCanvas::ScriptCanvasAssetBusRequestBus::Handler
{
public:
AZ_RTTI(ScriptCanvasAssetBase, "{D07DBDE4-A169-4650-871B-FC75AFEEB03E}", AZ::Data::AssetData);
AZ_CLASS_ALLOCATOR(ScriptCanvasAssetBase, AZ::SystemAllocator, 0);
ScriptCanvasAssetBase(const AZ::Data::AssetId& assetId = AZ::Data::AssetId(AZ::Uuid::CreateRandom()),
AZ::Data::AssetData::AssetStatus status = AZ::Data::AssetData::AssetStatus::NotLoaded)
: AZ::Data::AssetData(assetId, status)
{
ScriptCanvas::ScriptCanvasAssetBusRequestBus::Handler::BusConnect(GetId());
}
virtual ~ScriptCanvasAssetBase()
{
delete m_data;
ScriptCanvas::ScriptCanvasAssetBusRequestBus::Handler::BusDisconnect();
}
template <typename DataType>
DataType* GetScriptCanvasDataAs()
{
return azrtti_cast<DataType*>(m_data);
}
template <typename DataType>
const DataType* GetScriptCanvasDataAs() const
{
return azrtti_cast<DataType*>(m_data);
}
virtual ScriptCanvasData& GetScriptCanvasData()
{
return *m_data;
}
virtual const ScriptCanvasData& GetScriptCanvasData() const
{
return *m_data;
}
AZ::Entity* GetScriptCanvasEntity() const
{
return m_data->m_scriptCanvasEntity.get();
}
virtual void SetScriptCanvasEntity(AZ::Entity* scriptCanvasEntity)
{
if (m_data->m_scriptCanvasEntity.get() != scriptCanvasEntity)
{
m_data->m_scriptCanvasEntity.reset(scriptCanvasEntity);
}
}
virtual ScriptCanvas::AssetDescription GetAssetDescription() const = 0;
protected:
ScriptCanvasData* m_data;
void SetAsNewAsset() override
{
m_status = AZ::Data::AssetData::AssetStatus::Ready;
}
};
}
@@ -13,7 +13,6 @@
#include <AzCore/RTTI/ReflectContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <Editor/Include/ScriptCanvas/Assets/ScriptCanvasBaseAssetData.h>
#include "Attributes.h"
#include "Core.h"
@@ -317,6 +317,24 @@ namespace ScriptCanvasEditor
using GraphPtr = Graph*;
using GraphPtrConst = const Graph*;
class SourceDescription
{
public:
inline static constexpr const char* GetAssetGroup() { return "ScriptCanvas"; }
inline static constexpr const char* GetType() { return "{FA10C3DA-0717-4B72-8944-CD67D13DFA2B}"; }
inline static constexpr const char* GetName() { return "Script Canvas"; }
inline static constexpr const char* GetDescription() { return "Script Canvas Graph File"; }
inline static constexpr const char* GetSuggestedSavePath() { return "@projectroot@/scriptcanvas"; }
inline static constexpr const char* GetFileExtension() { return ".scriptcanvas"; }
inline static constexpr const char* GetGroup() { return "Script Canvas"; }
inline static constexpr const char* GetAssetNamePattern() { return "Untitled-%i"; }
inline static constexpr const char* GetFileFilter() { return "Script Canvas Files (*.scriptcanvas)"; }
inline static constexpr const char* GetAssetTypeDisplayName() { return "Script Canvas"; }
inline static constexpr const char* GetEntityName() { return "Script Canvas"; }
inline static constexpr const char* GetIconPath() { return "Icons/ScriptCanvas/Viewport/ScriptCanvas.png"; }
inline static AZ::Color GetDisplayColor() { return AZ::Color(0.5f, 0.5f, 0.5f, 0.5f); };
};
class SourceHandle
{
public:
@@ -15,26 +15,10 @@ set(FILES
Editor/SystemComponent.h
Editor/SystemComponent.cpp
Editor/QtMetaTypes.h
Editor/Assets/ScriptCanvasAssetTracker.cpp
Editor/Assets/ScriptCanvasAssetTracker.h
Editor/Assets/ScriptCanvasAssetTrackerBus.h
Editor/Assets/ScriptCanvasAssetHelpers.h
Editor/Assets/ScriptCanvasAssetHelpers.cpp
Editor/Assets/ScriptCanvasAssetTrackerDefinitions.h
Editor/Include/ScriptCanvas/Assets/ScriptCanvasBaseAssetData.h
Editor/Include/ScriptCanvas/Assets/ScriptCanvasBaseAssetData.cpp
Editor/Include/ScriptCanvas/Assets/ScriptCanvasAsset.h
Editor/Assets/ScriptCanvasAsset.cpp
Editor/Include/ScriptCanvas/Assets/ScriptCanvasAssetBus.h
Editor/Include/ScriptCanvas/Assets/ScriptCanvasAssetTypes.h
Editor/Include/ScriptCanvas/Assets/ScriptCanvasFileHandling.h
Editor/Include/ScriptCanvas/Assets/ScriptCanvasAssetHandler.h
Editor/Assets/ScriptCanvasFileHandling.cpp
Editor/Assets/ScriptCanvasAssetHandler.cpp
Editor/Assets/ScriptCanvasAssetHolder.h
Editor/Assets/ScriptCanvasAssetHolder.cpp
Editor/Assets/ScriptCanvasMemoryAsset.h
Editor/Assets/ScriptCanvasMemoryAsset.cpp
Editor/Assets/ScriptCanvasUndoHelper.h
Editor/Assets/ScriptCanvasUndoHelper.cpp
Editor/Include/ScriptCanvas/Bus/RequestBus.h
@@ -56,6 +40,8 @@ set(FILES
Editor/Include/ScriptCanvas/Components/EditorGraphVariableManagerComponent.h
Editor/Components/EditorGraphVariableManagerComponent.cpp
Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponent.h
Editor/Include/ScriptCanvas/Components/EditorDeprecationData.h
Editor/Include/ScriptCanvas/Components/EditorDeprecationData.cpp
Editor/Components/EditorScriptCanvasComponent.cpp
Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponentSerializer.h
Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponentSerializer.cpp
@@ -16,8 +16,6 @@ set(FILES
Include/ScriptCanvas/Asset/ExecutionLogAssetBus.h
Include/ScriptCanvas/Asset/RuntimeAsset.h
Include/ScriptCanvas/Asset/RuntimeAssetHandler.h
Include/ScriptCanvas/Asset/ScriptCanvasAssetBase.h
Include/ScriptCanvas/Asset/ScriptCanvasAssetData.h
Include/ScriptCanvas/Asset/SubgraphInterfaceAssetHandler.h
Include/ScriptCanvas/Core/ScriptCanvasBus.h
Include/ScriptCanvas/Core/ExecutionNotificationsBus.h