type parser.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPTypes.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "StructUtils/UserDefinedStruct.h"
|
||||
#include "UserDefinedStructure/UserDefinedStructEditorData.h"
|
||||
@@ -42,7 +43,7 @@ public:
|
||||
|
||||
// Resolve type
|
||||
FEdGraphPinType PinType;
|
||||
if (!MCPUtils::ResolveTypeFromString(Type, PinType, Result))
|
||||
if (!UMCPTypes::TextToType(Type, PinType, Result))
|
||||
return;
|
||||
|
||||
// Snapshot existing GUIDs so we can find the newly added one
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPTypes.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "Engine/Blueprint.h"
|
||||
@@ -128,7 +129,7 @@ public:
|
||||
if (Entry.Name.IsEmpty() || Entry.Type.IsEmpty()) continue;
|
||||
|
||||
FEdGraphPinType PinType;
|
||||
if (!MCPUtils::ResolveTypeFromString(Entry.Type, PinType))
|
||||
if (!UMCPTypes::TextToType(Entry.Type, PinType))
|
||||
return;
|
||||
|
||||
EntryNode->CreateUserDefinedPin(FName(*Entry.Name), PinType, EGPD_Output);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPTypes.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "MCPServer.h"
|
||||
#include "Engine/Blueprint.h"
|
||||
@@ -50,7 +51,7 @@ public:
|
||||
|
||||
// Resolve param type
|
||||
FEdGraphPinType PinType;
|
||||
if (!MCPUtils::ResolveTypeFromString(ParamType, PinType))
|
||||
if (!UMCPTypes::TextToType(ParamType, PinType))
|
||||
return;
|
||||
|
||||
// Find the entry node using 3 strategies
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPTypes.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "MCPServer.h"
|
||||
#include "Engine/Blueprint.h"
|
||||
@@ -62,7 +63,7 @@ public:
|
||||
|
||||
// Resolve the type
|
||||
FEdGraphPinType PinType;
|
||||
if (!MCPUtils::ResolveTypeFromString(VariableType, PinType))
|
||||
if (!UMCPTypes::TextToType(VariableType, PinType))
|
||||
return;
|
||||
|
||||
if (IsArray)
|
||||
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
|
||||
// Resolve the new type using the shared resolver (supports primitives, structs, enums, and object references)
|
||||
FEdGraphPinType NewPinType;
|
||||
if (!MCPUtils::ResolveTypeFromString(NewType, NewPinType))
|
||||
if (!UMCPTypes::TextToType(NewType, NewPinType))
|
||||
return;
|
||||
|
||||
// Find the entry node: K2Node_FunctionEntry in a function graph,
|
||||
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
ResolveInput = TypeCategory + TEXT(":") + NewType;
|
||||
}
|
||||
|
||||
if (!MCPUtils::ResolveTypeFromString(ResolveInput, NewPinType))
|
||||
if (!UMCPTypes::TextToType(ResolveInput, NewPinType))
|
||||
return;
|
||||
|
||||
// List affected nodes (get/set nodes for this variable)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPTypes.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "Class_ShowProperties.generated.h"
|
||||
|
||||
@@ -62,7 +63,7 @@ public:
|
||||
if (Prop->HasAnyPropertyFlags(CPF_RepNotify)) Flags.Append(TEXT(" RepNotify"));
|
||||
|
||||
UClass* OwnerClass = Prop->GetOwnerClass();
|
||||
UMCPServer::Printf(TEXT(" %s %s"), *MCPUtils::FormatPropertyType(Prop), *PropName);
|
||||
UMCPServer::Printf(TEXT(" %s %s"), *UMCPTypes::TypeToText(Prop), *PropName);
|
||||
if (OwnerClass && OwnerClass != FoundClass)
|
||||
UMCPServer::Printf(TEXT(" [%s]"), *MCPUtils::FormatName(OwnerClass));
|
||||
if (Flags.Len() > 0)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPProperty.h"
|
||||
#include "MCPTypes.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "Property_Dump.generated.h"
|
||||
|
||||
@@ -86,7 +87,7 @@ public:
|
||||
bool bEditable = !P->HasAnyPropertyFlags(CPF_EditConst);
|
||||
UMCPServer::Printf(TEXT(" %s %s %s = %s\n"),
|
||||
bEditable ? TEXT("editable") : TEXT("readonly"),
|
||||
*MCPUtils::FormatPropertyType(P.Prop),
|
||||
*UMCPTypes::TypeToText(P.Prop),
|
||||
*PropName,
|
||||
*ValueStr);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPTypes.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "ShowCommands.generated.h"
|
||||
|
||||
@@ -57,7 +58,7 @@ public:
|
||||
if (!bFirst) UMCPServer::Print(TEXT(","));
|
||||
bFirst = false;
|
||||
if (PropIt->HasMetaData(TEXT("Optional"))) UMCPServer::Print(TEXT("?"));
|
||||
UMCPServer::Print(MCPUtils::FormatPropertyType(*PropIt));
|
||||
UMCPServer::Print(UMCPTypes::TypeToText(*PropIt));
|
||||
UMCPServer::Print(TEXT(" "));
|
||||
UMCPServer::Print(MCPUtils::PropertyNameToJsonKey(PropIt->GetName()));
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPTypes.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "StructUtils/UserDefinedStruct.h"
|
||||
#include "Kismet2/BlueprintEditorUtils.h"
|
||||
@@ -63,7 +64,7 @@ public:
|
||||
if (Entry.Name.IsEmpty() || Entry.Type.IsEmpty()) continue;
|
||||
|
||||
FEdGraphPinType PinType;
|
||||
if (!MCPUtils::ResolveTypeFromString(Entry.Type, PinType))
|
||||
if (!UMCPTypes::TextToType(Entry.Type, PinType))
|
||||
continue;
|
||||
|
||||
// Snapshot existing GUIDs so we can find the newly added one.
|
||||
|
||||
@@ -258,7 +258,7 @@ void FlxBlueprintExporter::EmitMaterialProperty(UMaterialExpression* Expression,
|
||||
bool bEditable = !Prop->HasAnyPropertyFlags(CPF_EditConst);
|
||||
Out.Appendf(TEXT(" %s %s %s = %s\n"),
|
||||
bEditable ? TEXT("mxeditable") : TEXT("mxreadonly"),
|
||||
*MCPUtils::FormatPropertyType(Prop),
|
||||
*UMCPTypes::TypeToText(Prop),
|
||||
*MCPUtils::FormatName(Prop),
|
||||
*ValueStr);
|
||||
}
|
||||
|
||||
@@ -142,6 +142,18 @@ FString UMCPTypes::TypeToText(const FEdGraphPinType& PinType)
|
||||
return Inner;
|
||||
}
|
||||
|
||||
FString UMCPTypes::TypeToText(const FProperty *Property)
|
||||
{
|
||||
FEdGraphPinType PinType;
|
||||
if (!GetDefault<UEdGraphSchema_K2>()->ConvertPropertyToPinType(Property, PinType))
|
||||
{
|
||||
return TEXT("void");
|
||||
}
|
||||
else
|
||||
{
|
||||
return TypeToText(PinType);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Subsystem lifecycle
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "MCPUtils.h"
|
||||
#include "MCPTypes.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "Dom/JsonValue.h"
|
||||
@@ -477,12 +478,10 @@ bool MCPUtils::SaveBlueprintPackage(UBlueprint* BP)
|
||||
*BP->GetName(), bCompiled ? TEXT("yes") : TEXT("no"), (int32)SaveResult);
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
}// ============================================================
|
||||
// FindClassByName
|
||||
// ============================================================
|
||||
// FindClassByName / ResolveTypeFromString
|
||||
// ============================================================
|
||||
|
||||
|
||||
UClass* MCPUtils::FindClassByName(const FString& ClassName)
|
||||
{
|
||||
@@ -509,216 +508,6 @@ UClass* MCPUtils::FindClassByName(const FString& ClassName)
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool MCPUtils::ResolveTypeFromString(
|
||||
const FString& TypeName, FEdGraphPinType& OutPinType)
|
||||
{
|
||||
FString TypeLower = TypeName.ToLower();
|
||||
|
||||
if (TypeLower == TEXT("bool") || TypeLower == TEXT("boolean"))
|
||||
{
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Boolean;
|
||||
}
|
||||
else if (TypeLower == TEXT("int") || TypeLower == TEXT("int32") || TypeLower == TEXT("integer"))
|
||||
{
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Int;
|
||||
}
|
||||
else if (TypeLower == TEXT("int64"))
|
||||
{
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Int64;
|
||||
}
|
||||
else if (TypeLower == TEXT("float") || TypeLower == TEXT("double") || TypeLower == TEXT("real"))
|
||||
{
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Real;
|
||||
OutPinType.PinSubCategory = TEXT("double");
|
||||
}
|
||||
else if (TypeLower == TEXT("string"))
|
||||
{
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_String;
|
||||
}
|
||||
else if (TypeLower == TEXT("name"))
|
||||
{
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Name;
|
||||
}
|
||||
else if (TypeLower == TEXT("text"))
|
||||
{
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Text;
|
||||
}
|
||||
else if (TypeLower == TEXT("byte"))
|
||||
{
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Byte;
|
||||
}
|
||||
else if (TypeLower == TEXT("vector") || TypeLower == TEXT("fvector"))
|
||||
{
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Struct;
|
||||
OutPinType.PinSubCategoryObject = TBaseStructure<FVector>::Get();
|
||||
}
|
||||
else if (TypeLower == TEXT("rotator") || TypeLower == TEXT("frotator"))
|
||||
{
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Struct;
|
||||
OutPinType.PinSubCategoryObject = TBaseStructure<FRotator>::Get();
|
||||
}
|
||||
else if (TypeLower == TEXT("transform") || TypeLower == TEXT("ftransform"))
|
||||
{
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Struct;
|
||||
OutPinType.PinSubCategoryObject = TBaseStructure<FTransform>::Get();
|
||||
}
|
||||
else if (TypeLower == TEXT("linearcolor") || TypeLower == TEXT("flinearcolor"))
|
||||
{
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Struct;
|
||||
OutPinType.PinSubCategoryObject = TBaseStructure<FLinearColor>::Get();
|
||||
}
|
||||
else if (TypeLower == TEXT("vector2d") || TypeLower == TEXT("fvector2d"))
|
||||
{
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Struct;
|
||||
OutPinType.PinSubCategoryObject = TBaseStructure<FVector2D>::Get();
|
||||
}
|
||||
else if (TypeLower == TEXT("object"))
|
||||
{
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Object;
|
||||
OutPinType.PinSubCategoryObject = UObject::StaticClass();
|
||||
}
|
||||
else if (TypeName.StartsWith(TEXT("object:"), ESearchCase::IgnoreCase))
|
||||
{
|
||||
FString ClassName = TypeName.Mid(7); // after "object:"
|
||||
UClass* FoundClass = FindClassByName(ClassName);
|
||||
if (!FoundClass)
|
||||
{
|
||||
UMCPServer::Printf(TEXT("ERROR: Class '%s' not found for object reference type\n"), *ClassName);
|
||||
return false;
|
||||
}
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Object;
|
||||
OutPinType.PinSubCategoryObject = FoundClass;
|
||||
}
|
||||
else if (TypeName.StartsWith(TEXT("softobject:"), ESearchCase::IgnoreCase))
|
||||
{
|
||||
FString ClassName = TypeName.Mid(11); // after "softobject:"
|
||||
UClass* FoundClass = FindClassByName(ClassName);
|
||||
if (!FoundClass)
|
||||
{
|
||||
UMCPServer::Printf(TEXT("ERROR: Class '%s' not found for soft object reference type\n"), *ClassName);
|
||||
return false;
|
||||
}
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_SoftObject;
|
||||
OutPinType.PinSubCategoryObject = FoundClass;
|
||||
}
|
||||
else if (TypeName.StartsWith(TEXT("class:"), ESearchCase::IgnoreCase))
|
||||
{
|
||||
FString ClassName = TypeName.Mid(6); // after "class:"
|
||||
UClass* FoundClass = FindClassByName(ClassName);
|
||||
if (!FoundClass)
|
||||
{
|
||||
UMCPServer::Printf(TEXT("ERROR: Class '%s' not found for class reference type (TSubclassOf)\n"), *ClassName);
|
||||
return false;
|
||||
}
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Class;
|
||||
OutPinType.PinSubCategoryObject = FoundClass;
|
||||
}
|
||||
else if (TypeName.StartsWith(TEXT("softclass:"), ESearchCase::IgnoreCase))
|
||||
{
|
||||
FString ClassName = TypeName.Mid(10); // after "softclass:"
|
||||
UClass* FoundClass = FindClassByName(ClassName);
|
||||
if (!FoundClass)
|
||||
{
|
||||
UMCPServer::Printf(TEXT("ERROR: Class '%s' not found for soft class reference type\n"), *ClassName);
|
||||
return false;
|
||||
}
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_SoftClass;
|
||||
OutPinType.PinSubCategoryObject = FoundClass;
|
||||
}
|
||||
else if (TypeName.StartsWith(TEXT("interface:"), ESearchCase::IgnoreCase))
|
||||
{
|
||||
FString ClassName = TypeName.Mid(10); // after "interface:"
|
||||
UClass* FoundClass = FindClassByName(ClassName);
|
||||
if (!FoundClass)
|
||||
{
|
||||
UMCPServer::Printf(TEXT("ERROR: Class '%s' not found for interface reference type\n"), *ClassName);
|
||||
return false;
|
||||
}
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Interface;
|
||||
OutPinType.PinSubCategoryObject = FoundClass;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try as a struct (F-prefix or raw name)
|
||||
FString InternalName = TypeName;
|
||||
bool bTriedAsStruct = false;
|
||||
|
||||
if (TypeName.StartsWith(TEXT("F")) || TypeName.StartsWith(TEXT("S_")) || (!TypeName.StartsWith(TEXT("E"))))
|
||||
{
|
||||
if (TypeName.StartsWith(TEXT("F")))
|
||||
{
|
||||
InternalName = TypeName.Mid(1);
|
||||
}
|
||||
|
||||
UScriptStruct* FoundStruct = FindFirstObject<UScriptStruct>(*InternalName);
|
||||
if (!FoundStruct)
|
||||
{
|
||||
for (TObjectIterator<UScriptStruct> It; It; ++It)
|
||||
{
|
||||
if (It->GetName() == InternalName || It->GetName() == TypeName)
|
||||
{
|
||||
FoundStruct = *It;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FoundStruct)
|
||||
{
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Struct;
|
||||
OutPinType.PinSubCategoryObject = FoundStruct;
|
||||
bTriedAsStruct = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bTriedAsStruct)
|
||||
{
|
||||
// Try as an enum (E-prefix or raw name)
|
||||
FString EnumInternalName = TypeName;
|
||||
if (TypeName.StartsWith(TEXT("E")))
|
||||
{
|
||||
EnumInternalName = TypeName.Mid(1);
|
||||
}
|
||||
|
||||
UEnum* FoundEnum = FindFirstObject<UEnum>(*EnumInternalName);
|
||||
if (!FoundEnum)
|
||||
{
|
||||
for (TObjectIterator<UEnum> It; It; ++It)
|
||||
{
|
||||
if (It->GetName() == EnumInternalName || It->GetName() == TypeName)
|
||||
{
|
||||
FoundEnum = *It;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FoundEnum)
|
||||
{
|
||||
if (FoundEnum->GetCppForm() == UEnum::ECppForm::EnumClass)
|
||||
{
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Enum;
|
||||
}
|
||||
else
|
||||
{
|
||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Byte;
|
||||
}
|
||||
OutPinType.PinSubCategoryObject = FoundEnum;
|
||||
}
|
||||
else
|
||||
{
|
||||
UMCPServer::Printf(
|
||||
TEXT("ERROR: Unknown type '%s'. Use: bool, int, float, string, name, text, byte, vector, rotator, transform, object, a struct/enum name (e.g. FVector, EMyEnum), or colon syntax for references (object:Actor, softobject:Actor, class:Actor, softclass:Actor, interface:MyInterface)\n"),
|
||||
*TypeName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Material helpers
|
||||
// ============================================================
|
||||
@@ -1262,25 +1051,6 @@ FString MCPUtils::GetHandlerGroup(UClass* HandlerClass)
|
||||
return Name;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// FormatPropertyType — human-readable type name for a UPROPERTY
|
||||
// ============================================================
|
||||
|
||||
FString MCPUtils::FormatPropertyType(FProperty* Prop)
|
||||
{
|
||||
if (CastField<FStrProperty>(Prop)) return TEXT("string");
|
||||
if (CastField<FIntProperty>(Prop)) return TEXT("integer");
|
||||
if (CastField<FFloatProperty>(Prop) || CastField<FDoubleProperty>(Prop)) return TEXT("number");
|
||||
if (CastField<FBoolProperty>(Prop)) return TEXT("boolean");
|
||||
if (FStructProperty* SP = CastField<FStructProperty>(Prop))
|
||||
{
|
||||
FString StructName = SP->Struct->GetName();
|
||||
StructName.ReplaceInline(TEXT("MCP"), TEXT(""));
|
||||
return StructName;
|
||||
}
|
||||
return TEXT("string");
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// GetTemplate
|
||||
// ============================================================
|
||||
@@ -1412,7 +1182,7 @@ void MCPUtils::FormatCommandHelp(UClass* HandlerClass)
|
||||
{
|
||||
FProperty* Prop = *PropIt;
|
||||
FString Name = PropertyNameToJsonKey(Prop->GetName());
|
||||
FString Type = FormatPropertyType(Prop);
|
||||
FString Type = UMCPTypes::TypeToText(Prop);
|
||||
bool bOptional = Prop->HasMetaData(TEXT("Optional"));
|
||||
const FString& Desc = Prop->GetMetaData(TEXT("Description"));
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ public:
|
||||
|
||||
// Convert a pin type to a type string. Returns empty string on failure.
|
||||
static FString TypeToText(const FEdGraphPinType& PinType);
|
||||
|
||||
static FString TypeToText(const FProperty *Property);
|
||||
|
||||
// Try to parse a type. If there's a problem, returns an error
|
||||
// message. If all goes well, returns empty string.
|
||||
static FString TryTextToType(const FString& Text, FEdGraphPinType& OutPinType);
|
||||
|
||||
@@ -132,12 +132,8 @@ public:
|
||||
Result.Add(Typed);
|
||||
return Result;
|
||||
}
|
||||
static bool SaveBlueprintPackage(UBlueprint* BP);
|
||||
|
||||
// ----- Type resolution -----
|
||||
static bool SaveBlueprintPackage(UBlueprint* BP);
|
||||
static UClass* FindClassByName(const FString& ClassName);
|
||||
static bool ResolveTypeFromString(const FString& TypeName, FEdGraphPinType& OutPinType);
|
||||
static FString FormatPropertyType(FProperty* Prop);
|
||||
|
||||
// ----- Material helpers -----
|
||||
static void EnsureMaterialGraph(UMaterial* Material);
|
||||
|
||||
Reference in New Issue
Block a user