Good type-to-text routine in MCP
This commit is contained in:
Binary file not shown.
@@ -5,6 +5,7 @@
|
|||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "MCPServer.h"
|
#include "MCPServer.h"
|
||||||
|
#include "MCPTypes.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "EdGraph/EdGraph.h"
|
#include "EdGraph/EdGraph.h"
|
||||||
#include "EdGraph/EdGraphPin.h"
|
#include "EdGraph/EdGraphPin.h"
|
||||||
@@ -153,7 +154,7 @@ public:
|
|||||||
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
|
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
|
||||||
|
|
||||||
UMCPServer::Printf(TEXT("Changed '%s' to %s. Save %s.\n"),
|
UMCPServer::Printf(TEXT("Changed '%s' to %s. Save %s.\n"),
|
||||||
*ParamName, *MCPUtils::FormatPinType(NewPinType),
|
*ParamName, *UMCPTypes::TypeToText(NewPinType),
|
||||||
bSaved ? TEXT("succeeded") : TEXT("failed"));
|
bSaved ? TEXT("succeeded") : TEXT("failed"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPServer.h"
|
#include "MCPServer.h"
|
||||||
|
#include "MCPTypes.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
@@ -116,8 +117,8 @@ public:
|
|||||||
{
|
{
|
||||||
UMCPServer::Printf(TEXT("Dry run: would change %s from %s to %s\n"),
|
UMCPServer::Printf(TEXT("Dry run: would change %s from %s to %s\n"),
|
||||||
*MCPUtils::FormatName(*Found),
|
*MCPUtils::FormatName(*Found),
|
||||||
*MCPUtils::FormatPinType(Found->VarType),
|
*UMCPTypes::TypeToText(Found->VarType),
|
||||||
*MCPUtils::FormatPinType(NewPinType));
|
*UMCPTypes::TypeToText(NewPinType));
|
||||||
if (bHasAffected)
|
if (bHasAffected)
|
||||||
{
|
{
|
||||||
UMCPServer::Print(TEXT("Affected nodes:\n"));
|
UMCPServer::Print(TEXT("Affected nodes:\n"));
|
||||||
@@ -133,7 +134,7 @@ public:
|
|||||||
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
|
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
|
||||||
UMCPServer::Printf(TEXT("Changed %s to %s.%s\n"),
|
UMCPServer::Printf(TEXT("Changed %s to %s.%s\n"),
|
||||||
*MCPUtils::FormatName(*Found),
|
*MCPUtils::FormatName(*Found),
|
||||||
*MCPUtils::FormatPinType(NewPinType),
|
*UMCPTypes::TypeToText(NewPinType),
|
||||||
bSaved ? TEXT("") : TEXT(" WARNING: save failed."));
|
bSaved ? TEXT("") : TEXT(" WARNING: save failed."));
|
||||||
|
|
||||||
if (bHasAffected)
|
if (bHasAffected)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPServer.h"
|
#include "MCPServer.h"
|
||||||
|
#include "MCPTypes.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
@@ -65,7 +66,7 @@ public:
|
|||||||
for (const FBPVariableDescription& V : BP->NewVariables)
|
for (const FBPVariableDescription& V : BP->NewVariables)
|
||||||
{
|
{
|
||||||
UMCPServer::Printf(TEXT(" %s %s"),
|
UMCPServer::Printf(TEXT(" %s %s"),
|
||||||
*MCPUtils::FormatPinType(V.VarType),
|
*UMCPTypes::TypeToText(V.VarType),
|
||||||
*MCPUtils::FormatName(V));
|
*MCPUtils::FormatName(V));
|
||||||
if (!V.DefaultValue.IsEmpty())
|
if (!V.DefaultValue.IsEmpty())
|
||||||
UMCPServer::Printf(TEXT(" = %s"), *V.DefaultValue);
|
UMCPServer::Printf(TEXT(" = %s"), *V.DefaultValue);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPServer.h"
|
#include "MCPServer.h"
|
||||||
|
#include "MCPTypes.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
@@ -57,7 +58,7 @@ public:
|
|||||||
if (!bFirst) UMCPServer::Print(TEXT(", "));
|
if (!bFirst) UMCPServer::Print(TEXT(", "));
|
||||||
bFirst = false;
|
bFirst = false;
|
||||||
UMCPServer::Printf(TEXT("%s %s"),
|
UMCPServer::Printf(TEXT("%s %s"),
|
||||||
*MCPUtils::FormatPinType(PinInfo->PinType),
|
*UMCPTypes::TypeToText(PinInfo->PinType),
|
||||||
*PinInfo->PinName.ToString());
|
*PinInfo->PinName.ToString());
|
||||||
}
|
}
|
||||||
break; // only need the first entry node
|
break; // only need the first entry node
|
||||||
|
|||||||
@@ -45,8 +45,12 @@ private:
|
|||||||
if (!Node->bReadOnly)
|
if (!Node->bReadOnly)
|
||||||
{
|
{
|
||||||
UObject *SCO = Node->GetPinTypeNoResolve().PinSubCategoryObject.Get();
|
UObject *SCO = Node->GetPinTypeNoResolve().PinSubCategoryObject.Get();
|
||||||
FString Path = SCO ? SCO->GetPathName() : *Node->GetCachedAssetData().GetObjectPathString();
|
if (SCO) {
|
||||||
UMCPServer::Printf(TEXT("%s%s --- %s\n"), *Category, *Desc, *Path);
|
UMCPServer::Printf(TEXT("SCO %s %s\n"), *SCO->GetPackage()->GetName(), *SCO->GetName());
|
||||||
|
} else {
|
||||||
|
auto cad = Node->GetCachedAssetData();
|
||||||
|
UMCPServer::Printf(TEXT("CAD %s %s\n"), *cad.PackageName.ToString(), *cad.AssetName.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FString ChildCategory = FString::Printf(TEXT("%s%s|"), *Category, *Desc);
|
FString ChildCategory = FString::Printf(TEXT("%s%s|"), *Category, *Desc);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "BlueprintExporter.h"
|
#include "BlueprintExporter.h"
|
||||||
|
#include "MCPTypes.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "EdGraph/EdGraph.h"
|
#include "EdGraph/EdGraph.h"
|
||||||
@@ -211,7 +212,7 @@ void FlxBlueprintExporter::EmitNode(UEdGraphNode* Node)
|
|||||||
if (Pin->bHidden) continue;
|
if (Pin->bHidden) continue;
|
||||||
|
|
||||||
Output.Appendf(TEXT(" input %s %s = %s\n"),
|
Output.Appendf(TEXT(" input %s %s = %s\n"),
|
||||||
*MCPUtils::FormatPinType(Pin),
|
*UMCPTypes::TypeToText(Pin->PinType),
|
||||||
*MCPUtils::FormatName(Pin),
|
*MCPUtils::FormatName(Pin),
|
||||||
*FormatPinSource(Pin));
|
*FormatPinSource(Pin));
|
||||||
}
|
}
|
||||||
@@ -290,7 +291,7 @@ void FlxBlueprintExporter::EmitLocalVariables()
|
|||||||
{
|
{
|
||||||
FString Default = Var.DefaultValue.IsEmpty() ? TEXT("<default>") : Var.DefaultValue;
|
FString Default = Var.DefaultValue.IsEmpty() ? TEXT("<default>") : Var.DefaultValue;
|
||||||
Output.Appendf(TEXT("local %s %s = %s\n"),
|
Output.Appendf(TEXT("local %s %s = %s\n"),
|
||||||
*MCPUtils::FormatPinType(Var.VarType),
|
*UMCPTypes::TypeToText(Var.VarType),
|
||||||
*MCPUtils::FormatName(Var),
|
*MCPUtils::FormatName(Var),
|
||||||
*Default);
|
*Default);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ bool MCPAssetsBase::Info()
|
|||||||
|
|
||||||
// Query the asset registry
|
// Query the asset registry
|
||||||
IAssetRegistry& AR = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry").Get();
|
IAssetRegistry& AR = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry").Get();
|
||||||
while (AR.IsLoadingAssets()) FPlatformProcess::Sleep(0.1f);
|
|
||||||
|
|
||||||
TArray<FAssetData> Candidates;
|
TArray<FAssetData> Candidates;
|
||||||
AR.GetAssets(ConfigureFilter(), Candidates);
|
AR.GetAssets(ConfigureFilter(), Candidates);
|
||||||
|
|||||||
@@ -398,6 +398,12 @@ void UMCPServer::ClientThreadFunc(UMCPServer* Server, TSharedPtr<FClientConnecti
|
|||||||
|
|
||||||
if (Line.IsEmpty()) continue;
|
if (Line.IsEmpty()) continue;
|
||||||
|
|
||||||
|
// Wait for the asset registry to finish its initial scan.
|
||||||
|
{
|
||||||
|
IAssetRegistry& AR = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry").Get();
|
||||||
|
while (AR.IsLoadingAssets()) FPlatformProcess::Sleep(0.25f);
|
||||||
|
}
|
||||||
|
|
||||||
// Enqueue the line for game-thread processing
|
// Enqueue the line for game-thread processing
|
||||||
TSharedPtr<UMCPServer::FPendingMessage> Msg = MakeShared<UMCPServer::FPendingMessage>();
|
TSharedPtr<UMCPServer::FPendingMessage> Msg = MakeShared<UMCPServer::FPendingMessage>();
|
||||||
Msg->Line = Line;
|
Msg->Line = Line;
|
||||||
|
|||||||
@@ -1,140 +1,166 @@
|
|||||||
#include "MCPTypes.h"
|
#include "MCPTypes.h"
|
||||||
|
#include "Editor.h"
|
||||||
#include "EdGraphSchema_K2.h"
|
#include "EdGraphSchema_K2.h"
|
||||||
|
#include "UObject/UObjectIterator.h"
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Helper: format a UField name with module prefix if not in /Script/Engine.
|
// Choose Short Name
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
static FString FormatFieldName(UField* Field, const FString& TypePrefix)
|
FString UMCPTypes::ChooseShortName(UObject* Obj)
|
||||||
{
|
{
|
||||||
// Package name is /Script/ModuleName
|
if (!Cast<UScriptStruct>(Obj) && !Cast<UClass>(Obj) && !Cast<UEnum>(Obj))
|
||||||
FString ModuleName = Field->GetOutermost()->GetName().Mid(8);
|
return FString();
|
||||||
|
|
||||||
FString Name = TypePrefix + Field->GetName();
|
FString Path = Obj->GetPathName();
|
||||||
if (ModuleName != TEXT("Engine"))
|
FString *OldShort = PathToShort.Find(Path);
|
||||||
return ModuleName + TEXT("::") + Name;
|
if (OldShort != nullptr) return *OldShort;
|
||||||
return Name;
|
|
||||||
|
FString Name = Obj->GetName();
|
||||||
|
if (Name.EndsWith(TEXT("_C"))) Name.LeftChopInline(2);
|
||||||
|
|
||||||
|
FString Lower = Name.ToLower();
|
||||||
|
if (!ShortToPath.Contains(Lower))
|
||||||
|
{
|
||||||
|
ShortToPath.Add(Lower, Path);
|
||||||
|
PathToShort.Add(Path, Name);
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32 i = 2; ; ++i)
|
||||||
|
{
|
||||||
|
FString NumberedLower = FString::Printf(TEXT("%s%d"), *Lower, i);
|
||||||
|
if (!ShortToPath.Contains(NumberedLower))
|
||||||
|
{
|
||||||
|
FString NumberedName = FString::Printf(TEXT("%s%d"), *Name, i);
|
||||||
|
ShortToPath.Add(NumberedLower, Path);
|
||||||
|
PathToShort.Add(Path, NumberedName);
|
||||||
|
return NumberedName;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static FString FormatClassName(UClass* Class)
|
void UMCPTypes::ChooseShortNames(UPackage* Package)
|
||||||
{
|
{
|
||||||
FString Prefix = Class->IsChildOf(AActor::StaticClass()) ? TEXT("A") : TEXT("U");
|
if (Package == nullptr) return;
|
||||||
return FormatFieldName(Class, Prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
static FString FormatStructName(UScriptStruct* Struct)
|
ForEachObjectWithPackage(Package, [&](UObject* Obj)
|
||||||
{
|
{
|
||||||
return FormatFieldName(Struct, TEXT("F"));
|
ChooseShortName(Obj);
|
||||||
}
|
return true;
|
||||||
|
}, false);
|
||||||
static FString FormatEnumName(UEnum* Enum)
|
|
||||||
{
|
|
||||||
return FormatFieldName(Enum, TEXT("E"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// TypeToText
|
// TypeToText
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
static FString TerminalToText(const FEdGraphPinType& PinType)
|
FString UMCPTypes::TypeToTextInner(FName Category, FName SubCategory, UObject* SubCategoryObject)
|
||||||
{
|
{
|
||||||
const FName& Cat = PinType.PinCategory;
|
if (Category == UEdGraphSchema_K2::PC_Boolean) return TEXT("bool");
|
||||||
UObject* SubObj = PinType.PinSubCategoryObject.Get();
|
if (Category == UEdGraphSchema_K2::PC_Int) return TEXT("int32");
|
||||||
|
if (Category == UEdGraphSchema_K2::PC_Int64) return TEXT("int64");
|
||||||
|
if (Category == UEdGraphSchema_K2::PC_Name) return TEXT("Name");
|
||||||
|
if (Category == UEdGraphSchema_K2::PC_String) return TEXT("String");
|
||||||
|
if (Category == UEdGraphSchema_K2::PC_Text) return TEXT("Text");
|
||||||
|
|
||||||
if (Cat == UEdGraphSchema_K2::PC_Boolean) return TEXT("bool");
|
if (Category == UEdGraphSchema_K2::PC_Real)
|
||||||
if (Cat == UEdGraphSchema_K2::PC_Int) return TEXT("int32");
|
|
||||||
if (Cat == UEdGraphSchema_K2::PC_Int64) return TEXT("int64");
|
|
||||||
if (Cat == UEdGraphSchema_K2::PC_Name) return TEXT("FName");
|
|
||||||
if (Cat == UEdGraphSchema_K2::PC_String) return TEXT("FString");
|
|
||||||
if (Cat == UEdGraphSchema_K2::PC_Text) return TEXT("FText");
|
|
||||||
|
|
||||||
if (Cat == UEdGraphSchema_K2::PC_Real)
|
|
||||||
{
|
{
|
||||||
if (PinType.PinSubCategory == UEdGraphSchema_K2::PC_Float)
|
if (SubCategory == UEdGraphSchema_K2::PC_Float)
|
||||||
return TEXT("float");
|
return TEXT("float");
|
||||||
return TEXT("double");
|
return TEXT("double");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Cat == UEdGraphSchema_K2::PC_Byte)
|
if (Category == UEdGraphSchema_K2::PC_Byte)
|
||||||
{
|
{
|
||||||
if (UEnum* Enum = Cast<UEnum>(SubObj))
|
if (SubCategoryObject)
|
||||||
return FormatEnumName(Enum);
|
return ChooseShortName(SubCategoryObject);
|
||||||
return TEXT("uint8");
|
return TEXT("uint8");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Cat == UEdGraphSchema_K2::PC_Enum)
|
if (Category == UEdGraphSchema_K2::PC_Enum)
|
||||||
{
|
{
|
||||||
if (UEnum* Enum = Cast<UEnum>(SubObj))
|
if (SubCategoryObject)
|
||||||
return FormatEnumName(Enum);
|
return ChooseShortName(SubCategoryObject);
|
||||||
return TEXT("uint8");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Cat == UEdGraphSchema_K2::PC_Struct)
|
|
||||||
{
|
|
||||||
if (UScriptStruct* Struct = Cast<UScriptStruct>(SubObj))
|
|
||||||
return FormatStructName(Struct);
|
|
||||||
return FString();
|
return FString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Cat == UEdGraphSchema_K2::PC_Object)
|
if (SubCategoryObject)
|
||||||
{
|
{
|
||||||
if (UClass* Class = Cast<UClass>(SubObj))
|
FString Short = ChooseShortName(SubCategoryObject);
|
||||||
return FormatClassName(Class) + TEXT("*");
|
if (Short.IsEmpty()) return FString();
|
||||||
return FString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Cat == UEdGraphSchema_K2::PC_Class)
|
if (Category == UEdGraphSchema_K2::PC_Struct)
|
||||||
{
|
return Short;
|
||||||
if (UClass* Class = Cast<UClass>(SubObj))
|
if (Category == UEdGraphSchema_K2::PC_Object)
|
||||||
return FString::Printf(TEXT("TSubclassOf<%s>"), *FormatClassName(Class));
|
return Short;
|
||||||
return FString();
|
if (Category == UEdGraphSchema_K2::PC_Class)
|
||||||
}
|
return FString::Printf(TEXT("Class<%s>"), *Short);
|
||||||
|
if (Category == UEdGraphSchema_K2::PC_SoftObject)
|
||||||
if (Cat == UEdGraphSchema_K2::PC_SoftObject)
|
return FString::Printf(TEXT("Soft<%s>"), *Short);
|
||||||
{
|
if (Category == UEdGraphSchema_K2::PC_SoftClass)
|
||||||
if (UClass* Class = Cast<UClass>(SubObj))
|
return FString::Printf(TEXT("SoftClass<%s>"), *Short);
|
||||||
return FString::Printf(TEXT("TSoftObjectPtr<%s>"), *FormatClassName(Class));
|
if (Category == UEdGraphSchema_K2::PC_Interface)
|
||||||
return FString();
|
return Short;
|
||||||
}
|
|
||||||
|
|
||||||
if (Cat == UEdGraphSchema_K2::PC_SoftClass)
|
|
||||||
{
|
|
||||||
if (UClass* Class = Cast<UClass>(SubObj))
|
|
||||||
return FString::Printf(TEXT("TSoftClassPtr<%s>"), *FormatClassName(Class));
|
|
||||||
return FString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Cat == UEdGraphSchema_K2::PC_Interface)
|
|
||||||
{
|
|
||||||
if (UClass* Class = Cast<UClass>(SubObj))
|
|
||||||
return FString::Printf(TEXT("TScriptInterface<%s>"), *FormatClassName(Class));
|
|
||||||
return FString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FString();
|
return FString();
|
||||||
}
|
}
|
||||||
|
|
||||||
FString MCPTypes::TypeToText(const FEdGraphPinType& PinType)
|
FString UMCPTypes::TypeToText(const FEdGraphPinType& PinType)
|
||||||
{
|
{
|
||||||
FString Inner = TerminalToText(PinType);
|
UMCPTypes* Types = GEditor->GetEditorSubsystem<UMCPTypes>();
|
||||||
|
if (!Types) return FString();
|
||||||
|
|
||||||
|
FString Inner = Types->TypeToTextInner(PinType.PinCategory, PinType.PinSubCategory, PinType.PinSubCategoryObject.Get());
|
||||||
if (Inner.IsEmpty())
|
if (Inner.IsEmpty())
|
||||||
return FString();
|
return FString();
|
||||||
|
|
||||||
if (PinType.IsArray())
|
if (PinType.IsArray())
|
||||||
return FString::Printf(TEXT("TArray<%s>"), *Inner);
|
return FString::Printf(TEXT("Array<%s>"), *Inner);
|
||||||
if (PinType.IsSet())
|
if (PinType.IsSet())
|
||||||
return FString::Printf(TEXT("TSet<%s>"), *Inner);
|
return FString::Printf(TEXT("Set<%s>"), *Inner);
|
||||||
if (PinType.IsMap())
|
if (PinType.IsMap())
|
||||||
{
|
{
|
||||||
FEdGraphPinType ValueType;
|
FString ValueInner = Types->TypeToTextInner(
|
||||||
ValueType.PinCategory = PinType.PinValueType.TerminalCategory;
|
PinType.PinValueType.TerminalCategory,
|
||||||
ValueType.PinSubCategory = PinType.PinValueType.TerminalSubCategory;
|
PinType.PinValueType.TerminalSubCategory,
|
||||||
ValueType.PinSubCategoryObject = PinType.PinValueType.TerminalSubCategoryObject;
|
PinType.PinValueType.TerminalSubCategoryObject.Get());
|
||||||
FString ValueInner = TerminalToText(ValueType);
|
|
||||||
if (ValueInner.IsEmpty())
|
if (ValueInner.IsEmpty())
|
||||||
return FString();
|
return FString();
|
||||||
return FString::Printf(TEXT("TMap<%s, %s>"), *Inner, *ValueInner);
|
return FString::Printf(TEXT("Map<%s, %s>"), *Inner, *ValueInner);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Inner;
|
return Inner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Subsystem lifecycle
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void UMCPTypes::Initialize(FSubsystemCollectionBase& Collection)
|
||||||
|
{
|
||||||
|
Super::Initialize(Collection);
|
||||||
|
|
||||||
|
// Collect all packages and sort by name for stable short-name assignment.
|
||||||
|
TArray<UPackage*> Packages;
|
||||||
|
for (TObjectIterator<UPackage> It; It; ++It)
|
||||||
|
Packages.Add(*It);
|
||||||
|
Packages.Sort([](const UPackage& A, const UPackage& B) { return A.GetName() < B.GetName(); });
|
||||||
|
|
||||||
|
// Scan priority packages first, then everything else in sorted order.
|
||||||
|
ChooseShortNames(FindPackage(nullptr, TEXT("/Script/CoreUObject")));
|
||||||
|
ChooseShortNames(FindPackage(nullptr, TEXT("/Script/Engine")));
|
||||||
|
ChooseShortNames(FindPackage(nullptr, TEXT("/Script/Integration")));
|
||||||
|
|
||||||
|
for (UPackage* Pkg : Packages)
|
||||||
|
ChooseShortNames(Pkg);
|
||||||
|
|
||||||
|
UE_LOG(LogTemp, Display, TEXT("MCPTypes: Registered %d types"), ShortToPath.Num());
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMCPTypes::Deinitialize()
|
||||||
|
{
|
||||||
|
Super::Deinitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -251,21 +251,6 @@ bool MCPUtils::Identifies(const FString &Name, const UEdGraphNode* Node)
|
|||||||
// Formatting other things
|
// Formatting other things
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
FString MCPUtils::FormatPinType(const FEdGraphPinType& PinType)
|
|
||||||
{
|
|
||||||
if (UObject* SubObj = PinType.PinSubCategoryObject.Get())
|
|
||||||
{
|
|
||||||
return SubObj->GetName();
|
|
||||||
}
|
|
||||||
FString Type = PinType.PinCategory.ToString();
|
|
||||||
Type[0] = FChar::ToUpper(Type[0]);
|
|
||||||
return Type;
|
|
||||||
}
|
|
||||||
|
|
||||||
FString MCPUtils::FormatPinType(UEdGraphPin* Pin)
|
|
||||||
{
|
|
||||||
return FormatPinType(Pin->PinType);
|
|
||||||
}
|
|
||||||
|
|
||||||
FString MCPUtils::FormatNodeTitle(const UEdGraphNode *Node)
|
FString MCPUtils::FormatNodeTitle(const UEdGraphNode *Node)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
|
#include "EditorSubsystem.h"
|
||||||
#include "EdGraph/EdGraphPin.h"
|
#include "EdGraph/EdGraphPin.h"
|
||||||
|
#include "MCPTypes.generated.h"
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// MCPTypes — converts between FEdGraphPinType and a concise C++-like string.
|
// UMCPTypes — converts between FEdGraphPinType and a concise C++-like string.
|
||||||
//
|
//
|
||||||
// The text format mirrors GetCPPType where possible:
|
// The text format mirrors GetCPPType where possible:
|
||||||
// bool, uint8, int32, int64, float, double, FName, FString, FText
|
// bool, uint8, int32, int64, float, double, FName, FString, FText
|
||||||
@@ -20,27 +22,42 @@
|
|||||||
// TypeToText and TextToType are inverses of each other.
|
// TypeToText and TextToType are inverses of each other.
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class UMCPTypes : public UEditorSubsystem
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MCPTypes
|
|
||||||
{
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Convert an FEdGraphPinType to a concise string.
|
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
||||||
// Returns empty string on failure.
|
virtual void Deinitialize() override;
|
||||||
FString TypeToText(const FEdGraphPinType& PinType);
|
|
||||||
|
// Convert a pin type to a type string. Returns empty string on failure.
|
||||||
|
static FString TypeToText(const FEdGraphPinType& PinType);
|
||||||
|
|
||||||
// Convert a concise string back to an FEdGraphPinType.
|
// Convert a concise string back to an FEdGraphPinType.
|
||||||
// Returns true on success. Prints error via UMCPServer on failure.
|
// Returns true on success. Prints error via UMCPServer on failure.
|
||||||
bool TextToType(const FString& Text, FEdGraphPinType& OutPinType);
|
static bool TextToType(const FString& Text, FEdGraphPinType& OutPinType);
|
||||||
|
|
||||||
// Same as TextToType, but does not print an error message on failure.
|
// Same as TextToType, but does not print an error message on failure.
|
||||||
bool TryTextToType(const FString& Text, FEdGraphPinType& OutPinType);
|
static bool TryTextToType(const FString& Text, FEdGraphPinType& OutPinType);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
FString TypeToTextInner(FName Category, FName SubCategory, UObject* SubCategoryObject);
|
||||||
|
|
||||||
|
// Chooses a short name for the specified type, making sure not to
|
||||||
|
// choose the same name for two classes. If the object already has
|
||||||
|
// a short name, return it. If it's not a class, struct, enum, or
|
||||||
|
// interface, return empty string.
|
||||||
|
FString ChooseShortName(UObject* Obj);
|
||||||
|
|
||||||
|
// Choose short names for every type in the package.
|
||||||
|
void ChooseShortNames(UPackage* Package);
|
||||||
|
|
||||||
|
// Short name registry: bidirectional mapping between short names and full paths.
|
||||||
|
TMap<FString, FString> ShortToPath; // e.g. "vector" -> "/Script/CoreUObject.Vector"
|
||||||
|
TMap<FString, FString> PathToShort; // e.g. "/Script/CoreUObject.Vector" -> "Vector"
|
||||||
|
|
||||||
|
// Parser state (used by TextToType)
|
||||||
TArray<FString> Tokens;
|
TArray<FString> Tokens;
|
||||||
int32 Cursor = 0;
|
int32 Cursor = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -93,8 +93,6 @@ public:
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static FString FormatPinType(const FEdGraphPinType& PinType);
|
|
||||||
static FString FormatPinType(UEdGraphPin* Pin);
|
|
||||||
static FString FormatNodeTitle(const UEdGraphNode *Node);
|
static FString FormatNodeTitle(const UEdGraphNode *Node);
|
||||||
|
|
||||||
// ----- Enum helpers -----
|
// ----- Enum helpers -----
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ bool UlxTangible::AnimationStepIsFinished(AActor *target, const FlxAnimationStep
|
|||||||
|
|
||||||
UlxScriptedAnimations *UlxTangible::GetScriptedAnimations(AActor *Target)
|
UlxScriptedAnimations *UlxTangible::GetScriptedAnimations(AActor *Target)
|
||||||
{
|
{
|
||||||
UlxTangible *tan = GetActorTangibleOrLog(Target);
|
UlxTangible *tan = GetActorTangibleQuiet(Target);
|
||||||
if (tan == nullptr) return nullptr;
|
if (tan == nullptr) return nullptr;
|
||||||
if (tan->ScriptedAnimations == nullptr)
|
if (tan->ScriptedAnimations == nullptr)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user