Replace delimiters with unicode shapes
This commit is contained in:
@@ -77,7 +77,7 @@ WingFetcher& WingFetcher::Walk(const FString& Path)
|
||||
if (bError) return *this;
|
||||
|
||||
TArray<FString> Segments;
|
||||
Path.ParseIntoArray(Segments, TEXT(","));
|
||||
Path.ParseIntoArray(Segments, TEXT("│"));
|
||||
if (Segments.Num() == 0)
|
||||
{
|
||||
UWingServer::Print(TEXT("ERROR: Empty path\n"));
|
||||
|
||||
@@ -20,8 +20,8 @@ FString WingFunctionArgs::GetArgs(UEdGraphNode* Node)
|
||||
TStringBuilder<256> SB;
|
||||
for (const TSharedPtr<FUserPinInfo>& Pin : Editable->UserDefinedPins)
|
||||
{
|
||||
if (SB.Len() > 0) SB << TEXT(", ");
|
||||
SB << UWingTypes::TypeToText(Pin->PinType) << TEXT(" ") << Pin->PinName.ToString();
|
||||
if (SB.Len() > 0) SB << TEXT("│");
|
||||
SB << UWingTypes::TypeToText(Pin->PinType) << TEXT("◦") << Pin->PinName.ToString();
|
||||
}
|
||||
return FString(SB);
|
||||
}
|
||||
@@ -42,23 +42,23 @@ bool WingFunctionArgs::ParseArgs(const FString& Args, TArray<FParsedArg>& OutArg
|
||||
if (Trimmed.IsEmpty()) return true;
|
||||
|
||||
TArray<FString> Parts;
|
||||
Trimmed.ParseIntoArray(Parts, TEXT(","));
|
||||
Trimmed.ParseIntoArray(Parts, TEXT("│"));
|
||||
|
||||
for (const FString& Part : Parts)
|
||||
{
|
||||
FString Token = Part.TrimStartAndEnd();
|
||||
if (Token.IsEmpty()) continue;
|
||||
|
||||
// Split "type name" on the last space.
|
||||
int32 LastSpace;
|
||||
if (!Token.FindLastChar(TEXT(' '), LastSpace))
|
||||
// Split "type◦name" on the white bullet.
|
||||
FString TypeStr, NameStr;
|
||||
if (!Token.Split(TEXT("◦"), &TypeStr, &NameStr))
|
||||
{
|
||||
UWingServer::Printf(TEXT("ERROR: Expected 'type name' but got '%s'\n"), *Token);
|
||||
UWingServer::Printf(TEXT("ERROR: Expected 'type◦name' but got '%s'\n"), *Token);
|
||||
return false;
|
||||
}
|
||||
|
||||
FString TypeStr = Token.Left(LastSpace).TrimStartAndEnd();
|
||||
FString NameStr = Token.Mid(LastSpace + 1).TrimStartAndEnd();
|
||||
TypeStr.TrimStartAndEndInline();
|
||||
NameStr.TrimStartAndEndInline();
|
||||
|
||||
if (TypeStr.IsEmpty() || NameStr.IsEmpty())
|
||||
{
|
||||
|
||||
@@ -149,11 +149,11 @@ FString UWingTypes::TypeToTextInner(FName Category, FName SubCategory, UObject*
|
||||
if (Category == UEdGraphSchema_K2::PC_Object)
|
||||
return Short;
|
||||
if (Category == UEdGraphSchema_K2::PC_Class)
|
||||
return FString::Printf(TEXT("Class<%s>"), *Short);
|
||||
return FString::Printf(TEXT("Class◂%s▸"), *Short);
|
||||
if (Category == UEdGraphSchema_K2::PC_SoftObject)
|
||||
return FString::Printf(TEXT("Soft<%s>"), *Short);
|
||||
return FString::Printf(TEXT("Soft◂%s▸"), *Short);
|
||||
if (Category == UEdGraphSchema_K2::PC_SoftClass)
|
||||
return FString::Printf(TEXT("SoftClass<%s>"), *Short);
|
||||
return FString::Printf(TEXT("SoftClass◂%s▸"), *Short);
|
||||
if (Category == UEdGraphSchema_K2::PC_Interface)
|
||||
return Short;
|
||||
}
|
||||
@@ -171,9 +171,9 @@ FString UWingTypes::TypeToText(const FEdGraphPinType& PinType)
|
||||
return FString();
|
||||
|
||||
if (PinType.IsArray())
|
||||
return FString::Printf(TEXT("Array<%s>"), *Inner);
|
||||
return FString::Printf(TEXT("Array◂%s▸"), *Inner);
|
||||
if (PinType.IsSet())
|
||||
return FString::Printf(TEXT("Set<%s>"), *Inner);
|
||||
return FString::Printf(TEXT("Set◂%s▸"), *Inner);
|
||||
if (PinType.IsMap())
|
||||
{
|
||||
FString ValueInner = Types->TypeToTextInner(
|
||||
@@ -182,7 +182,7 @@ FString UWingTypes::TypeToText(const FEdGraphPinType& PinType)
|
||||
PinType.PinValueType.TerminalSubCategoryObject.Get());
|
||||
if (ValueInner.IsEmpty())
|
||||
return FString();
|
||||
return FString::Printf(TEXT("Map<%s, %s>"), *Inner, *ValueInner);
|
||||
return FString::Printf(TEXT("Map◂%s◆%s▸"), *Inner, *ValueInner);
|
||||
}
|
||||
|
||||
return Inner;
|
||||
@@ -428,29 +428,29 @@ bool UWingTypes::ParsePlainIdentifier(FEdGraphPinType& OutType)
|
||||
bool UWingTypes::ParseWrapped(FName Wrapper, FEdGraphPinType& OutType)
|
||||
{
|
||||
Cursor++;
|
||||
if (!ParseChar('<')) return false;
|
||||
if (!ParseChar(L'◂')) return false;
|
||||
if (!ParsePlainIdentifier(OutType)) return false;
|
||||
if (!Cast<UClass>(OutType.PinSubCategoryObject))
|
||||
{
|
||||
Error = FString::Printf(TEXT("%s is not a Class"), *OutType.PinSubCategoryObject->GetName());
|
||||
return false;
|
||||
}
|
||||
if (!ParseChar('>')) return false;
|
||||
if (!ParseChar(L'▸')) return false;
|
||||
OutType.PinCategory = Wrapper;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UWingTypes::ParseMaybeWrapped(FEdGraphPinType& OutType)
|
||||
{
|
||||
if (TokenIs(TEXT("Soft"), '<'))
|
||||
if (TokenIs(TEXT("Soft"), L'◂'))
|
||||
{
|
||||
return ParseWrapped(UEdGraphSchema_K2::PC_SoftObject, OutType);
|
||||
}
|
||||
else if (TokenIs(TEXT("Class"), '<'))
|
||||
else if (TokenIs(TEXT("Class"), L'◂'))
|
||||
{
|
||||
return ParseWrapped(UEdGraphSchema_K2::PC_Class, OutType);
|
||||
}
|
||||
else if (TokenIs(TEXT("SoftClass"), '<'))
|
||||
else if (TokenIs(TEXT("SoftClass"), L'◂'))
|
||||
{
|
||||
return ParseWrapped(UEdGraphSchema_K2::PC_SoftClass, OutType);
|
||||
}
|
||||
@@ -460,40 +460,40 @@ bool UWingTypes::ParseMaybeWrapped(FEdGraphPinType& OutType)
|
||||
bool UWingTypes::ParseArrayOrSet(FEdGraphPinType& OutType)
|
||||
{
|
||||
Cursor++;
|
||||
if (!ParseChar('<')) return false;
|
||||
if (!ParseChar(L'◂')) return false;
|
||||
if (!ParseMaybeWrapped(OutType)) return false;
|
||||
if (!ParseChar('>')) return false;
|
||||
if (!ParseChar(L'▸')) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UWingTypes::ParseMap(FEdGraphPinType& OutType)
|
||||
{
|
||||
Cursor++;
|
||||
if (!ParseChar('<')) return false;
|
||||
if (!ParseChar(L'◂')) return false;
|
||||
if (!ParsePlainIdentifier(OutType)) return false;
|
||||
if (!ParseChar(',')) return false;
|
||||
if (!ParseChar(L'◆')) return false;
|
||||
FEdGraphPinType ValueType;
|
||||
if (!ParseMaybeWrapped(ValueType)) return false;
|
||||
OutType.PinValueType.TerminalCategory = ValueType.PinCategory;
|
||||
OutType.PinValueType.TerminalSubCategory = ValueType.PinSubCategory;
|
||||
OutType.PinValueType.TerminalSubCategoryObject = ValueType.PinSubCategoryObject;
|
||||
if (!ParseChar('>')) return false;
|
||||
if (!ParseChar(L'▸')) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UWingTypes::ParseType(FEdGraphPinType& OutType)
|
||||
{
|
||||
if (TokenIs(TEXT("Array"), '<'))
|
||||
if (TokenIs(TEXT("Array"), L'◂'))
|
||||
{
|
||||
OutType.ContainerType = EPinContainerType::Array;
|
||||
if (!ParseArrayOrSet(OutType)) return false;
|
||||
}
|
||||
else if (TokenIs(TEXT("Set"), '<'))
|
||||
else if (TokenIs(TEXT("Set"), L'◂'))
|
||||
{
|
||||
OutType.ContainerType = EPinContainerType::Set;
|
||||
if (!ParseArrayOrSet(OutType)) return false;
|
||||
}
|
||||
else if (TokenIs(TEXT("Map"), '<'))
|
||||
else if (TokenIs(TEXT("Map"), L'◂'))
|
||||
{
|
||||
OutType.ContainerType = EPinContainerType::Map;
|
||||
if (!ParseMap(OutType)) return false;
|
||||
|
||||
@@ -51,7 +51,16 @@ extern int32 TrySavePackageSEH(
|
||||
#endif
|
||||
|
||||
// ============================================================
|
||||
// Name Formatting
|
||||
// Name sanitization
|
||||
//
|
||||
// Our parsers use Unicode geometric shape delimiters that
|
||||
// are unlikely to appear in names: ◂▸ for type brackets, ◆
|
||||
// for map key◆value, ◦ for type◦name in prototypes, │ for
|
||||
// list/path separation. If any of these characters appear
|
||||
// in a name, we replace them with safe ASCII equivalents.
|
||||
// One consequence of name sanitization is that we can't use
|
||||
// Unreal's name-lookup routines — the LLM only sees
|
||||
// sanitized names. So we do our own name lookups.
|
||||
// ============================================================
|
||||
|
||||
void WingUtils::SanitizeNameInPlace(FString &Name)
|
||||
@@ -61,7 +70,11 @@ void WingUtils::SanitizeNameInPlace(FString &Name)
|
||||
{
|
||||
TCHAR c = Name[Src];
|
||||
if (c < 0x20 || c == 0x7F) continue;
|
||||
if ((c == ' ') || (c == ',') || (c == ':')) c = '_';
|
||||
if (c == L'◂') c='<';
|
||||
if (c == L'▸') c='>';
|
||||
if (c == L'◆') c='*';
|
||||
if (c == L'◦') c='.';
|
||||
if (c == L'│') c = '|';
|
||||
Name[Dst++] = c;
|
||||
}
|
||||
if (Dst == 0) Name[Dst++] = '_';
|
||||
@@ -82,6 +95,10 @@ FString WingUtils::SanitizeName(FName Name)
|
||||
return Result;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Name Lookup
|
||||
// ============================================================
|
||||
|
||||
FString WingUtils::FormatName(const UWorld *World)
|
||||
{
|
||||
return World->GetPathName();
|
||||
|
||||
Reference in New Issue
Block a user