Files
integration/Plugins/UEWingman/Source/UEWingman/Public/WingProperty.h

143 lines
5.5 KiB
C++

#pragma once
#include "CoreMinimal.h"
#include "WingBasics.h"
struct FWingProperty
{
// To understand the following fields, imagine an object
// that contains a struct, which contains another struct,
// which contains another struct, which contains a field F.
// In that case, Object points to the object that
// contains everything, whereas Container points to the
// innermost struct that contains the property.
TStrongObjectPtr<UObject> Object = nullptr;
void* Container = nullptr;
FProperty* Prop = nullptr;
bool Editable = false;
// Construct a property reference.
//
FWingProperty(UObject *InObject, void* InContainer, FProperty* InProp, bool Edit)
: Object(InObject), Container(InContainer), Prop(InProp), Editable(Edit) {}
// Construct a null property reference.
//
FWingProperty() = default;
// Operator -> forwards to the FProperty.
//
FProperty* operator->() const { return Prop; }
// Store a value. On failure, return false, and print an
// error. These will do automatic conversion of numeric
// types to other numeric types, as long as the value
// fits. They will also do text to any type, as long as
// the value parses as a value of the desired type.
//
bool SetObject(UObject *Obj, WingOut Errors) const;
bool SetDouble(double D, WingOut Errors) const;
bool SetInt64(int64 I, WingOut Errors) const;
bool SetBool(bool B, WingOut Errors) const;
bool SetText(FString Value, WingOut Errors) const;
// Fetch a value. If an error occurs such as a type
// mismatch, returns an empty optional and prints an
// error. These will do automatic conversion of numeric
// types to other numeric types, as long as the value
// fits. They will also do any type to text, which is
// why the GetText version needs no error reporting.
//
TOptional<UObject*> GetObject(WingOut Errors) const;
TOptional<double> GetDouble(WingOut Errors) const;
TOptional<int64> GetInt64(WingOut Errors) const;
TOptional<bool> GetBool(WingOut Errors) const;
FString GetText() const;
// Get the text, replace newlines with whitespace, and truncate to the specified maximum length.
//
FString GetTruncatedText(int32 MaxLen) const;
// Print the property's editflag, type, name, and value.
//
void Print(WingOut Out) const;
// Get the Category metadata.
//
FString GetCategory() const;
// Return true if the property is not the null property reference.
//
explicit operator bool() const { return Prop != nullptr; }
// Get all the properties of the specified object or struct.
//
// This gets the properties that are literally present in the
// specified object or struct. No special interpretation is done.
// If mutable is false, all properties will be marked non-editable.
//
static TArray<FWingProperty> GetAll(UObject *Obj, void *Container, UStruct *Struct, bool Mutable);
// Get all the visible properties of the specified object or struct.
//
// This gets the properties that have CPF_Edit marked on them.
// If mutable is false, all properties will be marked non-editable.
//
static TArray<FWingProperty> GetVisible(UObject *Obj, void *Container, UStruct *Struct, bool Mutable);
static bool PopulateFromArgv(TArray<FWingProperty>& Props, TConstArrayView<FString> Argv, WingOut Errors);
// Convenience versions of GetAll and GetVisible for UObjects.
//
static TArray<FWingProperty> GetAll(UObject *Obj, bool Mutable)
{ return GetAll(Obj, Obj, Obj->GetClass(), Mutable); }
static TArray<FWingProperty> GetVisible(UObject *Obj, bool Mutable)
{ return GetVisible(Obj, Obj, Obj->GetClass(), Mutable); }
// Get just the names of the properties of the specified struct/class.
//
static TArray<FName> GetVisibleNames(UStruct *US);
// Remove any properties with the specified name.
//
static void Remove(TArray<FWingProperty>& Props, FName Name);
// Move any properties with the specified name to the out array.
//
static void Move(TArray<FWingProperty> &Out, TArray<FWingProperty> &In, FName Name);
// Return the "Details Panel" properties for the specified object.
//
// This is the set of properties that would typically appear in the
// details panel if you were to click the object in the editor. Note
// that this is not always the properties of the object itself. For
// example, if you click a widget, the details panel shows you
// properties of the widget, but also properties of the slot. If you
// click a material graph node, the details panel shows you properties
// of the node, but also properties of the material expression.
//
// If you do not specify mutable, then all properties will be marked
// non-editable.
//
static TArray<FWingProperty> GetDetails(UObject* Obj, bool Mutable);
private:
static bool IsUnsigned(FNumericProperty* Prop);
static bool IsPinTypeProperty(FProperty *Prop);
void PrintExpectsReceived(const TCHAR *Type, WingOut Errors) const;
bool CheckImportTextResult(const FString &Value, WingOut Errors) const;
bool CheckEditable(WingOut Errors) const;
// Convert int64 to double losslessly. If it can't be done, generate an error.
static bool LosslessInt64ToDouble(int64 I, double &D, WingOut Errors);
// Convert double to int64 losslessly. If it can't be done, generate an error.
static bool LosslessDoubleToInt64(double D, int64 &I, WingOut Errors);
// Unlike SetDouble, this function requires that NProp is a floating point property.
static bool SetDoubleInternal(FNumericProperty *NProp, void *Container, double D, WingOut Errors);
// Unlike SetInt64, this function requires that NProp is an integral property.
static bool SetInt64Internal(FNumericProperty *NProp, void *Container, int64 I, WingOut Errors);
};