Migrating toward WingPropHandle
This commit is contained in:
@@ -274,6 +274,31 @@ WingPropHandle::Handles WingPropHandle::GetDetails(UObject* Obj, bool Mutable)
|
|||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Organize by Name
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool WingPropHandle::OrganizeByName(const Handles &HList, TMap<FName, TSharedPtr<IPropertyHandle>> &Result)
|
||||||
|
{
|
||||||
|
Result.Empty();
|
||||||
|
TSet<FName> DuplicateNames;
|
||||||
|
for (const TSharedPtr<IPropertyHandle> &H : HList)
|
||||||
|
{
|
||||||
|
FName Name = H->GetProperty()->GetFName();
|
||||||
|
if (Result.Contains(Name)) DuplicateNames.Add(Name);
|
||||||
|
else Result.Add(Name, H);
|
||||||
|
}
|
||||||
|
if (DuplicateNames.IsEmpty()) return true;
|
||||||
|
UWingServer::Print(TEXT("More than one property with name:"));
|
||||||
|
for (FName DupName : DuplicateNames)
|
||||||
|
{
|
||||||
|
UWingServer::Printf(TEXT(" %s"), *WingUtils::ExternalizeID(DupName));
|
||||||
|
}
|
||||||
|
UWingServer::Print(TEXT("\n"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@@ -426,6 +451,59 @@ bool WingPropHandle::SetJson(IPropertyHandle& Handle, const TSharedPtr<FJsonValu
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WingPropHandle::PopulateFromJson(TArray<TSharedPtr<IPropertyHandle>>& Props, const FJsonObject& Json, bool AllOptional)
|
||||||
|
{
|
||||||
|
bool Ok = true;
|
||||||
|
|
||||||
|
// Organize the properties by name.
|
||||||
|
TMap<FName, TSharedPtr<IPropertyHandle>> OrganizedProps;
|
||||||
|
if (!OrganizeByName(Props, OrganizedProps)) Ok = false;
|
||||||
|
|
||||||
|
// Parse the keys in the json, make sure they're syntactically valid and
|
||||||
|
// that they match the names of actual properties, and that there are no dups.
|
||||||
|
TSet<FName> Specified;
|
||||||
|
for (const auto& KV : Json.Values)
|
||||||
|
{
|
||||||
|
FName Name = WingUtils::CheckInternalizeID(KV.Key);
|
||||||
|
if (Name.IsNone()) { Ok = false; continue; }
|
||||||
|
if (!OrganizedProps.Contains(Name))
|
||||||
|
{
|
||||||
|
UWingServer::Printf(TEXT("ERROR: Unknown parameter '%s'\n"), *KV.Key);
|
||||||
|
Ok = false;
|
||||||
|
}
|
||||||
|
if (!WingUtils::FindNoDuplicateName(Specified, Name, TEXT("parameter"))) Ok = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure that all required properties have been specified.
|
||||||
|
if (!AllOptional)
|
||||||
|
{
|
||||||
|
for (const TSharedPtr<IPropertyHandle> &H : Props)
|
||||||
|
{
|
||||||
|
if (H->HasMetaData(TEXT("Optional"))) continue;
|
||||||
|
FName Name = H->GetProperty()->GetFName();
|
||||||
|
if (!Specified.Contains(Name))
|
||||||
|
{
|
||||||
|
UWingServer::Printf(TEXT("Required parameter %s not specified\n"),
|
||||||
|
*WingUtils::ExternalizeID(Name));
|
||||||
|
Ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If anything is wrong, return early without setting anything.
|
||||||
|
if (!Ok) return false;
|
||||||
|
|
||||||
|
// Populate each property from JSON. This could fail too, but at this
|
||||||
|
// point, we're committed.
|
||||||
|
for (const auto& KV : Json.Values)
|
||||||
|
{
|
||||||
|
FName Name = WingUtils::CheckInternalizeID(KV.Key);
|
||||||
|
if (!SetJson(*OrganizedProps[Name], KV.Value)) Ok = false;
|
||||||
|
}
|
||||||
|
return Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Print
|
// Print
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "WingServer.h"
|
#include "WingServer.h"
|
||||||
#include "WingHandler.h"
|
#include "WingHandler.h"
|
||||||
#include "WingProperty.h"
|
#include "WingPropHandle.h"
|
||||||
#include "WingManual.h"
|
#include "WingManual.h"
|
||||||
#include "WingLogCapture.h"
|
#include "WingLogCapture.h"
|
||||||
#include "WingUtils.h"
|
#include "WingUtils.h"
|
||||||
@@ -328,7 +328,9 @@ void UWingServer::TryCallHandler(const FString &Line)
|
|||||||
Handler->ConfigurationObject = Found->Config.Get();
|
Handler->ConfigurationObject = Found->Config.Get();
|
||||||
|
|
||||||
// Populate the handler object with the request parameters.
|
// Populate the handler object with the request parameters.
|
||||||
if (!FWingProperty::PopulateFromJson(HandlerObj->GetClass(), HandlerObj.Get(), &*Request))
|
WingPropHandle Props;
|
||||||
|
WingPropHandle::Handles Handles = Props.AllProperties(HandlerObj.Get(), true, CPF_None);
|
||||||
|
if (!WingPropHandle::PopulateFromJson(Handles, *Request, false))
|
||||||
{
|
{
|
||||||
UWingServer::SuggestManual(WingManual::Section::HandlerHelp);
|
UWingServer::SuggestManual(WingManual::Section::HandlerHelp);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -56,9 +56,6 @@
|
|||||||
// Name sanitization
|
// Name sanitization
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
FName WingUtils::GetFName(const FWingProperty &Prop) { return Prop.Prop->GetFName(); }
|
|
||||||
FName WingUtils::GetFName(const TSharedPtr<IPropertyHandle> &H) { return H->GetProperty()->GetFName(); }
|
|
||||||
|
|
||||||
FString WingUtils::ExternalizeID(FName Name)
|
FString WingUtils::ExternalizeID(FName Name)
|
||||||
{
|
{
|
||||||
return WingTokenizer::ExternalizeID(Name);
|
return WingTokenizer::ExternalizeID(Name);
|
||||||
@@ -272,6 +269,17 @@ FString WingUtils::FormatName(const UWidget *Widget)
|
|||||||
return ExternalizeID(Widget->GetFName());
|
return ExternalizeID(Widget->GetFName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FName WingUtils::GetFName(const FWingProperty &Prop)
|
||||||
|
{
|
||||||
|
return Prop.Prop->GetFName();
|
||||||
|
}
|
||||||
|
|
||||||
|
FName WingUtils::GetFName(const TSharedPtr<IPropertyHandle> &H)
|
||||||
|
{
|
||||||
|
return H->GetProperty()->GetFName();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// Formatting other things
|
// Formatting other things
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
#include "IPropertyRowGenerator.h"
|
#include "IPropertyRowGenerator.h"
|
||||||
#include "PropertyHandle.h"
|
#include "PropertyHandle.h"
|
||||||
|
|
||||||
|
class FJsonObject;
|
||||||
|
class FJsonValue;
|
||||||
|
|
||||||
// WingPropHandle: A module that provides easy access to
|
// WingPropHandle: A module that provides easy access to
|
||||||
// IPropertyHandle objects. To use this module, construct a
|
// IPropertyHandle objects. To use this module, construct a
|
||||||
// WingPropHandle, then use it to fetch properties from
|
// WingPropHandle, then use it to fetch properties from
|
||||||
@@ -52,13 +55,27 @@ public:
|
|||||||
// expression properties), widgets (includes slot properties).
|
// expression properties), widgets (includes slot properties).
|
||||||
Handles GetDetails(UObject* Obj, bool Mutable);
|
Handles GetDetails(UObject* Obj, bool Mutable);
|
||||||
|
|
||||||
// Get/set text with special handling for enums (smarter prefix
|
// Organize properties by name. If there's more than one property
|
||||||
// matching via WingUtils::StringToEnum) and FEdGraphPinType
|
// of a given name, print an error and returns false, and returns a map
|
||||||
// (human-readable format via UWingTypes).
|
// that contains one of the two duplicates.
|
||||||
|
static bool OrganizeByName(const Handles &H, TMap<FName, TSharedPtr<IPropertyHandle>> &Result);
|
||||||
|
|
||||||
|
// Get/set text. Compared to the built in methods for getting and setting
|
||||||
|
// text, these support more concise enum values, FEdGraphPinType, and
|
||||||
|
// more concise Class properties.
|
||||||
static FString GetText(IPropertyHandle& Handle);
|
static FString GetText(IPropertyHandle& Handle);
|
||||||
static bool SetText(IPropertyHandle& Handle, const FString& Text);
|
static bool SetText(IPropertyHandle& Handle, const FString& Text);
|
||||||
|
|
||||||
|
// Store a Json value into a property handle. The Json value must be
|
||||||
|
// a string, number, or boolean.
|
||||||
static bool SetJson(IPropertyHandle& Handle, const TSharedPtr<FJsonValue>& JsonValue);
|
static bool SetJson(IPropertyHandle& Handle, const TSharedPtr<FJsonValue>& JsonValue);
|
||||||
|
|
||||||
|
// Populate a whole bunch of properties from a Json object. If
|
||||||
|
// AllOptional is true, the Json may supply a subset of the properties.
|
||||||
|
// If not, the Json must supply all of them, excepting properties that
|
||||||
|
// are explicitly marked Optional.
|
||||||
|
static bool PopulateFromJson(TArray<TSharedPtr<IPropertyHandle>>& Props, const FJsonObject& Json, bool AllOptional);
|
||||||
|
|
||||||
// Print a single property in a standardized format:
|
// Print a single property in a standardized format:
|
||||||
// editable|readonly Type Name = Value
|
// editable|readonly Type Name = Value
|
||||||
static void Print(IPropertyHandle& Handle, FStringBuilderBase& Out);
|
static void Print(IPropertyHandle& Handle, FStringBuilderBase& Out);
|
||||||
|
|||||||
Reference in New Issue
Block a user