UE-93573 Cycle check can fail on rewire

Since a new wire can disconnect an old wire - we need to ignore certain wires when building the map for link validation and cycle checking. With this fix we pass a list of links to ignore (wires to ignore in the graph) to the AST that's going to get build, and then perform cycle checking only with that.

#rb sara.schvartzman
#jira UE-93573

[CL 14577857 by Helge Mathee in ue5-main branch]
This commit is contained in:
Helge Mathee
2020-10-26 12:29:38 -04:00
parent e6aed42888
commit f5b12d86b3
4 changed files with 28 additions and 5 deletions

View File

@@ -823,6 +823,7 @@ FRigVMParserAST::FRigVMParserAST(URigVMGraph* InGraph, URigVMController* InContr
ObsoleteBlock = nullptr;
LastCycleCheckExpr = nullptr;
LinksToSkip = InSettings.LinksToSkip;
const TArray<URigVMNode*> Nodes = InGraph->GetNodes();
for (URigVMNode* Node : Nodes)
@@ -977,9 +978,14 @@ FRigVMExprAST* FRigVMParserAST::TraverseMutableNode(URigVMNode* InNode, FRigVMEx
}
}
TArray<URigVMPin*> TargetPins = SourcePin->GetLinkedTargetPins();
for (URigVMPin* TargetPin : TargetPins)
const TArray<URigVMLink*>& Links = SourcePin->GetLinks();
for(URigVMLink* Link : Links)
{
if (LinksToSkip.Contains(Link))
{
continue;
}
URigVMPin* TargetPin = Link->GetTargetPin();
TraverseMutableNode(TargetPin->GetNode(), ParentExpr);
}
}
@@ -1094,6 +1100,12 @@ FRigVMExprAST* FRigVMParserAST::TraversePin(URigVMPin* InPin, FRigVMExprAST* InP
ensure(!SubjectToExpression.Contains(InPin));
TArray<URigVMLink*> SourceLinks = InPin->GetSourceLinks(true);
if (LinksToSkip.Num() > 0)
{
const TArray<URigVMLink*>& LocalLinksToSkip = LinksToSkip;
SourceLinks.RemoveAll([LocalLinksToSkip](URigVMLink* LinkToCheck) { return LocalLinksToSkip.Contains(LinkToCheck); });
}
struct Local
{

View File

@@ -119,11 +119,12 @@ void URigVMGraph::Notify(ERigVMGraphNotifType InNotifType, UObject* InSubject)
ModifiedEvent.Broadcast(InNotifType, this, InSubject);
}
TSharedPtr<FRigVMParserAST> URigVMGraph::GetDiagnosticsAST(bool bForceRefresh)
TSharedPtr<FRigVMParserAST> URigVMGraph::GetDiagnosticsAST(bool bForceRefresh, TArray<URigVMLink*> InLinksToSkip)
{
if (DiagnosticsAST == nullptr || bForceRefresh)
{
FRigVMParserASTSettings Settings = FRigVMParserASTSettings::Fast();
Settings.LinksToSkip = InLinksToSkip;
DiagnosticsAST = MakeShareable(new FRigVMParserAST(this, nullptr, Settings));
}
return DiagnosticsAST;
@@ -164,7 +165,12 @@ bool URigVMGraph::IsNameAvailable(const FString& InName)
void URigVMGraph::PrepareCycleChecking(URigVMPin* InPin, bool bAsInput)
{
GetDiagnosticsAST()->PrepareCycleChecking(InPin);
TArray<URigVMLink*> LinksToSkip;
if (InPin)
{
LinksToSkip = InPin->GetLinks();
}
GetDiagnosticsAST(LinksToSkip.Num() > 0, LinksToSkip)->PrepareCycleChecking(InPin);
}
bool URigVMGraph::CanLink(URigVMPin* InSourcePin, URigVMPin* InTargetPin, FString* OutFailureReason)

View File

@@ -1103,6 +1103,10 @@ struct RIGVMDEVELOPER_API FRigVMParserASTSettings
UPROPERTY(EditAnywhere, Category = "AST")
bool bFoldConstantBranches;
// links to be ignored during the parse
UPROPERTY()
TArray<URigVMLink*> LinksToSkip;
// static method to provide fast AST parse settings
static FRigVMParserASTSettings Fast()
{
@@ -1334,6 +1338,7 @@ private:
const FRigVMExprAST* LastCycleCheckExpr;
TArray<ETraverseRelationShip> CycleCheckFlags;
TArray<URigVMLink*> LinksToSkip;
friend class FRigVMExprAST;
friend class URigVMCompiler;

View File

@@ -79,7 +79,7 @@ public:
void PrepareCycleChecking(URigVMPin* InPin, bool bAsInput);
virtual bool CanLink(URigVMPin* InSourcePin, URigVMPin* InTargetPin, FString* OutFailureReason = nullptr);
TSharedPtr<FRigVMParserAST> GetDiagnosticsAST(bool bForceRefresh = false);
TSharedPtr<FRigVMParserAST> GetDiagnosticsAST(bool bForceRefresh = false, TArray<URigVMLink*> InLinksToSkip = TArray<URigVMLink*>());
TSharedPtr<FRigVMParserAST> GetRuntimeAST(const FRigVMParserASTSettings& InSettings = FRigVMParserASTSettings::Optimized(), bool bForceRefresh = false);
void ClearAST(bool bClearDiagnostics = true, bool bClearRuntime = true);