Overhaul of manual-generation code
This commit is contained in:
@@ -12,6 +12,9 @@ class UWing_Documentation_Manual : public UWingHandler
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, meta=(Optional, Description="If specified, print only this section of the manual"))
|
||||
FString Section;
|
||||
|
||||
virtual void Register() override
|
||||
{
|
||||
UWingServer::AddHandler(this,
|
||||
@@ -19,6 +22,23 @@ public:
|
||||
}
|
||||
virtual void Handle() override
|
||||
{
|
||||
WingManual::PrintManual({WingManual::Section::All}, nullptr, false);
|
||||
if (Section.IsEmpty())
|
||||
{
|
||||
UWingManualSections::FetcherPaths();
|
||||
UWingManualSections::ExpressingTypes();
|
||||
UWingManualSections::VariableDeclarations();
|
||||
UWingManualSections::EscapeSequencesInFNames();
|
||||
UWingManualSections::MaterialEditing();
|
||||
UWingManualSections::ImportantCommands();
|
||||
}
|
||||
else
|
||||
{
|
||||
FName SectionName(*Section);
|
||||
if (!WingManual::PrintSection(SectionName))
|
||||
{
|
||||
WingOut::Stdout.Printf(TEXT("ERROR: Unknown manual section '%s'\nAvailable sections: "), *Section);
|
||||
WingManual::PrintSectionNames(WingManual::GetSections());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -53,7 +53,7 @@ void WingFetcher::PathFailed(const TCHAR* Expected)
|
||||
Errors.Printf(TEXT("ERROR: Path specifies a %s, but expected %s\n"), *Obj.Get()->GetClass()->GetName(), Expected);
|
||||
else
|
||||
Errors.Printf(TEXT("ERROR: Path led to a null pointer\n"));
|
||||
UWingServer::SuggestManual(WingManual::Section::Paths);
|
||||
UWingServer::SuggestManual(GET_FUNCTION_NAME_CHECKED(UWingManualSections, FetcherPaths));
|
||||
SetError();
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ WingFetcher& WingFetcher::TypeMismatch(const TCHAR* Walker, const TCHAR* Expecte
|
||||
Errors.Printf(TEXT("ERROR: Input to '%s' is %s, but expected %s\n"), Walker, *Obj.Get()->GetClass()->GetName(), Expected);
|
||||
else
|
||||
Errors.Printf(TEXT("ERROR: Path led to a null pointer\n"));
|
||||
UWingServer::SuggestManual(WingManual::Section::Paths);
|
||||
UWingServer::SuggestManual(GET_FUNCTION_NAME_CHECKED(UWingManualSections, FetcherPaths));
|
||||
SetError();
|
||||
return *this;
|
||||
}
|
||||
@@ -75,8 +75,8 @@ WingFetcher& WingFetcher::Walk(const FString& Path)
|
||||
if (Path.Contains(TEXT(" ")))
|
||||
{
|
||||
Errors.Printf(TEXT("ERROR: Paths may not contain whitespace."));
|
||||
UWingServer::SuggestManual(WingManual::Section::Paths);
|
||||
UWingServer::SuggestManual(WingManual::Section::EscapeSequences);
|
||||
UWingServer::SuggestManual(GET_FUNCTION_NAME_CHECKED(UWingManualSections, FetcherPaths));
|
||||
UWingServer::SuggestManual(GET_FUNCTION_NAME_CHECKED(UWingManualSections, EscapeSequencesInFNames));
|
||||
return SetError();
|
||||
}
|
||||
TArray<FString> Segments;
|
||||
@@ -84,7 +84,7 @@ WingFetcher& WingFetcher::Walk(const FString& Path)
|
||||
if (Segments.Num() == 0)
|
||||
{
|
||||
Errors.Print(TEXT("ERROR: Empty path\n"));
|
||||
UWingServer::SuggestManual(WingManual::Section::Paths);
|
||||
UWingServer::SuggestManual(GET_FUNCTION_NAME_CHECKED(UWingManualSections, FetcherPaths));
|
||||
return SetError();
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ WingFetcher& WingFetcher::Walk(const FString& Path)
|
||||
if (!Func)
|
||||
{
|
||||
Errors.Printf(TEXT("ERROR: Unknown path step '%s'\n"), *Key);
|
||||
UWingServer::SuggestManual(WingManual::Section::Paths);
|
||||
UWingServer::SuggestManual(GET_FUNCTION_NAME_CHECKED(UWingManualSections, FetcherPaths));
|
||||
return SetError();
|
||||
}
|
||||
(this->*Func)(Value);
|
||||
@@ -122,7 +122,7 @@ WingFetcher& WingFetcher::Asset(const FString& PackagePath)
|
||||
if (!PackagePath.StartsWith(TEXT("/")))
|
||||
{
|
||||
Errors.Printf(TEXT("ERROR: Path must start with '/', got '%s'\n"), *PackagePath);
|
||||
UWingServer::SuggestManual(WingManual::Section::Paths);
|
||||
UWingServer::SuggestManual(GET_FUNCTION_NAME_CHECKED(UWingManualSections, FetcherPaths));
|
||||
return SetError();
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ WingFetcher& WingFetcher::Graph(const FString& Value)
|
||||
if (!Value.IsEmpty())
|
||||
{
|
||||
Errors.Printf(TEXT("ERROR: Materials have only one graph, with a blank name.\n\n"));
|
||||
UWingServer::SuggestManual(WingManual::Section::Paths);
|
||||
UWingServer::SuggestManual(GET_FUNCTION_NAME_CHECKED(UWingManualSections, FetcherPaths));
|
||||
return SetError();
|
||||
}
|
||||
WingUtils::EnsureMaterialGraph(Mat);
|
||||
|
||||
@@ -58,42 +58,14 @@ void WingManual::PrintHandlerHelp(const FWingHandlerConfig& Handler)
|
||||
WingOut::Stdout.Print(TEXT("\n"));
|
||||
}
|
||||
|
||||
void WingManual::PrintManual(TSet<Section> Sections, const FWingHandlerConfig* Handler, bool Abridged)
|
||||
void UWingManualSections::FetcherPaths()
|
||||
{
|
||||
if (Sections.IsEmpty()) return;
|
||||
|
||||
const bool bPrintAll = Sections.Contains(Section::All);
|
||||
|
||||
if (Abridged)
|
||||
{
|
||||
WingOut::Stdout.Printf(TEXT("\n--- AUTOMATIC DOCUMENTATION ---\n"));
|
||||
}
|
||||
|
||||
if (Handler && (Sections.Contains(Section::HandlerHelp) || bPrintAll))
|
||||
{
|
||||
PrintHandlerHelp(*Handler);
|
||||
}
|
||||
|
||||
if (Sections.Contains(Section::Paths) || bPrintAll)
|
||||
{
|
||||
if (Abridged)
|
||||
{
|
||||
WingOut::Stdout.Print(TEXT(
|
||||
"\n PATHS: Here are some example paths:"
|
||||
"\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 FETCHER PATHS:"
|
||||
"\n"
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
WingOut::Stdout.Print(TEXT(
|
||||
"\n PATHS:"
|
||||
"\n"
|
||||
"\n Most commands require you to specify a path. A path starts"
|
||||
"\n with an asset name, followed by steps separated by ,"
|
||||
"\n that navigate into the asset. Some Examples:"
|
||||
"\n Most commands require you to specify a 'fetcher path'."
|
||||
"\n A fetcher path starts with an asset name, followed by"
|
||||
"\n steps 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"
|
||||
@@ -107,9 +79,10 @@ void WingManual::PrintManual(TSet<Section> Sections, const FWingHandlerConfig* H
|
||||
"\n component — move from a blueprint to a component"
|
||||
"\n levelblueprint — move from a world to a blueprint"
|
||||
"\n widget — move from a widget blueprint to a widget"
|
||||
"\n structprop — move into a struct property of an object"
|
||||
"\n"
|
||||
"\n Notice that paths use sanitized identifiers. See the section"
|
||||
"\n on identifier sanitization below for more information."
|
||||
"\n Notice that paths use escaped fnames. See the section"
|
||||
"\n on escape sequences in fnames below sfor more information."
|
||||
"\n"
|
||||
"\n Steps do not always require a parameter. For example, materials"
|
||||
"\n only have one graph, so you can just say:"
|
||||
@@ -117,29 +90,15 @@ void WingManual::PrintManual(TSet<Section> Sections, const FWingHandlerConfig* H
|
||||
"\n /Game/Materials/MyMaterial,graph"
|
||||
"\n"
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Sections.Contains(Section::Types) || bPrintAll)
|
||||
{
|
||||
if (Abridged)
|
||||
{
|
||||
void UWingManualSections::ExpressingTypes()
|
||||
{
|
||||
WingOut::Stdout.Print(TEXT(
|
||||
"\n TYPES: Here are some examples of valid types:"
|
||||
"\n Bool, String, Vector, Rotator, HitResult, Actor, Character,"
|
||||
"\n PlayerController, EBlendMode, EMovementMode, BP_Manny, BP_Quinn,"
|
||||
"\n Array<Int>, Set<String>, Map<Int,Actor>"
|
||||
"\n Soft<ABP_Manny>, Class<Pawn>, SoftClass<Pawn>"
|
||||
"\n EXPRESSING TYPES:"
|
||||
"\n"
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
WingOut::Stdout.Print(TEXT(
|
||||
"\n TYPES:"
|
||||
"\n"
|
||||
"\n To change variable types, or to express function prototypes, you will"
|
||||
"\n use our syntax for types. Here are some valid examples:"
|
||||
"\n To change the type of a variable, or to express function parameters,"
|
||||
"\n you will use our syntax for types. Here are some valid examples:"
|
||||
"\n"
|
||||
"\n Bool, String, Vector, Rotator, HitResult, Actor, Character,"
|
||||
"\n PlayerController, EBlendMode, EMovementMode, BP_Manny, BP_Quinn,"
|
||||
@@ -148,25 +107,14 @@ void WingManual::PrintManual(TSet<Section> Sections, const FWingHandlerConfig* H
|
||||
"\n"
|
||||
"\n Notice that it's 'Actor', not 'AActor'. Type names are not"
|
||||
"\n case-sensitive. When a blueprint like /Game/Testing/BP_Foo"
|
||||
"\n is used as a type, the typename is BP_Foo."
|
||||
"\n is used as a type, the typename is just BP_Foo. You can search"
|
||||
"\n for valid types using the TypeName_Search command."
|
||||
"\n"
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Sections.Contains(Section::VariableDeclarations) || bPrintAll)
|
||||
{
|
||||
if (Abridged)
|
||||
{
|
||||
WingOut::Stdout.Print(TEXT(
|
||||
"\n VARIABLE DECLARATIONS: example variable declarations:"
|
||||
"\n Array<Actor> Actors"
|
||||
"\n Float F (InstanceEditable)"
|
||||
"\n String S = This is the default value"
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
void UWingManualSections::VariableDeclarations()
|
||||
{
|
||||
WingOut::Stdout.Print(TEXT(
|
||||
"\n VARIABLE DECLARATIONS:"
|
||||
"\n"
|
||||
@@ -179,48 +127,20 @@ void WingManual::PrintManual(TSet<Section> Sections, const FWingHandlerConfig* H
|
||||
"\n String S = This is the default value"
|
||||
"\n"
|
||||
"\n The commands Variables_Add, Variables_Modify,"
|
||||
"\n and Variables_Remove can be used to edit: "
|
||||
"\n and Variables_Remove can be used to edit "
|
||||
"\n blueprint variables, graph local variables, graph input"
|
||||
"\n variables, graph output variables, and custom"
|
||||
"\n event node input variables. Event dispatchers are"
|
||||
"\n also graphs, so they too can be edited."
|
||||
"\n"
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Sections.Contains(Section::EscapeSequences) || bPrintAll)
|
||||
{
|
||||
if (Abridged)
|
||||
{
|
||||
void UWingManualSections::EscapeSequencesInFNames()
|
||||
{
|
||||
WingOut::Stdout.Print(TEXT(
|
||||
"\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 ESCAPE SEQUENCES IN FNAMES:"
|
||||
"\n"
|
||||
"\n FName(TEXT(\"No_Change\")) --> No_Change"
|
||||
"\n FName(TEXT(\"ίδιος\")) --> ίδιος"
|
||||
"\n FName(TEXT(\"✡✢❄\")) --> ✡✢❄"
|
||||
"\n FName(TEXT(\"Hello.There\")) --> Hello.There"
|
||||
"\n FName(TEXT(\"Hello There\")) --> Hello.There"
|
||||
"\n FName(TEXT(\"Hello\n\")) --> Hello
"
|
||||
"\n "
|
||||
"\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   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
|
||||
{
|
||||
WingOut::Stdout.Print(TEXT(
|
||||
"\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."
|
||||
@@ -230,34 +150,10 @@ void WingManual::PrintManual(TSet<Section> Sections, const FWingHandlerConfig* H
|
||||
"\n with a space in it, either use   or a period."
|
||||
"\n"
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Sections.Contains(Section::Whitespace) || bPrintAll)
|
||||
{
|
||||
WingOut::Stdout.Print(TEXT(
|
||||
"\n ABOUT WHITESPACE:"
|
||||
"\n Do not put excess whitespace into paths, typenames, or"
|
||||
"\n function prototypes, only use whitespace where it is required"
|
||||
"\n by the syntax."
|
||||
"\n"
|
||||
));
|
||||
}
|
||||
|
||||
if (Sections.Contains(Section::MaterialEditing) || bPrintAll)
|
||||
{
|
||||
if (Abridged)
|
||||
{
|
||||
WingOut::Stdout.Print(TEXT(
|
||||
"\n MATERIAL EDITING:"
|
||||
"\n We do not expose material expressions directly. Instead, use"
|
||||
"\n Details_Dump and Details_Set on the material graph nodes to"
|
||||
"\n edit material expression properties."
|
||||
"\n"
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
void UWingManualSections::MaterialEditing()
|
||||
{
|
||||
WingOut::Stdout.Print(TEXT(
|
||||
"\n MATERIAL EDITING:"
|
||||
"\n"
|
||||
@@ -267,15 +163,18 @@ void WingManual::PrintManual(TSet<Section> Sections, const FWingHandlerConfig* H
|
||||
"\n properties which actually come from the material expressions."
|
||||
"\n You can edit these using Details_Set on the node."
|
||||
"\n"
|
||||
"\n Don't overlook custom HLSL nodes. These can accomplish in\n"
|
||||
"\n a single node what would otherwise take many.\n"
|
||||
"\n"
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Sections.Contains(Section::ImportantCommands) || bPrintAll)
|
||||
{
|
||||
void UWingManualSections::ImportantCommands()
|
||||
{
|
||||
WingOut::Stdout.Print(TEXT(
|
||||
"\n COMMANDS YOU SHOULD KNOW ABOUT AND REMEMBER:"
|
||||
"\n Documentation_Manual: this explanation"
|
||||
"\n IMPORTANT COMMANDS:"
|
||||
"\n"
|
||||
"\n Documentation_Manual: print manual sections"
|
||||
"\n Documentation_Commands: a list of all the main commands"
|
||||
"\n Documentation_CreateAssets: Additional commands that create new assets"
|
||||
"\n Blueprint_Dump: a summary of any blueprint"
|
||||
@@ -283,16 +182,44 @@ void WingManual::PrintManual(TSet<Section> Sections, const FWingHandlerConfig* H
|
||||
"\n Details_Dump: Dump the details panel for a given object"
|
||||
"\n Details_Set: Manipulate the details panel for a given object"
|
||||
"\n"
|
||||
"\n You can use Documentation_Commands(Query=SomeCommand,Verbose=true)"
|
||||
"\n You can use Documentation_Commands(Query=Command,Verbose=true)"
|
||||
"\n to get detailed help for a specific command."
|
||||
"\n"
|
||||
"\n You can use Documentation_Manual(Section=Name) to print out"
|
||||
"\n a specific manual section."
|
||||
"\n"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if (Abridged)
|
||||
TSet<FName> WingManual::GetSections()
|
||||
{
|
||||
TSet<FName> Result;
|
||||
for (TFieldIterator<UFunction> It(UWingManualSections::StaticClass(), EFieldIterationFlags::None); It; ++It)
|
||||
{
|
||||
WingOut::Stdout.Printf(TEXT("\nUse command 'Documentation_Manual' to see the full manual.\n"));
|
||||
Result.Add(It->GetFName());
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
void WingManual::PrintSectionNames(const TSet<FName>& Sections)
|
||||
{
|
||||
if (Sections.IsEmpty()) return;
|
||||
bool bFirst = true;
|
||||
for (const FName& Section : Sections)
|
||||
{
|
||||
if (!bFirst) WingOut::Stdout.Print(TEXT(", "));
|
||||
bFirst = false;
|
||||
WingOut::Stdout.Printf(TEXT("%s"), *Section.ToString());
|
||||
}
|
||||
WingOut::Stdout.Print(TEXT("\n"));
|
||||
}
|
||||
|
||||
bool WingManual::PrintSection(FName Section)
|
||||
{
|
||||
UFunction* Func = UWingManualSections::StaticClass()->FindFunctionByName(Section);
|
||||
if (!Func) return false;
|
||||
UWingManualSections::StaticClass()->GetDefaultObject()->ProcessEvent(Func, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
void WingManual::Commands(EWingHandlerKind Kind, const FString& Query, bool Verbose)
|
||||
|
||||
@@ -175,6 +175,7 @@ FString UWingServer::HandleRequest(const FString& Line)
|
||||
LogCapture.bEnabled = true;
|
||||
WingOut::StdoutBuffer.Reset();
|
||||
SuggestedManualSections.Empty();
|
||||
bSuggestHandlerHelp = false;
|
||||
LastHandler = nullptr;
|
||||
|
||||
TryCallHandler(Line);
|
||||
@@ -186,10 +187,14 @@ FString UWingServer::HandleRequest(const FString& Line)
|
||||
WingOut::Stdout.Printf(TEXT("UE_LOG: %s\n"), *Msg);
|
||||
}
|
||||
LogCapture.CapturedErrors.Empty();
|
||||
if (bSuggestHandlerHelp && LastHandler)
|
||||
{
|
||||
WingManual::PrintHandlerHelp(*LastHandler);
|
||||
}
|
||||
if (!SuggestedManualSections.IsEmpty())
|
||||
{
|
||||
UWingServer::SuggestManual(WingManual::Section::HandlerHelp);
|
||||
WingManual::PrintManual(SuggestedManualSections, LastHandler, true);
|
||||
WingOut::Stdout.Print(TEXT("Suggested manual sections: "));
|
||||
WingManual::PrintSectionNames(SuggestedManualSections);
|
||||
}
|
||||
FString Result = WingOut::StdoutBuffer.ToString();
|
||||
WingOut::StdoutBuffer.Reset();
|
||||
@@ -227,7 +232,7 @@ void UWingServer::TryCallHandler(const FString &Line)
|
||||
if (!Found)
|
||||
{
|
||||
WingOut::Stdout.Printf(TEXT("Unknown command: %s"), *Command);
|
||||
UWingServer::SuggestManual(WingManual::Section::ImportantCommands);
|
||||
UWingServer::SuggestManual(GET_FUNCTION_NAME_CHECKED(UWingManualSections, ImportantCommands));
|
||||
return;
|
||||
}
|
||||
LastHandler = Found;
|
||||
@@ -241,7 +246,7 @@ void UWingServer::TryCallHandler(const FString &Line)
|
||||
TArray<FWingProperty> Props = FWingProperty::GetVisible(Handler);
|
||||
if (!FWingProperty::PopulateFromJson(Props, *Request, false, WingOut::Stdout))
|
||||
{
|
||||
UWingServer::SuggestManual(WingManual::Section::HandlerHelp);
|
||||
UWingServer::SuggestHandlerHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -430,7 +430,7 @@ void UWingTypes::PrintParseError(WingTokenizer& Tok, const TCHAR* Message, WingO
|
||||
{
|
||||
FString TypeText(Tok.GetRange(NAME_StartOfType, 1));
|
||||
Errors.Printf(TEXT("ERROR parsing type '%s' — %s\n"), *TypeText, Message);
|
||||
UWingServer::SuggestManual(WingManual::Section::Types);
|
||||
UWingServer::SuggestManual(GET_FUNCTION_NAME_CHECKED(UWingManualSections, ExpressingTypes));
|
||||
}
|
||||
|
||||
|
||||
@@ -626,7 +626,7 @@ bool UWingTypes::TextToType(WingTokenizer &Tok, FEdGraphPinType& OutPinType, con
|
||||
if (IsNone && OutPinType.IsContainer())
|
||||
{
|
||||
Errors.Printf(TEXT("ERROR: 'None' is not allowed in an array/set/map\n"));
|
||||
UWingServer::SuggestManual(WingManual::Section::HandlerHelp);
|
||||
UWingServer::SuggestHandlerHelp();
|
||||
OutPinType = FEdGraphPinType(); return false;
|
||||
}
|
||||
|
||||
@@ -634,7 +634,7 @@ bool UWingTypes::TextToType(WingTokenizer &Tok, FEdGraphPinType& OutPinType, con
|
||||
if (!Require.AllowNone && IsNone)
|
||||
{
|
||||
Errors.Printf(TEXT("ERROR: 'None' is not allowed here\n"));
|
||||
UWingServer::SuggestManual(WingManual::Section::HandlerHelp);
|
||||
UWingServer::SuggestHandlerHelp();
|
||||
OutPinType = FEdGraphPinType(); return false;
|
||||
}
|
||||
|
||||
@@ -644,7 +644,7 @@ bool UWingTypes::TextToType(WingTokenizer &Tok, FEdGraphPinType& OutPinType, con
|
||||
{
|
||||
FString Text(Tok.GetRange(NAME_StartOfType, 0));
|
||||
Errors.Printf(TEXT("ERROR: Type '%s' is a container, not allowed here\n"), *Text);
|
||||
UWingServer::SuggestManual(WingManual::Section::HandlerHelp);
|
||||
UWingServer::SuggestHandlerHelp();
|
||||
OutPinType = FEdGraphPinType(); return false;
|
||||
}
|
||||
}
|
||||
@@ -655,7 +655,7 @@ bool UWingTypes::TextToType(WingTokenizer &Tok, FEdGraphPinType& OutPinType, con
|
||||
{
|
||||
Errors.Printf(TEXT("ERROR: Need a type which is an %s, got a %s instead.\n"),
|
||||
*Require.PinCategory.ToString(), *OutPinType.PinCategory.ToString());
|
||||
UWingServer::SuggestManual(WingManual::Section::HandlerHelp);
|
||||
UWingServer::SuggestHandlerHelp();
|
||||
OutPinType = FEdGraphPinType(); return false;
|
||||
}
|
||||
}
|
||||
@@ -668,13 +668,13 @@ bool UWingTypes::TextToType(WingTokenizer &Tok, FEdGraphPinType& OutPinType, con
|
||||
{
|
||||
FString Text(Tok.GetRange(NAME_StartOfType, 0));
|
||||
Errors.Printf(TEXT("ERROR: '%s' is an interface, not a class\n"), *Text);
|
||||
UWingServer::SuggestManual(WingManual::Section::HandlerHelp);
|
||||
UWingServer::SuggestHandlerHelp();
|
||||
OutPinType = FEdGraphPinType(); return false;
|
||||
}
|
||||
if (!IsChildOf(OutPinType, Require.IsChildOf))
|
||||
{
|
||||
Errors.Printf(TEXT("ERROR: Type must derive from %s\n"), *WingUtils::FormatName(Require.IsChildOf));
|
||||
UWingServer::SuggestManual(WingManual::Section::HandlerHelp);
|
||||
UWingServer::SuggestHandlerHelp();
|
||||
OutPinType = FEdGraphPinType(); return false;
|
||||
}
|
||||
}
|
||||
@@ -685,7 +685,7 @@ bool UWingTypes::TextToType(WingTokenizer &Tok, FEdGraphPinType& OutPinType, con
|
||||
{
|
||||
FString Text(Tok.GetRange(NAME_StartOfType, 0));
|
||||
Errors.Printf(TEXT("ERROR: Not a blueprint type: %s\n"), *Text);
|
||||
UWingServer::SuggestManual(WingManual::Section::HandlerHelp);
|
||||
UWingServer::SuggestHandlerHelp();
|
||||
OutPinType = FEdGraphPinType(); return false;
|
||||
}
|
||||
}
|
||||
@@ -696,7 +696,7 @@ bool UWingTypes::TextToType(WingTokenizer &Tok, FEdGraphPinType& OutPinType, con
|
||||
{
|
||||
FString Text(Tok.GetRange(NAME_StartOfType, 0));
|
||||
Errors.Printf(TEXT("ERROR: Not a blueprintable type: %s\n"), *Text);
|
||||
UWingServer::SuggestManual(WingManual::Section::HandlerHelp);
|
||||
UWingServer::SuggestHandlerHelp();
|
||||
OutPinType = FEdGraphPinType(); return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ FName WingUtils::CheckInternalizeID(const FString &ExternalID, WingOut Errors)
|
||||
if (!Error.IsEmpty())
|
||||
{
|
||||
Errors.Printf(TEXT("%s\n"), *Error);
|
||||
UWingServer::SuggestManual(WingManual::Section::EscapeSequences);
|
||||
UWingServer::SuggestManual(GET_FUNCTION_NAME_CHECKED(UWingManualSections, EscapeSequencesInFNames));
|
||||
}
|
||||
return InternalID;
|
||||
}
|
||||
@@ -77,7 +77,7 @@ FName WingUtils::CheckProposedName(const FString &ExternalID, const TSet<FName>
|
||||
{
|
||||
Errors.Printf(TEXT("ERROR: id %s would not be a readable id, may not create item with this name"),
|
||||
*ExternalID);
|
||||
UWingServer::SuggestManual(WingManual::Section::EscapeSequences);
|
||||
UWingServer::SuggestManual(GET_FUNCTION_NAME_CHECKED(UWingManualSections, EscapeSequencesInFNames));
|
||||
return FName();
|
||||
}
|
||||
if (InUse.Contains(InternalID))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "CoreMinimal.h"
|
||||
#include "WingManual.generated.h"
|
||||
|
||||
struct FWingHandlerConfig;
|
||||
enum class EWingHandlerKind;
|
||||
@@ -7,23 +8,37 @@ enum class EWingHandlerKind;
|
||||
class WingManual
|
||||
{
|
||||
public:
|
||||
enum class Section
|
||||
{
|
||||
All,
|
||||
HandlerHelp,
|
||||
Paths,
|
||||
Types,
|
||||
VariableDeclarations,
|
||||
EscapeSequences,
|
||||
Whitespace,
|
||||
MaterialEditing,
|
||||
ImportantCommands,
|
||||
};
|
||||
|
||||
static void PrintHandlerPrototype(const FWingHandlerConfig& Handler);
|
||||
static void PrintHandlerArguments(const FWingHandlerConfig& Handler);
|
||||
static void PrintHandlerDescription(const FWingHandlerConfig& Handler);
|
||||
static void PrintHandlerHelp(const FWingHandlerConfig& Handler);
|
||||
static void PrintManual(TSet<Section> Sections, const FWingHandlerConfig* Handler, bool Abridged);
|
||||
static void Commands(EWingHandlerKind Kind, const FString& Query, bool Verbose);
|
||||
static TSet<FName> GetSections();
|
||||
static bool PrintSection(FName Section);
|
||||
static void PrintSectionNames(const TSet<FName>& Sections);
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
class UWingManualSections : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION()
|
||||
static void FetcherPaths();
|
||||
|
||||
UFUNCTION()
|
||||
static void ExpressingTypes();
|
||||
|
||||
UFUNCTION()
|
||||
static void VariableDeclarations();
|
||||
|
||||
UFUNCTION()
|
||||
static void EscapeSequencesInFNames();
|
||||
|
||||
UFUNCTION()
|
||||
static void MaterialEditing();
|
||||
|
||||
UFUNCTION()
|
||||
static void ImportantCommands();
|
||||
};
|
||||
|
||||
@@ -48,7 +48,10 @@ public:
|
||||
static void AddTouchedObject(UObject* Obj) { GWingServer->Notifier.AddTouchedObject(Obj); }
|
||||
|
||||
/** Suggest that a manual section be printed after the handler finishes. */
|
||||
static void SuggestManual(WingManual::Section Section) { GWingServer->SuggestedManualSections.Add(Section); }
|
||||
static void SuggestManual(FName Section) { GWingServer->SuggestedManualSections.Add(Section); }
|
||||
|
||||
/** Suggest that handler help be printed after the handler finishes. */
|
||||
static void SuggestHandlerHelp() { GWingServer->bSuggestHandlerHelp = true; }
|
||||
|
||||
/** Port the server is listening on. */
|
||||
int32 GetPort() const { return Port; }
|
||||
@@ -64,7 +67,8 @@ private:
|
||||
UPROPERTY()
|
||||
FWingNotifier Notifier;
|
||||
FWingHandlerConfig* LastHandler;
|
||||
TSet<WingManual::Section> SuggestedManualSections;
|
||||
bool bSuggestHandlerHelp;
|
||||
TSet<FName> SuggestedManualSections;
|
||||
FLogCaptureOutputDevice LogCapture; // installed once at startup, enabled per-request
|
||||
TArray<FWingHandlerConfig> WingHandlerRegistry; // sorted by Name
|
||||
void BuildWingHandlerRegistry();
|
||||
|
||||
Reference in New Issue
Block a user