122 lines
4.1 KiB
C
122 lines
4.1 KiB
C
|
|
////////////////////////////////////////////////////////////
|
||
|
|
//
|
||
|
|
// SlashCommand.h
|
||
|
|
//
|
||
|
|
// A command line plus a cursor, exposed to blueprint.
|
||
|
|
//
|
||
|
|
////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
#pragma once
|
||
|
|
|
||
|
|
#include "Containers/Array.h"
|
||
|
|
#include "Containers/Set.h"
|
||
|
|
#include "Containers/UnrealString.h"
|
||
|
|
#include "Containers/StringFwd.h"
|
||
|
|
#include "Common.h"
|
||
|
|
#include "SlashCommand.generated.h"
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////
|
||
|
|
//
|
||
|
|
// UlxSlashCommand
|
||
|
|
//
|
||
|
|
// Holds a command line (a string the user has typed) together
|
||
|
|
// with a cursor marking the current position within it. This
|
||
|
|
// is the object that wraps Unreal's FParse facilities so that
|
||
|
|
// blueprint can parse a typed command piece by piece, with the
|
||
|
|
// cursor advancing as each token is consumed.
|
||
|
|
//
|
||
|
|
////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
UCLASS(BlueprintType)
|
||
|
|
class UlxSlashCommand : public UObject
|
||
|
|
{
|
||
|
|
GENERATED_BODY()
|
||
|
|
|
||
|
|
private:
|
||
|
|
// The full command line that we are parsing.
|
||
|
|
//
|
||
|
|
FString CommandLine;
|
||
|
|
|
||
|
|
// The current parse position: an index into CommandLine.
|
||
|
|
//
|
||
|
|
int32 Cursor = 0;
|
||
|
|
|
||
|
|
// Known command names that have been registered while exploring
|
||
|
|
// possible parses for this line.
|
||
|
|
//
|
||
|
|
TSet<FString> KnownCommands;
|
||
|
|
|
||
|
|
// Prototypes whose command name matches this line.
|
||
|
|
//
|
||
|
|
TArray<FString> MatchingPrototypes;
|
||
|
|
|
||
|
|
// Skip leading whitespace at the cursor, then read characters up
|
||
|
|
// to (but not including) the next whitespace. The token is
|
||
|
|
// returned as a view into CommandLine, and the cursor is advanced
|
||
|
|
// past it.
|
||
|
|
//
|
||
|
|
// Returns an empty view if there is no nonwhitespace input left.
|
||
|
|
//
|
||
|
|
FStringView FetchToken();
|
||
|
|
|
||
|
|
public:
|
||
|
|
// Construct a slash command from a command line string.
|
||
|
|
// The cursor starts at the beginning.
|
||
|
|
//
|
||
|
|
UFUNCTION(BlueprintCallable)
|
||
|
|
static UlxSlashCommand* MakeSlashCommand(const FString& CommandLine);
|
||
|
|
|
||
|
|
// Return true if the string is a slash followed by one or more
|
||
|
|
// alphanumeric characters, and nothing else (e.g. "/foo").
|
||
|
|
//
|
||
|
|
static bool IsSlashCommand(const FString& Command);
|
||
|
|
|
||
|
|
// Reset the cursor to the start, then read the first token and
|
||
|
|
// check whether it matches the given literal, case-insensitively.
|
||
|
|
// The command name is recorded in KnownCommands either way. If it
|
||
|
|
// matched, the prototype is added to MatchingPrototypes. The token
|
||
|
|
// is consumed either way. Returns Success if it matched, Error
|
||
|
|
// otherwise.
|
||
|
|
//
|
||
|
|
UFUNCTION(BlueprintCallable, meta = (ExpandEnumAsExecs = "ReturnValue"))
|
||
|
|
ElxSuccessOrError CheckCommand(const FString& Literal, const FString& Prototype);
|
||
|
|
|
||
|
|
// Read the next whitespace-delimited word from the command line.
|
||
|
|
//
|
||
|
|
// This is the blueprint-callable form of FetchToken: it returns
|
||
|
|
// the token as an FString. Returns Error (with an empty Result)
|
||
|
|
// if there is no nonwhitespace input left, Success otherwise.
|
||
|
|
//
|
||
|
|
UFUNCTION(BlueprintCallable, meta = (ExpandEnumAsExecs = "ReturnValue"))
|
||
|
|
ElxSuccessOrError ReadToken(FString& Result);
|
||
|
|
|
||
|
|
// Read the next token and interpret it as an integer, using C++
|
||
|
|
// number syntax (optional sign; decimal, 0x hex, or leading-0
|
||
|
|
// octal). The whole token must be valid; "12abc" is rejected.
|
||
|
|
// Returns Error (with Result 0) on failure, Success otherwise.
|
||
|
|
//
|
||
|
|
UFUNCTION(BlueprintCallable, meta = (ExpandEnumAsExecs = "ReturnValue"))
|
||
|
|
ElxSuccessOrError ReadInteger(int32& Result);
|
||
|
|
|
||
|
|
// Read the next token and interpret it as a floating-point number,
|
||
|
|
// using C++ number syntax (optional sign, digits, dot, e/E
|
||
|
|
// exponent, trailing f). The whole token must be valid; "12abc"
|
||
|
|
// is rejected. Returns Error (with Result 0) on failure, Success
|
||
|
|
// otherwise.
|
||
|
|
//
|
||
|
|
UFUNCTION(BlueprintCallable, meta = (ExpandEnumAsExecs = "ReturnValue"))
|
||
|
|
ElxSuccessOrError ReadFloat(double& Result);
|
||
|
|
|
||
|
|
// Read the rest of the command line, from the cursor to the end,
|
||
|
|
// trimmed of leading and trailing whitespace. The cursor is
|
||
|
|
// advanced to the end. Always returns Success.
|
||
|
|
//
|
||
|
|
UFUNCTION(BlueprintCallable, meta = (ExpandEnumAsExecs = "ReturnValue"))
|
||
|
|
ElxSuccessOrError ReadRest(FString& Result);
|
||
|
|
|
||
|
|
// Return a user-facing error message describing why parsing failed.
|
||
|
|
//
|
||
|
|
UFUNCTION(BlueprintCallable)
|
||
|
|
FString GetErrorMessage() const;
|
||
|
|
};
|