很早之前的修改,我也忘了改什么了
This commit is contained in:
203
Source/AronaCore/Singleton/SampleManager.cpp
Normal file
203
Source/AronaCore/Singleton/SampleManager.cpp
Normal file
@@ -0,0 +1,203 @@
|
||||
#include "SampleManager.h"
|
||||
|
||||
#include "ExecutionTime.h"
|
||||
#include "Misc/AronaConfig.h"
|
||||
|
||||
FArchive& operator<<(FArchive& Ar, FSamplePathNode* In)
|
||||
{
|
||||
return *In << Ar;
|
||||
}
|
||||
|
||||
FSamplePathNode* FSamplePathNode::Create(const FString& Path)
|
||||
{
|
||||
if (!FPaths::DirectoryExists(Path))
|
||||
return nullptr;
|
||||
|
||||
FSamplePathNode* Root = new FSamplePathNode();
|
||||
Root->Value = Path;
|
||||
Root->NodeType = Type::Directory;
|
||||
Root->Parent = nullptr;
|
||||
|
||||
class FSamplePathVisitor : public IPlatformFile::FDirectoryStatVisitor
|
||||
{
|
||||
public:
|
||||
FSamplePathVisitor(FSamplePathNode* InRoot) : Root(InRoot)
|
||||
{
|
||||
|
||||
}
|
||||
virtual bool Visit(const TCHAR* FilenameOrDirectory, const FFileStatData& StatData) override
|
||||
{
|
||||
if (!StatData.bIsDirectory)
|
||||
{
|
||||
const FString& FilePath = FPaths::GetPath(FilenameOrDirectory);
|
||||
auto* PathNode = Root->GetNodeByPath(FilePath);
|
||||
if (!PathNode)
|
||||
{
|
||||
PathNode = Root->CreateNodeByPath(FilePath);
|
||||
}
|
||||
FSamplePathNode* SamplePathNode = PathNode->AddChild();
|
||||
SamplePathNode->NodeType = Type::File;
|
||||
SamplePathNode->Value = FPaths::GetCleanFilename(FilenameOrDirectory);
|
||||
return true;
|
||||
}
|
||||
Root->CreateNodeByPath(FilenameOrDirectory);
|
||||
return true;
|
||||
}
|
||||
FSamplePathNode* Root;
|
||||
} Visitor(Root);
|
||||
|
||||
IPlatformFile::GetPlatformPhysical().IterateDirectoryStatRecursively(*Path, Visitor);
|
||||
return Root;
|
||||
}
|
||||
|
||||
FSamplePathNode* FSamplePathNode::AddChild()
|
||||
{
|
||||
FSamplePathNode* ChildNode = new FSamplePathNode();
|
||||
ChildNode->Parent = this;
|
||||
Child.Add(ChildNode);
|
||||
return ChildNode;
|
||||
}
|
||||
|
||||
FSamplePathNode* FSamplePathNode::GetNodeByPath(const FString& Path)
|
||||
{
|
||||
if (FPaths::IsSamePath(Path, GetFullPath()))
|
||||
return this;
|
||||
if (FSamplePathNode** Node = GetRootNode()->ChildMap.Find(Path))
|
||||
return *Node;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FSamplePathNode* FSamplePathNode::CreateNodeByPath(FString Path)
|
||||
{
|
||||
const FString& FullPath = GetFullPath();
|
||||
if (FullPath == Path)
|
||||
return this;
|
||||
TArray<FString> Paths;
|
||||
FString Leaf;
|
||||
do
|
||||
{
|
||||
FString Temp = FPaths::GetPathLeaf(Path);
|
||||
if (Temp == Leaf)
|
||||
break;
|
||||
Leaf = Temp;
|
||||
Paths.Add(Path);
|
||||
Path = FPaths::GetPath(Path);
|
||||
if (Path == FullPath)
|
||||
break;
|
||||
}
|
||||
while (true);
|
||||
Algo::Reverse(Paths);
|
||||
return CreateNodeByPathInternal(Paths);
|
||||
}
|
||||
|
||||
FSamplePathNode* FSamplePathNode::CreateNodeByPathInternal(const TArray<FString>& Paths)
|
||||
{
|
||||
FSamplePathNode* RootNode = GetRootNode();
|
||||
for (auto Str : Paths)
|
||||
{
|
||||
FSamplePathNode* PathNode = GetNodeByPath(Str);
|
||||
if (!PathNode)
|
||||
{
|
||||
PathNode = AddChild();
|
||||
PathNode->Value = FPaths::GetPathLeaf(Str);
|
||||
PathNode->NodeType = Directory;
|
||||
RootNode->ChildMap.Add(Str, PathNode);
|
||||
}
|
||||
}
|
||||
return GetNodeByPath(Paths[0]);
|
||||
}
|
||||
|
||||
bool FSampleDirectoryCache::NeedRefresh()
|
||||
{
|
||||
if (!FPaths::FileExists(*GetCachePath()))
|
||||
return true;
|
||||
TArray<FString> PathsStr;
|
||||
FAronaConfig::GetValueArray("Sample", "Path", PathsStr);
|
||||
if (PathsStr.Num() != SamplePathNodes.Num())
|
||||
return true;
|
||||
// TODO: 比较路径是否相同
|
||||
return false;
|
||||
}
|
||||
|
||||
void FSampleDirectoryCache::Init()
|
||||
{
|
||||
Reload();
|
||||
if (NeedRefresh())
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void FSampleDirectoryCache::Reload()
|
||||
{
|
||||
Clear();
|
||||
TArray<uint8> Data;
|
||||
if (!FFileHelper::LoadFileToArray(Data, *GetCachePath()))
|
||||
return;
|
||||
FMemoryReader MemoryReader(Data);
|
||||
Serialize(MemoryReader);
|
||||
Save();
|
||||
}
|
||||
|
||||
void FSampleDirectoryCache::Refresh()
|
||||
{
|
||||
if (Loading || !NeedRefresh())
|
||||
return;
|
||||
|
||||
Async(EAsyncExecution::Thread, [this]()
|
||||
{
|
||||
Loading = true;
|
||||
RegenCache();
|
||||
Loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
void FSampleDirectoryCache::RegenCache()
|
||||
{
|
||||
DeleteCache();
|
||||
|
||||
FAronaConfig::GetValueArray("Sample", "Path", SamplePaths);
|
||||
for (auto Str : SamplePaths)
|
||||
{
|
||||
if (FSamplePathNode* SamplePathNode = FSamplePathNode::Create(Str))
|
||||
SamplePathNodes.Add(SamplePathNode);
|
||||
}
|
||||
Save();
|
||||
}
|
||||
|
||||
bool FSampleDirectoryCache::Save()
|
||||
{
|
||||
TArray<uint8> Data;
|
||||
FMemoryWriter MemoryWriter(Data);
|
||||
Serialize(MemoryWriter);
|
||||
return FFileHelper::SaveArrayToFile(Data, *GetCachePath());
|
||||
}
|
||||
|
||||
void FSampleDirectoryCache::Clear()
|
||||
{
|
||||
for (const auto PathNode : SamplePathNodes)
|
||||
{
|
||||
delete PathNode;
|
||||
}
|
||||
SamplePathNodes.Empty();
|
||||
}
|
||||
|
||||
void FSampleManager::Init()
|
||||
{
|
||||
Cache.Init();
|
||||
}
|
||||
|
||||
void FSampleManager::Refresh()
|
||||
{
|
||||
Cache.Refresh();
|
||||
}
|
||||
|
||||
void FSampleDirectoryCache::DeleteCache()
|
||||
{
|
||||
IPlatformFile::GetPlatformPhysical().DeleteFile(*GetCachePath());
|
||||
}
|
||||
|
||||
FString FSampleDirectoryCache::GetCachePath()
|
||||
{
|
||||
return FPaths::ProjectSavedDir() / TEXT("SampleCache");
|
||||
}
|
||||
Reference in New Issue
Block a user