dependency sort finished, but not tested

Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com>
This commit is contained in:
chcurran
2021-09-14 14:05:15 -07:00
parent f55737af11
commit 0e2f75492c
6 changed files with 174 additions and 19 deletions
@@ -342,7 +342,9 @@ namespace ScriptCanvasEditor
}
void Controller::OnUpgradeAllDependencySortEnd(const AZStd::vector<AZ::Data::AssetInfo>& sortedAssets)
void Controller::OnUpgradeAllDependencySortEnd
( const AZStd::vector<AZ::Data::AssetInfo>& sortedAssets
, [[maybe_unused]] const AZStd::vector<size_t>& sortedOrder)
{
m_view->progressBar->setRange(0, aznumeric_cast<int>(sortedAssets.size()));
}
@@ -78,7 +78,9 @@ namespace ScriptCanvasEditor
void OnUpgradeAllBegin() override;
void OnUpgradeAllComplete() override;
void OnUpgradeAllDependencySortBegin() override;
void OnUpgradeAllDependencySortEnd(const AZStd::vector<AZ::Data::AssetInfo>& sortedAssets) override;
void OnUpgradeAllDependencySortEnd
( const AZStd::vector<AZ::Data::AssetInfo>& sortedAssets
, const AZStd::vector<size_t>& sortedOrder) override;
};
}
}
@@ -8,6 +8,7 @@
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/string/string.h>
#define VE_LOG(...) LogBus::Broadcast(&LogTraits::Entry, __VA_ARGS__);
@@ -63,7 +63,9 @@ namespace ScriptCanvasEditor
virtual void OnUpgradeAllBegin() = 0;
virtual void OnUpgradeAllComplete() = 0;
virtual void OnUpgradeAllDependencySortBegin() = 0;
virtual void OnUpgradeAllDependencySortEnd(const AZStd::vector<AZ::Data::AssetInfo>& sortedAssets) = 0;
virtual void OnUpgradeAllDependencySortEnd
( const AZStd::vector<AZ::Data::AssetInfo>& assets
, const AZStd::vector<size_t>& sortedOrder) = 0;
};
using ModelNotificationsBus = AZ::EBus<ModelNotificationsTraits>;
}
@@ -6,9 +6,11 @@
*
*/
#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/Core/Graph.h>
namespace ModifierCpp
{
@@ -23,7 +25,8 @@ namespace ScriptCanvasEditor
( const ModifyConfiguration& modification
, AZStd::vector<AZ::Data::AssetInfo>&& assets
, AZStd::function<void()> onComplete)
: m_config(modification)
: m_state(State::GatheringDependencies)
, m_config(modification)
, m_assets(assets)
, m_onComplete(onComplete)
{
@@ -31,12 +34,22 @@ namespace ScriptCanvasEditor
AZ::SystemTickBus::Handler::BusConnect();
}
const AZ::Data::AssetInfo& Modifier::GetCurrentAsset() const
{
return m_state == State::GatheringDependencies
? m_assets[m_assetIndex]
: m_assets[m_dependencyOrderedIndicies[m_assetIndex]];
: m_assets[m_dependencyOrderedAssetIndicies[m_assetIndex]];
}
AZStd::unordered_set<size_t>& Modifier::GetOrCreateDependencyIndexSet()
{
auto iter = m_dependencies.find(m_assetIndex);
if (iter == m_dependencies.end())
{
iter = m_dependencies.insert_or_assign(m_assetIndex, AZStd::unordered_set<size_t>()).first;
}
return iter->second;
}
void Modifier::GatherDependencies()
@@ -45,10 +58,19 @@ namespace ScriptCanvasEditor
AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
AZ_Assert(serializeContext, "SerializeContext is required to enumerate dependent assets in the ScriptCanvas file");
/*
auto asset = LoadAsset();
if (!asset
|| !asset.GetAs<ScriptCanvasAsset>()
|| !asset.GetAs<ScriptCanvasAsset>()->GetScriptCanvasGraph()
|| !asset.GetAs<ScriptCanvasAsset>()->GetScriptCanvasGraph()->GetGraphData())
{
VE_LOG("Modifier: Failed to load asset %s for modification, even though it scanned properly");
return;
}
// AZStd::unordered_multimap<AZStd::string, AssetBuilderSDK::SourceFileDependency> jobDependenciesByKey;
auto assetFilter = [this, &jobDependenciesByKey]
auto graphData = asset.GetAs<ScriptCanvasAsset>()->GetScriptCanvasGraph()->GetGraphData();
auto dependencyGrabber = [this]
( void* instancePointer
, const AZ::SerializeContext::ClassData* classData
, [[maybe_unused]] const AZ::SerializeContext::ClassElement* classElement)
@@ -59,11 +81,15 @@ namespace ScriptCanvasEditor
const auto* subgraphAsset = reinterpret_cast<AZ::Data::Asset<const ScriptCanvas::SubgraphInterfaceAsset>*>(instancePointer);
if (subgraphAsset->GetId().IsValid())
{
// AssetBuilderSDK::SourceFileDependency dependency;
// dependency.m_sourceFileDependencyUUID = subgraphAsset->GetId().m_guid;
// jobDependenciesByKey.insert({ s_scriptCanvasProcessJobKey, dependency });
// this->m_processEditorAssetDependencies.push_back
// ({ subgraphAsset->GetId(), azTypeId, AZ::Data::AssetLoadBehavior::PreLoad });
if (auto iter = m_assetInfoIndexById.find(subgraphAsset->GetId().m_guid); iter != m_assetInfoIndexById.end())
{
GetOrCreateDependencyIndexSet().insert(iter->second);
}
else
{
VE_LOG("Modifier: Dependency found that was not picked up by the scanner: %s"
, subgraphAsset->GetId().ToString<AZStd::string>().c_str());
}
}
}
// always continue, make note of the script canvas dependencies
@@ -71,9 +97,9 @@ namespace ScriptCanvasEditor
};
AZ_Verify(serializeContext->EnumerateInstanceConst
( sourceGraph->GetGraphData()
( graphData
, azrtti_typeid<ScriptCanvas::GraphData>()
, assetFilter
, dependencyGrabber
, {}
, AZ::SerializeContext::ENUM_ACCESS_FOR_READ
, nullptr
@@ -81,13 +107,12 @@ namespace ScriptCanvasEditor
// Flush asset database events to ensure no asset references are held by closures queued on Ebuses.
AZ::Data::AssetManager::Instance().DispatchEvents();
*/
}
AZ::Data::Asset<AZ::Data::AssetData> Modifier::LoadAsset()
{
AZ::Data::Asset<AZ::Data::AssetData> asset = AZ::Data::AssetManager::Instance().GetAsset
(GetCurrentAsset().m_assetId
( GetCurrentAsset().m_assetId
, azrtti_typeid<ScriptCanvasAsset>()
, AZ::Data::AssetLoadBehavior::PreLoad);
@@ -116,5 +141,109 @@ namespace ScriptCanvasEditor
break;
}
}
const AZStd::unordered_set<size_t>* Modifier::Sorter::GetDependencies(size_t index) const
{
auto iter = modifier->m_dependencies.find(index);
return iter != modifier->m_dependencies.end() ? &iter->second : nullptr;
}
void Modifier::Sorter::Sort()
{
for (size_t index = 0; index != modifier->m_assets.size(); ++index)
{
Visit(index);
}
/*
L ← Empty list that will contain the sorted nodes
(m_dependencyOrderedAssetIndicies)
while exists nodes without a permanent mark do
select an unmarked node n
visit(n)
*/
}
void Modifier::Sorter::Visit(size_t index)
{
if (markedPermanent.contains(index))
{
return;
}
if (markedTemporary.contains(index))
{
AZ_Error
( ScriptCanvas::k_VersionExplorerWindow.data()
, false
, "Modifier: Dependency sort has failed during, circular dependency detected for Asset: %s"
, modifier->GetCurrentAsset().m_relativePath.c_str());
return;
}
markedTemporary.insert(index);
if (auto dependencies = GetDependencies(index))
{
for (auto& dependency : *dependencies)
{
Visit(dependency);
}
}
markedTemporary.erase(index);
markedPermanent.insert(index);
modifier->m_dependencyOrderedAssetIndicies.push_back(index);
}
void Modifier::SortGraphsByDependencies()
{
m_dependencyOrderedAssetIndicies.reserve(m_assets.size());
Sorter sorter;
sorter.modifier = this;
sorter.Sort();
}
void Modifier::TickGatherDependencies()
{
if (m_assetIndex == 0)
{
if (m_config.successfulDependencyUpgradeRequired)
{
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnUpgradeAllDependencySortBegin);
m_assetInfoIndexById.reserve(m_assets.size());
for (size_t index = 0; index != m_assets.size(); ++index)
{
m_assetInfoIndexById.insert({ m_assets[index].m_assetId.m_guid, index });
}
}
else
{
m_dependencyOrderedAssetIndicies.reserve(m_assets.size());
for (size_t index = 0; index != m_assets.size(); ++index)
{
m_dependencyOrderedAssetIndicies.push_back(index);
}
}
}
if (m_assetIndex == m_assets.size())
{
SortGraphsByDependencies();
ModelNotificationsBus::Broadcast
( &ModelNotificationsTraits::OnUpgradeAllDependencySortEnd
, m_assets
, m_dependencyOrderedAssetIndicies);
m_assetIndex = 0;
m_state = State::ModifyingGraphs;
}
else
{
GatherDependencies();
++m_assetIndex;
}
}
}
}
@@ -28,6 +28,20 @@ namespace ScriptCanvasEditor
, AZStd::function<void()> onComplete);
private:
friend class Sorter;
struct Sorter
{
Modifier* modifier;
AZStd::unordered_set<size_t> markedPermanent;
AZStd::unordered_set<size_t> markedTemporary;
void Sort();
private:
void Visit(size_t index);
const AZStd::unordered_set<size_t>* GetDependencies(size_t index) const;
};
enum class State
{
GatheringDependencies,
@@ -37,15 +51,20 @@ namespace ScriptCanvasEditor
State m_state = State::GatheringDependencies;
size_t m_assetIndex = 0;
AZStd::function<void()> m_onComplete;
// asset infos in scanned order
AZStd::vector<AZ::Data::AssetInfo> m_assets;
AZStd::vector<size_t> m_dependencyOrderedIndicies;
// dependency sorted order indices into the asset vector
AZStd::vector<size_t> m_dependencyOrderedAssetIndicies;
// dependency indices by asset info index (only exist if graphs have them)
AZStd::unordered_map<size_t, AZStd::unordered_set<size_t>> m_dependencies;
AZStd::unordered_map<AZ::Uuid, size_t> m_assetInfoIndexById;
AZStd::vector<size_t> m_failures;
ModifyConfiguration m_config;
ModificationResult m_result;
void GatherDependencies();
const AZ::Data::AssetInfo& GetCurrentAsset() const;
AZStd::unordered_set<size_t>& GetOrCreateDependencyIndexSet();
AZ::Data::Asset<AZ::Data::AssetData> LoadAsset();
void SortGraphsByDependencies();
void OnSystemTick() override;