From 1586ec9268a867955567caef49c829afde68bf74 Mon Sep 17 00:00:00 2001 From: jyelon Date: Tue, 7 Apr 2026 18:20:28 -0400 Subject: [PATCH] WingFetcher stores strong object pointers --- .../Source/UEWingman/Private/WingFetcher.cpp | 46 +++++++++---------- .../Source/UEWingman/Public/WingFetcher.h | 13 +++--- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/Plugins/UEWingman/Source/UEWingman/Private/WingFetcher.cpp b/Plugins/UEWingman/Source/UEWingman/Private/WingFetcher.cpp index 41aeab48..cda062a8 100644 --- a/Plugins/UEWingman/Source/UEWingman/Private/WingFetcher.cpp +++ b/Plugins/UEWingman/Source/UEWingman/Private/WingFetcher.cpp @@ -38,22 +38,22 @@ void WingFetcher::SetObj(UObject* InObj) { if (!bSkipNotify) UWingServer::AddTouchedObject(InObj); - Obj = InObj; + Obj.Reset(InObj); ResultPin = nullptr; } void WingFetcher::SetPin(UEdGraphPin* InPin) { ResultPin = InPin; - Obj = nullptr; + Obj.Reset(); } WingFetcher& WingFetcher::SetError() { bError = true; - Obj = nullptr; + Obj.Reset(); ResultPin = nullptr; - OriginalAsset = nullptr; + OriginalAsset.Reset(); Editor = nullptr; return *this; } @@ -63,7 +63,7 @@ void WingFetcher::PathFailed(const TCHAR* Expected) if (ResultPin) Errors.Printf(TEXT("ERROR: Path specifies a pin, but expected %s\n"), Expected); else if (Obj) - Errors.Printf(TEXT("ERROR: Path specifies a %s, but expected %s\n"), *Obj->GetClass()->GetName(), Expected); + Errors.Printf(TEXT("ERROR: Path specifies a %s, but expected %s\n"), *Obj.Get()->GetClass()->GetName(), Expected); else Errors.Printf(TEXT("ERROR: Path led to a null pointer\n")); UWingServer::SuggestManual(WingManual::Section::Paths); @@ -75,7 +75,7 @@ WingFetcher& WingFetcher::TypeMismatch(const TCHAR* Walker, const TCHAR* Expecte if (ResultPin) Errors.Printf(TEXT("ERROR: Input to '%s' is a pin, but expected %s\n"), Walker, Expected); else if (Obj) - Errors.Printf(TEXT("ERROR: Input to '%s' is %s, but expected %s\n"), Walker, *Obj->GetClass()->GetName(), Expected); + Errors.Printf(TEXT("ERROR: Input to '%s' is %s, but expected %s\n"), Walker, *Obj.Get()->GetClass()->GetName(), Expected); else Errors.Printf(TEXT("ERROR: Path led to a null pointer\n")); UWingServer::SuggestManual(WingManual::Section::Paths); @@ -154,16 +154,16 @@ WingFetcher& WingFetcher::Asset(const FString& PackagePath) return SetError(); } - OriginalAsset = Obj; + 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)) + if (!Sub || !Sub->OpenEditorForAsset(Obj.Get())) { Errors.Printf(TEXT("ERROR: Could not open editor for '%s'\n"), *PackagePath); return SetError(); } - Editor = Sub->FindEditorForAsset(OriginalAsset, false); + Editor = Sub->FindEditorForAsset(OriginalAsset.Get(), false); if (!Editor) { Errors.Printf(TEXT("ERROR: Could not find editor instance for '%s'\n"), *PackagePath); @@ -171,7 +171,7 @@ WingFetcher& WingFetcher::Asset(const FString& PackagePath) } // If this is a material, use the editor's transient copy. - if (UMaterial* Mat = ::Cast(Obj)) + if (UMaterial* Mat = ::Cast(Obj.Get())) { IMaterialEditor *MatEditor = static_cast(Editor); SetObj(MatEditor->GetMaterialInterface()->GetBaseMaterial()); @@ -182,10 +182,10 @@ WingFetcher& WingFetcher::Asset(const FString& PackagePath) bool WingFetcher::CheckAssetIsA(UClass* StaticClass) { if (bError) return false; - if (!OriginalAsset || !OriginalAsset->IsA(StaticClass)) + if (!OriginalAsset || !OriginalAsset.Get()->IsA(StaticClass)) { Errors.Printf(TEXT("ERROR: Asset is %s, expected %s\n"), - OriginalAsset ? *OriginalAsset->GetClass()->GetName() : TEXT("null"), + OriginalAsset ? *OriginalAsset.Get()->GetClass()->GetName() : TEXT("null"), *StaticClass->GetName()); SetError(); return false; @@ -198,7 +198,7 @@ WingFetcher& WingFetcher::Graph(const FString& Value) if (bError) return *this; // Material with blank graph name - if (UMaterial* Mat = ::Cast(Obj)) + if (UMaterial* Mat = ::Cast(Obj.Get())) { if (!Value.IsEmpty()) { @@ -216,7 +216,7 @@ WingFetcher& WingFetcher::Graph(const FString& Value) return *this; } - UBlueprint* BP = ::Cast(Obj); + UBlueprint* BP = ::Cast(Obj.Get()); if (!BP) { TypeMismatch(TEXT("graph"), TEXT("Blueprint or Material")); @@ -244,7 +244,7 @@ WingFetcher& WingFetcher::Node(const FString& Value) if (bError) return *this; // If current object is not a graph, refuse. - UEdGraph *Graph = ::Cast(Obj); + UEdGraph *Graph = ::Cast(Obj.Get()); if (Graph == nullptr) { TypeMismatch(TEXT("node"), TEXT("Graph")); @@ -271,7 +271,7 @@ WingFetcher& WingFetcher::Pin(const FString& Value) { if (bError) return *this; - UEdGraphNode* N = ::Cast(Obj); + UEdGraphNode* N = ::Cast(Obj.Get()); if (!N) { TypeMismatch(TEXT("pin"), TEXT("node")); @@ -295,7 +295,7 @@ WingFetcher& WingFetcher::Component(const FString& Value) { if (bError) return *this; - UBlueprint* BP = ::Cast(Obj); + UBlueprint* BP = ::Cast(Obj.Get()); if (!BP) { TypeMismatch(TEXT("component"), TEXT("Blueprint")); @@ -322,7 +322,7 @@ WingFetcher& WingFetcher::Widget(const FString& Value) { if (bError) return *this; - UWidgetBlueprint* WidgetBP = ::Cast(Obj); + UWidgetBlueprint* WidgetBP = ::Cast(Obj.Get()); if (!WidgetBP) { TypeMismatch(TEXT("widget"), TEXT("WidgetBlueprint")); @@ -349,7 +349,7 @@ WingFetcher& WingFetcher::LevelBlueprint(const FString& Value) { if (bError) return *this; - UWorld* World = ::Cast(Obj); + UWorld* World = ::Cast(Obj.Get()); if (!World) { TypeMismatch(TEXT("levelblueprint"), TEXT("world")); @@ -389,14 +389,14 @@ WingFetcher& WingFetcher::StructProp(const FString& Value) FStructProperty* StructProp = nullptr; // The "host" is the object containing this property. - UObject *HostObject = Obj; - void *HostBase = Obj; - UStruct *HostType = Obj->GetClass(); + UObject *HostObject = Obj.Get(); + void *HostBase = Obj.Get(); + UStruct *HostType = Obj.Get()->GetClass(); bool HostEditable = true; // If we are *already* inside a UWingStructPointer, update the host // fields, to make it possible to navigate even further inside. - if (UWingStructPointer *SPtr = ::Cast(Obj)) + if (UWingStructPointer *SPtr = ::Cast(Obj.Get())) { HostObject = SPtr->Object; HostBase = SPtr->StructBase; diff --git a/Plugins/UEWingman/Source/UEWingman/Public/WingFetcher.h b/Plugins/UEWingman/Source/UEWingman/Public/WingFetcher.h index 3ab286fd..c5011d1a 100644 --- a/Plugins/UEWingman/Source/UEWingman/Public/WingFetcher.h +++ b/Plugins/UEWingman/Source/UEWingman/Public/WingFetcher.h @@ -1,6 +1,7 @@ #pragma once #include "CoreMinimal.h" +#include "UObject/StrongObjectPtr.h" #include "WingUtils.h" class UEdGraphPin; @@ -69,7 +70,7 @@ public: template T *Cast() { if (bError) return nullptr; - T* Result = ::Cast(Obj); + T* Result = ::Cast(Obj.Get()); if (Result == nullptr) PathFailed(*T::StaticClass()->GetName()); return Result; } @@ -77,13 +78,13 @@ public: // Get the current object as a UObject if it is one, // otherwise nullptr. Does not generate errors. // - UObject* GetObj() const { return Obj; } + UObject* GetObj() const { return Obj.Get(); } // Get the asset from where it all began: the first // step in the walk path. If the asset couldn't be // loaded, returns nullptr. Does not generate errors. // - UObject* GetAsset() const { return OriginalAsset; } + UObject* GetAsset() const { return OriginalAsset.Get(); } // Get the asset from where it all began: the first // step in the walk path, as a specified type. Errors @@ -92,7 +93,7 @@ public: template T* CastAsset() { if (!CheckAssetIsA(T::StaticClass())) return nullptr; - return ::Cast(OriginalAsset); + return ::Cast(OriginalAsset.Get()); } // When an asset is loaded, an editor is automatically @@ -127,11 +128,11 @@ public: private: // The Current Object. Only one of these can be non-null. - UObject* Obj = nullptr; + TStrongObjectPtr Obj; UEdGraphPin* ResultPin = nullptr; // The Starting Asset and the Editor we Opened. - UObject* OriginalAsset = nullptr; + TStrongObjectPtr OriginalAsset; IAssetEditorInstance* Editor = nullptr; // True if an error has occurred.