EdGraph_ExtDependencyViewer.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. // Copyright 2017-2021 marynate. All Rights Reserved.
  2. #include "EdGraph_ExtDependencyViewer.h"
  3. #include "EdGraphNode_ExtDependency.h"
  4. #include "ExtContentBrowserSingleton.h"
  5. #include "ExtAssetData.h"
  6. #include "ExtAssetThumbnail.h"
  7. #include "EdGraph/EdGraphPin.h"
  8. #include "AssetRegistry/ARFilter.h"
  9. #include "AssetRegistry/AssetRegistryModule.h"
  10. #include "AssetThumbnail.h"
  11. #include "SExtDependencyViewer.h"
  12. #include "SExtDependencyNode.h"
  13. #include "GraphEditor.h"
  14. #include "ICollectionManager.h"
  15. #include "CollectionManagerModule.h"
  16. #include "Engine/AssetManager.h"
  17. #include "AssetManagerEditorModule.h"
  18. #include "Logging/TokenizedMessage.h"
  19. UEdGraph_ExtDependencyViewer::UEdGraph_ExtDependencyViewer(const FObjectInitializer& ObjectInitializer)
  20. : Super(ObjectInitializer)
  21. {
  22. AssetThumbnailPool = MakeShareable( new FExtAssetThumbnailPool(1024) );
  23. MaxSearchDepth = 1;
  24. MaxSearchBreadth = 15;
  25. bLimitSearchDepth = true;
  26. bLimitSearchBreadth = false;
  27. bIsShowSoftReferences = true;
  28. bIsShowHardReferences = true;
  29. bIsShowManagementReferences = false;
  30. bIsShowSearchableNames = false;
  31. bIsShowNativePackages = true;
  32. NodeXSpacing = 400.f;
  33. }
  34. void UEdGraph_ExtDependencyViewer::BeginDestroy()
  35. {
  36. AssetThumbnailPool.Reset();
  37. Super::BeginDestroy();
  38. }
  39. void UEdGraph_ExtDependencyViewer::SetGraphRoot(const TArray<FExtAssetIdentifier>& GraphRootIdentifiers, const FIntPoint& GraphRootOrigin)
  40. {
  41. CurrentGraphRootIdentifiers = GraphRootIdentifiers;
  42. CurrentGraphRootOrigin = GraphRootOrigin;
  43. // If we're focused on a searchable name, enable that flag
  44. for (const FExtAssetIdentifier& AssetId : GraphRootIdentifiers)
  45. {
  46. if (AssetId.IsValue())
  47. {
  48. bIsShowSearchableNames = true;
  49. }
  50. else if (AssetId.GetPrimaryAssetId().IsValid())
  51. {
  52. if (UAssetManager::IsInitialized())
  53. {
  54. UAssetManager::Get().UpdateManagementDatabase();
  55. }
  56. bIsShowManagementReferences = true;
  57. }
  58. }
  59. }
  60. const TArray<FExtAssetIdentifier>& UEdGraph_ExtDependencyViewer::GetCurrentGraphRootIdentifiers() const
  61. {
  62. return CurrentGraphRootIdentifiers;
  63. }
  64. void UEdGraph_ExtDependencyViewer::SetReferenceViewer(TSharedPtr<SExtDependencyViewer> InViewer)
  65. {
  66. ReferenceViewer = InViewer;
  67. }
  68. bool UEdGraph_ExtDependencyViewer::GetSelectedAssetsForMenuExtender(const class UEdGraphNode* Node, TArray<FExtAssetIdentifier>& SelectedAssets) const
  69. {
  70. if (!ReferenceViewer.IsValid())
  71. {
  72. return false;
  73. }
  74. TSharedPtr<SGraphEditor> GraphEditor = ReferenceViewer.Pin()->GetGraphEditor();
  75. if (!GraphEditor.IsValid())
  76. {
  77. return false;
  78. }
  79. TSet<UObject*> SelectedNodes = GraphEditor->GetSelectedNodes();
  80. for (FGraphPanelSelectionSet::TConstIterator It(SelectedNodes); It; ++It)
  81. {
  82. if (UEdGraphNode_ExtDependency* ReferenceNode = Cast<UEdGraphNode_ExtDependency>(*It))
  83. {
  84. if (!ReferenceNode->IsCollapsed())
  85. {
  86. SelectedAssets.Add(ReferenceNode->GetIdentifier());
  87. }
  88. }
  89. }
  90. return true;
  91. }
  92. UEdGraphNode_ExtDependency* UEdGraph_ExtDependencyViewer::RebuildGraph()
  93. {
  94. RemoveAllNodes();
  95. UEdGraphNode_ExtDependency* NewRootNode = ConstructNodes(CurrentGraphRootIdentifiers, CurrentGraphRootOrigin);
  96. NotifyGraphChanged();
  97. return NewRootNode;
  98. }
  99. bool UEdGraph_ExtDependencyViewer::IsSearchDepthLimited() const
  100. {
  101. return bLimitSearchDepth;
  102. }
  103. bool UEdGraph_ExtDependencyViewer::IsSearchBreadthLimited() const
  104. {
  105. return bLimitSearchBreadth;
  106. }
  107. bool UEdGraph_ExtDependencyViewer::IsShowSoftReferences() const
  108. {
  109. return bIsShowSoftReferences;
  110. }
  111. bool UEdGraph_ExtDependencyViewer::IsShowHardReferences() const
  112. {
  113. return bIsShowHardReferences;
  114. }
  115. bool UEdGraph_ExtDependencyViewer::IsShowManagementReferences() const
  116. {
  117. return bIsShowManagementReferences;
  118. }
  119. bool UEdGraph_ExtDependencyViewer::IsShowSearchableNames() const
  120. {
  121. return bIsShowSearchableNames;
  122. }
  123. bool UEdGraph_ExtDependencyViewer::IsShowNativePackages() const
  124. {
  125. return bIsShowNativePackages;
  126. }
  127. void UEdGraph_ExtDependencyViewer::SetSearchDepthLimitEnabled(bool newEnabled)
  128. {
  129. bLimitSearchDepth = newEnabled;
  130. }
  131. void UEdGraph_ExtDependencyViewer::SetSearchBreadthLimitEnabled(bool newEnabled)
  132. {
  133. bLimitSearchBreadth = newEnabled;
  134. }
  135. void UEdGraph_ExtDependencyViewer::SetShowSoftReferencesEnabled(bool newEnabled)
  136. {
  137. bIsShowSoftReferences = newEnabled;
  138. }
  139. void UEdGraph_ExtDependencyViewer::SetShowHardReferencesEnabled(bool newEnabled)
  140. {
  141. bIsShowHardReferences = newEnabled;
  142. }
  143. void UEdGraph_ExtDependencyViewer::SetShowManagementReferencesEnabled(bool newEnabled)
  144. {
  145. bIsShowManagementReferences = newEnabled;
  146. }
  147. void UEdGraph_ExtDependencyViewer::SetShowSearchableNames(bool newEnabled)
  148. {
  149. bIsShowSearchableNames = newEnabled;
  150. }
  151. void UEdGraph_ExtDependencyViewer::SetShowNativePackages(bool newEnabled)
  152. {
  153. bIsShowNativePackages = newEnabled;
  154. }
  155. int32 UEdGraph_ExtDependencyViewer::GetSearchDepthLimit() const
  156. {
  157. return MaxSearchDepth;
  158. }
  159. int32 UEdGraph_ExtDependencyViewer::GetSearchBreadthLimit() const
  160. {
  161. return MaxSearchBreadth;
  162. }
  163. void UEdGraph_ExtDependencyViewer::SetSearchDepthLimit(int32 NewDepthLimit)
  164. {
  165. MaxSearchDepth = NewDepthLimit;
  166. }
  167. void UEdGraph_ExtDependencyViewer::SetSearchBreadthLimit(int32 NewBreadthLimit)
  168. {
  169. MaxSearchBreadth = NewBreadthLimit;
  170. }
  171. FName UEdGraph_ExtDependencyViewer::GetCurrentCollectionFilter() const
  172. {
  173. return CurrentCollectionFilter;
  174. }
  175. void UEdGraph_ExtDependencyViewer::SetCurrentCollectionFilter(FName NewFilter)
  176. {
  177. CurrentCollectionFilter = NewFilter;
  178. }
  179. bool UEdGraph_ExtDependencyViewer::GetEnableCollectionFilter() const
  180. {
  181. return bEnableCollectionFilter;
  182. }
  183. void UEdGraph_ExtDependencyViewer::SetEnableCollectionFilter(bool bEnabled)
  184. {
  185. bEnableCollectionFilter = bEnabled;
  186. }
  187. float UEdGraph_ExtDependencyViewer::GetNodeXSpacing() const
  188. {
  189. return NodeXSpacing;
  190. }
  191. void UEdGraph_ExtDependencyViewer::SetNodeXSpacing(float NewNodeXSpacing)
  192. {
  193. #if ECB_FEA_REF_VIEWER_NODE_SPACING
  194. NodeXSpacing = FMath::Clamp<float>(NewNodeXSpacing, 200.f, 10000.f);
  195. #endif
  196. }
  197. FAssetManagerDependencyQuery UEdGraph_ExtDependencyViewer::GetReferenceSearchFlags(bool bHardOnly) const
  198. {
  199. using namespace UE::AssetRegistry;
  200. FAssetManagerDependencyQuery Query;
  201. Query.Categories = EDependencyCategory::None;
  202. Query.Flags = EDependencyQuery::NoRequirements;
  203. bool bLocalIsShowSoftReferences = bIsShowSoftReferences && !bHardOnly;
  204. if (bLocalIsShowSoftReferences || bIsShowHardReferences)
  205. {
  206. Query.Categories |= EDependencyCategory::Package;
  207. Query.Flags |= bLocalIsShowSoftReferences ? EDependencyQuery::NoRequirements : EDependencyQuery::Hard;
  208. Query.Flags |= bIsShowHardReferences ? EDependencyQuery::NoRequirements : EDependencyQuery::Soft;
  209. //Query.Flags |= Settings->IsShowEditorOnlyReferences() ? EDependencyQuery::NoRequirements : EDependencyQuery::Game;
  210. }
  211. if (bIsShowSearchableNames && !bHardOnly)
  212. {
  213. Query.Categories |= EDependencyCategory::SearchableName;
  214. }
  215. if (bIsShowManagementReferences)
  216. {
  217. Query.Categories |= EDependencyCategory::Manage;
  218. Query.Flags |= bHardOnly ? EDependencyQuery::Direct : EDependencyQuery::NoRequirements;
  219. }
  220. return Query;
  221. }
  222. UEdGraphNode_ExtDependency* UEdGraph_ExtDependencyViewer::ConstructNodes(const TArray<FExtAssetIdentifier>& GraphRootIdentifiers, const FIntPoint& GraphRootOrigin )
  223. {
  224. UEdGraphNode_ExtDependency* RootNode = NULL;
  225. if (GraphRootIdentifiers.Num() > 0 )
  226. {
  227. TSet<FName> AllowedPackageNames;
  228. if (ShouldFilterByCollection())
  229. {
  230. FCollectionManagerModule& CollectionManagerModule = FCollectionManagerModule::GetModule();
  231. TArray<FSoftObjectPath> AssetPaths;
  232. CollectionManagerModule.Get().GetAssetsInCollection(CurrentCollectionFilter, ECollectionShareType::CST_All, AssetPaths);
  233. AllowedPackageNames.Reserve(AssetPaths.Num());
  234. for (FSoftObjectPath& AssetPath : AssetPaths)
  235. {
  236. AllowedPackageNames.Add(FName(*FPackageName::ObjectPathToPackageName(AssetPath.ToString())));
  237. }
  238. }
  239. TMap<FExtAssetIdentifier, int32> ReferencerNodeSizes;
  240. TSet<FExtAssetIdentifier> VisitedReferencerSizeNames;
  241. int32 ReferencerDepth = 1;
  242. RecursivelyGatherSizes(/*bReferencers=*/true, GraphRootIdentifiers, AllowedPackageNames, ReferencerDepth, VisitedReferencerSizeNames, ReferencerNodeSizes);
  243. TMap<FExtAssetIdentifier, int32> DependencyNodeSizes;
  244. TSet<FExtAssetIdentifier> VisitedDependencySizeNames;
  245. int32 DependencyDepth = 1;
  246. RecursivelyGatherSizes(/*bReferencers=*/false, GraphRootIdentifiers, AllowedPackageNames, DependencyDepth, VisitedDependencySizeNames, DependencyNodeSizes);
  247. TSet<FName> AllPackageNames;
  248. auto AddPackage = [](const FExtAssetIdentifier& AssetId, TSet<FName>& PackageNames)
  249. {
  250. // Only look for asset data if this is a package
  251. if (!AssetId.IsValue())
  252. {
  253. PackageNames.Add(AssetId.PackageName);
  254. }
  255. };
  256. for (const FExtAssetIdentifier& AssetId : VisitedReferencerSizeNames)
  257. {
  258. AddPackage(AssetId, AllPackageNames);
  259. }
  260. for (const FExtAssetIdentifier& AssetId : VisitedDependencySizeNames)
  261. {
  262. AddPackage(AssetId, AllPackageNames);
  263. }
  264. TMap<FName, FExtAssetData> PackagesToAssetDataMap;
  265. GatherAssetData(AllPackageNames, PackagesToAssetDataMap);
  266. // Create the root node
  267. RootNode = CreateReferenceNode();
  268. RootNode->SetupReferenceNode(GraphRootOrigin, GraphRootIdentifiers, PackagesToAssetDataMap.FindRef(GraphRootIdentifiers[0].PackageName));
  269. TSet<FExtAssetIdentifier> VisitedReferencerNames;
  270. int32 VisitedReferencerDepth = 1;
  271. RecursivelyConstructNodes(/*bReferencers=*/true, RootNode, GraphRootIdentifiers, GraphRootOrigin, ReferencerNodeSizes, PackagesToAssetDataMap, AllowedPackageNames, VisitedReferencerDepth, VisitedReferencerNames);
  272. TSet<FExtAssetIdentifier> VisitedDependencyNames;
  273. int32 VisitedDependencyDepth = 1;
  274. RecursivelyConstructNodes(/*bReferencers=*/false, RootNode, GraphRootIdentifiers, GraphRootOrigin, DependencyNodeSizes, PackagesToAssetDataMap, AllowedPackageNames, VisitedDependencyDepth, VisitedDependencyNames);
  275. }
  276. return RootNode;
  277. }
  278. int32 UEdGraph_ExtDependencyViewer::RecursivelyGatherSizes(bool bReferencers, const TArray<FExtAssetIdentifier>& Identifiers, const TSet<FName>& AllowedPackageNames, int32 CurrentDepth, TSet<FExtAssetIdentifier>& VisitedNames, TMap<FExtAssetIdentifier, int32>& OutNodeSizes) const
  279. {
  280. check(Identifiers.Num() > 0);
  281. VisitedNames.Append(Identifiers);
  282. FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
  283. TArray<FExtAssetIdentifier> ReferenceNames;
  284. const FAssetManagerDependencyQuery DependencyQuery = GetReferenceSearchFlags(false);
  285. if ( bReferencers )
  286. {
  287. for (const FExtAssetIdentifier& AssetId : Identifiers)
  288. {
  289. FExtContentBrowserSingleton::GetAssetRegistry().GetReferencers(AssetId, ReferenceNames, DependencyQuery.Categories);
  290. }
  291. }
  292. else
  293. {
  294. for (const FExtAssetIdentifier& AssetId : Identifiers)
  295. {
  296. FExtContentBrowserSingleton::GetAssetRegistry().GetDependencies(AssetId, ReferenceNames, DependencyQuery.Categories);
  297. }
  298. }
  299. if (!bIsShowNativePackages)
  300. {
  301. auto RemoveNativePackage = [](const FExtAssetIdentifier& InAsset) { return InAsset.PackageName.ToString().StartsWith(TEXT("/Script")) && !InAsset.IsValue(); };
  302. ReferenceNames.RemoveAll(RemoveNativePackage);
  303. }
  304. int32 NodeSize = 0;
  305. if ( ReferenceNames.Num() > 0 && !ExceedsMaxSearchDepth(CurrentDepth) )
  306. {
  307. int32 NumReferencesMade = 0;
  308. int32 NumReferencesExceedingMax = 0;
  309. #if ECB_LEGACY
  310. // Filter for our registry source
  311. IAssetManagerEditorModule::Get().FilterAssetIdentifiersForCurrentRegistrySource(ReferenceNames, GetReferenceSearchFlags(false), !bReferencers);
  312. #endif
  313. // Since there are referencers, use the size of all your combined referencers.
  314. // Do not count your own size since there could just be a horizontal line of nodes
  315. for (FExtAssetIdentifier& AssetId : ReferenceNames)
  316. {
  317. if ( !VisitedNames.Contains(AssetId) && (!AssetId.IsPackage() || !ShouldFilterByCollection() || AllowedPackageNames.Contains(AssetId.PackageName)) )
  318. {
  319. if ( !ExceedsMaxSearchBreadth(NumReferencesMade) )
  320. {
  321. TArray<FExtAssetIdentifier> NewPackageNames;
  322. NewPackageNames.Add(AssetId);
  323. NodeSize += RecursivelyGatherSizes(bReferencers, NewPackageNames, AllowedPackageNames, CurrentDepth + 1, VisitedNames, OutNodeSizes);
  324. NumReferencesMade++;
  325. }
  326. else
  327. {
  328. NumReferencesExceedingMax++;
  329. }
  330. }
  331. }
  332. if ( NumReferencesExceedingMax > 0 )
  333. {
  334. // Add one size for the collapsed node
  335. NodeSize++;
  336. }
  337. }
  338. if ( NodeSize == 0 )
  339. {
  340. // If you have no valid children, the node size is just 1 (counting only self to make a straight line)
  341. NodeSize = 1;
  342. }
  343. OutNodeSizes.Add(Identifiers[0], NodeSize);
  344. return NodeSize;
  345. }
  346. void UEdGraph_ExtDependencyViewer::GatherAssetData(const TSet<FName>& AllPackageNames, TMap<FName, FExtAssetData>& OutPackageToAssetDataMap) const
  347. {
  348. FARFilter Filter;
  349. for ( auto PackageIt = AllPackageNames.CreateConstIterator(); PackageIt; ++PackageIt )
  350. {
  351. const FString& PackageName = (*PackageIt).ToString();
  352. //const FString& PackagePath = PackageName + TEXT(".") + FPackageName::GetLongPackageAssetName(PackageName);
  353. //Filter.ObjectPaths.Add( FName(*PackagePath) );
  354. Filter.PackageNames.Add(FName(*PackageName));
  355. }
  356. TArray<FExtAssetData> AssetDataList;
  357. FExtContentBrowserSingleton::GetAssetRegistry().GetAssets(Filter, AssetDataList);
  358. for ( auto AssetIt = AssetDataList.CreateConstIterator(); AssetIt; ++AssetIt )
  359. {
  360. OutPackageToAssetDataMap.Add((*AssetIt).PackageName, *AssetIt);
  361. }
  362. }
  363. UEdGraphNode_ExtDependency* UEdGraph_ExtDependencyViewer::RecursivelyConstructNodes(bool bReferencers, UEdGraphNode_ExtDependency* RootNode, const TArray<FExtAssetIdentifier>& Identifiers, const FIntPoint& NodeLoc, const TMap<FExtAssetIdentifier, int32>& NodeSizes, const TMap<FName, FExtAssetData>& PackagesToAssetDataMap, const TSet<FName>& AllowedPackageNames, int32 CurrentDepth, TSet<FExtAssetIdentifier>& VisitedNames)
  364. {
  365. check(Identifiers.Num() > 0);
  366. VisitedNames.Append(Identifiers);
  367. UEdGraphNode_ExtDependency* NewNode = NULL;
  368. if ( RootNode->GetIdentifier() == Identifiers[0] )
  369. {
  370. // Don't create the root node. It is already created!
  371. NewNode = RootNode;
  372. }
  373. else
  374. {
  375. NewNode = CreateReferenceNode();
  376. NewNode->SetupReferenceNode(NodeLoc, Identifiers, PackagesToAssetDataMap.FindRef(Identifiers[0].PackageName));
  377. }
  378. FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
  379. TArray<FExtAssetIdentifier> ReferenceNames;
  380. TArray<FExtAssetIdentifier> HardReferenceNames;
  381. const FAssetManagerDependencyQuery HardOnlyDependencyQuery = GetReferenceSearchFlags(true);
  382. const FAssetManagerDependencyQuery DependencyQuery = GetReferenceSearchFlags(false);
  383. if ( bReferencers )
  384. {
  385. for (const FExtAssetIdentifier& AssetId : Identifiers)
  386. {
  387. FExtContentBrowserSingleton::GetAssetRegistry().GetReferencers(AssetId, HardReferenceNames, HardOnlyDependencyQuery.Categories);
  388. FExtContentBrowserSingleton::GetAssetRegistry().GetReferencers(AssetId, ReferenceNames, DependencyQuery.Categories);
  389. }
  390. }
  391. else
  392. {
  393. for (const FExtAssetIdentifier& AssetId : Identifiers)
  394. {
  395. FExtContentBrowserSingleton::GetAssetRegistry().GetDependencies(AssetId, HardReferenceNames, HardOnlyDependencyQuery.Categories);
  396. FExtContentBrowserSingleton::GetAssetRegistry().GetDependencies(AssetId, ReferenceNames, DependencyQuery.Categories);
  397. }
  398. }
  399. if (!bIsShowNativePackages)
  400. {
  401. auto RemoveNativePackage = [](const FExtAssetIdentifier& InAsset) { return InAsset.PackageName.ToString().StartsWith(TEXT("/Script")) && !InAsset.IsValue(); };
  402. HardReferenceNames.RemoveAll(RemoveNativePackage);
  403. ReferenceNames.RemoveAll(RemoveNativePackage);
  404. }
  405. if ( ReferenceNames.Num() > 0 && !ExceedsMaxSearchDepth(CurrentDepth) )
  406. {
  407. FIntPoint ReferenceNodeLoc = NodeLoc;
  408. if ( bReferencers )
  409. {
  410. // Referencers go left
  411. ReferenceNodeLoc.X -= NodeXSpacing;
  412. }
  413. else
  414. {
  415. // Dependencies go right
  416. ReferenceNodeLoc.X += NodeXSpacing;
  417. }
  418. const int32 NodeSizeY = 200;
  419. const int32 TotalReferenceSizeY = NodeSizes.FindChecked(Identifiers[0]) * NodeSizeY;
  420. ReferenceNodeLoc.Y -= TotalReferenceSizeY * 0.5f;
  421. ReferenceNodeLoc.Y += NodeSizeY * 0.5f;
  422. int32 NumReferencesMade = 0;
  423. int32 NumReferencesExceedingMax = 0;
  424. #if ECB_LEGACY
  425. // Filter for our registry source
  426. IAssetManagerEditorModule::Get().FilterAssetIdentifiersForCurrentRegistrySource(ReferenceNames, GetReferenceSearchFlags(false), !bReferencers);
  427. IAssetManagerEditorModule::Get().FilterAssetIdentifiersForCurrentRegistrySource(HardReferenceNames, GetReferenceSearchFlags(false), !bReferencers);
  428. #endif
  429. for ( int32 RefIdx = 0; RefIdx < ReferenceNames.Num(); ++RefIdx )
  430. {
  431. FExtAssetIdentifier ReferenceName = ReferenceNames[RefIdx];
  432. if ( !VisitedNames.Contains(ReferenceName) && (!ReferenceName.IsPackage() || !ShouldFilterByCollection() || AllowedPackageNames.Contains(ReferenceName.PackageName)) )
  433. {
  434. bool bIsHardReference = HardReferenceNames.Contains(ReferenceName);
  435. if ( !ExceedsMaxSearchBreadth(NumReferencesMade) )
  436. {
  437. int32 ThisNodeSizeY = ReferenceName.IsValue() ? 100 : NodeSizeY;
  438. const int32 RefSizeY = NodeSizes.FindChecked(ReferenceName);
  439. FIntPoint RefNodeLoc;
  440. RefNodeLoc.X = ReferenceNodeLoc.X;
  441. RefNodeLoc.Y = ReferenceNodeLoc.Y + RefSizeY * ThisNodeSizeY * 0.5 - ThisNodeSizeY * 0.5;
  442. TArray<FExtAssetIdentifier> NewIdentifiers;
  443. NewIdentifiers.Add(ReferenceName);
  444. UEdGraphNode_ExtDependency* ReferenceNode = RecursivelyConstructNodes(bReferencers, RootNode, NewIdentifiers, RefNodeLoc, NodeSizes, PackagesToAssetDataMap, AllowedPackageNames, CurrentDepth + 1, VisitedNames);
  445. if (bIsHardReference)
  446. {
  447. if (bReferencers)
  448. {
  449. ReferenceNode->GetDependencyPin()->PinType.PinCategory = TEXT("hard");
  450. }
  451. else
  452. {
  453. ReferenceNode->GetReferencerPin()->PinType.PinCategory = TEXT("hard"); //-V595
  454. }
  455. }
  456. bool bIsMissingOrInvalid = ReferenceNode->IsMissingOrInvalid();
  457. if (bIsMissingOrInvalid)
  458. {
  459. if (bReferencers)
  460. {
  461. ReferenceNode->GetDependencyPin()->PinType.PinSubCategory = TEXT("invalid");
  462. }
  463. else
  464. {
  465. ReferenceNode->GetReferencerPin()->PinType.PinSubCategory = TEXT("invalid");
  466. }
  467. ReferenceNode->bHasCompilerMessage = true;
  468. if (!bIsHardReference)
  469. {
  470. ReferenceNode->ErrorType = EMessageSeverity::Warning;
  471. }
  472. else
  473. {
  474. ReferenceNode->ErrorType = EMessageSeverity::Error;
  475. }
  476. }
  477. if ( ensure(ReferenceNode) )
  478. {
  479. if ( bReferencers )
  480. {
  481. NewNode->AddReferencer( ReferenceNode );
  482. }
  483. else
  484. {
  485. ReferenceNode->AddReferencer( NewNode );
  486. }
  487. ReferenceNodeLoc.Y += RefSizeY * ThisNodeSizeY;
  488. }
  489. NumReferencesMade++;
  490. }
  491. else
  492. {
  493. NumReferencesExceedingMax++;
  494. }
  495. }
  496. }
  497. if ( NumReferencesExceedingMax > 0 )
  498. {
  499. // There are more references than allowed to be displayed. Make a collapsed node.
  500. UEdGraphNode_ExtDependency* ReferenceNode = CreateReferenceNode();
  501. FIntPoint RefNodeLoc;
  502. RefNodeLoc.X = ReferenceNodeLoc.X;
  503. RefNodeLoc.Y = ReferenceNodeLoc.Y;
  504. if ( ensure(ReferenceNode) )
  505. {
  506. ReferenceNode->SetReferenceNodeCollapsed(RefNodeLoc, NumReferencesExceedingMax);
  507. if ( bReferencers )
  508. {
  509. NewNode->AddReferencer( ReferenceNode );
  510. }
  511. else
  512. {
  513. ReferenceNode->AddReferencer( NewNode );
  514. }
  515. }
  516. }
  517. }
  518. return NewNode;
  519. }
  520. const TSharedPtr<FExtAssetThumbnailPool>& UEdGraph_ExtDependencyViewer::GetAssetThumbnailPool() const
  521. {
  522. return AssetThumbnailPool;
  523. }
  524. bool UEdGraph_ExtDependencyViewer::ExceedsMaxSearchDepth(int32 Depth) const
  525. {
  526. return bLimitSearchDepth && Depth > MaxSearchDepth;
  527. }
  528. bool UEdGraph_ExtDependencyViewer::ExceedsMaxSearchBreadth(int32 Breadth) const
  529. {
  530. return bLimitSearchBreadth && Breadth > MaxSearchBreadth;
  531. }
  532. UEdGraphNode_ExtDependency* UEdGraph_ExtDependencyViewer::CreateReferenceNode()
  533. {
  534. const bool bSelectNewNode = false;
  535. return Cast<UEdGraphNode_ExtDependency>(CreateNode(UEdGraphNode_ExtDependency::StaticClass(), bSelectNewNode));
  536. }
  537. void UEdGraph_ExtDependencyViewer::RemoveAllNodes()
  538. {
  539. TArray<UEdGraphNode*> NodesToRemove = Nodes;
  540. for (int32 NodeIndex = 0; NodeIndex < NodesToRemove.Num(); ++NodeIndex)
  541. {
  542. RemoveNode(NodesToRemove[NodeIndex]);
  543. }
  544. }
  545. bool UEdGraph_ExtDependencyViewer::ShouldFilterByCollection() const
  546. {
  547. return bEnableCollectionFilter && CurrentCollectionFilter != NAME_None;
  548. }