Files
UnrealEngineUWP/Engine/Source/Editor/PhysicsAssetEditor/Private/PhysicsAssetGraph/SPhysicsAssetGraph.h
dave jones2 35ce29a928 UE-110714 - SGraphPanel::OnPaint crash in physics asset editor
Upon construction, SPhysicsAssetGraphNodeOutputPin objects will register callbacks for its pins. However, these objects can potentially reference destroyed UEdGraphPin instances after an undo occurs, since UEdGraphPin deserializaiton will destroy existing pins. There's also a secondary issue where the nodes appear to be disconnected after undo.

The most straightforward fix here is to make SPhysicsAssetGraph a FEditorUndoClient, and then rebuild the underlying graph object.
#jira UE-110714
#rb jamie.dale

[CL 16355305 by dave jones2 in ue5-main branch]
2021-05-17 13:34:29 -04:00

80 lines
2.6 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "PersonaDelegates.h"
#include "GraphEditor.h"
#include "Containers/ArrayView.h"
#include "EditorUndoClient.h"
class UObject;
class UPhysicsAsset;
class UPhysicsAssetGraph;
class IEditableSkeleton;
class UBoneProxy;
class SPhysicsAssetGraph;
class UPhysicsConstraintTemplate;
class USkeletalBodySetup;
class FPhysicsAssetEditor;
/** Delegate used to inform clients of a graph's creation */
DECLARE_DELEGATE_OneParam(FOnPhysicsAssetGraphCreated, const TSharedRef<SPhysicsAssetGraph>& /*InPhysicsAssetGraph*/);
/** Delegate used to communicate graph selection */
DECLARE_DELEGATE_OneParam(FOnGraphObjectsSelected, const TArrayView<UObject*>& /*InObjects*/);
class SPhysicsAssetGraph : public SCompoundWidget, public FEditorUndoClient
{
public:
SLATE_BEGIN_ARGS(SPhysicsAssetGraph){}
SLATE_END_ARGS()
~SPhysicsAssetGraph();
/** SWidget interface */
virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override;
/** FEditorUndoClient interface */
virtual void PostUndo(bool bSuccess) override;
virtual void PostRedo(bool bSuccess) override;
/** Constructs this widget with InArgs */
void Construct(const FArguments& InArgs, const TSharedRef<FPhysicsAssetEditor>& InPhysicsAssetEditor, UPhysicsAsset* InPhysicsAsset, const TSharedRef<IEditableSkeleton>& InEditableSkeleton, FOnGraphObjectsSelected InOnGraphObjectSelected);
/** Set the selected bodies/constraints */
void SelectObjects(const TArray<USkeletalBodySetup*>& InBodies, const TArray<UPhysicsConstraintTemplate*>& InConstraints);
private:
/** Called to create context menu when right-clicking on graph */
FActionMenuContent OnCreateGraphActionMenu(UEdGraph* InGraph, const FVector2D& InNodePosition, const TArray<UEdGraphPin*>& InDraggedPins, bool bAutoExpand, SGraphEditor::FActionMenuClosed InOnMenuClosed);
/** Called when the path is being edited */
void OnSearchBarTextChanged(const FText& NewText);
/** Sets the new path for the viewer */
void OnSearchBarTextCommitted(const FText& NewText, ETextCommit::Type CommitInfo);
void RegisterActions();
void HandleSelectionChanged(const FGraphPanelSelectionSet& SelectionSet);
void HandleNodeDoubleClicked(UEdGraphNode* InNode);
private:
TSharedPtr<SGraphEditor> GraphEditor;
UPhysicsAssetGraph* GraphObj;
FOnGraphObjectsSelected OnGraphObjectsSelected;
bool bZoomToFit;
bool bSelecting;
/** As selection broadcasting is deferred in the graph, we need to block re-broadcasting a for a few frames on refresh */
int32 BlockSelectionBroadcastCounter;
};