source save asset-free WIP

Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com>
This commit is contained in:
chcurran
2021-11-08 10:00:45 -08:00
committed by Chris Burel
parent d40b9fc809
commit 1ea245e46c
9 changed files with 269 additions and 150 deletions
@@ -186,6 +186,7 @@ namespace ScriptCanvasEditor
, 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;
@@ -139,4 +139,64 @@ namespace ScriptCanvasEditor
return AZ::Success(ScriptCanvasEditor::SourceHandle(scriptCanvasData, {}, path));
}
AZ::Outcome<void, AZStd::string> SaveToStream(const SourceHandle& source, AZ::IO::GenericStream& stream)
{
namespace JSRU = AZ::JsonSerializationUtils;
if (!source)
{
return AZ::Failure(AZStd::string("no source graph to save"));
}
if (source.Path().empty())
{
return AZ::Failure(AZStd::string("no destination path specified"));
}
AZ::SerializeContext* serializeContext = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext);
if (!serializeContext)
{
return AZ::Failure(AZStd::string("no serialize context available to properly save source file"));
}
auto graphData = source.Get()->GetOwnership();
if (!graphData)
{
return AZ::Failure(AZStd::string("source is missing save container"));
}
if (graphData->GetEditorGraph() != source.Get())
{
return AZ::Failure(AZStd::string("source save container refers to incorrect graph"));
}
auto saveTarget = graphData->ModGraph();
if (saveTarget || !saveTarget->GetGraphData())
{
return AZ::Failure(AZStd::string("source save container failed to return graph data"));
}
AZ::JsonSerializerSettings settings;
settings.m_metadata.Create<ScriptCanvas::SerializationListeners>();
auto listeners = settings.m_metadata.Find<ScriptCanvas::SerializationListeners>();
AZ_Assert(listeners, "Failed to create SerializationListeners");
ScriptCanvasFileHandlingCpp::CollectNodes(saveTarget->GetGraphData()->m_nodes, *listeners);
settings.m_keepDefaults = false;
settings.m_serializeContext = serializeContext;
for (auto listener : *listeners)
{
listener->OnSerialize();
}
auto saveOutcome = JSRU::SaveObjectToStream<ScriptCanvas::ScriptCanvasData>(graphData.get(), stream, nullptr, &settings);
if (!saveOutcome.IsSuccess())
{
return AZ::Failure(AZStd::string("JSON serialization failed to save source: %s", saveOutcome.GetError().c_str()));
}
return AZ::Success();
}
}
@@ -1067,6 +1067,11 @@ namespace ScriptCanvasEditor
m_owner = &owner;
}
ScriptCanvas::DataPtr Graph::GetOwnership() const
{
return ScriptCanvas::DataPtr(const_cast<Graph*>(this)->m_owner);
}
bool Graph::CreateConnection(const GraphCanvas::ConnectionId& connectionId, const GraphCanvas::Endpoint& sourcePoint, const GraphCanvas::Endpoint& targetPoint)
{
if (!sourcePoint.IsValid() || !targetPoint.IsValid())
@@ -26,10 +26,12 @@ namespace ScriptCanvas
namespace ScriptCanvasEditor
{
AZ::Outcome<ScriptCanvasEditor::SourceHandle, AZStd::string> LoadFromFile(AZStd::string_view path);
AZ::Outcome<SourceHandle, AZStd::string> LoadFromFile(AZStd::string_view path);
AZ::Outcome<void, AZStd::string> LoadDataFromJson
( ScriptCanvas::ScriptCanvasData& dataTarget
, AZStd::string_view source
, AZ::SerializeContext& serializeContext);
}
AZ::Outcome<void, AZStd::string> SaveToStream(const SourceHandle& source, AZ::IO::GenericStream& stream);
}
@@ -309,6 +309,7 @@ namespace ScriptCanvasEditor
const GraphStatisticsHelper& GetNodeUsageStatistics() const;
void MarkOwnership(ScriptCanvas::ScriptCanvasData& owner);
ScriptCanvas::DataPtr GetOwnership() const;
// Finds and returns all nodes within the graph that are of the specified type
template <typename NodeType>
@@ -393,6 +394,7 @@ namespace ScriptCanvasEditor
bool m_saveFormatConverted = true;
ScriptCanvasEditor::SourceHandle m_assetId;
// #sc_editor_asset temporary step in cleaning up the graph / asset class structure. This reference is deliberately weak.
ScriptCanvas::ScriptCanvasData* m_owner;
};
}
@@ -1723,17 +1723,18 @@ namespace ScriptCanvasEditor
// return AZ::Success(outTabIndex);
}
bool MainWindow::OnFileSave(const Callbacks::OnSave& saveCB)
bool MainWindow::OnFileSave()
{
return SaveAssetAsImpl(m_activeGraph, saveCB);
return SaveAssetImpl(m_activeGraph, Save::InPlace);
}
bool MainWindow::OnFileSaveAs(const Callbacks::OnSave& saveCB)
bool MainWindow::OnFileSaveAs()
{
return SaveAssetAsImpl(m_activeGraph, saveCB);
return SaveAssetImpl(m_activeGraph, Save::As);
}
bool MainWindow::SaveAssetImpl(const ScriptCanvasEditor::SourceHandle& assetId, const Callbacks::OnSave& saveCB)
/*
bool MainWindow::SaveAssetImpl_OLD(const ScriptCanvasEditor::SourceHandle& assetId, const Callbacks::OnSave& saveCB)
{
if (!assetId.IsValid())
{
@@ -1748,7 +1749,7 @@ namespace ScriptCanvasEditor
if (fileState == Tracker::ScriptCanvasFileState::NEW)
{
saveSuccessful = SaveAssetAsImpl(assetId, saveCB);
saveSuccessful = SaveAssetImpl(assetId, saveCB);
}
else if (fileState == Tracker::ScriptCanvasFileState::MODIFIED
|| fileState == Tracker::ScriptCanvasFileState::SOURCE_REMOVED)
@@ -1759,8 +1760,16 @@ namespace ScriptCanvasEditor
return saveSuccessful;
}
*/
bool MainWindow::SaveAssetAsImpl(const ScriptCanvasEditor::SourceHandle& inMemoryAssetId, const Callbacks::OnSave& saveCB)
// 1. SaveAssetImpl
// 2. SaveAs
// // 3. OnSaveCallback
// SaveAsEnd
// SaveAssetImpl end
bool MainWindow::SaveAssetImpl(const ScriptCanvasEditor::SourceHandle& inMemoryAssetId, Save /*save*/)
{
if (!inMemoryAssetId.IsValid())
{
@@ -1803,11 +1812,12 @@ namespace ScriptCanvasEditor
AZ::IO::FileIOBase::GetInstance()->ResolvePath("@engroot@", assetRootChar.data(), assetRootChar.size());
assetRoot = assetRootChar.data();
/* if (!AZ::StringFunc::StartsWith(filePath, assetRoot))
{
QMessageBox::information(this, "Unable to Save", AZStd::string::format("You must select a path within the current project\n\n%s", assetRoot.c_str()).c_str());
}
else*/ if (AzFramework::StringFunc::Path::GetFileName(filePath.c_str(), fileName))
// if (!AZ::StringFunc::StartsWith(filePath, assetRoot))
// {
// QMessageBox::information(this, "Unable to Save", AZStd::string::format("You must select a path within the current project\n\n%s", assetRoot.c_str()).c_str());
// }
// else
if (AzFramework::StringFunc::Path::GetFileName(filePath.c_str(), fileName))
{
isValidFileName = !(fileName.empty());
}
@@ -1833,7 +1843,7 @@ namespace ScriptCanvasEditor
return false;
}
SaveAs(internalStringFile, inMemoryAssetId, saveCB);
SaveAs(internalStringFile, inMemoryAssetId);
m_newlySavedFile = internalStringFile;
@@ -1842,103 +1852,95 @@ namespace ScriptCanvasEditor
return true;
}
return false;
}
void MainWindow::OnSaveCallback(bool /*saveSuccess*/, AZ::Data::AssetPtr /*fileAsset*/, ScriptCanvasEditor::SourceHandle /*previousFileAssetId*/)
void MainWindow::OnSaveCallback(bool saveSuccess, ScriptCanvasEditor::SourceHandle memoryAsset)
{
// #sc_editor_asset yikes...just save the thing...move to ::SaveAsset maybe
/*
ScriptCanvasMemoryAsset::pointer memoryAsset;
AZStd::string tabName = m_tabBar->tabText(m_tabBar->currentIndex()).toUtf8().data();
int saveTabIndex = m_tabBar->currentIndex();
int saveTabIndex = m_tabBar->FindTab(memoryAsset);
AZStd::string tabName = saveTabIndex >= 0 ? m_tabBar->tabText(saveTabIndex).toUtf8().data() : "";
if (saveSuccess)
{
AssetTrackerRequestBus::BroadcastResult(memoryAsset, &AssetTrackerRequests::GetAsset, fileAsset->GetId());
AZ_Assert(memoryAsset, "At this point we must have a MemoryAsset");
// #sc_editor_asset find a tab with the same path name and close non focused old ones with the same name
// Update the editor with the new information about this asset.
const ScriptCanvasEditor::SourceHandle& fileAssetId = memoryAsset->GetFileAssetId();
saveTabIndex = m_tabBar->FindTab(fileAssetId);
const ScriptCanvasEditor::SourceHandle& fileAssetId = memoryAsset;
// We've saved as over a new graph, so we need to close the old one.
if (saveTabIndex != m_tabBar->currentIndex())
{
// Invalidate the file asset id so we don't delete trigger the asset flow.
m_tabBar->setTabData(saveTabIndex, QVariant::fromValue(GraphTabMetaData));
m_tabBar->setTabData(saveTabIndex, QVariant::fromValue(Widget::GraphTabMetadata()));
m_tabBar->CloseTab(saveTabIndex);
saveTabIndex = -1;
}
// #sc_editor_asset clean up these actions as well, save and close, save as and close, just save, etc
if (saveTabIndex < 0)
{
// This asset had not been saved yet, we will need to use the in memory asset Id to get the index.
saveTabIndex = m_tabBar->FindTab(memoryAsset->GetId());
// saveTabIndex = m_tabBar->FindTab(memoryAsset->GetId());
if (saveTabIndex < 0)
{
// Finally, we may have Saved-As and we need the previous file asset Id to find the tab
saveTabIndex = m_tabBar->FindTab(previousFileAssetId);
//saveTabIndex = m_tabBar->FindTab(previousFileAssetId);
}
}
AzFramework::StringFunc::Path::GetFileName(memoryAsset->GetAbsolutePath().c_str(), tabName);
AzFramework::StringFunc::Path::GetFileName(memoryAsset.Path().c_str(), tabName);
// Update the tab's assetId to the file asset Id (necessary when saving a new asset)
// used to be configure tab...sets the name and file state
m_tabBar->ConfigureTab(saveTabIndex, fileAssetId, tabName);
// #sc_editor_asset used to be configure tab...sets the name and file state
// m_tabBar->ConfigureTab(saveTabIndex, fileAssetId, tabName);
GeneralAssetNotificationBus::Event(memoryAsset->GetId(), &GeneralAssetNotifications::OnAssetVisualized);
auto requestorIter = m_assetCreationRequests.find(fileAsset->GetId());
if (requestorIter != m_assetCreationRequests.end())
{
auto editorComponents = AZ::EntityUtils::FindDerivedComponents<EditorScriptCanvasComponent>(requestorIter->second.first);
if (editorComponents.empty())
{
auto firstRequestBus = EditorScriptCanvasComponentRequestBus::FindFirstHandler(requestorIter->second.first);
if (firstRequestBus)
{
firstRequestBus->SetAssetId(fileAsset->GetId());
}
}
else
{
for (auto editorComponent : editorComponents)
{
if (editorComponent->GetId() == requestorIter->second.second)
{
editorComponent->SetAssetId(fileAsset->GetId());
break;
}
}
}
m_assetCreationRequests.erase(requestorIter);
}
// GeneralAssetNotificationBus::Event(memoryAsset, &GeneralAssetNotifications::OnAssetVisualized);
//
// auto requestorIter = m_assetCreationRequests.find(fileAsset->GetId());
//
// if (requestorIter != m_assetCreationRequests.end())
// {
// auto editorComponents = AZ::EntityUtils::FindDerivedComponents<EditorScriptCanvasComponent>(requestorIter->second.first);
//
// if (editorComponents.empty())
// {
// auto firstRequestBus = EditorScriptCanvasComponentRequestBus::FindFirstHandler(requestorIter->second.first);
//
// if (firstRequestBus)
// {
// firstRequestBus->SetAssetId(fileAsset->GetId());
// }
// }
// else
// {
// for (auto editorComponent : editorComponents)
// {
// if (editorComponent->GetId() == requestorIter->second.second)
// {
// editorComponent->SetAssetId(fileAsset->GetId());
// break;
// }
// }
// }
//
// m_assetCreationRequests.erase(requestorIter);
// }
// Soft switch the asset id here. We'll do a double scene switch down below to actually switch the active assetid
m_activeGraph = fileAssetId;
}
else
{
// #sc_editor_asset this seems to remove the unsaved indicator even on failure
// Use the previous memory asset to find what we had setup as our display
AssetTrackerRequestBus::BroadcastResult(memoryAsset, &AssetTrackerRequests::GetAsset, m_activeGraph);
// AssetTrackerRequestBus::BroadcastResult(memoryAsset, &AssetTrackerRequests::GetAsset, m_activeGraph);
// Drop off our file modifier status for our display name when we fail to save.
if (tabName.at(tabName.size() -1) == '*')
{
tabName = tabName.substr(0, tabName.size() - 2);
}
// if (tabName.at(tabName.size() -1) == '*')
// {
// tabName = tabName.substr(0, tabName.size() - 2);
// }
}
if (m_tabBar->currentIndex() != saveTabIndex)
@@ -1961,7 +1963,7 @@ namespace ScriptCanvasEditor
const bool displayAsNotification = true;
RunGraphValidation(displayAsNotification);
// This is called during saving, so the is scaving flag is always true Need to update the state after this callback is complete. So schedule for next system tick.
// This is called during saving, so the is saving flag is always true Need to update the state after this callback is complete. So schedule for next system tick.
AddSystemTickAction(SystemTickActionFlag::UpdateSaveMenuState);
if (m_closeCurrentGraphAfterSave)
@@ -1974,69 +1976,27 @@ namespace ScriptCanvasEditor
EnableAssetView(memoryAsset);
UnblockCloseRequests();
*/
}
bool MainWindow::ActivateAndSaveAsset(const ScriptCanvasEditor::SourceHandle& unsavedAssetId, const Callbacks::OnSave& saveCB)
bool MainWindow::ActivateAndSaveAsset(const ScriptCanvasEditor::SourceHandle& unsavedAssetId)
{
SetActiveAsset(unsavedAssetId);
return OnFileSave(saveCB);
return OnFileSave();
}
void MainWindow::SaveAs(AZStd::string_view /*path*/, ScriptCanvasEditor::SourceHandle /*inMemoryAssetId*/, const Callbacks::OnSave& /*onSave*/)
void MainWindow::SaveAs(AZStd::string_view path, ScriptCanvasEditor::SourceHandle inMemoryAssetId)
{
/*
PrepareAssetForSave(inMemoryAssetId);
AZ_TracePrintf("ScriptCanvas", "Saving %s to %.*s", inMemoryAssetId.Path().c_str(), path.data());
// #sc_editor_asset maybe delete this
DisableAssetView(inMemoryAssetId);
ScriptCanvasMemoryAsset::pointer memoryAsset;
AssetTrackerRequestBus::BroadcastResult(memoryAsset, &AssetTrackerRequests::GetAsset, inMemoryAssetId);
// use the file saver, make new version that works on source handle and not asset
// then...connect the failed and succeed versions
// to OnSaveCallBack
// Disable the current view if we are saving.
if (memoryAsset)
{
DisableAssetView(memoryAsset);
}
auto onSaveCallback = [this, onSave](bool saveSuccess, AZ::Data::AssetPtr asset, ScriptCanvasEditor::SourceHandle previousAssetId)
{
OnSaveCallback(saveSuccess, asset, previousAssetId);
if (onSave)
{
AZStd::invoke(onSave, saveSuccess, asset, previousAssetId);
}
};
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); }
);
}
UpdateSaveState();
BlockCloseRequests();
*/
UpdateSaveState();
BlockCloseRequests();
}
void MainWindow::OnFileOpen()
@@ -2802,7 +2762,7 @@ namespace ScriptCanvasEditor
//
// if (fileState == Tracker::ScriptCanvasFileState::NEW)
// {
// SaveAssetAsImpl(fileAssetId, saveCB);
// SaveAssetImpl(fileAssetId, saveCB);
// }
// else
// {
@@ -2822,7 +2782,7 @@ namespace ScriptCanvasEditor
if (tabdata.isValid())
{
auto assetId = tabdata.value<Widget::GraphTabMetadata>();
SaveAssetAsImpl(assetId.m_assetId, nullptr);
SaveAssetImpl(assetId.m_assetId, Save::InPlace);
}
}
@@ -4761,11 +4721,11 @@ namespace ScriptCanvasEditor
//connect(m_unitTestDockWidget, &QDockWidget::visibilityChanged, this, &MainWindow::OnViewVisibilityChanged);
}
void MainWindow::DisableAssetView(ScriptCanvasMemoryAsset::pointer memoryAsset)
void MainWindow::DisableAssetView(const ScriptCanvasEditor::SourceHandle& memoryAssetId)
{
if (memoryAsset->GetView())
if (auto view = m_tabBar->ModTabView(m_tabBar->FindTab(memoryAssetId)))
{
memoryAsset->GetView()->DisableView();
view->DisableView();
}
m_tabBar->setEnabled(false);
@@ -4785,11 +4745,11 @@ namespace ScriptCanvasEditor
m_autoSaveTimer.stop();
}
void MainWindow::EnableAssetView(ScriptCanvasMemoryAsset::pointer memoryAsset)
void MainWindow::EnableAssetView(const ScriptCanvasEditor::SourceHandle& memoryAssetId)
{
if (memoryAsset->GetView())
if (auto view = m_tabBar->ModTabView(m_tabBar->FindTab(memoryAssetId)))
{
memoryAsset->GetView()->EnableView();
view->EnableView();
}
m_tabBar->setEnabled(true);
@@ -325,12 +325,17 @@ namespace ScriptCanvasEditor
// File menu
void OnFileNew();
bool OnFileSave(const Callbacks::OnSave& saveCB);
bool OnFileSaveAs(const Callbacks::OnSave& saveCB);
bool OnFileSaveCaller(){return OnFileSave(nullptr);};
bool OnFileSaveAsCaller(){return OnFileSaveAs(nullptr);};
bool SaveAssetImpl(const ScriptCanvasEditor::SourceHandle& assetId, const Callbacks::OnSave& saveCB);
bool SaveAssetAsImpl(const ScriptCanvasEditor::SourceHandle& assetId, const Callbacks::OnSave& saveCB);
bool OnFileSave();
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,
As
};
bool SaveAssetImpl(const ScriptCanvasEditor::SourceHandle& assetId, Save save);
void OnFileOpen();
// Edit menu
@@ -554,9 +559,9 @@ namespace ScriptCanvasEditor
void closeEvent(QCloseEvent *event) override;
UnsavedChangesOptions ShowSaveDialog(const QString& filename);
bool ActivateAndSaveAsset(const ScriptCanvasEditor::SourceHandle& unsavedAssetId, const Callbacks::OnSave& onSave);
bool ActivateAndSaveAsset(const ScriptCanvasEditor::SourceHandle& unsavedAssetId);
void SaveAs(AZStd::string_view path, ScriptCanvasEditor::SourceHandle assetId, const Callbacks::OnSave& onSave);
void SaveAs(AZStd::string_view path, ScriptCanvasEditor::SourceHandle assetId);
void OpenFile(const char* fullPath);
void CreateMenus();
@@ -667,8 +672,8 @@ namespace ScriptCanvasEditor
}
}
void DisableAssetView(ScriptCanvasMemoryAsset::pointer memoryAsset);
void EnableAssetView(ScriptCanvasMemoryAsset::pointer memoryAsset);
void DisableAssetView(const ScriptCanvasEditor::SourceHandle& memoryAssetId);
void EnableAssetView(const ScriptCanvasEditor::SourceHandle& memoryAssetId);
QWidget* m_host = nullptr;
@@ -783,6 +788,6 @@ namespace ScriptCanvasEditor
//! this object manages the Save/Restore operations
Workspace* m_workspace;
void OnSaveCallback(bool saveSuccess, AZ::Data::AssetPtr, ScriptCanvasEditor::SourceHandle previousFileAssetId);
void OnSaveCallback(bool saveSuccess, ScriptCanvasEditor::SourceHandle previousFileAssetId);
};
}
@@ -186,12 +186,73 @@ namespace ScriptCanvasEditor
});
}
void FileSaver::OnSourceFileReleased(const SourceHandle& source)
{
AZStd::string tmpFileName;
// here we are saving the graph to a temp file instead of the original file and then copying the temp file to the original file.
// This ensures that AP will not a get a file change notification on an incomplete graph file causing it to fail processing. Temp files are ignored by AP.
if (!AZ::IO::CreateTempFileName(source.Path().c_str(), tmpFileName))
{
FileSaveResult result;
result.fileSaveError = "Failure to create temporary file name";
m_onComplete(result);
return;
}
bool tempSavedSucceeded = false;
AZ::IO::FileIOStream fileStream(tmpFileName.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText);
if (fileStream.IsOpen())
{
if (asset.GetType() == azrtti_typeid<ScriptCanvasEditor::ScriptCanvasAsset>())
{
ScriptCanvasEditor::ScriptCanvasAssetHandler handler;
tempSavedSucceeded = handler.SaveAssetData(asset, &fileStream);
}
fileStream.Close();
}
if (!tempSavedSucceeded)
{
FileSaveResult result;
result.fileSaveError = "Save asset data to temporary file failed";
m_onComplete(result);
return;
}
AzToolsFramework::SourceControlCommandBus::Broadcast
( &AzToolsFramework::SourceControlCommandBus::Events::RequestEdit
, fullPath.c_str()
, true
, [this, fullPath, tmpFileName]([[maybe_unused]] bool success, const AzToolsFramework::SourceControlFileInfo& info)
{
constexpr const size_t k_maxAttemps = 10;
if (!info.IsReadOnly())
{
PerformMove(tmpFileName, fullPath, k_maxAttemps);
}
else if (m_onReadOnlyFile && m_onReadOnlyFile())
{
AZ::IO::SystemFile::SetWritable(info.m_filePath.c_str(), true);
PerformMove(tmpFileName, fullPath, k_maxAttemps);
}
else
{
FileSaveResult result;
result.fileSaveError = "Source file was and remained read-only";
result.tempFileRemovalError = RemoveTempFile(tmpFileName);
m_onComplete(result);
}
});
}
AZStd::string FileSaver::RemoveTempFile(AZStd::string_view tempFile)
{
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
if (!fileIO)
{
return "GraphUpgradeComplete: No FileIO instance";
return "No FileIO instance";
}
if (fileIO->Exists(tempFile.data()) && !fileIO->Remove(tempFile.data()))
@@ -202,13 +263,34 @@ namespace ScriptCanvasEditor
return "";
}
void FileSaver::Save(const SourceHandle& source)
{
if (source.Path().empty())
{
FileSaveResult result;
result.fileSaveError = "No save location specified";
m_onComplete(result);
}
else
{
auto streamer = AZ::Interface<AZ::IO::IStreamer>::Get();
AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(source.Path());
streamer->SetRequestCompleteCallback(flushRequest, [this, source]([[maybe_unused]] AZ::IO::FileRequestHandle request)
{
this->OnSourceFileReleased(source);
});
streamer->QueueRequest(flushRequest);
}
}
void FileSaver::Save(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
// #sc_editor_asset fix this path from the version explorer
AZStd::string relativePath, fullPath;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(relativePath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, asset.GetId());
bool fullPathFound = false;
AzToolsFramework::AssetSystemRequestBus::BroadcastResult
(fullPathFound
( fullPathFound
, &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath
, relativePath, fullPath);
@@ -30,11 +30,13 @@ namespace ScriptCanvasEditor
, AZStd::function<void(const FileSaveResult& result)> onComplete);
void Save(AZ::Data::Asset<AZ::Data::AssetData> asset);
void Save(const SourceHandle& source);
private:
AZStd::function<void(const FileSaveResult& result)> m_onComplete;
AZStd::function<bool()> m_onReadOnlyFile;
void OnSourceFileReleased(const SourceHandle& source);
void OnSourceFileReleased(AZ::Data::Asset<AZ::Data::AssetData> asset);
void PerformMove