Files
UnrealEngineUWP/Engine/Source/Editor/ReferenceViewer/Private/EdGraph_ReferenceViewer.cpp
PaulEremeeff 3d878d5a79 PR #996: Fixing PVS-Studio warnings (Contributed by PaulEremeeff)
I have reviewed each change carefully, but it is a large change and I could have missed something! Here is a summary of the types of changes in this CL:
 * Made nullptr checks consistent (the plurality of the changes are of this type)
 * Completed switch statements (IE, switch did not explicitly handle default case, but had unhandled enum entries - this is the second most popular type of fix)
 * Removed unused variables
 * Removed redundant initializations
 * WidgetNavigationCustomization.cpp was fixed by the owner
 * integers converted to floats where result was stored in a float
 * Removed redundent null checks (e.g. before delete statements)
 * Renamed variables to prevent non-obvious shadowing
 * Fixed use of bitwise & when checking for equality to an enum entry (which is often 0)
 * Fixes for some copy paste errors (e.g. FoliageEdMode.cpp)

[CL 2498053 by Dan Oconnor in Main branch]
2015-03-31 20:12:31 -04:00

366 lines
11 KiB
C++

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#include "ReferenceViewerPrivatePCH.h"
#include "AssetRegistryModule.h"
#include "AssetThumbnail.h"
UEdGraph_ReferenceViewer::UEdGraph_ReferenceViewer(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
AssetThumbnailPool = MakeShareable( new FAssetThumbnailPool(1024) );
MaxSearchDepth = 1;
MaxSearchBreadth = 15;
bLimitSearchDepth = true;
bLimitSearchBreadth = true;
}
void UEdGraph_ReferenceViewer::BeginDestroy()
{
if ( AssetThumbnailPool.IsValid() )
{
AssetThumbnailPool->ReleaseResources();
AssetThumbnailPool.Reset();
}
Super::BeginDestroy();
}
void UEdGraph_ReferenceViewer::SetGraphRoot(const TArray<FName>& GraphRootPackageNames, const FIntPoint& GraphRootOrigin)
{
CurrentGraphRootPackageNames = GraphRootPackageNames;
CurrentGraphRootOrigin = GraphRootOrigin;
}
const TArray<FName>& UEdGraph_ReferenceViewer::GetCurrentGraphRootPackageNames() const
{
return CurrentGraphRootPackageNames;
}
UEdGraphNode_Reference* UEdGraph_ReferenceViewer::RebuildGraph()
{
RemoveAllNodes();
UEdGraphNode_Reference* NewRootNode = ConstructNodes(CurrentGraphRootPackageNames, CurrentGraphRootOrigin);
NotifyGraphChanged();
return NewRootNode;
}
bool UEdGraph_ReferenceViewer::IsSearchDepthLimited() const
{
return bLimitSearchDepth;
}
bool UEdGraph_ReferenceViewer::IsSearchBreadthLimited() const
{
return bLimitSearchBreadth;
}
void UEdGraph_ReferenceViewer::SetSearchDepthLimitEnabled(bool newEnabled)
{
bLimitSearchDepth = newEnabled;
}
void UEdGraph_ReferenceViewer::SetSearchBreadthLimitEnabled(bool newEnabled)
{
bLimitSearchBreadth = newEnabled;
}
int32 UEdGraph_ReferenceViewer::GetSearchDepthLimit() const
{
return MaxSearchDepth;
}
int32 UEdGraph_ReferenceViewer::GetSearchBreadthLimit() const
{
return MaxSearchBreadth;
}
void UEdGraph_ReferenceViewer::SetSearchDepthLimit(int32 NewDepthLimit)
{
MaxSearchDepth = NewDepthLimit;
}
void UEdGraph_ReferenceViewer::SetSearchBreadthLimit(int32 NewBreadthLimit)
{
MaxSearchBreadth = NewBreadthLimit;
}
UEdGraphNode_Reference* UEdGraph_ReferenceViewer::ConstructNodes(const TArray<FName>& GraphRootPackageNames, const FIntPoint& GraphRootOrigin )
{
UEdGraphNode_Reference* RootNode = NULL;
if ( GraphRootPackageNames.Num() > 0 )
{
TMap<FName, int32> ReferencerNodeSizes;
TSet<FName> VisitedReferencerSizeNames;
int32 ReferencerDepth = 1;
RecursivelyGatherSizes(/*bReferencers=*/true, GraphRootPackageNames, ReferencerDepth, VisitedReferencerSizeNames, ReferencerNodeSizes);
TMap<FName, int32> DependencyNodeSizes;
TSet<FName> VisitedDependencySizeNames;
int32 DependencyDepth = 1;
RecursivelyGatherSizes(/*bReferencers=*/false, GraphRootPackageNames, DependencyDepth, VisitedDependencySizeNames, DependencyNodeSizes);
TSet<FName> AllPackageNames = VisitedReferencerSizeNames;
AllPackageNames.Append(VisitedDependencySizeNames);
TMap<FName, FAssetData> PackagesToAssetDataMap;
GatherAssetData(AllPackageNames, PackagesToAssetDataMap);
// Create the root node
RootNode = CreateReferenceNode();
RootNode->SetupReferenceNode(GraphRootOrigin, GraphRootPackageNames, PackagesToAssetDataMap.FindRef(GraphRootPackageNames[0]));
TSet<FName> VisitedReferencerNames;
int32 VisitedReferencerDepth = 1;
RecursivelyConstructNodes(/*bReferencers=*/true, RootNode, GraphRootPackageNames, GraphRootOrigin, ReferencerNodeSizes, PackagesToAssetDataMap, VisitedReferencerDepth, VisitedReferencerNames);
TSet<FName> VisitedDependencyNames;
int32 VisitedDependencyDepth = 1;
RecursivelyConstructNodes(/*bReferencers=*/false, RootNode, GraphRootPackageNames, GraphRootOrigin, DependencyNodeSizes, PackagesToAssetDataMap, VisitedDependencyDepth, VisitedDependencyNames);
}
return RootNode;
}
int32 UEdGraph_ReferenceViewer::RecursivelyGatherSizes(bool bReferencers, const TArray<FName>& PackageNames, int32 CurrentDepth, TSet<FName>& VisitedNames, TMap<FName, int32>& OutNodeSizes) const
{
check(PackageNames.Num() > 0);
VisitedNames.Append(PackageNames);
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
TArray<FName> ReferenceNames;
if ( bReferencers )
{
for ( auto NameIt = PackageNames.CreateConstIterator(); NameIt; ++NameIt )
{
AssetRegistryModule.Get().GetReferencers(*NameIt, ReferenceNames);
}
}
else
{
for ( auto NameIt = PackageNames.CreateConstIterator(); NameIt; ++NameIt )
{
AssetRegistryModule.Get().GetDependencies(*NameIt, ReferenceNames);
}
}
int32 NodeSize = 0;
if ( ReferenceNames.Num() > 0 && !ExceedsMaxSearchDepth(CurrentDepth) )
{
int32 NumReferencesMade = 0;
int32 NumReferencesExceedingMax = 0;
// Since there are referencers, use the size of all your combined referencers.
// Do not count your own size since there could just be a horizontal line of nodes
for ( auto RefIt = ReferenceNames.CreateConstIterator(); RefIt; ++RefIt )
{
if ( !VisitedNames.Contains(*RefIt) )
{
if ( !ExceedsMaxSearchBreadth(NumReferencesMade) )
{
TArray<FName> NewPackageNames;
NewPackageNames.Add(*RefIt);
NodeSize += RecursivelyGatherSizes(bReferencers, NewPackageNames, CurrentDepth + 1, VisitedNames, OutNodeSizes);
NumReferencesMade++;
}
else
{
NumReferencesExceedingMax++;
}
}
}
if ( NumReferencesExceedingMax > 0 )
{
// Add one size for the collapsed node
NodeSize++;
}
}
if ( NodeSize == 0 )
{
// If you have no valid children, the node size is just 1 (counting only self to make a straight line)
NodeSize = 1;
}
OutNodeSizes.Add(PackageNames[0], NodeSize);
return NodeSize;
}
void UEdGraph_ReferenceViewer::GatherAssetData(const TSet<FName>& AllPackageNames, TMap<FName, FAssetData>& OutPackageToAssetDataMap) const
{
// Take a guess to find the asset instead of searching for it. Most packages have a single asset in them with the same name as the package.
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
FARFilter Filter;
for ( auto PackageIt = AllPackageNames.CreateConstIterator(); PackageIt; ++PackageIt )
{
const FString& PackageName = (*PackageIt).ToString();
const FString& PackagePath = PackageName + TEXT(".") + FPackageName::GetLongPackageAssetName(PackageName);
Filter.ObjectPaths.Add( FName(*PackagePath) );
}
TArray<FAssetData> AssetDataList;
AssetRegistryModule.Get().GetAssets(Filter, AssetDataList);
for ( auto AssetIt = AssetDataList.CreateConstIterator(); AssetIt; ++AssetIt )
{
OutPackageToAssetDataMap.Add((*AssetIt).PackageName, *AssetIt);
}
}
UEdGraphNode_Reference* UEdGraph_ReferenceViewer::RecursivelyConstructNodes(bool bReferencers, UEdGraphNode_Reference* RootNode, const TArray<FName>& PackageNames, const FIntPoint& NodeLoc, const TMap<FName, int32>& NodeSizes, const TMap<FName, FAssetData>& PackagesToAssetDataMap, int32 CurrentDepth, TSet<FName>& VisitedNames)
{
check(PackageNames.Num() > 0);
VisitedNames.Append(PackageNames);
UEdGraphNode_Reference* NewNode = NULL;
if ( RootNode->GetPackageName() == PackageNames[0] )
{
// Don't create the root node. It is already created!
NewNode = RootNode;
}
else
{
NewNode = CreateReferenceNode();
NewNode->SetupReferenceNode(NodeLoc, PackageNames, PackagesToAssetDataMap.FindRef(PackageNames[0]));
}
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
TArray<FName> ReferenceNames;
if ( bReferencers )
{
for ( auto NameIt = PackageNames.CreateConstIterator(); NameIt; ++NameIt )
{
AssetRegistryModule.Get().GetReferencers(*NameIt, ReferenceNames);
}
}
else
{
for ( auto NameIt = PackageNames.CreateConstIterator(); NameIt; ++NameIt )
{
AssetRegistryModule.Get().GetDependencies(*NameIt, ReferenceNames);
}
}
if ( ReferenceNames.Num() > 0 && !ExceedsMaxSearchDepth(CurrentDepth) )
{
FIntPoint ReferenceNodeLoc = NodeLoc;
if ( bReferencers )
{
// Referencers go left
ReferenceNodeLoc.X -= 800;
}
else
{
// Dependencies go right
ReferenceNodeLoc.X += 800;
}
const int32 NodeSizeY = 200;
const int32 TotalReferenceSizeY = NodeSizes.FindChecked(PackageNames[0]) * NodeSizeY;
ReferenceNodeLoc.Y -= TotalReferenceSizeY * 0.5f;
ReferenceNodeLoc.Y += NodeSizeY * 0.5f;
int32 NumReferencesMade = 0;
int32 NumReferencesExceedingMax = 0;
for ( int32 RefIdx = 0; RefIdx < ReferenceNames.Num(); ++RefIdx )
{
FName ReferenceName = ReferenceNames[RefIdx];
if ( !VisitedNames.Contains(ReferenceName) )
{
if ( !ExceedsMaxSearchBreadth(NumReferencesMade) )
{
const int32 RefSizeY = NodeSizes.FindChecked(ReferenceName);
FIntPoint RefNodeLoc;
RefNodeLoc.X = ReferenceNodeLoc.X;
RefNodeLoc.Y = ReferenceNodeLoc.Y + RefSizeY * NodeSizeY * 0.5 - NodeSizeY * 0.5;
TArray<FName> NewPackageNames;
NewPackageNames.Add(ReferenceName);
UEdGraphNode_Reference* ReferenceNode = RecursivelyConstructNodes(bReferencers, RootNode, NewPackageNames, RefNodeLoc, NodeSizes, PackagesToAssetDataMap, CurrentDepth + 1, VisitedNames);
if ( ensure(ReferenceNode) )
{
if ( bReferencers )
{
NewNode->AddReferencer( ReferenceNode );
}
else
{
ReferenceNode->AddReferencer( NewNode );
}
ReferenceNodeLoc.Y += RefSizeY * NodeSizeY;
}
NumReferencesMade++;
}
else
{
NumReferencesExceedingMax++;
}
}
}
if ( NumReferencesExceedingMax > 0 )
{
// There are more references than allowed to be displayed. Make a collapsed node.
UEdGraphNode_Reference* ReferenceNode = CreateReferenceNode();
FIntPoint RefNodeLoc;
RefNodeLoc.X = ReferenceNodeLoc.X;
RefNodeLoc.Y = ReferenceNodeLoc.Y;
if ( ensure(ReferenceNode) )
{
ReferenceNode->SetReferenceNodeCollapsed(RefNodeLoc, NumReferencesExceedingMax);
if ( bReferencers )
{
NewNode->AddReferencer( ReferenceNode );
}
else
{
ReferenceNode->AddReferencer( NewNode );
}
}
}
}
return NewNode;
}
const TSharedPtr<FAssetThumbnailPool>& UEdGraph_ReferenceViewer::GetAssetThumbnailPool() const
{
return AssetThumbnailPool;
}
bool UEdGraph_ReferenceViewer::ExceedsMaxSearchDepth(int32 Depth) const
{
return bLimitSearchDepth && Depth > MaxSearchDepth;
}
bool UEdGraph_ReferenceViewer::ExceedsMaxSearchBreadth(int32 Breadth) const
{
return bLimitSearchBreadth && Breadth > MaxSearchBreadth;
}
UEdGraphNode_Reference* UEdGraph_ReferenceViewer::CreateReferenceNode()
{
const bool bSelectNewNode = false;
return Cast<UEdGraphNode_Reference>(CreateNode(UEdGraphNode_Reference::StaticClass(), bSelectNewNode));
}
void UEdGraph_ReferenceViewer::RemoveAllNodes()
{
TArray<UEdGraphNode*> NodesToRemove = Nodes;
for (int32 NodeIndex = 0; NodeIndex < NodesToRemove.Num(); ++NodeIndex)
{
RemoveNode(NodesToRemove[NodeIndex]);
}
}