Files
integration/Plugins/BlueprintMCP/Source/BlueprintMCP/Public/MCPFetcher.h
2026-03-12 21:31:41 -04:00

102 lines
3.0 KiB
C++

#pragma once
#include "CoreMinimal.h"
#include "MCPUtils.h"
class UEdGraphPin;
// Resolves a path string into a UObject or UEdGraphPin.
//
// A path starts with a package path (e.g. "/Game/Widgets/WB_Hotkeys"),
// followed by zero or more comma-separated walker segments of the form
// "key:value". Each segment navigates from the current object to a child.
//
// The list of supported walkers is defined by GetWalkerTable().
//
// Example paths:
// /Game/Widgets/WB_Hotkeys,graph:ReadLuaConfiguration,node:Self_Reference_03,pin:Result
// /Game/Tangibles/TAN_Character,component:CharacterMesh0
//
// Builder-style usage:
// MCPFetcher F(cb);
// if (!F.Walk(Path).Ok()) return;
//
// MCPFetcher F(cb, ExistingObj);
// if (!F.Graph("EventGraph").Node("MyNode").Ok()) return;
//
class MCPFetcher
{
public:
bool bError = false;
UObject* Obj = nullptr;
UEdGraphPin* ResultPin = nullptr;
MCPErrorCallback ErrorCB = nullptr;
MCPFetcher(MCPErrorCallback CB) : ErrorCB(CB) {}
MCPFetcher(MCPErrorCallback CB, UObject* O) : Obj(O), ErrorCB(CB) {}
// Starting point is always Asset.
MCPFetcher& Asset(const FString& PackagePath);
// Walk one step.
MCPFetcher& Graph(const FString& Value);
MCPFetcher& Node(const FString& Value);
MCPFetcher& Pin(const FString& Value);
MCPFetcher& Component(const FString& Value);
MCPFetcher& LevelBlueprint(const FString& Value);
MCPFetcher& MatExp(const FString& Value);
// Parse string and walk multiple steps.
MCPFetcher& Walk(const FString& Path);
// C++-only walk step: resolve to the editable template
// (e.g. Blueprint → CDO, everything else → as-is).
MCPFetcher& Template();
// C++-only navigation: drill down to a specific type.
MCPFetcher& ToBlueprint();
MCPFetcher& ToGraph();
// Walker table entry.
struct FWalker
{
const TCHAR* Key; // e.g. "graph", "node", "matexp"
const TCHAR* Description; // brief help text
MCPFetcher& (MCPFetcher::*Func)(const FString& Value);
};
// Returns the static table of all supported walkers.
static const TArray<FWalker>& GetWalkerTable();
bool Ok() const { return !bError; }
const TArray<UObject*>& Visited() const { return Chain; }
void PreEdit() { MCPUtils::PreEdit(Chain); }
void PostEdit() { MCPUtils::PostEdit(Chain); }
template<class T> T *Cast()
{
if (bError) return nullptr;
T* Result = ::Cast<T>(Obj);
if (Result == nullptr)
TypeMismatch(TEXT("Cast"), *T::StaticClass()->GetName());
return Result;
}
private:
TArray<UObject*> Chain;
static bool StrEq(const FString& A, const TCHAR* B) { return A.Equals(B, ESearchCase::IgnoreCase); }
void SetObj(UObject* InObj) { if (InObj) Chain.AddUnique(InObj); Obj = InObj; ResultPin = nullptr; }
void SetPin(UEdGraphPin* InPin) { ResultPin = InPin; Obj = nullptr; }
MCPFetcher& SetError(const FString& Msg);
MCPFetcher& TypeMismatch(const TCHAR* Walker, const TCHAR* Expected);
const FWalker* GetWalker(const FString& Key);
};
template<> inline UEdGraphPin* MCPFetcher::Cast<UEdGraphPin>()
{
if (bError) return nullptr;
if (!ResultPin)
TypeMismatch(TEXT("Cast"), TEXT("pin"));
return ResultPin;
}