#pragma once #include "Singleton.h" struct FSamplePathNode; FArchive& operator<<(FArchive& Ar, FSamplePathNode* In); struct FSamplePathNode { ~FSamplePathNode() { for (const auto* ChildNode : Child) { delete ChildNode; } Child.Empty(); } enum Type : uint8 { File, Directory }; static FSamplePathNode* Create(const FString& Path); FSamplePathNode* AddChild(); FSamplePathNode* GetNodeByPath(const FString& Path); FSamplePathNode* CreateNodeByPath(FString Path); FString GetFullPath() const { return Parent ? Parent->GetFullPath() / Value : Value; } FString GetValue() const { return Value; } bool IsRoot() const { return Parent == nullptr; } FSamplePathNode* GetRootNode() { return Parent ? Parent->GetRootNode() : this; } FArchive& operator<<(FArchive& Ar) { if (Ar.IsLoading()) { FString FullPath; Ar << FullPath; Ar << Value; uint8 TempNodeType; Ar << TempNodeType; NodeType = (Type)TempNodeType; int32 ChildCount; Ar << ChildCount; for (int32 i = 0; i < ChildCount; ++i) { FSamplePathNode* ChildNode = new FSamplePathNode(); ChildNode->Parent = this; Ar << ChildNode; Child.Add(ChildNode); } if (TempNodeType == Directory) GetRootNode()->ChildMap.Add(FullPath, this); } else { FString FullPath = GetFullPath(); Ar << FullPath; Ar << Value; uint8 TempNodeType = NodeType; Ar << TempNodeType; int32 ChildCount = Child.Num(); Ar << ChildCount; for (int32 i = 0; i < ChildCount; ++i) { Ar << Child[i]; } } return Ar; } FString Value; Type NodeType; TArray Child; FSamplePathNode* Parent; TMap ChildMap; // 仅根节点 private: FSamplePathNode* CreateNodeByPathInternal(const TArray& Paths); }; class FSampleDirectoryCache { public: bool NeedRefresh(); void Init(); void Reload(); void Refresh(); void RegenCache(); bool Save(); void Clear(); static FString GetCachePath(); static void DeleteCache(); FArchive& Serialize(FArchive& Ar) { Ar << SamplePaths; if (Ar.IsLoading()) { int32 ChildCount; Ar << ChildCount; for (int i = 0; i < ChildCount; ++i) { auto Node = new FSamplePathNode(); Ar << Node; SamplePathNodes.Add(Node); } } else { int32 ChildCount = SamplePathNodes.Num(); Ar << ChildCount; for (int i = 0; i < ChildCount; ++i) { Ar << SamplePathNodes[i]; } } return Ar; } TArray SamplePaths; TArray SamplePathNodes; std::atomic_bool Loading; }; class FSampleManager : public TSingleton { public: virtual void Init() override; void Refresh(); private: TArray SamplePaths; FSampleDirectoryCache Cache; };