more aggressively release graph memory in version explorer

Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com>
This commit is contained in:
chcurran
2021-11-18 10:41:46 -08:00
committed by Chris Burel
parent 4342501804
commit 727d1b3815
10 changed files with 80 additions and 91 deletions
@@ -48,7 +48,6 @@ namespace ScriptCanvasBuilder
SharedHandlers HandleAssetTypes()
{
SharedHandlers handlers;
// handlers.m_editorAssetHandler = RegisterHandler<ScriptCanvasEditor::ScriptCanvasAsset, ScriptCanvasEditor::ScriptCanvasAssetHandler>("scriptcanvas", false);
handlers.m_subgraphInterfaceHandler = RegisterHandler<ScriptCanvas::SubgraphInterfaceAsset, ScriptCanvas::SubgraphInterfaceAssetHandler>("scriptcanvas_fn_compiled", true);
handlers.m_runtimeAssetHandler = RegisterHandler<ScriptCanvas::RuntimeAsset, JobDependencyVerificationHandler>("scriptcanvas_compiled", true);
@@ -35,7 +35,6 @@ namespace ScriptCanvasBuilder
{
void Worker::Activate(const AssetHandlers& handlers)
{
m_editorAssetHandler = handlers.m_editorAssetHandler;
m_runtimeAssetHandler = handlers.m_runtimeAssetHandler;
m_subgraphInterfaceHandler = handlers.m_subgraphInterfaceHandler;
}
@@ -255,49 +254,14 @@ namespace ScriptCanvasBuilder
return;
}
if (!m_editorAssetHandler)
{
AZ_Error(s_scriptCanvasBuilder, false, R"(Exporting of .scriptcanvas for "%s" file failed as no editor asset handler was registered for script canvas. The ScriptCanvas Gem might not be enabled.)", fullPath.data());
return;
}
if (!m_runtimeAssetHandler)
{
AZ_Error(s_scriptCanvasBuilder, false, R"(Exporting of .scriptcanvas for "%s" file failed as no runtime asset handler was registered for script canvas.)", fullPath.data());
return;
}
AZStd::shared_ptr<AZ::Data::AssetDataStream> assetDataStream = AZStd::make_shared<AZ::Data::AssetDataStream>();
AZ::IO::FileIOStream stream(fullPath.c_str(), 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.", fullPath.data());
return;
}
// Read the asset into a memory buffer, then hand ownership of the buffer to assetDataStream
{
AZ::IO::FileIOStream ioStream;
if (!ioStream.Open(fullPath.data(), AZ::IO::OpenMode::ModeRead))
{
AZ_Warning(s_scriptCanvasBuilder, false, "CreateJobs for \"%s\" failed because the source file could not be opened.", fullPath.data());
return;
}
AZStd::vector<AZ::u8> fileBuffer(ioStream.GetLength());
size_t bytesRead = ioStream.Read(fileBuffer.size(), fileBuffer.data());
if (bytesRead != ioStream.GetLength())
{
AZ_Warning(s_scriptCanvasBuilder, false, AZStd::string::format("File failed to read completely: %s", fullPath.data()).c_str());
return;
}
assetDataStream->Open(AZStd::move(fileBuffer));
}
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> asset;
asset.Create(request.m_sourceFileUUID);
if (m_editorAssetHandler->LoadAssetDataFromStream(asset, assetDataStream, nullptr) != AZ::Data::AssetHandler::LoadResult::LoadComplete)
auto loadOutcome = ScriptCanvasEditor::LoadFromFile(request.m_fullPath);
if (!loadOutcome.IsSuccess())
{
AZ_Error(s_scriptCanvasBuilder, false, R"(Loading of ScriptCanvas asset for source file "%s" has failed)", fullPath.data());
return;
@@ -310,9 +274,11 @@ namespace ScriptCanvasBuilder
AzFramework::StringFunc::Path::Join(request.m_tempDirPath.c_str(), fileNameOnly.c_str(), runtimeScriptCanvasOutputPath, true, true);
AzFramework::StringFunc::Path::ReplaceExtension(runtimeScriptCanvasOutputPath, ScriptCanvas::RuntimeAsset::GetFileExtension());
auto sourceHandle = loadOutcome.TakeValue();
if (request.m_jobDescription.m_jobKey == s_scriptCanvasProcessJobKey)
{
AZ::Entity* buildEntity = asset.Get()->GetScriptCanvasEntity();
AZ::Entity* buildEntity = sourceHandle.Get()->GetEntity();
ProcessTranslationJobInput input;
input.assetID = AZ::Data::AssetId(request.m_sourceFileUUID, AZ_CRC("RuntimeData", 0x163310ae));
input.request = &request;
@@ -62,6 +62,7 @@ namespace ScriptCanvasBuilder
ForceBuildForDevTest0,
ForceBuildForDevTest1,
ForceBuildForDevTest2,
// add new entries above
Current,
@@ -73,7 +74,6 @@ namespace ScriptCanvasBuilder
struct AssetHandlers
{
AZ::Data::AssetHandler* m_editorAssetHandler = nullptr;
AZ::Data::AssetHandler* m_editorFunctionAssetHandler = nullptr;
AZ::Data::AssetHandler* m_runtimeAssetHandler = nullptr;
AZ::Data::AssetHandler* m_subgraphInterfaceHandler = nullptr;
@@ -84,7 +84,6 @@ namespace ScriptCanvasBuilder
struct SharedHandlers
{
HandlerOwnership m_editorAssetHandler{};
HandlerOwnership m_editorFunctionAssetHandler{};
HandlerOwnership m_runtimeAssetHandler{};
HandlerOwnership m_subgraphInterfaceHandler{};
@@ -173,7 +172,6 @@ namespace ScriptCanvasBuilder
void ShutDown() override {};
private:
AZ::Data::AssetHandler* m_editorAssetHandler = nullptr;
AZ::Data::AssetHandler* m_runtimeAssetHandler = nullptr;
AZ::Data::AssetHandler* m_subgraphInterfaceHandler = nullptr;
@@ -34,15 +34,13 @@
namespace ScriptCanvasBuilder
{
AssetHandlers::AssetHandlers(SharedHandlers& source)
: m_editorAssetHandler(source.m_editorAssetHandler.first)
, m_editorFunctionAssetHandler(source.m_editorFunctionAssetHandler.first)
: m_editorFunctionAssetHandler(source.m_editorFunctionAssetHandler.first)
, m_runtimeAssetHandler(source.m_runtimeAssetHandler.first)
, m_subgraphInterfaceHandler(source.m_subgraphInterfaceHandler.first)
{}
void SharedHandlers::DeleteOwnedHandlers()
{
DeleteIfOwned(m_editorAssetHandler);
DeleteIfOwned(m_editorFunctionAssetHandler);
DeleteIfOwned(m_runtimeAssetHandler);
DeleteIfOwned(m_subgraphInterfaceHandler);
@@ -32,13 +32,6 @@ namespace ScriptCanvasEditor
AZ::SystemTickBus::Handler::BusConnect();
}
const SourceHandle& Modifier::GetCurrentAsset() const
{
return m_state == State::GatheringDependencies
? m_assets[m_assetIndex]
: m_assets[m_dependencyOrderedAssetIndicies[m_assetIndex]];
}
AZStd::unordered_set<size_t>& Modifier::GetOrCreateDependencyIndexSet()
{
auto iter = m_dependencies.find(m_assetIndex);
@@ -101,36 +94,40 @@ namespace ScriptCanvasEditor
{
anyFailures = true;
VE_LOG("Modifier: ERROR - Failed to gather dependencies from graph data: %s"
, GetCurrentAsset().Path().c_str())
, ModCurrentAsset().Path().c_str())
}
}
else
{
anyFailures = true;
VE_LOG("Modifier: ERROR - Failed to load asset %s for modification, even though it scanned properly"
, GetCurrentAsset().Path().c_str());
, ModCurrentAsset().Path().c_str());
}
ModelNotificationsBus::Broadcast
( &ModelNotificationsTraits::OnUpgradeDependenciesGathered
, GetCurrentAsset()
, ModCurrentAsset()
, anyFailures ? Result::Failure : Result::Success);
ReleaseCurrentAsset();
// Flush asset database events to ensure no asset references are held by closures queued on Ebuses.
AZ::Data::AssetManager::Instance().DispatchEvents();
}
SourceHandle Modifier::LoadAsset()
{
auto outcome = LoadFromFile(GetCurrentAsset().Path().c_str());
if (outcome.IsSuccess())
auto& handle = ModCurrentAsset();
if (!handle.IsValid())
{
return outcome.TakeValue();
}
else
{
return {};
auto outcome = LoadFromFile(handle.Path().c_str());
if (outcome.IsSuccess())
{
handle = outcome.TakeValue();
}
}
return handle;
}
void Modifier::ModificationComplete(const ModificationResult& result)
@@ -147,12 +144,19 @@ namespace ScriptCanvasEditor
}
}
SourceHandle& Modifier::ModCurrentAsset()
{
return m_state == State::GatheringDependencies
? m_assets[m_assetIndex]
: m_assets[m_dependencyOrderedAssetIndicies[m_assetIndex]];
}
void Modifier::ModifyCurrentAsset()
{
m_result = {};
m_result.asset = GetCurrentAsset();
m_result.asset = ModCurrentAsset();
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnUpgradeModificationBegin, m_config, GetCurrentAsset());
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnUpgradeModificationBegin, m_config, ModCurrentAsset());
if (auto asset = LoadAsset(); asset.IsValid())
{
@@ -169,13 +173,19 @@ namespace ScriptCanvasEditor
void Modifier::ModifyNextAsset()
{
ModelNotificationsBus::Broadcast
( &ModelNotificationsTraits::OnUpgradeModificationEnd, m_config, GetCurrentAsset(), m_result);
( &ModelNotificationsTraits::OnUpgradeModificationEnd, m_config, ModCurrentAsset(), m_result);
ModificationNotificationsBus::Handler::BusDisconnect();
m_modifyState = ModifyState::Idle;
ReleaseCurrentAsset();
++m_assetIndex;
m_result = {};
}
void Modifier::ReleaseCurrentAsset()
{
ModCurrentAsset() = ModCurrentAsset().Describe();
}
void Modifier::ReportModificationError(AZStd::string_view report)
{
m_result.asset = {};
@@ -286,7 +296,7 @@ namespace ScriptCanvasEditor
m_dependencyOrderedAssetIndicies.push_back(index);
}
// go straight into ModifyinGraphs
// go straight into ModifyingGraphs
m_assetIndex = m_assets.size();
}
}
@@ -309,6 +319,7 @@ namespace ScriptCanvasEditor
else
{
GatherDependencies();
ReleaseCurrentAsset();
++m_assetIndex;
}
}
@@ -370,7 +381,7 @@ namespace ScriptCanvasEditor
(ScriptCanvas::k_VersionExplorerWindow.data()
, false
, "Modifier: Dependency sort has failed during, circular dependency detected for Asset: %s"
, modifier->GetCurrentAsset().Path().c_str());
, modifier->ModCurrentAsset().Path().c_str());
return;
}
@@ -83,12 +83,13 @@ namespace ScriptCanvasEditor
FileSaveResult m_fileSaveResult;
void GatherDependencies();
const SourceHandle& GetCurrentAsset() const;
AZStd::unordered_set<size_t>& GetOrCreateDependencyIndexSet();
SourceHandle LoadAsset();
SourceHandle& ModCurrentAsset();
void ModifyCurrentAsset();
void ModifyNextAsset();
void ModificationComplete(const ModificationResult& result) override;
void ReleaseCurrentAsset();
void ReportModificationError(AZStd::string_view report);
void ReportModificationSuccess();
void ReportSaveResult();
@@ -32,8 +32,12 @@ namespace ScannerCpp
&& entry->GetFullPath().ends_with(".scriptcanvas"))
{
auto sourceEntry = azrtti_cast<const AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry*>(entry);
AZStd::string fullPath = sourceEntry->GetFullPath();
AzFramework::StringFunc::Path::Normalize(fullPath);
result.m_catalogAssets.push_back(
ScriptCanvasEditor::SourceHandle(nullptr, sourceEntry->GetSourceUuid(), sourceEntry->GetFullPath()));
ScriptCanvasEditor::SourceHandle(nullptr, sourceEntry->GetSourceUuid(), fullPath));
}
const int rowCount = model.rowCount(index);
@@ -79,23 +83,18 @@ namespace ScriptCanvasEditor
{
if (m_config.filter && m_config.filter(asset) == ScanConfiguration::Filter::Exclude)
{
VE_LOG("Scanner: Excluded: %s ", GetCurrentAsset().Path().c_str());
m_result.m_filteredAssets.push_back(GetCurrentAsset().Describe());
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnScanFilteredGraph, GetCurrentAsset());
VE_LOG("Scanner: Excluded: %s ", ModCurrentAsset().Path().c_str());
m_result.m_filteredAssets.push_back(ModCurrentAsset().Describe());
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnScanFilteredGraph, ModCurrentAsset());
}
else
{
VE_LOG("Scanner: Included: %s ", GetCurrentAsset().Path().c_str());
m_result.m_unfiltered.push_back(GetCurrentAsset().Describe());
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnScanUnFilteredGraph, GetCurrentAsset());
VE_LOG("Scanner: Included: %s ", ModCurrentAsset().Path().c_str());
m_result.m_unfiltered.push_back(ModCurrentAsset().Describe());
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnScanUnFilteredGraph, ModCurrentAsset());
}
}
const SourceHandle& Scanner::GetCurrentAsset() const
{
return m_result.m_catalogAssets[m_catalogAssetIndex];
}
const ScanResult& Scanner::GetResult() const
{
return m_result;
@@ -103,7 +102,7 @@ namespace ScriptCanvasEditor
SourceHandle Scanner::LoadAsset()
{
auto fileOutcome = LoadFromFile(GetCurrentAsset().Path().c_str());
auto fileOutcome = LoadFromFile(ModCurrentAsset().Path().c_str());
if (fileOutcome.IsSuccess())
{
return fileOutcome.GetValue();
@@ -114,6 +113,11 @@ namespace ScriptCanvasEditor
}
}
SourceHandle& Scanner::ModCurrentAsset()
{
return m_result.m_catalogAssets[m_catalogAssetIndex];
}
void Scanner::OnSystemTick()
{
if (m_catalogAssetIndex == m_result.m_catalogAssets.size())
@@ -130,17 +134,17 @@ namespace ScriptCanvasEditor
{
if (auto asset = LoadAsset(); asset.IsValid())
{
VE_LOG("Scanner: Loaded: %s ", GetCurrentAsset().Path().c_str());
VE_LOG("Scanner: Loaded: %s ", ModCurrentAsset().Path().c_str());
FilterAsset(asset);
}
else
{
VE_LOG("Scanner: Failed to load: %s ", GetCurrentAsset().Path().c_str());
m_result.m_loadErrors.push_back(GetCurrentAsset());
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnScanLoadFailure, GetCurrentAsset());
VE_LOG("Scanner: Failed to load: %s ", ModCurrentAsset().Path().c_str());
m_result.m_loadErrors.push_back(ModCurrentAsset().Describe());
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnScanLoadFailure, ModCurrentAsset());
}
VE_LOG("Scanner: scan of %s complete", GetCurrentAsset().Path().c_str());
VE_LOG("Scanner: scan of %s complete", ModCurrentAsset().Path().c_str());
++m_catalogAssetIndex;
}
}
@@ -34,8 +34,8 @@ namespace ScriptCanvasEditor
ScanResult m_result;
void FilterAsset(SourceHandle);
const SourceHandle& GetCurrentAsset() const;
SourceHandle LoadAsset();
SourceHandle& ModCurrentAsset();
void OnSystemTick() override;
};
}
@@ -27,7 +27,7 @@
#define OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED
#define EDITOR_ASSET_SUPPORT_ENABLED
// #define EDITOR_ASSET_SUPPORT_ENABLED
namespace AZ
{
@@ -52,6 +52,7 @@ namespace GraphCpp
VariablePanelSymantics,
AddVersionData,
RemoveFunctionGraphMarker,
FixupVersionDataTypeId,
// label your version above
Current
};
@@ -71,13 +72,24 @@ namespace ScriptCanvas
componentElementNode.AddElementWithData(context, "m_assetType", azrtti_typeid<RuntimeAsset>());
}
if (componentElementNode.GetVersion() < GraphCpp::GraphVersion::RemoveFunctionGraphMarker)
if (componentElementNode.GetVersion() <= GraphCpp::GraphVersion::RemoveFunctionGraphMarker)
{
componentElementNode.RemoveElementByName(AZ_CRC_CE("isFunctionGraph"));
}
if (componentElementNode.GetVersion() < GraphCpp::GraphVersion::FixupVersionDataTypeId)
{
if (auto subElement = componentElementNode.FindSubElement(AZ_CRC_CE("versionData")))
{
if (subElement->GetId() == azrtti_typeid<SlotId>())
{
componentElementNode.RemoveElementByName(AZ_CRC_CE("versionData"));
}
}
}
return true;
}
}s
Graph::Graph(const ScriptCanvasId& scriptCanvasId)
: m_scriptCanvasId(scriptCanvasId)