EM_Task/UnrealEd/Private/ParamParser.cpp
Boshuang Zhao 5144a49c9b add
2026-02-13 16:18:33 +08:00

305 lines
7.4 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
ParamParser.cpp: Functions to help parse commands.
What's happening: When the Visual Basic level editor is being used,
this code exchanges messages with Visual Basic. This lets Visual Basic
affect the world, and it gives us a way of sending world information back
to Visual Basic.
=============================================================================*/
#include "CoreTypes.h"
#include "Logging/LogMacros.h"
#include "Misc/Parse.h"
#include "Math/Vector.h"
#include "Math/Rotator.h"
/*-----------------------------------------------------------------------------
Getters.
All of these functions return 1 if the appropriate item was
fetched, or 0 if not.
-----------------------------------------------------------------------------*/
DEFINE_LOG_CATEGORY_STATIC(LogParamParser, Log, All);
//
// Get a floating-point vector (X=, Y=, Z=).
//
bool GetFVECTOR(const TCHAR* Stream, FVector& Value)
{
int32 NumVects = 0;
Value = FVector::ZeroVector;
// Support for old format.
NumVects += FParse::Value(Stream, TEXT("X="), Value.X);
NumVects += FParse::Value(Stream, TEXT("Y="), Value.Y);
NumVects += FParse::Value(Stream, TEXT("Z="), Value.Z);
// New format.
if (NumVects == 0)
{
Value.X = FCString::Atof(Stream);
Stream = FCString::Strchr(Stream, ',');
if (!Stream)
{
return 0;
}
Stream++;
Value.Y = FCString::Atof(Stream);
Stream = FCString::Strchr(Stream, ',');
if (!Stream)
{
return 0;
}
Stream++;
Value.Z = FCString::Atof(Stream);
NumVects = 3;
}
return NumVects == 3;
}
/**
* Get a floating-point vector (X Y Z)
*
* @param The stream which has the vector in it
* @param this is an out param which will have the FVector
*
* @return this will return the current location in the stream after having processed the Vector out of it
**/
const TCHAR* GetFVECTORSpaceDelimited(const TCHAR* Stream, FVector& Value)
{
if (Stream == NULL)
{
return NULL;
}
Value = FVector::ZeroVector;
Value.X = FCString::Atof(Stream);
// UE_LOG(LogParamParser, Warning, TEXT("Value.X %f"), Value.X );
Stream = FCString::Strchr(Stream, ' ');
if (!Stream)
{
return Stream;
}
Stream++;
Value.Y = FCString::Atof(Stream);
// UE_LOG(LogParamParser, Warning, TEXT("Value.Y %f"), Value.Y );
Stream = FCString::Strchr(Stream, ' ');
if (!Stream)
{
return Stream;
}
Stream++;
Value.Z = FCString::Atof(Stream);
// UE_LOG(LogParamParser, Warning, TEXT("Value.Z %f"), Value.Z );
return Stream;
}
//
// Get a string enclosed in parenthesis.
//
bool GetSUBSTRING(
const TCHAR* Stream,
const TCHAR* Match,
TCHAR* Value,
int32 MaxLen)
{
const TCHAR* Found = FCString::Strifind(Stream, Match);
const TCHAR* Start;
if (Found == NULL)
return false; // didn't match.
Start = Found + FCString::Strlen(Match);
if (*Start != '(')
return false;
FCString::Strncpy(Value, Start + 1, MaxLen);
TCHAR* Temp = FCString::Strchr(Value, ')');
if (Temp)
*Temp = 0;
return true;
}
//
// Get a floating-point vector (X=, Y=, Z=).
//
bool GetFVECTOR(
const TCHAR* Stream,
const TCHAR* Match,
FVector& Value)
{
TCHAR Temp[80];
if (!GetSUBSTRING(Stream, Match, Temp, 80))
return false;
return GetFVECTOR(Temp, Value);
}
//
// Get a set of rotations (PITCH=, YAW=, ROLL=), return whether anything got parsed.
//
bool GetFROTATOR(
const TCHAR* Stream,
FRotator& Rotation,
int32 ScaleFactor)
{
float Temp = 0.0;
int32 N = 0;
Rotation = FRotator::ZeroRotator;
// Old format.
if (FParse::Value(Stream, TEXT("PITCH="), Temp))
{
Rotation.Pitch = Temp * ScaleFactor;
N++;
}
if (FParse::Value(Stream, TEXT("YAW="), Temp))
{
Rotation.Yaw = Temp * ScaleFactor;
N++;
}
if (FParse::Value(Stream, TEXT("ROLL="), Temp))
{
Rotation.Roll = Temp * ScaleFactor;
N++;
}
// New format.
if (N == 0)
{
Rotation.Pitch = FCString::Atof(Stream) * ScaleFactor;
Stream = FCString::Strchr(Stream, ',');
if (!Stream)
{
return false;
}
Rotation.Yaw = FCString::Atof(++Stream) * ScaleFactor;
Stream = FCString::Strchr(Stream, ',');
if (!Stream)
{
return false;
}
Rotation.Roll = FCString::Atof(++Stream) * ScaleFactor;
return true;
}
return true;
}
/**
* Get an int based FRotator (X Y Z)
*
* @param The stream which has the rotator in it
* @param this is an out param which will have the FRotator
*
* @return this will return the current location in the stream after having processed the rotator out of it
**/
const TCHAR* GetFROTATORSpaceDelimited(
const TCHAR* Stream,
FRotator& Rotation,
int32 ScaleFactor)
{
if (Stream == NULL)
{
return NULL;
}
Rotation = FRotator::ZeroRotator;
Rotation.Pitch = FCString::Atof(Stream) * ScaleFactor;
// UE_LOG(LogParamParser, Warning, TEXT("Rotation.Pitch %d"), Rotation.Pitch );
Stream = FCString::Strchr(Stream, ' ');
if (!Stream)
{
return Stream;
}
Rotation.Yaw = FCString::Atof(++Stream) * ScaleFactor;
// UE_LOG(LogParamParser, Warning, TEXT("Rotation.Yaw %d"), Rotation.Yaw );
Stream = FCString::Strchr(Stream, ' ');
if (!Stream)
{
return Stream;
}
Rotation.Roll = FCString::Atof(++Stream) * ScaleFactor;
// UE_LOG(LogParamParser, Warning, TEXT("Rotation.Roll %d"), Rotation.Roll );
return Stream;
}
//
// Get a rotation value, return whether anything got parsed.
//
bool GetFROTATOR(
const TCHAR* Stream,
const TCHAR* Match,
FRotator& Value,
int32 ScaleFactor)
{
TCHAR Temp[80];
if (!GetSUBSTRING(Stream, Match, Temp, 80))
return false;
return GetFROTATOR(Temp, Value, ScaleFactor);
}
//
// Gets a "BEGIN" string. Returns 1 if gotten, 0 if not.
// If not gotten, doesn't affect anything.
//
bool GetBEGIN(const TCHAR** Stream, const TCHAR* Match)
{
const TCHAR* Original = *Stream;
if (FParse::Command(Stream, TEXT("BEGIN")) && FParse::Command(Stream, Match))
return true;
*Stream = Original;
return false;
}
//
// Gets an "END" string. Returns 1 if gotten, 0 if not.
// If not gotten, doesn't affect anything.
//
bool GetEND(const TCHAR** Stream, const TCHAR* Match)
{
const TCHAR* Original = *Stream;
if (FParse::Command(Stream, TEXT("END")) && FParse::Command(Stream, Match))
return 1; // Gotten.
*Stream = Original;
return false;
}
//
// Gets an "REMOVE" string. Returns true if gotten, false if not.
// If not gotten, doesn't affect anything.
//
bool GetREMOVE(const TCHAR** Stream, const TCHAR* Match)
{
const TCHAR* Original = *Stream;
if (FParse::Command(Stream, TEXT("REMOVE")) && FParse::Command(Stream, Match))
return true; // Gotten.
*Stream = Original;
return false;
}
//
// Output a vector.
//
TCHAR* SetFVECTOR(TCHAR* Dest, const FVector* FVector)
{
FCString::Sprintf(Dest, TEXT("%+013.6f,%+013.6f,%+013.6f"), FVector->X, FVector->Y, FVector->Z);
return Dest;
}