// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "Containers/Array.h" #include "Containers/UnrealString.h" #include "Internationalization/Text.h" #include "StructViewerModule.h" #include "Templates/SharedPointer.h" #include "UObject/Class.h" #include "UObject/NameTypes.h" #include "UObject/SoftObjectPath.h" #include "UObject/WeakObjectPtrTemplates.h" class IPropertyHandle; class UScriptStruct; class UUserDefinedStruct; struct FAssetData; /** Common data representing an unfiltered hierarchy of nodes */ class FStructViewerNodeData : public TSharedFromThis { public: /** Create a dummy node */ FStructViewerNodeData(); /** Create a node representing the given struct */ explicit FStructViewerNodeData(const UScriptStruct* InStruct); /** Create a node representing the given struct asset (may be unloaded) */ explicit FStructViewerNodeData(const FAssetData& InStructAsset); /** Get the unlocalized name of the struct we represent */ const FString& GetStructName() const { return StructName; } /** Get the localized name of the struct we represent */ FText GetStructDisplayName() const { return StructDisplayName; } /** Get the full object path to the struct we represent */ FSoftObjectPath GetStructPath() const { return StructPath; } /** Get the full object path to the parent of the struct we represent */ FSoftObjectPath GetParentStructPath() const { return ParentStructPath; } /** Get the struct that we represent (for loaded struct assets, or native structs) */ const UScriptStruct* GetStruct() const; /** Get the struct asset that we represent (for loaded struct assets) */ const UUserDefinedStruct* GetStructAsset() const; /** * Trigger a load of the struct we represent. * @return True if the struct was loaded (or was already loaded), false otherwise. */ bool LoadStruct() const; /** Get the pointer to the parent data node (if any) */ TSharedPtr GetParentNode() const { return ParentNode.Pin(); } /** Get the list of child data nodes */ const TArray>& GetChildNodes() const { return ChildNodes; } /** Adds the specified child to this node */ void AddChild(const TSharedRef& InChild); /** Adds the specified child to this node, only if a node representing the struct doesn't already exist as a child */ void AddUniqueChild(const TSharedRef& InChild); /** Remove the child representing the given struct path (if present) */ bool RemoveChild(const FSoftObjectPath& InStructPath); private: /** The unlocalized name of the struct we represent */ FString StructName; /** The localized name of the struct we represent */ mutable FText StructDisplayName; /** The full object path to the struct we represent */ FSoftObjectPath StructPath; /** The full object path to the parent of the struct we represent */ FSoftObjectPath ParentStructPath; /** The struct that we represent (for loaded struct assets, or native structs) */ mutable TWeakObjectPtr Struct; /** Pointer to the parent data node (if any) */ TWeakPtr ParentNode; /** List of child data nodes */ TArray> ChildNodes; }; /** Filtered data representing a filtered hierarchy of nodes */ class FStructViewerNode : public TSharedFromThis { public: /** Create a dummy node */ FStructViewerNode(); /** Create a node representing the given data */ FStructViewerNode(const TSharedRef& InData, const TSharedPtr& InPropertyHandle, const bool InPassedFilter); /** Get the unlocalized name of the struct we represent */ const FString& GetStructName() const { return NodeData->GetStructName(); } /** Get the localized name of the struct we represent */ FText GetStructDisplayName() const { return NodeData->GetStructDisplayName(); } /** Get the display name of the struct we represent, built based on the given option */ FText GetStructDisplayName(const EStructViewerNameTypeToDisplay InNameType) const; /** Get the full object path to the struct we represent */ FSoftObjectPath GetStructPath() const { return NodeData->GetStructPath(); } /** Get the full object path to the parent of the struct we represent */ FSoftObjectPath GetParentStructPath() const { return NodeData->GetParentStructPath(); } /** Get the struct that we represent (for loaded struct assets, or native structs) */ const UScriptStruct* GetStruct() const { return NodeData->GetStruct(); } /** Get the struct asset that we represent (for loaded struct assets) */ const UUserDefinedStruct* GetStructAsset() const { return NodeData->GetStructAsset(); } /** * Trigger a load of the struct we represent. * @return True if the struct was loaded (or was already loaded), false otherwise. */ bool LoadStruct() const { return NodeData->LoadStruct(); } /** Get the pointer to the parent node (if any) */ TSharedPtr GetParentNode() const { return ParentNode.Pin(); } /** Get the list of child nodes */ const TArray>& GetChildNodes() const { return ChildNodes; } /** Adds the specified child to this node */ void AddChild(const TSharedRef& InChild); /** Adds the specified child to this node, only if a node representing the struct doesn't already exist as a child */ void AddUniqueChild(const TSharedRef& InChild); /** Sort the child nodes based on FStructViewerNode::SortPredicate */ void SortChildren(); /** Sort the child nodes recursively based on FStructViewerNode::SortPredicate */ void SortChildrenRecursive(); /** Predicate function that can be used to sort instances by struct name */ static bool SortPredicate(const TSharedPtr& InA, const TSharedPtr& InB); /** Sorts the array of nodes either by a custom sort function, or by using the default one (::SortPredicate) */ static void SortNodes(TArray>& Nodes, const TSharedPtr& PropertyHandle = { }); /** Check whether this struct is restricted for the specific context */ bool IsRestricted() const; /** Get the property this filtered node will be working on */ const TSharedPtr& GetPropertyHandle() const { return PropertyHandle; } /** True if the struct passed the filter */ bool PassedFilter() const { return bPassedFilter; } /** True if the struct passed the filter */ void PassedFilter(const bool InPassedFilter) { bPassedFilter = InPassedFilter; } private: /** Reference to the common data this filtered node represents */ TSharedRef NodeData; /** The property this filtered node will be working on */ TSharedPtr PropertyHandle; /** True if the struct passed the filter */ bool bPassedFilter; /** Pointer to the parent node (if any) */ TWeakPtr ParentNode; /** List of child nodes */ TArray> ChildNodes; };