Files
UnrealEngineUWP/Engine/Source/Developer/RigVMDeveloper/Private/RigVMModel/Nodes/RigVMFunctionReferenceNode.cpp
helge mathee 3acbeeb2d3 RigVM: Store a hash along side each graph identifying the structural state
Avoid rebuilding graphs if we don't need to. hashes contain the structure of each node, the structure of any used data type and the structure of each used template.

#rb sara.schvartzman
#preflight https://horde.devtools.epicgames.com/job/63ee1c6fc9692d7c04423941

[CL 24280391 by helge mathee in ue5-main branch]
2023-02-17 08:46:05 -05:00

217 lines
6.3 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "RigVMModel/Nodes/RigVMFunctionReferenceNode.h"
#include "RigVMModel/RigVMFunctionLibrary.h"
#include "RigVMCore/RigVMGraphFunctionDefinition.h"
#include "RigVMCore/RigVMGraphFunctionHost.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(RigVMFunctionReferenceNode)
FString URigVMFunctionReferenceNode::GetNodeTitle() const
{
return ReferencedFunctionHeader.NodeTitle;
}
FLinearColor URigVMFunctionReferenceNode::GetNodeColor() const
{
return ReferencedFunctionHeader.NodeColor;
}
FText URigVMFunctionReferenceNode::GetToolTipText() const
{
return ReferencedFunctionHeader.Tooltip;
}
FString URigVMFunctionReferenceNode::GetNodeCategory() const
{
return ReferencedFunctionHeader.Category;
}
FString URigVMFunctionReferenceNode::GetNodeKeywords() const
{
return ReferencedFunctionHeader.Keywords;
}
bool URigVMFunctionReferenceNode::RequiresVariableRemapping() const
{
TArray<FRigVMExternalVariable> InnerVariables;
return RequiresVariableRemappingInternal(InnerVariables);
}
bool URigVMFunctionReferenceNode::RequiresVariableRemappingInternal(TArray<FRigVMExternalVariable>& InnerVariables) const
{
bool bHostedInDifferencePackage = false;
FRigVMGraphFunctionIdentifier LibraryPointer = ReferencedFunctionHeader.LibraryPointer;
const FString& LibraryPackagePath = LibraryPointer.LibraryNode.GetLongPackageName();
const FString& ThisPacakgePath = GetPackage()->GetPathName();
bHostedInDifferencePackage = LibraryPackagePath != ThisPacakgePath;
if(bHostedInDifferencePackage)
{
InnerVariables = ReferencedFunctionHeader.ExternalVariables;
if(InnerVariables.Num() == 0)
{
return false;
}
}
return bHostedInDifferencePackage;
}
bool URigVMFunctionReferenceNode::IsFullyRemapped() const
{
TArray<FRigVMExternalVariable> InnerVariables;
if(!RequiresVariableRemappingInternal(InnerVariables))
{
return true;
}
for(const FRigVMExternalVariable& InnerVariable : InnerVariables)
{
const FName InnerVariableName = InnerVariable.Name;
const FName* OuterVariableName = VariableMap.Find(InnerVariableName);
if(OuterVariableName == nullptr)
{
return false;
}
check(!OuterVariableName->IsNone());
}
return true;
}
TArray<FRigVMExternalVariable> URigVMFunctionReferenceNode::GetExternalVariables() const
{
return GetExternalVariables(true);
}
TArray<FRigVMExternalVariable> URigVMFunctionReferenceNode::GetExternalVariables(bool bRemapped) const
{
TArray<FRigVMExternalVariable> Variables;
if(!bRemapped)
{
Variables = ReferencedFunctionHeader.ExternalVariables;
}
else
{
if(RequiresVariableRemappingInternal(Variables))
{
for(FRigVMExternalVariable& Variable : Variables)
{
const FName* OuterVariableName = VariableMap.Find(Variable.Name);
if(OuterVariableName != nullptr)
{
check(!OuterVariableName->IsNone());
Variable.Name = *OuterVariableName;
}
}
}
}
return Variables;
}
FName URigVMFunctionReferenceNode::GetOuterVariableName(const FName& InInnerVariableName) const
{
if(const FName* OuterVariableName = VariableMap.Find(InInnerVariableName))
{
return *OuterVariableName;
}
return NAME_None;
}
uint32 URigVMFunctionReferenceNode::GetStructureHash() const
{
const FRigVMRegistry& Registry = FRigVMRegistry::Get();
uint32 Hash = Super::GetStructureHash();
Hash = HashCombine(Hash, GetTypeHash(ReferencedFunctionHeader.Name.ToString()));
Hash = HashCombine(Hash, GetTypeHash(ReferencedFunctionHeader.NodeTitle));
Hash = HashCombine(Hash, GetTypeHash(ReferencedFunctionHeader.LibraryPointer.LibraryNode.ToString()));
Hash = HashCombine(Hash, GetTypeHash(ReferencedFunctionHeader.Keywords));
Hash = HashCombine(Hash, GetTypeHash(ReferencedFunctionHeader.Tooltip.ToString()));
Hash = HashCombine(Hash, GetTypeHash(ReferencedFunctionHeader.NodeColor));
for(const FRigVMGraphFunctionArgument& Argument : ReferencedFunctionHeader.Arguments)
{
Hash = HashCombine(Hash, GetTypeHash(Argument.Name.ToString()));
Hash = HashCombine(Hash, GetTypeHash((int32)Argument.Direction));
const TRigVMTypeIndex TypeIndex = Registry.GetTypeIndexFromCPPType(Argument.CPPType.ToString());
Hash = HashCombine(Hash, Registry.GetHashForType(TypeIndex));
for(const TPair<FString, FText>& Pair : Argument.PathToTooltip)
{
Hash = HashCombine(Hash, GetTypeHash(Pair.Key));
Hash = HashCombine(Hash, GetTypeHash(Pair.Value.ToString()));
}
}
for(const FRigVMExternalVariable& ExternalVariable : ReferencedFunctionHeader.ExternalVariables)
{
Hash = HashCombine(Hash, GetTypeHash(ExternalVariable.Name.ToString()));
const TRigVMTypeIndex TypeIndex = Registry.GetTypeIndexFromCPPType(ExternalVariable.TypeName.ToString());
Hash = HashCombine(Hash, Registry.GetHashForType(TypeIndex));
}
return Hash;
}
const FRigVMGraphFunctionData* URigVMFunctionReferenceNode::GetReferencedFunctionData() const
{
if (IRigVMGraphFunctionHost* Host = ReferencedFunctionHeader.GetFunctionHost())
{
return Host->GetRigVMGraphFunctionStore()->FindFunction(ReferencedFunctionHeader.LibraryPointer);
}
return nullptr;
}
FText URigVMFunctionReferenceNode::GetToolTipTextForPin(const URigVMPin* InPin) const
{
check(InPin);
URigVMPin* RootPin = InPin->GetRootPin();
const FRigVMGraphFunctionArgument* Argument = ReferencedFunctionHeader.Arguments.FindByPredicate([RootPin](const FRigVMGraphFunctionArgument& Argument)
{
return Argument.Name == RootPin->GetFName();
});
if (Argument)
{
if (const FText* Tooltip = Argument->PathToTooltip.Find(InPin->GetSegmentPath(false)))
{
return *Tooltip;
}
}
return Super::GetToolTipTextForPin(InPin);
}
FRigVMGraphFunctionIdentifier URigVMFunctionReferenceNode::GetFunctionIdentifier() const
{
return GetReferencedFunctionHeader().LibraryPointer;
}
bool URigVMFunctionReferenceNode::IsReferencedFunctionHostLoaded() const
{
return ReferencedFunctionHeader.LibraryPointer.HostObject.ResolveObject() != nullptr;
}
bool URigVMFunctionReferenceNode::IsReferencedNodeLoaded() const
{
return ReferencedFunctionHeader.LibraryPointer.LibraryNode.ResolveObject() != nullptr;
}
URigVMLibraryNode* URigVMFunctionReferenceNode::LoadReferencedNode() const
{
UObject* LibraryNode = ReferencedFunctionHeader.LibraryPointer.LibraryNode.ResolveObject();
if (!LibraryNode)
{
LibraryNode = ReferencedFunctionHeader.LibraryPointer.LibraryNode.TryLoad();
}
return Cast<URigVMLibraryNode>(LibraryNode);
}