diff --git a/SHADE_Engine/SHADE_Engine.vcxproj b/SHADE_Engine/SHADE_Engine.vcxproj index 50bcc7eb..178b98f7 100644 --- a/SHADE_Engine/SHADE_Engine.vcxproj +++ b/SHADE_Engine/SHADE_Engine.vcxproj @@ -116,6 +116,7 @@ + @@ -199,6 +200,7 @@ + diff --git a/SHADE_Engine/SHADE_Engine.vcxproj.filters b/SHADE_Engine/SHADE_Engine.vcxproj.filters index 7752c7fb..c28e339e 100644 --- a/SHADE_Engine/SHADE_Engine.vcxproj.filters +++ b/SHADE_Engine/SHADE_Engine.vcxproj.filters @@ -19,6 +19,9 @@ {B3E3FAFD-9FDD-2350-884A-BA6074E389BC} + + {8A8E2B37-7646-6D84-DF4D-46E0CB240875} + {1653CE33-0220-293F-2B39-17E717655ECD} @@ -156,6 +159,9 @@ Engine + + Filesystem + Graphics\Buffers @@ -407,6 +413,9 @@ Engine + + Filesystem + Graphics\Buffers diff --git a/SHADE_Engine/src/Filesystem/SHFileSystem.cpp b/SHADE_Engine/src/Filesystem/SHFileSystem.cpp new file mode 100644 index 00000000..5663dadd --- /dev/null +++ b/SHADE_Engine/src/Filesystem/SHFileSystem.cpp @@ -0,0 +1,135 @@ +#include "SHpch.h" +#include "SHFileSystem.h" +#include "fileapi.h" +#include +#include +#include + +namespace SHADE +{ + char const FOLDER_MAX_COUNT {15}; + + std::unordered_map> SHFileSystem::folders; + FolderPointer SHFileSystem::root {nullptr}; + + SHFolder::SHFolder(FolderHandle id, FolderName name) + :id{ id }, name{ name }, subFolders(0), folded{ false }, path{""} + { + } + + FolderLocation SHFileSystem::CreateNewFolderHere(FolderName name, FolderLocation here) noexcept + { + if (here == 0) + { + if (!folders.contains(0)) + { + folders[0] = std::make_unique(0, "root"); + } + + auto const count = static_cast(folders[here]->subFolders.size()); + + assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n"); + + auto const location = static_cast(count); + + CreateFolder(folders[0]->path, here, location, name); + + return location; + } + + assert(folders.contains(here), "Folder creation location does not exist/invalid\n"); + + auto const count = static_cast(folders[here]->subFolders.size()); + + FolderHandle location = here; + location <<= FOLDER_BIT_ALLOCATE; + location |= count; + + assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n"); + CreateFolder(folders[0]->path, here, location, name); + + return location; + } + + bool SHFileSystem::DeleteFolder(FolderPointer location) noexcept + { + assert(folders.contains(location->id), "Delete target does not exist/invalid.\n"); + + for (auto const& subFolder : folders[location->id]->subFolders) + { + DeleteFolder(subFolder); + } + + RemoveDirectoryA(folders[location->id]->path.c_str()); + return true; + } + + void SHFileSystem::StartupFillDirectories(FolderPath path) noexcept + { + std::queue 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( + CreateDirectoryA(path.c_str(), nullptr), + "Failed to create folder\n" + ); + + folders[location] = std::make_unique(location, name); + folders[location]->path = path; + folders[parent]->subFolders.push_back(folders[location].get()); + + 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(location, name); + folders[location]->path = path; + folders[parent]->subFolders.push_back(folders[location].get()); + + return folders[location].get(); + } +} diff --git a/SHADE_Engine/src/Filesystem/SHFileSystem.h b/SHADE_Engine/src/Filesystem/SHFileSystem.h new file mode 100644 index 00000000..9b8b94a2 --- /dev/null +++ b/SHADE_Engine/src/Filesystem/SHFileSystem.h @@ -0,0 +1,57 @@ +#pragma once + +#include +#include +#include +#include + +namespace SHADE +{ + class SHFolder; + + typedef unsigned char FolderCounter; + typedef unsigned char FileCounter; + typedef uint64_t FolderLocation; + typedef uint64_t FolderHandle; + typedef std::string FolderName; + typedef std::string FolderPath; + typedef SHFolder* FolderPointer; + + constexpr char FOLDER_BIT_ALLOCATE{ 4 }; + constexpr char FOLDER_MAX_DEPTH{ 16 }; + + class SHFolder + { + public: + SHFolder(FolderHandle id, FolderName name); + + FolderHandle id; + FolderName name; + std::vector subFolders; + + bool folded; + + private: + FolderPath path; + friend class SHFileSystem; + }; + + class SHFileSystem + { + public: + static FolderLocation CreateNewFolderHere(FolderName name, FolderLocation here = 0) noexcept; + + static bool DeleteFolder(FolderPointer location) noexcept; + + static void StartupFillDirectories(FolderPath path) noexcept; + + private: + static FolderPointer root; + + static std::unordered_map> folders; + + 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; + }; +} \ No newline at end of file