Better handling of property mutability, and also, walk into structs.
This commit is contained in:
@@ -281,7 +281,7 @@ public:
|
||||
}
|
||||
|
||||
// Set the 'Class' property.
|
||||
TArray<FWingProperty> Props = FWingProperty::GetAll(Factory, CPF_Edit);
|
||||
TArray<FWingProperty> Props = FWingProperty::GetVisible(Factory);
|
||||
FWingProperty::Remove(Props, TEXT("BlueprintType"));
|
||||
if (Props.Num() != 1)
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
UObject* Target = F.Walk(Object).Cast<UObject>();
|
||||
if (!Target) return;
|
||||
|
||||
TArray<FWingProperty> Props = FWingProperty::GetDetails(Target, CPF_Edit, false);
|
||||
TArray<FWingProperty> Props = FWingProperty::GetDetails(Target, false);
|
||||
|
||||
// Group by category, preserving within-category order.
|
||||
TSortedMap<FString, TArray<FWingProperty>> Categories;
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
UObject* Obj = F.Walk(Object).Cast<UObject>();
|
||||
if (!Obj) return;
|
||||
|
||||
TArray<FWingProperty> Props = FWingProperty::GetDetails(Obj, CPF_Edit, false);
|
||||
TArray<FWingProperty> Props = FWingProperty::GetDetails(Obj, false);
|
||||
FWingProperty* P = WingUtils::FindOneWithExternalID(Property, Props, TEXT("Property"), WingOut::Stdout);
|
||||
if (!P) return;
|
||||
|
||||
|
||||
@@ -35,10 +35,10 @@ public:
|
||||
UObject* Obj = F.Walk(Object).Cast<UObject>();
|
||||
if (!Obj) return;
|
||||
|
||||
TArray<FWingProperty> Props = FWingProperty::GetDetails(Obj, CPF_Edit, true);
|
||||
TArray<FWingProperty> Props = FWingProperty::GetDetails(Obj, true);
|
||||
FWingProperty* P = WingUtils::FindOneWithExternalID(Property, Props, TEXT("Property"), WingOut::Stdout);
|
||||
if (!P) return;
|
||||
|
||||
|
||||
if (P->SetText(Value, WingOut::Stdout))
|
||||
WingOut::Stdout.Print(TEXT("OK\n"));
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
TArray<FWingProperty> Props = FWingProperty::GetDetails(Obj, CPF_Edit, true);
|
||||
TArray<FWingProperty> Props = FWingProperty::GetDetails(Obj, true);
|
||||
|
||||
// Validation pass — resolve all properties before modifying anything.
|
||||
for (const auto& Pair : Properties.Json->Values)
|
||||
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
// Parse the json array, turning it into an array of spawn node entries.
|
||||
TArray<FSpawnNodeEntry> Entries;
|
||||
FSpawnNodeEntry Entry;
|
||||
TArray<FWingProperty> Props = FWingProperty::GetAll(&Entry, CPF_None);
|
||||
TArray<FWingProperty> Props = FWingProperty::GetAll(&Entry);
|
||||
for (const TSharedPtr<FJsonValue>& Elt : Nodes.Array)
|
||||
{
|
||||
if (!FWingProperty::PopulateFromJson(Props, *Elt, false, WingOut::Stdout)) return;
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
UEdGraphNode* Node = F.Node(Entry.Node).Cast<UEdGraphNode>();
|
||||
if (!Node) return;
|
||||
|
||||
TArray<FWingProperty> All = FWingProperty::GetDetails(Node, CPF_Edit, true);
|
||||
TArray<FWingProperty> All = FWingProperty::GetDetails(Node, true);
|
||||
FWingProperty *P = WingUtils::FindOneWithExternalID(Entry.Name, All, TEXT("Property"), WingOut::Stdout);
|
||||
if (!P) return;
|
||||
|
||||
@@ -121,7 +121,7 @@ public:
|
||||
}
|
||||
|
||||
FSetNodeDefaultEntry Entry;
|
||||
TArray<FWingProperty> Props = FWingProperty::GetAll(&Entry, CPF_None);
|
||||
TArray<FWingProperty> Props = FWingProperty::GetAll(&Entry);
|
||||
for (const TSharedPtr<FJsonValue>& PinVal : Pins.Array)
|
||||
{
|
||||
if (!FWingProperty::PopulateFromJson(Props, *PinVal, false, WingOut::Stdout)) continue;
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
int32 SuccessCount = 0;
|
||||
|
||||
FMoveNodeEntry Entry;
|
||||
TArray<FWingProperty> Props = FWingProperty::GetAll(&Entry, CPF_None);
|
||||
TArray<FWingProperty> Props = FWingProperty::GetAll(&Entry);
|
||||
for (const TSharedPtr<FJsonValue>& Elt : Nodes.Array)
|
||||
{
|
||||
if (!FWingProperty::PopulateFromJson(Props, *Elt, false, WingOut::Stdout)) continue;
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
int32 TotalCount = Connections.Array.Num();
|
||||
|
||||
FConnectPinsEntry Entry;
|
||||
TArray<FWingProperty> EntryProps = FWingProperty::GetAll(&Entry, CPF_None);
|
||||
TArray<FWingProperty> EntryProps = FWingProperty::GetAll(&Entry);
|
||||
for (const TSharedPtr<FJsonValue>& ConnVal : Connections.Array)
|
||||
{
|
||||
if (!FWingProperty::PopulateFromJson(EntryProps, *ConnVal, false, WingOut::Stdout))
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
int32 TotalDisconnected = 0;
|
||||
|
||||
FDisconnectPinEntry Entry;
|
||||
TArray<FWingProperty> EntryProps = FWingProperty::GetAll(&Entry, CPF_None);
|
||||
TArray<FWingProperty> EntryProps = FWingProperty::GetAll(&Entry);
|
||||
for (const TSharedPtr<FJsonValue>& DiscVal : Disconnections.Array)
|
||||
{
|
||||
if (!FWingProperty::PopulateFromJson(EntryProps, *DiscVal, false, WingOut::Stdout)) continue;
|
||||
|
||||
@@ -50,7 +50,7 @@ bool WingFactories::CanCreate(TSubclassOf<UFactory> FactoryClass)
|
||||
|
||||
TArray<FName> WingFactories::GetParameterNames(TSubclassOf<UFactory> FactoryClass)
|
||||
{
|
||||
return FWingProperty::GetNames(FactoryClass, CPF_Edit);
|
||||
return FWingProperty::GetVisibleNames(FactoryClass);
|
||||
}
|
||||
|
||||
UObject* WingFactories::CreateAsset(const FString& Path, UFactory* Factory, WingOut Errors)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "WingFetcher.h"
|
||||
#include "WingServer.h"
|
||||
#include "WingHandler.h"
|
||||
#include "WingUtils.h"
|
||||
#include "WingActorComponent.h"
|
||||
#include "Engine/Blueprint.h"
|
||||
@@ -29,6 +30,7 @@ WingFetcher::WalkFunc WingFetcher::GetWalker(const FString& Step)
|
||||
if (Step.Equals(TEXT("component"), ESearchCase::IgnoreCase)) return &WingFetcher::Component;
|
||||
if (Step.Equals(TEXT("widget"), ESearchCase::IgnoreCase)) return &WingFetcher::Widget;
|
||||
if (Step.Equals(TEXT("levelblueprint"), ESearchCase::IgnoreCase)) return &WingFetcher::LevelBlueprint;
|
||||
if (Step.Equals(TEXT("structprop"), ESearchCase::IgnoreCase)) return &WingFetcher::StructProp;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -370,3 +372,50 @@ WingFetcher& WingFetcher::LevelBlueprint(const FString& Value)
|
||||
SetObj(LevelBP);
|
||||
return *this;
|
||||
}
|
||||
|
||||
WingFetcher& WingFetcher::StructProp(const FString& Value)
|
||||
{
|
||||
if (bError) return *this;
|
||||
|
||||
FName InternalID = WingUtils::CheckInternalizeID(Value, Errors);
|
||||
if (InternalID.IsNone()) return SetError();
|
||||
|
||||
if (!Obj)
|
||||
{
|
||||
TypeMismatch(TEXT("structprop"), TEXT("UObject"));
|
||||
return SetError();
|
||||
}
|
||||
|
||||
FStructProperty* StructProp = nullptr;
|
||||
|
||||
// The "host" is the object containing this property.
|
||||
UObject *HostObject = Obj;
|
||||
void *HostBase = Obj;
|
||||
UStruct *HostType = Obj->GetClass();
|
||||
bool HostEditable = true;
|
||||
|
||||
// If we are *already* inside a UWingStructPointer, update the host
|
||||
// fields, to make it possible to navigate even further inside.
|
||||
if (UWingStructPointer *SPtr = ::Cast<UWingStructPointer>(Obj))
|
||||
{
|
||||
HostObject = SPtr->Object;
|
||||
HostBase = SPtr->StructBase;
|
||||
HostType = SPtr->StructType;
|
||||
HostEditable = SPtr->Editable;
|
||||
}
|
||||
|
||||
StructProp = FindFProperty<FStructProperty>(HostType, InternalID);
|
||||
if (!StructProp)
|
||||
{
|
||||
Errors.Printf(TEXT("ERROR: No struct property '%s' found on %s\n"), *Value, *HostType->GetName());
|
||||
return SetError();
|
||||
}
|
||||
|
||||
UWingStructPointer* Ptr = NewObject<UWingStructPointer>();
|
||||
Ptr->Object = HostObject;
|
||||
Ptr->StructType = StructProp->Struct;
|
||||
Ptr->StructBase = StructProp->ContainerPtrToValuePtr<void>(HostBase);
|
||||
Ptr->Editable = HostEditable && StructProp->HasAllPropertyFlags(CPF_Edit);
|
||||
SetObj(Ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ void WingGraphExport::EmitNode(UEdGraphNode* Node)
|
||||
|
||||
void WingGraphExport::EmitNodeProperties(UEdGraphNode* Node, WingOut Out, bool bPrimary)
|
||||
{
|
||||
TArray<FWingProperty> Props = FWingProperty::GetDetails(Node, CPF_Edit, false);
|
||||
TArray<FWingProperty> Props = FWingProperty::GetDetails(Node, false);
|
||||
|
||||
FString PrimaryCategory;
|
||||
if (UMaterialGraphNode* MatNode = Cast<UMaterialGraphNode>(Node))
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
bool FWingProperty::SetObject(UObject *Obj, WingOut Errors) const
|
||||
{
|
||||
if (!CheckEditable(Errors)) return false;
|
||||
FObjectPropertyBase *OProp = CastField<FObjectPropertyBase>(Prop);
|
||||
if (!OProp)
|
||||
{
|
||||
@@ -47,6 +48,7 @@ bool FWingProperty::SetObject(UObject *Obj, WingOut Errors) const
|
||||
|
||||
bool FWingProperty::SetDouble(double D, WingOut Errors) const
|
||||
{
|
||||
if (!CheckEditable(Errors)) return false;
|
||||
FNumericProperty *NProp = CastField<FNumericProperty>(Prop);
|
||||
if (!NProp)
|
||||
{
|
||||
@@ -95,6 +97,7 @@ bool FWingProperty::SetDouble(double D, WingOut Errors) const
|
||||
|
||||
bool FWingProperty::SetInt64(int64 I, WingOut Errors) const
|
||||
{
|
||||
if (!CheckEditable(Errors)) return false;
|
||||
FNumericProperty *NProp = CastField<FNumericProperty>(Prop);
|
||||
if (!NProp)
|
||||
{
|
||||
@@ -133,6 +136,7 @@ bool FWingProperty::SetInt64(int64 I, WingOut Errors) const
|
||||
|
||||
bool FWingProperty::SetBool(bool B, WingOut Errors) const
|
||||
{
|
||||
if (!CheckEditable(Errors)) return false;
|
||||
if (FBoolProperty* BoolProp = CastField<FBoolProperty>(Prop))
|
||||
{
|
||||
Prop->SetValue_InContainer(Container, &B);
|
||||
@@ -144,6 +148,8 @@ bool FWingProperty::SetBool(bool B, WingOut Errors) const
|
||||
|
||||
bool FWingProperty::SetText(FString Value, WingOut Errors) const
|
||||
{
|
||||
if (!CheckEditable(Errors)) return false;
|
||||
|
||||
// Pin types get parsed by UWingTypes.
|
||||
if (IsPinTypeProperty(Prop))
|
||||
{
|
||||
@@ -201,6 +207,8 @@ bool FWingProperty::SetText(FString Value, WingOut Errors) const
|
||||
|
||||
bool FWingProperty::SetJson(const FJsonValue &JsonValue, WingOut Errors) const
|
||||
{
|
||||
if (!CheckEditable(Errors)) return false;
|
||||
|
||||
if (JsonValue.Type == EJson::String)
|
||||
{
|
||||
return SetText(JsonValue.AsString(), Errors);
|
||||
@@ -376,28 +384,35 @@ FString FWingProperty::GetCategory() const
|
||||
return Result;
|
||||
}
|
||||
|
||||
void FWingProperty::GetAll(FWingStructAndUStruct Obj, EPropertyFlags Flags, TArray<FWingProperty> &Props)
|
||||
{
|
||||
for (TFieldIterator<FProperty> It(Obj.UStructPtr); It; ++It)
|
||||
{
|
||||
if (Flags != 0 && !It->HasAnyPropertyFlags(Flags)) continue;
|
||||
Props.Add(FWingProperty(*It, Obj.StructPtr));
|
||||
}
|
||||
}
|
||||
|
||||
TArray<FWingProperty> FWingProperty::GetAll(FWingStructAndUStruct Obj, EPropertyFlags Flags)
|
||||
TArray<FWingProperty> FWingProperty::GetAll(FWingStructAndUStruct Obj)
|
||||
{
|
||||
TArray<FWingProperty> Result;
|
||||
GetAll(Obj, Flags, Result);
|
||||
for (TFieldIterator<FProperty> It(Obj.UStructPtr); It; ++It)
|
||||
{
|
||||
bool Editable = !It->HasAnyPropertyFlags(CPF_EditConst);
|
||||
Result.Add(FWingProperty(*It, Obj.StructPtr, Editable));
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
TArray<FName> FWingProperty::GetNames(UStruct *US, EPropertyFlags Flags)
|
||||
TArray<FWingProperty> FWingProperty::GetVisible(FWingStructAndUStruct Obj)
|
||||
{
|
||||
TArray<FWingProperty> Result;
|
||||
for (TFieldIterator<FProperty> It(Obj.UStructPtr); It; ++It)
|
||||
{
|
||||
if (!It->HasAllPropertyFlags(CPF_Edit)) continue;
|
||||
bool Editable = !It->HasAnyPropertyFlags(CPF_EditConst);
|
||||
Result.Add(FWingProperty(*It, Obj.StructPtr, Editable));
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
TArray<FName> FWingProperty::GetVisibleNames(UStruct *US)
|
||||
{
|
||||
TArray<FName> Result;
|
||||
for (TFieldIterator<FProperty> It(US); It; ++It)
|
||||
{
|
||||
if (Flags != 0 && !It->HasAnyPropertyFlags(Flags)) continue;
|
||||
if (!It->HasAllPropertyFlags(CPF_Edit)) continue;
|
||||
Result.Add(It->GetFName());
|
||||
}
|
||||
return Result;
|
||||
@@ -419,10 +434,20 @@ void FWingProperty::Move(TArray<FWingProperty> &Out, TArray<FWingProperty> &In,
|
||||
In.SetNum(Dst);
|
||||
}
|
||||
|
||||
TArray<FWingProperty> FWingProperty::GetDetails(UObject* Obj, EPropertyFlags Flags, bool Mutable)
|
||||
TArray<FWingProperty> FWingProperty::GetDetails(UObject* Obj, bool Mutable)
|
||||
{
|
||||
if (!Obj) return {};
|
||||
|
||||
// If it's a UWingStructPointer, return the properties
|
||||
// of the struct instead. Propagate editability of the host.
|
||||
if (UWingStructPointer *SP = Cast<UWingStructPointer>(Obj))
|
||||
{
|
||||
TArray<FWingProperty> Result =
|
||||
GetVisible(FWingStructAndUStruct(SP->StructBase, SP->StructType));
|
||||
if (!Mutable || (!SP->Editable)) StripEditable(Result);
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Blueprints don't have editable properties. So
|
||||
// instead, we fetch properties from the generated CDO.
|
||||
if (UBlueprint *BP = ::Cast<UBlueprint>(Obj))
|
||||
@@ -446,7 +471,7 @@ TArray<FWingProperty> FWingProperty::GetDetails(UObject* Obj, EPropertyFlags Fla
|
||||
}
|
||||
}
|
||||
|
||||
TArray<FWingProperty> Result = GetAll(Obj, Flags);
|
||||
TArray<FWingProperty> Result = GetVisible(Obj);
|
||||
|
||||
// If it's a Material Graph node, also collect properties from
|
||||
// the associated material expression.
|
||||
@@ -455,7 +480,7 @@ TArray<FWingProperty> FWingProperty::GetDetails(UObject* Obj, EPropertyFlags Fla
|
||||
{
|
||||
if (UMaterialExpression* Expr = MatNode->MaterialExpression)
|
||||
{
|
||||
GetAll(Expr, Flags, Result);
|
||||
Result.Append(GetVisible(Expr));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,10 +491,11 @@ TArray<FWingProperty> FWingProperty::GetDetails(UObject* Obj, EPropertyFlags Fla
|
||||
FWingProperty::Remove(Result, TEXT("Slot"));
|
||||
if (UPanelSlot* Slot = Widget->Slot)
|
||||
{
|
||||
GetAll(Slot, Flags, Result);
|
||||
Result.Append(GetVisible(Slot));
|
||||
}
|
||||
}
|
||||
|
||||
if (!Mutable) StripEditable(Result);
|
||||
return Result;
|
||||
}
|
||||
|
||||
@@ -555,4 +581,20 @@ bool FWingProperty::CheckImportTextResult(const FString &Value, WingOut Errors)
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FWingProperty::StripEditable(TArray<FWingProperty> &Props)
|
||||
{
|
||||
for (FWingProperty &Elt : Props) Elt.Editable = false;
|
||||
}
|
||||
|
||||
bool FWingProperty::CheckEditable(WingOut Errors) const
|
||||
{
|
||||
if (!Editable)
|
||||
{
|
||||
Errors.Printf(TEXT("ERROR: Cannot edit property %s, not marked editable"),
|
||||
*WingUtils::FormatName(Prop));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -331,7 +331,7 @@ void UWingServer::TryCallHandler(const FString &Line)
|
||||
Handler->Configuration = Found;
|
||||
|
||||
// Populate the handler object with the request parameters.
|
||||
TArray<FWingProperty> Props = FWingProperty::GetAll(Handler, CPF_Edit);
|
||||
TArray<FWingProperty> Props = FWingProperty::GetVisible(Handler);
|
||||
if (!FWingProperty::PopulateFromJson(Props, *Request, false, WingOut::Stdout))
|
||||
{
|
||||
UWingServer::SuggestManual(WingManual::Section::HandlerHelp);
|
||||
@@ -365,8 +365,6 @@ void UWingServer::AcceptNewConnections()
|
||||
Client->Socket = ClientSocket;
|
||||
Client->ThreadFuture = Async(EAsyncExecution::Thread, [this, Client]() { ClientThreadFunc(this, Client); });
|
||||
Clients.Add(Client);
|
||||
|
||||
UE_LOG(LogTemp, Display, TEXT("UEWingman: Client connected."));
|
||||
}
|
||||
|
||||
void UWingServer::CleanupFinishedClients()
|
||||
@@ -448,10 +446,8 @@ void UWingServer::ClientThreadFunc(UWingServer* Server, TSharedPtr<FClientConnec
|
||||
}
|
||||
|
||||
Client->bDone = true;
|
||||
UE_LOG(LogTemp, Display, TEXT("UEWingman: Client disconnected."));
|
||||
}
|
||||
|
||||
|
||||
// ============================================================
|
||||
// BuildWingHandlerRegistry
|
||||
// ============================================================
|
||||
|
||||
@@ -319,7 +319,7 @@ WingVariables::Var WingVariables::LoadBlueprintVariableDescription(FBPVariableDe
|
||||
FProperty* Prop = CDO->GetClass()->FindPropertyByName(Desc.VarName);
|
||||
if (Prop)
|
||||
{
|
||||
Result.DefaultValue = FWingProperty(Prop, CDO).GetText();
|
||||
Result.DefaultValue = FWingProperty(Prop, CDO, false).GetText();
|
||||
Result.DefaultSpecified = true;
|
||||
}
|
||||
}
|
||||
@@ -494,7 +494,7 @@ bool WingVariables::ModifyBlueprintDefaults(WingOut Errors)
|
||||
*WingTokenizer::ExternalizeID(Input.Name));
|
||||
return false;
|
||||
}
|
||||
if (!FWingProperty(Prop, CDO).SetText(Input.DefaultValue, Errors)) return false;
|
||||
if (!FWingProperty(Prop, CDO, true).SetText(Input.DefaultValue, Errors)) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -54,6 +54,7 @@ public:
|
||||
WingFetcher& Component(const FString& Value);
|
||||
WingFetcher& Widget(const FString& Value);
|
||||
WingFetcher& LevelBlueprint(const FString& Value);
|
||||
WingFetcher& StructProp(const FString& Value);
|
||||
|
||||
// Return true if there haven't been any errors.
|
||||
// Note that errors always automatically generate
|
||||
|
||||
@@ -94,6 +94,9 @@ struct FWingStructAndUStruct
|
||||
void *StructPtr;
|
||||
UStruct *UStructPtr;
|
||||
|
||||
// Explicit constructor.
|
||||
explicit FWingStructAndUStruct(void *Base, UStruct *S) : StructPtr(Base), UStructPtr(S) {}
|
||||
|
||||
// Copy constructor.
|
||||
FWingStructAndUStruct(FWingStructAndUStruct &Src) : StructPtr(Src.StructPtr), UStructPtr(Src.UStructPtr) {}
|
||||
|
||||
@@ -103,4 +106,29 @@ struct FWingStructAndUStruct
|
||||
// Construct from a UStruct pointer.
|
||||
template<class T, typename = std::enable_if_t<!std::is_base_of_v<UObject, T>>>
|
||||
FWingStructAndUStruct(T *Struct) : StructPtr(Struct), UStructPtr(Struct->StaticStruct()) {}
|
||||
};
|
||||
|
||||
|
||||
// WingStructPointer: Allows us to store a pointer to a
|
||||
// ustruct in a variable of class UObject, through the magic
|
||||
// of an extra level of indirection. If the struct is part of
|
||||
// a UObject, then the Object field should be point at the
|
||||
// object to ensure it doesn't get garbage collected. If the
|
||||
// editable flag is false, it means the struct is for viewing
|
||||
// only.
|
||||
|
||||
UCLASS()
|
||||
class UWingStructPointer : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY()
|
||||
UObject* Object;
|
||||
|
||||
UPROPERTY()
|
||||
UStruct* StructType;
|
||||
|
||||
void *StructBase;
|
||||
|
||||
bool Editable;
|
||||
};
|
||||
@@ -12,11 +12,12 @@ struct FWingProperty
|
||||
|
||||
FProperty* Prop = nullptr;
|
||||
void* Container = nullptr;
|
||||
bool Editable = false;
|
||||
|
||||
// Construct a property reference.
|
||||
//
|
||||
FWingProperty(FProperty* InProp, void* InContainer)
|
||||
: Prop(InProp), Container(InContainer) {}
|
||||
FWingProperty(FProperty* InProp, void* InContainer, bool Edit)
|
||||
: Prop(InProp), Container(InContainer), Editable(Edit) {}
|
||||
|
||||
// Construct a null property reference.
|
||||
//
|
||||
@@ -57,7 +58,7 @@ struct FWingProperty
|
||||
//
|
||||
FString GetTruncatedText(int32 MaxLen) const;
|
||||
|
||||
// Print the property's type, name, and value.
|
||||
// Print the property's editflag, type, name, and value.
|
||||
//
|
||||
void Print(WingOut Out) const;
|
||||
|
||||
@@ -69,16 +70,22 @@ struct FWingProperty
|
||||
//
|
||||
explicit operator bool() const { return Prop != nullptr; }
|
||||
|
||||
// Get the raw properties of the specified object or struct.
|
||||
// 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.
|
||||
//
|
||||
static TArray<FWingProperty> GetAll(FWingStructAndUStruct Obj, EPropertyFlags Flags);
|
||||
static TArray<FWingProperty> GetAll(FWingStructAndUStruct Obj);
|
||||
|
||||
// Get all the visible properties of the specified object or struct.
|
||||
//
|
||||
// This gets the properties that have CPF_Edit marked on them.
|
||||
//
|
||||
static TArray<FWingProperty> GetVisible(FWingStructAndUStruct Obj);
|
||||
|
||||
// Get just the names of the properties of the specified struct/class.
|
||||
//
|
||||
static TArray<FName> GetNames(UStruct *US, EPropertyFlags Flags);
|
||||
static TArray<FName> GetVisibleNames(UStruct *US);
|
||||
|
||||
// Remove any properties with the specified name.
|
||||
//
|
||||
@@ -98,12 +105,10 @@ struct FWingProperty
|
||||
// click a material graph node, the details panel shows you properties
|
||||
// of the node, but also properties of the material expression.
|
||||
//
|
||||
// When editing an inherited ActorComponent, you're actually editing
|
||||
// properties that *override* the original properties of the ActorComponent.
|
||||
// The 'mutable' flag tells it whether to create overrides for these
|
||||
// properties.
|
||||
// If you do not specify mutable, then all properties will be marked
|
||||
// non-editable.
|
||||
//
|
||||
static TArray<FWingProperty> GetDetails(UObject* Obj, EPropertyFlags Flags, bool Mutable);
|
||||
static TArray<FWingProperty> GetDetails(UObject* Obj, bool Mutable);
|
||||
|
||||
// Functions to populate properties from a JSON object.
|
||||
//
|
||||
@@ -113,8 +118,9 @@ struct FWingProperty
|
||||
bool AllOptional, WingOut Errors);
|
||||
|
||||
private:
|
||||
static void GetAll(FWingStructAndUStruct Obj, EPropertyFlags Flags, TArray<FWingProperty> &Props);
|
||||
static void StripEditable(TArray<FWingProperty> &Props);
|
||||
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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user