SP3-105 SP3-106

Folder tree building done
Location bit shift done
This commit is contained in:
Xiao Qi 2022-09-13 11:27:51 +08:00
parent 9a223098f6
commit 47f716f72b
2 changed files with 94 additions and 22 deletions

View File

@ -1,15 +1,19 @@
#include "SHpch.h"
#include "SHFileSystem.h" #include "SHFileSystem.h"
#include "fileapi.h" #include "fileapi.h"
#include <filesystem>
#include <cassert> #include <cassert>
#include <queue>
namespace SHADE namespace SHADE
{ {
char const FOLDER_MAX_COUNT {15}; char const FOLDER_MAX_COUNT {15};
std::unordered_map<FolderLocation, std::unique_ptr<SHFolder>> SHFileSystem::folders; std::unordered_map<FolderLocation, std::unique_ptr<SHFolder>> SHFileSystem::folders;
FolderPointer SHFileSystem::root {nullptr};
SHFolder::SHFolder(FolderHandle id, FolderName name) SHFolder::SHFolder(FolderHandle id, FolderName name)
:id{id}, name{name}, subFolders(0) :id{ id }, name{ name }, subFolders(0), folded{ false }, path{""}
{ {
} }
@ -22,54 +26,110 @@ namespace SHADE
folders[0] = std::make_unique<SHFolder>(0, "root"); folders[0] = std::make_unique<SHFolder>(0, "root");
} }
FolderCounter const count = static_cast<FolderCounter>(folders[here]->subFolders.size()); auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n"); assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n");
FolderHandle const location = static_cast<FolderLocation>(count); auto const location = static_cast<FolderLocation>(count);
CreateFolderHelper(folders[0]->path, here, location, name); CreateFolder(folders[0]->path, here, location, name);
return location; return location;
} }
assert(folders.contains(here), "Folder creation location does not exist/invalid\n"); assert(folders.contains(here), "Folder creation location does not exist/invalid\n");
FolderCounter const count = static_cast<FolderCounter>(folders[here]->subFolders.size()); auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
FolderHandle location = here; FolderHandle location = here;
location <<= 4; location <<= FOLDER_BIT_ALLOCATE;
location |= count; location |= count;
assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n"); assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n");
CreateFolderHelper(folders[0]->path, here, location, name); CreateFolder(folders[0]->path, here, location, name);
return location; return location;
} }
bool SHFileSystem::DeleteFolder(FolderLocation location) noexcept bool SHFileSystem::DeleteFolder(FolderPointer location) noexcept
{ {
assert(folders.contains(location), "Delete target does not exist/invalid.\n"); assert(folders.contains(location->id), "Delete target does not exist/invalid.\n");
for (auto const& subFolder : folders[location]->subFolders) for (auto const& subFolder : folders[location->id]->subFolders)
{ {
DeleteFolder(subFolder); DeleteFolder(subFolder);
} }
RemoveDirectoryA(folders[location]->path.string().c_str()); RemoveDirectoryA(folders[location->id]->path.c_str());
return true; return true;
} }
bool SHFileSystem::CreateFolderHelper(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept void SHFileSystem::StartupFillDirectories(FolderPath path) noexcept
{
std::queue<FolderPointer> folderQueue;
folderQueue.push(RegisterFolder(path, 0, 0, "Root"));
while (!folderQueue.empty())
{
auto folder = folderQueue.front();
folderQueue.pop();
FolderCounter count = 0;
for (auto const& dirEntry : std::filesystem::directory_iterator(folder->path))
{
if (!dirEntry.is_directory())
{
continue;
}
FolderLocation location = folder->id;
location <<= FOLDER_BIT_ALLOCATE;
location |= ++count;
std::string name = dirEntry.path().string();
name = name.substr(name.find_last_of('/') + 1, name.length() - name.find_last_of('/'));
FolderPointer newFolder{ RegisterFolder(
dirEntry.path().string(),
folder->id,
location,
name)
};
folderQueue.push(newFolder);
folder->subFolders.push_back(newFolder);
}
}
}
FolderPointer SHFileSystem::CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept
{ {
assert( assert(
CreateDirectoryA(path.string().c_str(), nullptr), CreateDirectoryA(path.c_str(), nullptr),
"Failed to create folder\n" "Failed to create folder\n"
); );
folders[location] = std::make_unique<SHFolder>(location, name); folders[location] = std::make_unique<SHFolder>(location, name);
folders[parent]->subFolders.push_back(location); folders[location]->path = path;
folders[parent]->subFolders.push_back(folders[location].get());
return true; return FolderMakeHelper(path, parent, location, name);
}
FolderPointer SHFileSystem::RegisterFolder(FolderPath path, FolderLocation parent, FolderHandle location,
FolderName name) noexcept
{
return FolderMakeHelper(path, parent, location, name);
}
FolderPointer SHFileSystem::FolderMakeHelper(FolderPath path, FolderLocation parent, FolderHandle location,
FolderName name) noexcept
{
folders[location] = std::make_unique<SHFolder>(location, name);
folders[location]->path = path;
folders[parent]->subFolders.push_back(folders[location].get());
return folders[location].get();
} }
} }

View File

@ -3,17 +3,21 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <memory> #include <memory>
#include <filesystem>
#include <unordered_map> #include <unordered_map>
namespace SHADE namespace SHADE
{ {
class SHFolder;
typedef unsigned char FolderCounter; typedef unsigned char FolderCounter;
typedef unsigned char FileCounter; typedef unsigned char FileCounter;
typedef uint32_t FolderLocation; typedef uint64_t FolderLocation;
typedef uint32_t FolderHandle; typedef uint64_t FolderHandle;
typedef std::string FolderName; typedef std::string FolderName;
typedef std::filesystem::path FolderPath; typedef std::string FolderPath;
typedef SHFolder* FolderPointer;
constexpr char FOLDER_BIT_ALLOCATE{ 4 };
constexpr char FOLDER_MAX_DEPTH{ 26 };
class SHFolder class SHFolder
{ {
@ -22,7 +26,9 @@ namespace SHADE
FolderHandle id; FolderHandle id;
FolderName name; FolderName name;
std::vector<FolderHandle> subFolders; std::vector<FolderPointer> subFolders;
bool folded;
private: private:
FolderPath path; FolderPath path;
@ -34,11 +40,17 @@ namespace SHADE
public: public:
static FolderLocation CreateNewFolderHere(FolderName name, FolderLocation here = 0) noexcept; static FolderLocation CreateNewFolderHere(FolderName name, FolderLocation here = 0) noexcept;
static bool DeleteFolder(FolderLocation location) noexcept; static bool DeleteFolder(FolderPointer location) noexcept;
static void StartupFillDirectories(FolderPath path) noexcept;
private: private:
static FolderPointer root;
static std::unordered_map<FolderLocation, std::unique_ptr<SHFolder>> folders; static std::unordered_map<FolderLocation, std::unique_ptr<SHFolder>> folders;
static bool CreateFolderHelper(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept; static FolderPointer CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept;
static FolderPointer RegisterFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept;
static FolderPointer FolderMakeHelper(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept;
}; };
} }