More cleanup of Internal/External IDs

This commit is contained in:
2026-03-29 15:11:45 -04:00
parent 091bfe1ad2
commit 6041641c74
10 changed files with 43 additions and 57 deletions

View File

@@ -49,10 +49,10 @@ public:
if (!BP) return; if (!BP) return;
// Check that the proposed name is valid // Check that the proposed name is valid
FName InternalID = WingUtils::CheckProposedName(Component);
if (InternalID.IsNone()) return;
TArray<UWingComponentReference*> AllComponents = UWingComponentReference::GetAll(BP); TArray<UWingComponentReference*> AllComponents = UWingComponentReference::GetAll(BP);
if (!WingUtils::FindNoneWithExternalID(Component, AllComponents, TEXT("Component"))) return; if (!WingUtils::FindNoneWithInternalID(InternalID, AllComponents, TEXT("Component"))) return;
FString InternalName = WingUtils::CheckProposedName(Component);
if (InternalName.IsEmpty()) return;
// Resolve the component class by name // Resolve the component class by name
UWingTypes::Requirements Req; UWingTypes::Requirements Req;
@@ -69,7 +69,7 @@ public:
if (!ParentComp) return; if (!ParentComp) return;
// Create the SCS node // Create the SCS node
if (!UWingComponentReference::AddComponent(BP, ComponentClass, ParentComp, FName(*InternalName))) return; if (!UWingComponentReference::AddComponent(BP, ComponentClass, ParentComp, InternalID)) return;
UWingServer::Printf(TEXT("Component Added.\n")); UWingServer::Printf(TEXT("Component Added.\n"));
} }

View File

@@ -76,17 +76,17 @@ public:
} }
// Check graph name uniqueness and legality // Check graph name uniqueness and legality
if (!WingUtils::FindNoneWithExternalID(Graph, WingUtils::AllGraphs(BP), TEXT("Graph"))) FName InternalID = WingUtils::CheckProposedName(Graph);
if (InternalID.IsNone()) return;
if (!WingUtils::FindNoneWithInternalID(InternalID, WingUtils::AllGraphs(BP), TEXT("Graph")))
return; return;
FString InternalName = WingUtils::CheckProposedName(Graph);
if (InternalName.IsEmpty()) return;
// Validate argument and return value types before making changes // Validate argument and return value types before making changes
if (!Arguments.IsEmpty() && !WingFunctionArgs::CheckArgs(Arguments)) return; if (!Arguments.IsEmpty() && !WingFunctionArgs::CheckArgs(Arguments)) return;
if (!ReturnValues.IsEmpty() && !WingFunctionArgs::CheckArgs(ReturnValues)) return; if (!ReturnValues.IsEmpty() && !WingFunctionArgs::CheckArgs(ReturnValues)) return;
// Create the Graph // Create the Graph
UEdGraph* NewGraph = FBlueprintEditorUtils::CreateNewGraph(BP, FName(InternalName), UEdGraph* NewGraph = FBlueprintEditorUtils::CreateNewGraph(BP, InternalID,
UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass()); UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass());
if (!NewGraph) if (!NewGraph)
{ {

View File

@@ -45,15 +45,14 @@ public:
if (!BP) return; if (!BP) return;
// Check validity of the proposed name // Check validity of the proposed name
if (!WingUtils::FindNoneWithExternalID(Name, BP->NewVariables, TEXT("Variable"))) return; FName InternalID = WingUtils::CheckProposedName(Name);
FString InternalName = WingUtils::CheckProposedName(Name); if (InternalID.IsNone()) return;
if (InternalName.IsEmpty()) return; if (!WingUtils::FindNoneWithInternalID(InternalID, BP->NewVariables, TEXT("Variable"))) return;
FName VarFName(InternalName);
// Add the variable with a default type // Add the variable with a default type
FEdGraphPinType DefaultType; FEdGraphPinType DefaultType;
DefaultType.PinCategory = UEdGraphSchema_K2::PC_Int; DefaultType.PinCategory = UEdGraphSchema_K2::PC_Int;
if (!FBlueprintEditorUtils::AddMemberVariable(BP, VarFName, DefaultType)) if (!FBlueprintEditorUtils::AddMemberVariable(BP, InternalID, DefaultType))
{ {
UWingServer::Printf(TEXT("ERROR: Failed to add variable '%s' to %s\n"), *Name, *WingUtils::FormatName(BP)); UWingServer::Printf(TEXT("ERROR: Failed to add variable '%s' to %s\n"), *Name, *WingUtils::FormatName(BP));
return; return;

View File

@@ -43,11 +43,10 @@ public:
if (!BP) return; if (!BP) return;
// Check for valid proposed name // Check for valid proposed name
if (!WingUtils::FindNoneWithExternalID(Dispatcher, BP->NewVariables, TEXT("Variable"))) return; FName InternalID = WingUtils::CheckProposedName(Dispatcher);
if (!WingUtils::FindNoneWithExternalID(Dispatcher, WingUtils::AllGraphs(BP), TEXT("Graph"))) return; if (InternalID.IsNone()) return;
FString InternalName = WingUtils::CheckProposedName(Dispatcher); if (!WingUtils::FindNoneWithInternalID(InternalID, BP->NewVariables, TEXT("Variable"))) return;
if (InternalName.IsEmpty()) return; if (!WingUtils::FindNoneWithInternalID(InternalID, WingUtils::AllGraphs(BP), TEXT("Graph"))) return;
FName VarFName(InternalName);
// Make sure the argument types are valid. // Make sure the argument types are valid.
if (!WingFunctionArgs::CheckArgs(Arguments)) return; if (!WingFunctionArgs::CheckArgs(Arguments)) return;
@@ -55,7 +54,7 @@ public:
// Add the delegate variable // Add the delegate variable
FEdGraphPinType DelegateType; FEdGraphPinType DelegateType;
DelegateType.PinCategory = UEdGraphSchema_K2::PC_MCDelegate; DelegateType.PinCategory = UEdGraphSchema_K2::PC_MCDelegate;
if (!FBlueprintEditorUtils::AddMemberVariable(BP, VarFName, DelegateType)) if (!FBlueprintEditorUtils::AddMemberVariable(BP, InternalID, DelegateType))
{ {
UWingServer::Printf(TEXT("ERROR: Failed to add event dispatcher '%s' to %s\n"), *Dispatcher, *WingUtils::FormatName(BP)); UWingServer::Printf(TEXT("ERROR: Failed to add event dispatcher '%s' to %s\n"), *Dispatcher, *WingUtils::FormatName(BP));
return; return;
@@ -63,7 +62,7 @@ public:
// Create the signature graph // Create the signature graph
const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>(); const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();
UEdGraph* SigGraph = FBlueprintEditorUtils::CreateNewGraph(BP, VarFName, UEdGraph* SigGraph = FBlueprintEditorUtils::CreateNewGraph(BP, InternalID,
UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass()); UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass());
if (!SigGraph) if (!SigGraph)
{ {

View File

@@ -28,6 +28,6 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingTokenizer T(Input); WingTokenizer T(Input);
T.PrintEverything(); T.PrintEverything(UWingServer::GetPrintBuffer());
} }
}; };

View File

@@ -66,13 +66,13 @@ public:
} }
// Validate the proposed name. // Validate the proposed name.
FString UnsanitizedName = WingUtils::CheckProposedName(Name); FName InternalID = WingUtils::CheckProposedName(Name);
if (UnsanitizedName.IsEmpty()) return; if (InternalID.IsNone()) return;
// Check that the name is unique among existing widgets. // Check that the name is unique among existing widgets.
TArray<UWidget*> AllWidgets; TArray<UWidget*> AllWidgets;
Tree->GetAllWidgets(AllWidgets); Tree->GetAllWidgets(AllWidgets);
if (!WingUtils::FindNoneWithExternalID(Name, AllWidgets, TEXT("Widget"))) return; if (!WingUtils::FindNoneWithInternalID(InternalID, AllWidgets, TEXT("Widget"))) return;
// If a parent is specified, find it and verify it's a panel. // If a parent is specified, find it and verify it's a panel.
UPanelWidget* ParentPanel = nullptr; UPanelWidget* ParentPanel = nullptr;
@@ -94,11 +94,10 @@ public:
// Create the widget. // Create the widget.
UWidget* NewWidget; UWidget* NewWidget;
FName WidgetFName(*UnsanitizedName);
if (WidgetClass->IsChildOf(UUserWidget::StaticClass())) if (WidgetClass->IsChildOf(UUserWidget::StaticClass()))
NewWidget = CreateWidget<UUserWidget>(Tree, WidgetClass, WidgetFName); NewWidget = CreateWidget<UUserWidget>(Tree, WidgetClass, InternalID);
else else
NewWidget = NewObject<UWidget>(Tree, WidgetClass, WidgetFName, RF_Transactional); NewWidget = NewObject<UWidget>(Tree, WidgetClass, InternalID, RF_Transactional);
if (!NewWidget) if (!NewWidget)
{ {

View File

@@ -1,5 +1,4 @@
#include "WingTokenizer.h" #include "WingTokenizer.h"
#include "WingServer.h"
void WingCharacterClasses::Assign(Cat Category, FStringView String) void WingCharacterClasses::Assign(Cat Category, FStringView String)
@@ -193,11 +192,11 @@ WingTokenizer::WingTokenizer(const FString& Input)
if (!Error.IsEmpty()) Tokens.Empty(); if (!Error.IsEmpty()) Tokens.Empty();
} }
void WingTokenizer::PrintEverything() const void WingTokenizer::PrintEverything(FStringBuilderBase &Out) const
{ {
if (!Error.IsEmpty()) if (!Error.IsEmpty())
{ {
UWingServer::Printf(TEXT("Error: %s\n"), *Error); Out.Appendf(TEXT("Error: %s\n"), *Error);
} }
for (const Token& T : Tokens) for (const Token& T : Tokens)
{ {
@@ -215,9 +214,9 @@ void WingTokenizer::PrintEverything() const
} }
} }
if (T.Type >= 0x20 && T.Type <= 0x7E) if (T.Type >= 0x20 && T.Type <= 0x7E)
UWingServer::Printf(TEXT("Token '%c': %s\n"), T.Type, *ExtraStr); Out.Appendf(TEXT("Token '%c': %s\n"), T.Type, *ExtraStr);
else else
UWingServer::Printf(TEXT("Token %04X: %s\n"), (int32)T.Type, *ExtraStr); Out.Appendf(TEXT("Token %04X: %s\n"), (int32)T.Type, *ExtraStr);
} }
} }
@@ -300,17 +299,6 @@ FString WingTokenizer::TryInternalizeID(const FString &ExternalID, FString &Erro
return InternalID; return InternalID;
} }
FString WingTokenizer::CheckInternalizeID(const FString &ExternalID)
{
FString Error;
FString InternalID = TryInternalizeID(ExternalID, Error);
if (!Error.IsEmpty())
{
UWingServer::Printf(TEXT("%s\n"), *Error);
UWingServer::SuggestManual(WingManual::Section::EscapeSequences);
}
return InternalID;
}
FString WingTokenizer::SimplifyID(const FString &ID) FString WingTokenizer::SimplifyID(const FString &ID)
{ {

View File

@@ -64,18 +64,25 @@ FString WingUtils::ExternalizeID(FName Name)
FName WingUtils::CheckInternalizeID(const FString &ExternalID) FName WingUtils::CheckInternalizeID(const FString &ExternalID)
{ {
return FName(WingTokenizer::CheckInternalizeID(ExternalID)); FString Error;
FString InternalID = WingTokenizer::TryInternalizeID(ExternalID, Error);
if (!Error.IsEmpty())
{
UWingServer::Printf(TEXT("%s\n"), *Error);
UWingServer::SuggestManual(WingManual::Section::EscapeSequences);
}
return FName(InternalID);
} }
FString WingUtils::CheckProposedName(const FString &ExternalID) FName WingUtils::CheckProposedName(const FString &ExternalID)
{ {
FString InternalID = WingTokenizer::CheckInternalizeID(ExternalID); FName InternalID = CheckInternalizeID(ExternalID);
if (!InternalID.IsEmpty() && !WingTokenizer::WouldExternalizeReadably(InternalID)) if (!InternalID.IsNone() && !WingTokenizer::WouldExternalizeReadably(InternalID.ToString()))
{ {
UWingServer::Printf(TEXT("ERROR: id %s would not be a readable id, may not create item with this name"), UWingServer::Printf(TEXT("ERROR: id %s would not be a readable id, may not create item with this name"),
*ExternalID); *ExternalID);
UWingServer::SuggestManual(WingManual::Section::EscapeSequences); UWingServer::SuggestManual(WingManual::Section::EscapeSequences);
return FString(); return FName();
} }
return InternalID; return InternalID;
} }

View File

@@ -144,12 +144,6 @@ struct WingTokenizer
// string and sets the error message. // string and sets the error message.
static FString TryInternalizeID(const FString &ExternalID, FString &Error); static FString TryInternalizeID(const FString &ExternalID, FString &Error);
// Calls TryInternalizeName. If this generates an
// error, prints the error message, suggests the manual
// entry on identifier sanitization, and returns empty
// string.
static FString CheckInternalizeID(const FString &ExternalID);
// Simplify an ID. This removes any non-identifier // Simplify an ID. This removes any non-identifier
// characters from the ID. Be careful! This could // characters from the ID. Be careful! This could
// remove the whole identifier! So obviously this // remove the whole identifier! So obviously this
@@ -157,8 +151,8 @@ struct WingTokenizer
// that's OK. // that's OK.
static FString SimplifyID(const FString &ID); static FString SimplifyID(const FString &ID);
// Print all tokens to the log for debugging. // Print all tokens into a string builder for debugging.
void PrintEverything() const; void PrintEverything(FStringBuilderBase &Out) const;
private: private:
// Add a token to the token array. // Add a token to the token array.

View File

@@ -197,7 +197,7 @@ public:
// empty string. // empty string.
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
[[nodiscard]] static FString CheckProposedName(const FString &Name); static FName CheckProposedName(const FString &Name);
static FString FormatNodeTitle(const UEdGraphNode *Node); static FString FormatNodeTitle(const UEdGraphNode *Node);