Starting to convert old search functions to new ones

This commit is contained in:
2026-03-29 01:14:58 -04:00
parent 2ad86bac1d
commit 843e16b177
18 changed files with 62 additions and 64 deletions

Binary file not shown.

View File

@@ -50,7 +50,7 @@ public:
// Check that the proposed name is valid
TArray<UWingComponentReference*> AllComponents = UWingComponentReference::GetAll(BP);
if (!WingUtils::FindExactlyNoneNamed(Component, AllComponents, TEXT("Component"))) return;
if (!WingUtils::FindNoneWithExternalID(Component, AllComponents, TEXT("Component"))) return;
FString InternalName = WingUtils::CheckProposedName(Component);
if (InternalName.IsEmpty()) return;
@@ -65,7 +65,7 @@ public:
if (!UWingComponentReference::CheckValidComponentClass(ComponentClass)) return;
// Find the specified parent component
UWingComponentReference* ParentComp = WingUtils::FindExactlyOneNamed(Parent, AllComponents, TEXT("Component"));
UWingComponentReference* ParentComp = WingUtils::FindOneWithExternalID(Parent, AllComponents, TEXT("Component"));
if (!ParentComp) return;
// Create the SCS node

View File

@@ -42,7 +42,7 @@ public:
// Find the new parent among all components (if specified)
UBlueprint *BP = CompRef->BP;
TArray<UWingComponentReference*> AllComponents = UWingComponentReference::GetAll(BP);
UWingComponentReference* NewParent = WingUtils::FindExactlyOneNamed(Parent, AllComponents, TEXT("Component"));
UWingComponentReference* NewParent = WingUtils::FindOneWithExternalID(Parent, AllComponents, TEXT("Component"));
if (!NewParent) return;
if (!CompRef->ReparentComponent(NewParent)) return;

View File

@@ -76,7 +76,7 @@ public:
}
// Check graph name uniqueness and legality
if (!WingUtils::FindExactlyNoneNamed(Graph, WingUtils::AllGraphs(BP), TEXT("Graph")))
if (!WingUtils::FindNoneWithExternalID(Graph, WingUtils::AllGraphs(BP), TEXT("Graph")))
return;
FString InternalName = WingUtils::CheckProposedName(Graph);
if (InternalName.IsEmpty()) return;

View File

@@ -45,7 +45,7 @@ public:
if (!BP) return;
// Check validity of the proposed name
if (!WingUtils::FindExactlyNoneNamed(Name, BP->NewVariables, TEXT("Variable"))) return;
if (!WingUtils::FindNoneWithExternalID(Name, BP->NewVariables, TEXT("Variable"))) return;
FString InternalName = WingUtils::CheckProposedName(Name);
if (InternalName.IsEmpty()) return;
FName VarFName(InternalName);

View File

@@ -43,8 +43,8 @@ public:
if (!BP) return;
// Check for valid proposed name
if (!WingUtils::FindExactlyNoneNamed(Dispatcher, BP->NewVariables, TEXT("Variable"))) return;
if (!WingUtils::FindExactlyNoneNamed(Dispatcher, WingUtils::AllGraphs(BP), TEXT("Graph"))) return;
if (!WingUtils::FindNoneWithExternalID(Dispatcher, BP->NewVariables, TEXT("Variable"))) return;
if (!WingUtils::FindNoneWithExternalID(Dispatcher, WingUtils::AllGraphs(BP), TEXT("Graph"))) return;
FString InternalName = WingUtils::CheckProposedName(Dispatcher);
if (InternalName.IsEmpty()) return;
FName VarFName(InternalName);

View File

@@ -37,9 +37,9 @@ public:
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
if (!BP) return;
FBPVariableDescription* Var = WingUtils::FindExactlyOneNamed(Dispatcher, BP->NewVariables, TEXT("Dispatcher"));
FBPVariableDescription* Var = WingUtils::FindOneWithExternalID(Dispatcher, BP->NewVariables, TEXT("Dispatcher"));
if (!Var) return;
TObjectPtr<UEdGraph>* SigGraph = WingUtils::FindExactlyOneNamed(Dispatcher, BP->DelegateSignatureGraphs, TEXT("Dispatcher Signature Graph"));
TObjectPtr<UEdGraph>* SigGraph = WingUtils::FindOneWithExternalID(Dispatcher, BP->DelegateSignatureGraphs, TEXT("Dispatcher Signature Graph"));
if (!SigGraph) return;
UEdGraph* Graph = *SigGraph;

View File

@@ -39,9 +39,9 @@ public:
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
if (!BP) return;
FBPVariableDescription* Var = WingUtils::FindExactlyOneNamed(Dispatcher, BP->NewVariables, TEXT("Dispatcher"));
FBPVariableDescription* Var = WingUtils::FindOneWithExternalID(Dispatcher, BP->NewVariables, TEXT("Dispatcher"));
if (!Var) return;
TObjectPtr<UEdGraph>* SigGraph = WingUtils::FindExactlyOneNamed(Dispatcher, BP->DelegateSignatureGraphs, TEXT("Dispatcher Signature Graph"));
TObjectPtr<UEdGraph>* SigGraph = WingUtils::FindOneWithExternalID(Dispatcher, BP->DelegateSignatureGraphs, TEXT("Dispatcher Signature Graph"));
if (!SigGraph) return;
TWeakObjectPtr<UK2Node_EditablePinBase> EntryNode;

View File

@@ -41,9 +41,9 @@ public:
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
if (!BP) return;
FBPVariableDescription* Var = WingUtils::FindExactlyOneNamed(Dispatcher, BP->NewVariables, TEXT("Dispatcher"));
FBPVariableDescription* Var = WingUtils::FindOneWithExternalID(Dispatcher, BP->NewVariables, TEXT("Dispatcher"));
if (!Var) return;
TObjectPtr<UEdGraph>* SigGraph = WingUtils::FindExactlyOneNamed(Dispatcher, BP->DelegateSignatureGraphs, TEXT("Dispatcher Signature Graph"));
TObjectPtr<UEdGraph>* SigGraph = WingUtils::FindOneWithExternalID(Dispatcher, BP->DelegateSignatureGraphs, TEXT("Dispatcher Signature Graph"));
if (!SigGraph) return;
// Make sure the argument types are valid.

View File

@@ -72,13 +72,13 @@ public:
// Check that the name is unique among existing widgets.
TArray<UWidget*> AllWidgets;
Tree->GetAllWidgets(AllWidgets);
if (!WingUtils::FindExactlyNoneNamed(Name, AllWidgets, TEXT("Widget"))) return;
if (!WingUtils::FindNoneWithExternalID(Name, AllWidgets, TEXT("Widget"))) return;
// If a parent is specified, find it and verify it's a panel.
UPanelWidget* ParentPanel = nullptr;
if (!Parent.IsEmpty())
{
UWidget* ParentWidget = WingUtils::FindExactlyOneNamed(Parent, AllWidgets, TEXT("Widget"));
UWidget* ParentWidget = WingUtils::FindOneWithExternalID(Parent, AllWidgets, TEXT("Widget"));
if (!ParentWidget) return;
if (!WingWidgets::CheckCanBeParent(ParentWidget)) return;
ParentPanel = Cast<UPanelWidget>(ParentWidget);

View File

@@ -56,7 +56,7 @@ public:
FString WidgetName = WingUtils::FormatName(TargetWidget);
// Find the new parent and verify it's a panel with room.
UWidget* ParentWidget = WingUtils::FindExactlyOneNamed(Parent, AllWidgets, TEXT("Widget"));
UWidget* ParentWidget = WingUtils::FindOneWithExternalID(Parent, AllWidgets, TEXT("Widget"));
if (!ParentWidget) return;
if (!WingWidgets::CheckCanBeParent(ParentWidget)) return;
UPanelWidget* ParentPanel = Cast<UPanelWidget>(ParentWidget);

View File

@@ -7,7 +7,7 @@
FWingBlueprintVar::FWingBlueprintVar(UBlueprint* BP, const FString& VarName)
{
Desc = WingUtils::FindExactlyOneNamed(VarName, BP->NewVariables, TEXT("Variable"));
Desc = WingUtils::FindOneWithExternalID(VarName, BP->NewVariables, TEXT("Variable"));
if (!Desc) return;
if (Desc->VarType.PinCategory == UEdGraphSchema_K2::PC_MCDelegate)
{

View File

@@ -89,7 +89,7 @@ WingFetcher& WingFetcher::Walk(const FString& Path)
{
UWingServer::Printf(TEXT("ERROR: Paths may not contain whitespace."));
UWingServer::SuggestManual(WingManual::Section::Paths);
UWingServer::SuggestManual(WingManual::Section::IdentifierSanitization);
UWingServer::SuggestManual(WingManual::Section::EscapeSequences);
return SetError();
}
TArray<FString> Segments;
@@ -224,7 +224,7 @@ WingFetcher& WingFetcher::Graph(const FString& Value)
}
TArray<UEdGraph*> Graphs = WingUtils::AllGraphs(BP);
UEdGraph* Found = WingUtils::FindExactlyOneNamed(Value, Graphs, TEXT("graph"));
UEdGraph* Found = WingUtils::FindOneWithExternalID(Value, Graphs, TEXT("graph"));
if (!Found)
{
UWingServer::Printf(TEXT("Graphs that exist in blueprint:\n"));
@@ -253,7 +253,7 @@ WingFetcher& WingFetcher::Node(const FString& Value)
// Get the nodes from the graph.
TArray<UEdGraphNode *> AllNodes = WingUtils::AllNodes(Graph);
UEdGraphNode *Node = WingUtils::FindExactlyOneNamed(Value, AllNodes, TEXT("node"));
UEdGraphNode *Node = WingUtils::FindOneWithExternalID(Value, AllNodes, TEXT("node"));
if (Node == nullptr)
{
UWingServer::Printf(TEXT("Nodes that exist in graph:\n"));
@@ -277,7 +277,7 @@ WingFetcher& WingFetcher::Pin(const FString& Value)
TypeMismatch(TEXT("pin"), TEXT("node"));
return SetError();
}
UEdGraphPin *Found = WingUtils::FindExactlyOneNamed(Value, N->Pins, TEXT("pin"));
UEdGraphPin *Found = WingUtils::FindOneWithExternalID(Value, N->Pins, TEXT("pin"));
if (!Found)
{
UWingServer::Printf(TEXT("Pins that exist in the node:\n"));
@@ -303,7 +303,7 @@ WingFetcher& WingFetcher::Component(const FString& Value)
}
TArray<UWingComponentReference*> AllComponents = UWingComponentReference::GetAll(BP);
UWingComponentReference* Found = WingUtils::FindExactlyOneNamed(Value, AllComponents, TEXT("component"));
UWingComponentReference* Found = WingUtils::FindOneWithExternalID(Value, AllComponents, TEXT("component"));
if (!Found)
{
UWingServer::Printf(TEXT("Components that exist in the blueprint:\n"));
@@ -331,7 +331,7 @@ WingFetcher& WingFetcher::Widget(const FString& Value)
TArray<UWidget*> AllWidgets;
WidgetBP->WidgetTree->GetAllWidgets(AllWidgets);
UWidget* Found = WingUtils::FindExactlyOneNamed(Value, AllWidgets, TEXT("widget"));
UWidget* Found = WingUtils::FindOneWithExternalID(Value, AllWidgets, TEXT("widget"));
if (!Found)
{
UWingServer::Printf(TEXT("Widgets that exist in the blueprint:\n"));

View File

@@ -9,7 +9,7 @@ TSet<WingManual::Section> WingManual::AllSections()
Section::Paths,
Section::Types,
Section::ParameterLists,
Section::IdentifierSanitization,
Section::EscapeSequences,
Section::Whitespace,
Section::MaterialEditing,
Section::ImportantCommands,
@@ -111,9 +111,9 @@ void WingManual::PrintManual(TSet<Section> Sections, UClass *Handler, bool Abrid
"\n with an asset name, followed by steps separated by ,"
"\n that navigate into the asset. Some Examples:"
"\n"
"\n /Game/Widgets/WB_Hotkeys,widget:Canvas·122"
"\n /Game/Testing/BP_Test,graph:Rescale·Actor,node:K2Node_CallFunction_0,pin:Scale"
"\n /Game/Chars/BP_Manny,component:Camera·Boom"
"\n /Game/Widgets/WB_Hotkeys,widget:Canvas.122"
"\n /Game/Testing/BP_Test,graph:Rescale.Actor,node:K2Node_CallFunction_0,pin:Scale"
"\n /Game/Chars/BP_Manny,component:Camera.Boom"
"\n"
"\n The navigation steps supported are:"
"\n"
@@ -201,47 +201,45 @@ void WingManual::PrintManual(TSet<Section> Sections, UClass *Handler, bool Abrid
}
}
if (Sections.Contains(Section::IdentifierSanitization))
if (Sections.Contains(Section::EscapeSequences))
{
if (Abridged)
{
UWingServer::Print(TEXT(
"\n IDENTIFIER SANITIZATION:"
"\n Identifiers in unreal can contain whitespace and punctuation."
"\n We sanitize these characters on output:"
"\n USING HTML ESCAPE SEQUENCES:"
"\n When we output FNames, we use HTML escape sequences for the"
"\n following marks: \\\"'(),.:;<=>& We also escape control"
"\n characters, and some (but not all) unicode characters."
"\n We also translate spaces to periods. Examples:"
"\n"
"\n space → ·"
"\n < → ◁"
"\n > "
"\n , → ▾"
"\n FName(TEXT(\"No_Change\")) --> No_Change"
"\n FName(TEXT(\"ίδιος\")) --> ίδιος"
"\n FName(TEXT(\"✡✢❄\")) --> &#10017;&#10018;&#10052;"
"\n FName(TEXT(\"Hello.There\")) --> Hello&period;There"
"\n FName(TEXT(\"Hello There\")) --> Hello.There"
"\n FName(TEXT(\"Hello\n\")) --> Hello&NewLine;"
"\n "
"\n We do the reverse translation on input. Therefore, you will always"
"\n see sanitized versions of identifiers, and you must always use"
"\n sanitized versions of identifiers:"
"\n When sending FNames to UE Wingman, you *must* escape the marks"
"\n listed above and control characters, but you *may* escape"
"\n any character. To send an FName with a space in it, either"
"\n use &#32; or a period."
"\n"
"\n Currently, this escaping *only* applies to FNames. It"
"\n doesn't work to use escapes in asset names or file names."
"\n"
));
}
else
{
UWingServer::Print(TEXT(
"\n IDENTIFIER SANITIZATION:"
"\n USING HTML ESCAPE SEQUENCES:"
"\n When we output FNames, we use HTML escape sequences for the"
"\n following marks: \\\"'(),.:;<=>&, and for certain other characters."
"\n We also translate spaces to periods."
"\n"
"\n Identifiers in Unreal can contain spaces and punctuation marks."
"\n Those punctuation marks could confuse our parsers. For example,"
"\n How would we parse Array<X> if the typename X contained a less-than?"
"\n So, we automatically translate these characters on output:"
"\n"
"\n space → ·"
"\n < → ◁"
"\n > → ▷"
"\n , → ▾"
"\n "
"\n We do the reverse translation on input. Therefore, you will always"
"\n see sanitized versions of identifiers, and you must always use"
"\n sanitized versions of identifiers:"
"\n"
"\n Correct: /Game/Testing/BP_Test,graph:Get·Cursor·Location"
"\n Wrong: /Game/Testing/BP_Test,graph:Get Cursor Location"
"\n When sending FNames to UE Wingman, you *must* escape the marks"
"\n listed above, but you *may* escape any character. To send an FName"
"\n with a space in it, either use &#32; or a period."
"\n"
));
}

View File

@@ -307,7 +307,7 @@ FString WingTokenizer::CheckInternalizeID(const FString &ExternalID)
if (!Error.IsEmpty())
{
UWingServer::Printf(TEXT("%s\n"), *Error);
UWingServer::SuggestManual(WingManual::Section::IdentifierSanitization);
UWingServer::SuggestManual(WingManual::Section::EscapeSequences);
}
return InternalID;
}

View File

@@ -77,7 +77,7 @@ FString WingUtils::CheckProposedName(const FString &ExternalID)
{
UWingServer::Printf(TEXT("ERROR: id %s would not be a readable id, may not create item with this name"),
*ExternalID);
UWingServer::SuggestManual(WingManual::Section::IdentifierSanitization);
UWingServer::SuggestManual(WingManual::Section::EscapeSequences);
return FString();
}
return InternalID;

View File

@@ -10,7 +10,7 @@ public:
Paths,
Types,
ParameterLists,
IdentifierSanitization,
EscapeSequences,
Whitespace,
MaterialEditing,
ImportantCommands,

View File

@@ -69,7 +69,7 @@ public:
static FName GetFName(const UWidget *Widget) { return Widget->GetFName(); }
template<typename ArrayType>
static auto FindOneWithInternalID(FName InternalID, ArrayType &Array, const TCHAR *Kind)
static auto FindOneWithInternalID(FName InternalID, ArrayType &&Array, const TCHAR *Kind)
{
decltype(EltAsPtr(Array, Array[0])) Result = nullptr;
int Count = 0;
@@ -79,7 +79,7 @@ public:
}
template<typename ArrayType>
static auto FindOneWithExternalID(const FString &ExternalID, ArrayType &Array, const TCHAR *Kind)
static auto FindOneWithExternalID(const FString &ExternalID, ArrayType &&Array, const TCHAR *Kind)
{
decltype(EltAsPtr(Array, Array[0])) Result = nullptr;
FName InternalID = CheckInternalizeID(ExternalID);
@@ -88,7 +88,7 @@ public:
}
template<typename ArrayType>
static bool FindNoneWithInternalID(FName InternalID, ArrayType &Array, const TCHAR *Kind)
static bool FindNoneWithInternalID(FName InternalID, ArrayType &&Array, const TCHAR *Kind)
{
for (auto &Elt : Array) if (GetFName(Elt) == InternalID)
return CheckExactlyNoneNamed(1, Kind, InternalID);
@@ -96,7 +96,7 @@ public:
}
template<typename ArrayType>
static bool FindNoneWithExternalID(const FString &ExternalID, ArrayType &Array, const TCHAR *Kind)
static bool FindNoneWithExternalID(const FString &ExternalID, ArrayType &&Array, const TCHAR *Kind)
{
FName InternalID = CheckInternalizeID(ExternalID);
if (InternalID.IsNone()) return false;