From 9dd4031847db6ef40c40a190dfc167e0700e61df Mon Sep 17 00:00:00 2001 From: jyelon Date: Tue, 7 Apr 2026 18:43:58 -0400 Subject: [PATCH] Don't store the editor in the WingFetcher. --- .../UEWingman/Handlers/GraphNode_Remove.h | 9 +++++-- .../Source/UEWingman/Private/WingFetcher.cpp | 26 +++++++------------ .../Source/UEWingman/Private/WingUtils.cpp | 24 +++++++++++++++++ .../Source/UEWingman/Public/WingFetcher.h | 15 +---------- .../Source/UEWingman/Public/WingUtils.h | 5 +++- 5 files changed, 45 insertions(+), 34 deletions(-) diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Remove.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Remove.h index 5252d5b2..cda23304 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Remove.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Remove.h @@ -53,8 +53,13 @@ public: { // Use the material editor's DeleteNodes to properly remove // both the graph node and the underlying material expression. - IMaterialEditor* MatEditor = F.CastEditor(); - if (!MatEditor) return; + UMaterial* Material = F.CastAsset(); + if (!Material) return; + + IAssetEditorInstance* Editor = WingUtils::CheckOpenEditorForAsset(Material, WingOut::Stdout); + if (!Editor) return; + + IMaterialEditor* MatEditor = static_cast(Editor); MatEditor->DeleteNodes({FoundNode}); } else diff --git a/Plugins/UEWingman/Source/UEWingman/Private/WingFetcher.cpp b/Plugins/UEWingman/Source/UEWingman/Private/WingFetcher.cpp index cda062a8..766a44d6 100644 --- a/Plugins/UEWingman/Source/UEWingman/Private/WingFetcher.cpp +++ b/Plugins/UEWingman/Source/UEWingman/Private/WingFetcher.cpp @@ -18,7 +18,6 @@ #include "WidgetBlueprint.h" #include "Blueprint/WidgetTree.h" #include "Components/Widget.h" -#include "Subsystems/AssetEditorSubsystem.h" #include "WingServer.h" #include "WingManual.h" @@ -54,7 +53,6 @@ WingFetcher& WingFetcher::SetError() Obj.Reset(); ResultPin = nullptr; OriginalAsset.Reset(); - Editor = nullptr; return *this; } @@ -156,26 +154,20 @@ WingFetcher& WingFetcher::Asset(const FString& PackagePath) OriginalAsset.Reset(Obj.Get()); - // Open the editor for this asset (or bring it to front if already open). - UAssetEditorSubsystem* Sub = GEditor->GetEditorSubsystem(); - if (!Sub || !Sub->OpenEditorForAsset(Obj.Get())) - { - Errors.Printf(TEXT("ERROR: Could not open editor for '%s'\n"), *PackagePath); - return SetError(); - } - Editor = Sub->FindEditorForAsset(OriginalAsset.Get(), false); - if (!Editor) - { - Errors.Printf(TEXT("ERROR: Could not find editor instance for '%s'\n"), *PackagePath); - return SetError(); - } - - // If this is a material, use the editor's transient copy. + // If this is a material, open the editor and get the transient copy. + // If it's not a material, try to open the editor, but it's okay if we can't. if (UMaterial* Mat = ::Cast(Obj.Get())) { + IAssetEditorInstance* Editor = WingUtils::CheckOpenEditorForAsset(OriginalAsset.Get(), Errors); + if (!Editor) return SetError(); IMaterialEditor *MatEditor = static_cast(Editor); SetObj(MatEditor->GetMaterialInterface()->GetBaseMaterial()); } + else + { + WingUtils::CheckOpenEditorForAsset(OriginalAsset.Get(), nullptr); + } + return *this; } diff --git a/Plugins/UEWingman/Source/UEWingman/Private/WingUtils.cpp b/Plugins/UEWingman/Source/UEWingman/Private/WingUtils.cpp index 5a3d41d6..8a7d2cdb 100644 --- a/Plugins/UEWingman/Source/UEWingman/Private/WingUtils.cpp +++ b/Plugins/UEWingman/Source/UEWingman/Private/WingUtils.cpp @@ -490,6 +490,30 @@ UObject *WingUtils::GetGeneratedCDO(UBlueprint *BP) return BP->GeneratedClass->GetDefaultObject(); } +// ============================================================ +// Editor helpers +// ============================================================ + +IAssetEditorInstance* WingUtils::CheckOpenEditorForAsset(UObject* Asset, WingOut Errors) +{ + const FString AssetPath = Asset ? Asset->GetPathName() : TEXT("null"); + UAssetEditorSubsystem* Sub = GEditor ? GEditor->GetEditorSubsystem() : nullptr; + if (!Sub || !Sub->OpenEditorForAsset(Asset)) + { + Errors.Printf(TEXT("ERROR: Could not open editor for '%s'\n"), *AssetPath); + return nullptr; + } + + IAssetEditorInstance* Editor = Sub->FindEditorForAsset(Asset, false); + if (!Editor) + { + Errors.Printf(TEXT("ERROR: Could not find editor instance for '%s'\n"), *AssetPath); + return nullptr; + } + + return Editor; +} + // ============================================================ // Material helpers // ============================================================ diff --git a/Plugins/UEWingman/Source/UEWingman/Public/WingFetcher.h b/Plugins/UEWingman/Source/UEWingman/Public/WingFetcher.h index c5011d1a..d4dd9a15 100644 --- a/Plugins/UEWingman/Source/UEWingman/Public/WingFetcher.h +++ b/Plugins/UEWingman/Source/UEWingman/Public/WingFetcher.h @@ -96,18 +96,6 @@ public: return ::Cast(OriginalAsset.Get()); } - // When an asset is loaded, an editor is automatically - // opened. Get the editor. You must specify the type - // that you expect the asset to be, and the type to cast - // the editor to. Does not generate errors. - // - template - EditorType* CastEditor() - { - if (!CheckAssetIsA(AssetType::StaticClass())) return nullptr; - return static_cast(Editor); - } - // Calling SkipNotify disables change notifications // for objects visited by this fetcher. Useful for // read-only operations that don't modify anything. @@ -131,9 +119,8 @@ private: TStrongObjectPtr Obj; UEdGraphPin* ResultPin = nullptr; - // The Starting Asset and the Editor we Opened. + // The Starting Asset. TStrongObjectPtr OriginalAsset; - IAssetEditorInstance* Editor = nullptr; // True if an error has occurred. bool bError = false; diff --git a/Plugins/UEWingman/Source/UEWingman/Public/WingUtils.h b/Plugins/UEWingman/Source/UEWingman/Public/WingUtils.h index 20d19ba3..29673e21 100644 --- a/Plugins/UEWingman/Source/UEWingman/Public/WingUtils.h +++ b/Plugins/UEWingman/Source/UEWingman/Public/WingUtils.h @@ -24,6 +24,7 @@ class UAnimStateTransitionNode; class IPropertyHandle; class UScriptStruct; class UEnum; +class IAssetEditorInstance; struct FBPInterfaceDescription; struct FWingProperty; class IPropertyHandle; @@ -246,6 +247,9 @@ public: static TArray AllNodes(UEdGraph *Graph); static TArray GetAncestorBlueprints(UBlueprint *BP, bool OldestFirst = false); static UObject *GetGeneratedCDO(UBlueprint *BP); + + // ----- Editor helpers ----- + static IAssetEditorInstance* CheckOpenEditorForAsset(UObject* Asset, WingOut Errors); // ----- Material helpers ----- static void EnsureMaterialGraph(UMaterial* Material); @@ -277,4 +281,3 @@ public: static bool CheckCanRename(UEdGraphNode* Node, const FString &Name, WingOut Errors); static bool CheckNewObjectNotNull(UObject *Obj, const TCHAR *Kind, WingOut Errors); }; -