Files
integration/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/Handlers/UMCPHandler_CreateEnumAsset.h

98 lines
3.4 KiB
C
Raw Normal View History

2026-03-08 22:17:14 -04:00
#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
#include "MCPAssetFinder.h"
#include "MCPUtils.h"
#include "StructUtils/UserDefinedStruct.h"
#include "Engine/UserDefinedEnum.h"
#include "Kismet2/BlueprintEditorUtils.h"
#include "UserDefinedStructure/UserDefinedStructEditorData.h"
#include "Kismet2/EnumEditorUtils.h"
#include "AssetRegistry/AssetRegistryModule.h"
#include "AssetRegistry/IAssetRegistry.h"
#include "AssetToolsModule.h"
#include "IAssetTools.h"
#include "Factories/StructureFactory.h"
#include "Factories/EnumFactory.h"
#include "UMCPHandler_CreateEnumAsset.generated.h"
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
UCLASS()
class UMCPHandler_CreateEnumAsset : public UObject, public IMCPHandler
{
GENERATED_BODY()
public:
UPROPERTY(meta=(Description="Full package path for the new enum (e.g. '/Game/DataTypes/E_MyEnum')"))
FString AssetPath;
UPROPERTY(meta=(Description="Array of enum value names"))
FMCPJsonArray Values;
virtual FString GetDescription() const override
{
return TEXT("Create a new UserDefinedEnum asset with the specified values.");
}
virtual void Handle(const FJsonObject* Json, FJsonObject* Result) override
{
FString PackagePath, AssetName;
if (!MCPUtils::SplitAssetPath(AssetPath, PackagePath, AssetName))
{
return MCPUtils::MakeErrorJson(Result, TEXT("assetPath must be a full path (e.g. '/Game/DataTypes/E_MyEnum')"));
}
TArray<FString> EnumValues;
for (const TSharedPtr<FJsonValue>& Val : Values.Array)
{
FString Str = Val->AsString();
if (!Str.IsEmpty()) EnumValues.Add(Str);
}
if (EnumValues.Num() == 0)
{
return MCPUtils::MakeErrorJson(Result, TEXT("Missing or empty required field: values (array of strings)"));
}
// Create the enum using AssetTools
FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools");
IAssetTools& AssetTools = AssetToolsModule.Get();
UEnumFactory* Factory = NewObject<UEnumFactory>();
UObject* NewAsset = AssetTools.CreateAsset(AssetName, PackagePath, UUserDefinedEnum::StaticClass(), Factory);
if (!NewAsset)
{
return MCPUtils::MakeErrorJson(Result, TEXT("Failed to create UserDefinedEnum asset"));
}
UUserDefinedEnum* NewEnum = Cast<UUserDefinedEnum>(NewAsset);
if (!NewEnum)
{
return MCPUtils::MakeErrorJson(Result, TEXT("Created asset is not a UserDefinedEnum"));
}
// Add enum values — UUserDefinedEnum starts with a MAX value.
// We need to add entries before MAX.
for (int32 i = 0; i < EnumValues.Num(); ++i)
{
// AddNewEnumeratorForUserDefinedEnum adds before the _MAX entry (returns void)
FEnumEditorUtils::AddNewEnumeratorForUserDefinedEnum(NewEnum);
// The new entry is at index (NumEnums - 2) because _MAX is last
int32 NewIndex = NewEnum->NumEnums() - 2;
FEnumEditorUtils::SetEnumeratorDisplayName(NewEnum, NewIndex, FText::FromString(EnumValues[i]));
}
// Save
bool bSaved = MCPUtils::SaveGenericPackage(NewEnum);
Result->SetStringField(TEXT("assetName"), AssetName);
Result->SetNumberField(TEXT("valueCount"), EnumValues.Num());
Result->SetBoolField(TEXT("saved"), bSaved);
}
};