Working on Asset_Create
This commit is contained in:
39
Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Create.h
Normal file
39
Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Create.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "WingServer.h"
|
||||
#include "WingHandler.h"
|
||||
#include "WingFactories.h"
|
||||
#include "Asset_Create.generated.h"
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
class UWing_Asset_Create : public UObject, public IWingHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(meta=(Description="Full asset path for the new asset (e.g. '/Game/MyFolder/MyAsset')"))
|
||||
FString AssetPath;
|
||||
|
||||
UPROPERTY(meta=(Description="Factory type name from Asset_SearchTypes (e.g. 'Material', 'Blueprint')"))
|
||||
FString Factory;
|
||||
|
||||
UPROPERTY(meta=(Optional, Description="Factory configuration properties as key-value pairs"))
|
||||
FWingJsonObject Config;
|
||||
|
||||
virtual FString GetDescription() const override
|
||||
{
|
||||
return TEXT("Create a new asset using a factory. Use Asset_SearchTypes to find "
|
||||
"available factory types and their configurable properties.");
|
||||
}
|
||||
|
||||
virtual void Handle() override
|
||||
{
|
||||
UWingFactories::CreateAsset(AssetPath, Factory, Config);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "WingServer.h"
|
||||
#include "WingHandler.h"
|
||||
#include "WingFactories.h"
|
||||
#include "Asset_SearchTypes.generated.h"
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
class UWing_Asset_SearchTypes : public UObject, public IWingHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(meta=(Description="Query string, can contain *"))
|
||||
FString Query;
|
||||
|
||||
UPROPERTY(meta=(Optional, Description="Maximum number of results (default 50)"))
|
||||
int32 MaxResults = 50;
|
||||
|
||||
virtual FString GetDescription() const override
|
||||
{
|
||||
return TEXT("Search for asset factory types that can be used with Asset_Create. "
|
||||
"Returns factory names and their configurable properties.");
|
||||
}
|
||||
|
||||
virtual void Handle() override
|
||||
{
|
||||
FString ExtQuery = TEXT("*") + Query + TEXT("*");
|
||||
const TArray<UWingFactories::Info>& All = UWingFactories::AllFactories();
|
||||
|
||||
int32 Count = 0;
|
||||
for (const UWingFactories::Info& Entry : All)
|
||||
{
|
||||
if (Count >= MaxResults) break;
|
||||
if (!Entry.CanCreateNew()) continue;
|
||||
if (!Entry.Name.MatchesWildcard(ExtQuery, ESearchCase::IgnoreCase)) continue;
|
||||
|
||||
UWingServer::Printf(TEXT("%s\n"), *Entry.Name);
|
||||
|
||||
for (const FName& Prop : Entry.Config)
|
||||
{
|
||||
UWingServer::Printf(TEXT(" %s\n"), *Prop.ToString());
|
||||
}
|
||||
|
||||
Count++;
|
||||
}
|
||||
|
||||
if (Count == 0)
|
||||
{
|
||||
UWingServer::Print(TEXT("No matching factory types found.\n"));
|
||||
}
|
||||
else if (Count >= MaxResults)
|
||||
{
|
||||
UWingServer::Printf(TEXT("WARNING: Reached limit of %d results. You may specify MaxResults.\n"), MaxResults);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
UBlueprint* NewBP = FKismetEditorUtilities::CreateBlueprint(
|
||||
ParentClassObj,
|
||||
Maker.Package(),
|
||||
FName(*Maker.Name()),
|
||||
Maker.GetFName(),
|
||||
BlueprintType,
|
||||
UBlueprint::StaticClass(),
|
||||
UBlueprintGeneratedClass::StaticClass()
|
||||
|
||||
181
Plugins/UEWingman/Source/UEWingman/Private/WingFactories.cpp
Normal file
181
Plugins/UEWingman/Source/UEWingman/Private/WingFactories.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
#include "WingFactories.h"
|
||||
#include "WingServer.h"
|
||||
#include "Editor.h"
|
||||
#include "WingUtils.h"
|
||||
#include "WingProperty.h"
|
||||
#include "WingPackageMaker.h"
|
||||
#include "Kismet2/KismetEditorUtilities.h"
|
||||
#include "Kismet2/EnumEditorUtils.h"
|
||||
#include "Factories/BlueprintFactory.h"
|
||||
#include "Factories/EnumFactory.h"
|
||||
#include "Algo/BinarySearch.h"
|
||||
|
||||
void UWingFactories::Initialize(FSubsystemCollectionBase& Collection)
|
||||
{
|
||||
Super::Initialize(Collection);
|
||||
PopulateRegistry();
|
||||
}
|
||||
|
||||
const TArray<UWingFactories::Info>& UWingFactories::AllFactories()
|
||||
{
|
||||
return GEditor->GetEditorSubsystem<UWingFactories>()->Registry;
|
||||
}
|
||||
|
||||
bool UWingFactories::Info::CanCreateNew() const
|
||||
{
|
||||
return FactoryClass->GetDefaultObject<UFactory>()->CanCreateNew();
|
||||
}
|
||||
|
||||
void UWingFactories::PopulateRegistry()
|
||||
{
|
||||
TArray<UClass*> FactoryClasses;
|
||||
GetDerivedClasses(UFactory::StaticClass(), FactoryClasses);
|
||||
|
||||
// Populate it with initial data.
|
||||
for (UClass* Class : FactoryClasses)
|
||||
{
|
||||
if (Class->HasAnyClassFlags(CLASS_Abstract)) continue;
|
||||
|
||||
Info Entry;
|
||||
Entry.Name = DeriveFactoryName(Class);
|
||||
Entry.FactoryClass = Class;
|
||||
Entry.Config = FWingProperty::GetNames(Class, CPF_Edit);
|
||||
Registry.Add(MoveTemp(Entry));
|
||||
}
|
||||
|
||||
// Sort the registry.
|
||||
Registry.Sort([](const Info& A, const Info& B) { return A.Name < B.Name; });
|
||||
|
||||
// Blacklist certain bad factories.
|
||||
DisableFactory(TEXT("PhysicsAsset")); // PhysicsAsset factory pops a modal dialog
|
||||
}
|
||||
|
||||
void UWingFactories::DisableFactory(const TCHAR* Name)
|
||||
{
|
||||
Info* Entry = Find(Name);
|
||||
if (!Entry)
|
||||
{
|
||||
UE_LOG(LogTemp, Fatal, TEXT("UWingFactories::DisableFactory: factory '%s' not found"), Name);
|
||||
return;
|
||||
}
|
||||
Entry->Disabled = true;
|
||||
}
|
||||
|
||||
UObject* UWingFactories::CreateAsset(const FString& Path, const FString& FactoryName, FWingJsonObject& Config)
|
||||
{
|
||||
UWingFactories* Self = GEditor->GetEditorSubsystem<UWingFactories>();
|
||||
|
||||
// Look up the factory info.
|
||||
const Info* FactoryInfo = Self->Find(FactoryName);
|
||||
if (!FactoryInfo)
|
||||
{
|
||||
UWingServer::Printf(TEXT("ERROR: Unknown factory '%s'\n"), *FactoryName);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Make sure this is the a creation factory, as opposed to an import factory.
|
||||
if (!FactoryInfo->CanCreateNew())
|
||||
{
|
||||
UWingServer::Printf(TEXT("ERROR: Factory '%s' cannot create objects from scratch\n"), *FactoryName);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Validate the path, and that there's not already something there.
|
||||
WingPackageMaker Maker(Path);
|
||||
if (!Maker.Ok()) return nullptr;
|
||||
FName Name = Maker.GetFName();
|
||||
|
||||
// Create the factory instance.
|
||||
UFactory* Factory = NewObject<UFactory>(GetTransientPackage(), FactoryInfo->FactoryClass);
|
||||
|
||||
// Get the editable properties
|
||||
TArray<FWingProperty> Props =
|
||||
FWingProperty::GetNamed(Factory->GetClass(), Factory, FactoryInfo->Config);
|
||||
|
||||
// if there is no config table, make a blank config table.
|
||||
TSharedPtr<FJsonObject> ConfigJson = Config.Json;
|
||||
if (ConfigJson == nullptr) ConfigJson = MakeShared<FJsonObject>();
|
||||
|
||||
// Populate the configuration properties from the json.
|
||||
if (!FWingProperty::PopulateFromJson(Props, ConfigJson.Get(), false))
|
||||
return nullptr;
|
||||
|
||||
// Pre-check: block factories that would cause problems.
|
||||
// In particular, this blocks those that would pop a dialog.
|
||||
if (!PreCheck(Factory, Name, Path)) return nullptr;
|
||||
|
||||
// Create the asset.
|
||||
if (!Maker.Make()) return nullptr;
|
||||
UObject* NewAsset = Factory->FactoryCreateNew(
|
||||
FactoryInfo->FactoryClass->GetDefaultObject<UFactory>()->GetSupportedClass(),
|
||||
Maker.Package(),
|
||||
Name,
|
||||
RF_Public | RF_Standalone | RF_Transactional,
|
||||
nullptr,
|
||||
GWarn
|
||||
);
|
||||
if (!NewAsset)
|
||||
{
|
||||
UWingServer::Printf(TEXT("ERROR: Factory '%s' returned null\n"), *FactoryName);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UWingServer::Printf(TEXT("Created: %s\n"), *WingUtils::ExternalizeID(Name));
|
||||
return NewAsset;
|
||||
}
|
||||
|
||||
bool UWingFactories::PreCheck(UFactory* Factory, FName Name, const FString &Path)
|
||||
{
|
||||
// Blueprint factories: FactoryCreateNew pops FMessageDialog if ParentClass is invalid.
|
||||
if (UBlueprintFactory* BPFactory = Cast<UBlueprintFactory>(Factory))
|
||||
{
|
||||
if (!BPFactory->ParentClass)
|
||||
{
|
||||
UWingServer::Print(TEXT("ERROR: ParentClass must be set\n"));
|
||||
return false;
|
||||
}
|
||||
if (!FKismetEditorUtilities::CanCreateBlueprintOfClass(BPFactory->ParentClass))
|
||||
{
|
||||
UWingServer::Printf(TEXT("ERROR: Cannot create a blueprint based on class '%s'\n"), *BPFactory->ParentClass->GetName());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Enum factory: FactoryCreateNew pops FMessageDialog if the name already exists.
|
||||
if (UEnumFactory* EFactory = Cast<UEnumFactory>(Factory))
|
||||
{
|
||||
if(!FEnumEditorUtils::IsNameAvailebleForUserDefinedEnum(Name))
|
||||
{
|
||||
UWingServer::Printf(TEXT("Enum name is already taken: %s"),
|
||||
*WingUtils::ExternalizeID(Name));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
UWingFactories::Info* UWingFactories::Find(const FString& Name)
|
||||
{
|
||||
int32 Index = Algo::LowerBound(Registry, Name, [](Info& Entry, const FString& N) {
|
||||
return Entry.Name < N;
|
||||
});
|
||||
if (Index < Registry.Num() && Registry[Index].Name == Name)
|
||||
{
|
||||
return &Registry[Index];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FString UWingFactories::DeriveFactoryName(UClass* FactoryClass)
|
||||
{
|
||||
FString Name = FactoryClass->GetName();
|
||||
if (Name.EndsWith(TEXT("FactoryNew")))
|
||||
{
|
||||
Name.LeftChopInline(10);
|
||||
}
|
||||
else if (Name.EndsWith(TEXT("Factory")))
|
||||
{
|
||||
Name.LeftChopInline(7);
|
||||
}
|
||||
return Name;
|
||||
}
|
||||
@@ -60,11 +60,6 @@ void WingManual::PrintHandlerHelp(UClass* HandlerClass)
|
||||
|
||||
void WingManual::PrintManual(TSet<Section> Sections, UClass *Handler, bool Abridged)
|
||||
{
|
||||
if (Handler == nullptr)
|
||||
{
|
||||
Sections.Remove(Section::HandlerHelp);
|
||||
}
|
||||
|
||||
if (Sections.IsEmpty()) return;
|
||||
|
||||
const bool bPrintAll = Sections.Contains(Section::All);
|
||||
@@ -74,7 +69,7 @@ void WingManual::PrintManual(TSet<Section> Sections, UClass *Handler, bool Abrid
|
||||
UWingServer::Printf(TEXT("\n--- AUTOMATIC DOCUMENTATION ---\n"));
|
||||
}
|
||||
|
||||
if (Sections.Contains(Section::HandlerHelp) || bPrintAll)
|
||||
if (Handler && (Sections.Contains(Section::HandlerHelp) || bPrintAll))
|
||||
{
|
||||
PrintHandlerHelp(Handler);
|
||||
}
|
||||
@@ -286,6 +281,9 @@ void WingManual::PrintManual(TSet<Section> Sections, UClass *Handler, bool Abrid
|
||||
"\n Graph_Dump: a fairly detailed listing of any Graph"
|
||||
"\n Property_Dump: show information on many objects"
|
||||
"\n"
|
||||
"\n You can use ShowCommands(Query=SomeCommand,Verbose=true)"
|
||||
"\n to get detailed help for a specific command."
|
||||
"\n"
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "WingPackageMaker.h"
|
||||
#include "AssetRegistry/AssetRegistryModule.h"
|
||||
|
||||
WingPackageMaker::WingPackageMaker(const FString& InFullPath)
|
||||
: FullPath(InFullPath)
|
||||
{
|
||||
if (!CheckNewAssetPath(InFullPath))
|
||||
{
|
||||
bError = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool WingPackageMaker::CheckNewAssetPath(const FString& Path)
|
||||
{
|
||||
if (!FPackageName::IsValidTextForLongPackageName(Path))
|
||||
{
|
||||
UWingServer::Printf(TEXT("ERROR: Package path '%s' is not a valid package name\n"), *Path);
|
||||
return false;
|
||||
}
|
||||
if (!Path.StartsWith(TEXT("/Game")))
|
||||
{
|
||||
UWingServer::Printf(TEXT("ERROR: Package path '%s' must start with '/Game'\n"), *Path);
|
||||
return false;
|
||||
}
|
||||
if (FindObject<UPackage>(nullptr, *Path))
|
||||
{
|
||||
UWingServer::Printf(TEXT("ERROR: An asset already exists at '%s'\n"), *Path);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool WingPackageMaker::Make()
|
||||
{
|
||||
if (bError) return false;
|
||||
Pkg = CreatePackage(*FullPath);
|
||||
if (!Pkg)
|
||||
{
|
||||
UWingServer::Printf(TEXT("ERROR: Failed to create package at '%s'\n"), *FullPath);
|
||||
bError = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
Pkg->ClearFlags(RF_Transient);
|
||||
Pkg->SetIsExternallyReferenceable(true);
|
||||
Pkg->MarkPackageDirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -107,9 +107,27 @@ bool FWingProperty::SetText(FString Value)
|
||||
*Value, *WingUtils::FormatName(Prop), *Prop->GetCPPType());
|
||||
return false;
|
||||
}
|
||||
if (!CheckImportTextResult(Value)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FWingProperty::CheckImportTextResult(const FString &Value)
|
||||
{
|
||||
uint8 *VP = Prop->ContainerPtrToValuePtr<uint8>(Container);
|
||||
if (FObjectPropertyBase *OProp = CastField<FObjectPropertyBase>(Prop))
|
||||
{
|
||||
UObject *Obj = OProp->GetObjectPropertyValue(VP);
|
||||
if (Obj == nullptr && Value.TrimStartAndEnd().Compare(TEXT("None"), ESearchCase::IgnoreCase) != 0)
|
||||
{
|
||||
UWingServer::Printf(TEXT("ERROR: Failed to parse '%s' for property '%s'\n"),
|
||||
*Value, *WingUtils::FormatName(Prop));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool FWingProperty::SetJson(const TSharedPtr<FJsonValue> &JsonValue)
|
||||
{
|
||||
if (JsonValue->Type == EJson::String)
|
||||
@@ -235,6 +253,41 @@ void FWingProperty::Collect(UStruct* StructType, void* Container, TArray<FWingPr
|
||||
}
|
||||
}
|
||||
|
||||
TArray<FWingProperty> FWingProperty::GetAll(UObject* Object, EPropertyFlags Flags)
|
||||
{
|
||||
return GetAll(Object->GetClass(), Object, Flags);
|
||||
}
|
||||
|
||||
TArray<FWingProperty> FWingProperty::GetAll(UStruct* StructType, void* Container, EPropertyFlags Flags)
|
||||
{
|
||||
TArray<FWingProperty> Result;
|
||||
Collect(StructType, Container, Result, Flags);
|
||||
return Result;
|
||||
}
|
||||
|
||||
TArray<FWingProperty> FWingProperty::GetNamed(UStruct* StructType, void* Container, const TArray<FName> &Names)
|
||||
{
|
||||
TArray<FWingProperty> Result;
|
||||
for (FName Name : Names)
|
||||
{
|
||||
FProperty *Prop = StructType->FindPropertyByName(Name);
|
||||
if (Prop != nullptr) Result.Emplace(Prop, Container);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
TArray<FName> FWingProperty::GetNames(UStruct *StructType, EPropertyFlags Flags)
|
||||
{
|
||||
TArray<FName> Result;
|
||||
for (TFieldIterator<FProperty> It(StructType); It; ++It)
|
||||
{
|
||||
if (Flags != 0 && !It->HasAnyPropertyFlags(Flags)) continue;
|
||||
Result.Add(It->GetFName());
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
void FWingProperty::Remove(TArray<FWingProperty>& Props, const FString& Name)
|
||||
{
|
||||
Props.RemoveAll([&](const FWingProperty& P) { return P.Prop->GetName() == Name; });
|
||||
@@ -312,17 +365,6 @@ TArray<FWingProperty> FWingProperty::GetDetailsGeneral(UObject* Obj, EPropertyFl
|
||||
return Result;
|
||||
}
|
||||
|
||||
TArray<FWingProperty> FWingProperty::GetAll(UObject* Object, EPropertyFlags Flags)
|
||||
{
|
||||
return GetAll(Object->GetClass(), Object, Flags);
|
||||
}
|
||||
|
||||
TArray<FWingProperty> FWingProperty::GetAll(UStruct* StructType, void* Container, EPropertyFlags Flags)
|
||||
{
|
||||
TArray<FWingProperty> Result;
|
||||
Collect(StructType, Container, Result, Flags);
|
||||
return Result;
|
||||
}
|
||||
|
||||
TArray<FWingProperty> FWingProperty::FindAllSubstring(const TArray<FWingProperty>& Props, const FString& Substring)
|
||||
{
|
||||
|
||||
42
Plugins/UEWingman/Source/UEWingman/Public/WingFactories.h
Normal file
42
Plugins/UEWingman/Source/UEWingman/Public/WingFactories.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "EditorSubsystem.h"
|
||||
#include "Factories/Factory.h"
|
||||
#include "WingHandler.h"
|
||||
#include "WingFactories.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class UWingFactories : public UEditorSubsystem
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
struct Info
|
||||
{
|
||||
FString Name;
|
||||
UClass* FactoryClass = nullptr;
|
||||
TArray<FName> Config;
|
||||
bool Disabled = false;
|
||||
bool CanCreateNew() const;
|
||||
};
|
||||
|
||||
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
||||
virtual void Deinitialize() override {}
|
||||
|
||||
static const TArray<Info>& AllFactories();
|
||||
|
||||
// Create an asset on disk, using a factory. Returns the main object.
|
||||
// If there are problems, prints error messages and returns nullptr.
|
||||
static UObject *CreateAsset(const FString &Path, const FString &Factory, FWingJsonObject &Config);
|
||||
|
||||
private:
|
||||
TArray<Info> Registry;
|
||||
|
||||
Info* Find(const FString& Name);
|
||||
|
||||
void PopulateRegistry();
|
||||
void DisableFactory(const TCHAR* Name);
|
||||
static bool PreCheck(UFactory *Factory, FName Name, const FString &Path);
|
||||
static FString DeriveFactoryName(UClass* FactoryClass);
|
||||
};
|
||||
@@ -12,43 +12,13 @@
|
||||
class WingPackageMaker
|
||||
{
|
||||
public:
|
||||
WingPackageMaker(const FString& InFullPath)
|
||||
: FullPath(InFullPath)
|
||||
{
|
||||
// Path must start with /Game.
|
||||
if (!FullPath.StartsWith(TEXT("/Game")))
|
||||
{
|
||||
UWingServer::Printf(TEXT("ERROR: Package path '%s' must start with '/Game'\n"), *FullPath);
|
||||
bError = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for an existing asset at this path.
|
||||
if (FindObject<UPackage>(nullptr, *FullPath))
|
||||
{
|
||||
UWingServer::Printf(TEXT("ERROR: An asset already exists at '%s'\n"), *FullPath);
|
||||
bError = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
WingPackageMaker(const FString& InFullPath);
|
||||
|
||||
bool Ok() const { return !bError; }
|
||||
|
||||
bool Make()
|
||||
{
|
||||
if (bError) return false;
|
||||
Pkg = CreatePackage(*FullPath);
|
||||
if (!Pkg)
|
||||
{
|
||||
UWingServer::Printf(TEXT("ERROR: Failed to create package at '%s'\n"), *FullPath);
|
||||
bError = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Make();
|
||||
UPackage* Package() const { return Pkg; }
|
||||
FString Name() const { return FPackageName::GetShortName(FullPath); }
|
||||
FString GetName() const { return FPackageName::GetShortName(FullPath); }
|
||||
FName GetFName() const { return FName(GetName()); }
|
||||
|
||||
template<typename AssetClass, typename FactoryClass>
|
||||
AssetClass* CreateAsset()
|
||||
@@ -72,4 +42,6 @@ private:
|
||||
FString FullPath;
|
||||
UPackage* Pkg = nullptr;
|
||||
bool bError = false;
|
||||
|
||||
static bool CheckNewAssetPath(const FString& Path);
|
||||
};
|
||||
|
||||
@@ -59,6 +59,14 @@ struct FWingProperty
|
||||
static TArray<FWingProperty> GetAll(UObject* Object, EPropertyFlags Flags);
|
||||
static TArray<FWingProperty> GetAll(UStruct* StructType, void* Container, EPropertyFlags Flags);
|
||||
|
||||
// Get the names of the properties in the specified class.
|
||||
//
|
||||
static TArray<FName> GetNames(UStruct *StructType, EPropertyFlags Flags);
|
||||
|
||||
// Get the named properties.
|
||||
//
|
||||
static TArray<FWingProperty> GetNamed(UStruct* StructType, void* Container, const TArray<FName> &Names);
|
||||
|
||||
// Functions to find items by name in an array of properties.
|
||||
//
|
||||
static TArray<FWingProperty> FindAllSubstring(const TArray<FWingProperty>& Props, const FString& Substring);
|
||||
@@ -76,4 +84,5 @@ private:
|
||||
static TArray<FWingProperty> GetDetailsGeneral(UObject* Obj, EPropertyFlags Flags, bool Mutable);
|
||||
void PrintExpectsReceived(const TCHAR *Type);
|
||||
static void Collect(UStruct* Struct, void* Container, TArray<FWingProperty> &Props, EPropertyFlags Flags);
|
||||
bool CheckImportTextResult(const FString &Value);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user