From 017cbf90c5497b5b01644b1cfdcd70c7c709b79a Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Fri, 28 Oct 2022 19:07:48 +0800 Subject: [PATCH 01/10] Changed filesystem interface in preparation for asset browser functionalities --- SHADE_Engine/src/Assets/SHAsset.h | 1 - SHADE_Engine/src/Assets/SHAssetManager.cpp | 14 +- SHADE_Engine/src/Assets/SHAssetManager.h | 2 +- SHADE_Engine/src/Filesystem/SHFileSystem.cpp | 128 +++---------------- SHADE_Engine/src/Filesystem/SHFileSystem.h | 71 +++------- SHADE_Engine/src/Filesystem/SHFolder.h | 58 +++++++++ 6 files changed, 99 insertions(+), 175 deletions(-) create mode 100644 SHADE_Engine/src/Filesystem/SHFolder.h diff --git a/SHADE_Engine/src/Assets/SHAsset.h b/SHADE_Engine/src/Assets/SHAsset.h index 86e8a722..e8a0d629 100644 --- a/SHADE_Engine/src/Assets/SHAsset.h +++ b/SHADE_Engine/src/Assets/SHAsset.h @@ -23,6 +23,5 @@ namespace SHADE AssetID id; AssetType type; AssetPath path; - FolderLocation location; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 228f3fdc..61ee09c4 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -12,7 +12,6 @@ #include #include "SHAssetManager.h" #include "SHAssetMetaHandler.h" -#include "Filesystem/SHFileSystem.h" #include "Libraries/Loaders/SHMeshLoader.h" #include "Libraries/Loaders/SHTextureLoader.h" @@ -178,8 +177,7 @@ namespace SHADE name, id, type, - GenerateNewPath(name, type), - 0 + GenerateNewPath(name, type) ); return id; } @@ -250,8 +248,7 @@ namespace SHADE { SHAsset newAsset { - .name = path.stem().string(), - .location = 0 + .name = path.stem().string() }; auto const ext{ path.extension().string() }; @@ -289,7 +286,6 @@ namespace SHADE result.type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string()); result.id = GenerateAssetID(result.type); result.path = path; - result.location = 0; return result; } @@ -316,8 +312,7 @@ namespace SHADE { SHAsset newAsset { - .name = path.stem().string(), - .location = 0 + .name = path.stem().string() }; auto const ext{ path.extension().string() }; @@ -342,8 +337,7 @@ namespace SHADE for (auto const& mesh : meshes) { SHAsset meshAsset{ - .name = mesh->header.name, - .location = 0 + .name = mesh->header.name }; meshAsset.path = SHMeshCompiler::CompileMeshBinary(*mesh, path).value(); meshAsset.id = GenerateAssetID(AssetType::MESH); diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index bc6f8878..aa08ab9c 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -13,7 +13,7 @@ #include "SHAsset.h" #include "Asset Types/SHAssetData.h" #include "Assets/Libraries/Loaders/SHAssetLoader.h" -#include +#include "Filesystem/SHFileSystem.h" #include "SH_API.h" diff --git a/SHADE_Engine/src/Filesystem/SHFileSystem.cpp b/SHADE_Engine/src/Filesystem/SHFileSystem.cpp index bd34ed71..8e3432ad 100644 --- a/SHADE_Engine/src/Filesystem/SHFileSystem.cpp +++ b/SHADE_Engine/src/Filesystem/SHFileSystem.cpp @@ -6,81 +6,39 @@ 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{""} + SHFolder::SHFolder(FolderName name) + :name{ name }, subFolders(0), folded{ false }, path{""} { } - FolderLocation SHFileSystem::CreateNewFolderHere(FolderName name, FolderLocation here) noexcept + FolderPointer SHFileSystem::CreateNewFolderHere(FolderPointer parent, FolderName name) noexcept { - if (here == 0) - { - if (!folders.contains(0)) - { - folders[0] = std::make_unique(0, "root"); - } + for (auto const& folder : parent->subFolders) + { + if (name == folder->name) + { + SHLOG_ERROR("Unable to create subfolder {} at {} as it already exists", name, folder->name); + return nullptr; + } + } - auto const count = static_cast(folders[here]->subFolders.size()); - - if (count >= FOLDER_MAX_COUNT) - { - SHLOG_ERROR("Max subfolder reached: {}\n", name); - } + auto result = new SHFolder(name); + parent->subFolders.push_back(result); - auto const location = static_cast(count); - - CreateFolder(folders[0]->path, here, location, name); - - return location; - } - - if (!folders.contains(here)) - { - SHLOG_ERROR("Folder creation location does not exist/invalid: {}\n", here); - } - - auto const count = static_cast(folders[here]->subFolders.size()); - - FolderHandle location = here; - location <<= FOLDER_BIT_ALLOCATE; - location |= count; - - if (count >= FOLDER_MAX_COUNT) - { - SHLOG_ERROR("Max subfolder reached: {}\n", name); - } - - CreateFolder(folders[0]->path, here, location, name); - - return location; + return result; } bool SHFileSystem::DeleteFolder(FolderPointer location) noexcept { - if (!folders.contains(location->id)) - { - SHLOG_ERROR("Delete target does not exist/invalid: {}\n", location->name); - } - - for (auto const& subFolder : folders[location->id]->subFolders) - { - DeleteFolder(subFolder); - } - - RemoveDirectoryA(folders[location->id]->path.c_str()); + //TODO IMPLEMENT return true; } - void SHFileSystem::StartupFillDirectories(FolderPath path) noexcept + FolderPointer SHFileSystem::BuildDirectory(FolderPath path) noexcept { std::queue folderQueue; - - folderQueue.push(RegisterFolder(path, 0, 0, "Root")); + auto result = new SHFolder("root"); + folderQueue.push(result); while (!folderQueue.empty()) { @@ -101,59 +59,15 @@ namespace SHADE continue; } - FolderLocation location = folder->id; - location <<= FOLDER_BIT_ALLOCATE; - location |= ++count; + std::string name = dirEntry.path().stem().string(); - 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) - }; + FolderPointer newFolder{ new SHFolder(name) }; folderQueue.push(newFolder); folder->subFolders.push_back(newFolder); } } - } - FolderPointer SHFileSystem::GetRoot() noexcept - { - return root; - } - - FolderPointer SHFileSystem::CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept - { - - if (!CreateDirectoryA(path.c_str(), nullptr)) - { - SHLOG_ERROR("Failed to create folder: {}\n", path); - } - - 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(); + return result; } } diff --git a/SHADE_Engine/src/Filesystem/SHFileSystem.h b/SHADE_Engine/src/Filesystem/SHFileSystem.h index 8df794fd..b4f0b0a7 100644 --- a/SHADE_Engine/src/Filesystem/SHFileSystem.h +++ b/SHADE_Engine/src/Filesystem/SHFileSystem.h @@ -1,70 +1,29 @@ +/****************************************************************************** + * \file SHFileSystem.h + * \author Loh Xiao Qi + * \date 28 October 2022 + * \brief + * + * \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction + * or disclosure of this file or its contents without the prior + * written consent of Digipen Institute of Technology is prohibited. + ******************************************************************************/ #pragma once -#include -#include -#include -#include +#include "SHFolder.h" 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 FileName; - typedef std::string FolderPath; - typedef std::string FilePath; - typedef std::string FileExt; - typedef SHFolder* FolderPointer; - - constexpr char FOLDER_BIT_ALLOCATE{ 4 }; - constexpr char FOLDER_MAX_DEPTH{ 16 }; - - struct SHFile - { - FileName name; - FilePath path; - FileExt ext; - }; - - class SHFolder - { - public: - SHFolder(FolderHandle id, FolderName name); - - FolderHandle id; - FolderName name; - std::vector subFolders; - std::vector files; - - 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; - - static FolderPointer GetRoot() noexcept; + static FolderPointer BuildDirectory(FolderPath path) noexcept; private: - static FolderPointer root; + static FolderPointer CreateNewFolderHere(FolderPointer parent, FolderName name) noexcept; + static bool DeleteFolder(FolderPointer location) noexcept; - 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; + friend class SHFolder; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Filesystem/SHFolder.h b/SHADE_Engine/src/Filesystem/SHFolder.h new file mode 100644 index 00000000..86cdc008 --- /dev/null +++ b/SHADE_Engine/src/Filesystem/SHFolder.h @@ -0,0 +1,58 @@ +/****************************************************************************** + * \file SHFolder.h + * \author Loh Xiao Qi + * \date 28 October 2022 + * \brief + * + * \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction + * or disclosure of this file or its contents without the prior + * written consent of Digipen Institute of Technology is prohibited. + ******************************************************************************/ +#pragma once + +#include +#include +#include "Assets/SHAssetMacros.h" + +namespace SHADE +{ + class SHFolder; + + typedef unsigned char FolderCounter; + typedef unsigned char FileCounter; + typedef std::string FolderName; + typedef std::string FileName; + typedef std::string FolderPath; + typedef std::string FilePath; + typedef std::string FileExt; + typedef SHFolder* FolderPointer; + + // Forward Declare + class SHFileSystem; + + struct SHFile + { + FileName name; + FilePath path; + FileExt ext; + + }; + + class SHFolder + { + public: + SHFolder(FolderName name); + + FolderName name; + std::vector subFolders; + std::vector files; + + bool folded; + + FolderPointer CreateSubFolderHere(FolderName name); + + private: + FolderPath path; + friend class SHFileSystem; + }; +} From 6ce143665a5a5e9faadd0e93c492f2dda015684f Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Fri, 28 Oct 2022 20:48:50 +0800 Subject: [PATCH 02/10] Added scene and prefab asset classes Added scene and prefab text based loaders Added write functions to all asset loaders to overwrite data --- .../src/Assets/Asset Types/SHPrefabAsset.h | 23 ++++ .../src/Assets/Asset Types/SHSceneAsset.h | 23 ++++ .../Assets/Libraries/Loaders/SHAssetLoader.h | 1 + .../Assets/Libraries/Loaders/SHMeshLoader.cpp | 52 +++++++++ .../Assets/Libraries/Loaders/SHMeshLoader.h | 2 +- .../Loaders/SHShaderSourceLoader.cpp | 23 ++++ .../Libraries/Loaders/SHShaderSourceLoader.h | 2 +- .../Libraries/Loaders/SHTextBasedLoader.cpp | 82 +++++++++++++ .../Libraries/Loaders/SHTextBasedLoader.h | 21 ++++ .../Libraries/Loaders/SHTextureLoader.cpp | 110 +++++++++++++----- .../Libraries/Loaders/SHTextureLoader.h | 3 +- SHADE_Engine/src/Assets/SHAssetMacros.h | 2 + SHADE_Engine/src/Assets/SHAssetManager.cpp | 5 +- SHADE_Engine/src/Assets/SHAssetManager.h | 5 +- SHADE_Engine/src/Assets/SHAssetManager.hpp | 27 ++++- 15 files changed, 343 insertions(+), 38 deletions(-) create mode 100644 SHADE_Engine/src/Assets/Asset Types/SHPrefabAsset.h create mode 100644 SHADE_Engine/src/Assets/Asset Types/SHSceneAsset.h create mode 100644 SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.cpp create mode 100644 SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.h diff --git a/SHADE_Engine/src/Assets/Asset Types/SHPrefabAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHPrefabAsset.h new file mode 100644 index 00000000..0db299b2 --- /dev/null +++ b/SHADE_Engine/src/Assets/Asset Types/SHPrefabAsset.h @@ -0,0 +1,23 @@ +/****************************************************************************** + * \file SHPrefabAsset.h + * \author Loh Xiao Qi + * \date 28 October 2022 + * \brief + * + * \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction + * or disclosure of this file or its contents without the prior + * written consent of Digipen Institute of Technology is prohibited. + ******************************************************************************/ +#pragma once + +#include "SHAssetData.h" +#include + +namespace SHADE +{ + struct SHPrefabAsset : SHAssetData + { + std::string name; + std::string data; + }; +} diff --git a/SHADE_Engine/src/Assets/Asset Types/SHSceneAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHSceneAsset.h new file mode 100644 index 00000000..0f7061b1 --- /dev/null +++ b/SHADE_Engine/src/Assets/Asset Types/SHSceneAsset.h @@ -0,0 +1,23 @@ +/****************************************************************************** + * \file SHSceneAsset.h + * \author Loh Xiao Qi + * \date 28 October 2022 + * \brief + * + * \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction + * or disclosure of this file or its contents without the prior + * written consent of Digipen Institute of Technology is prohibited. + ******************************************************************************/ +#pragma once + +#include "SHAssetData.h" +#include + +namespace SHADE +{ + struct SHSceneAsset : SHAssetData + { + std::string name; + std::string data; + }; +} diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHAssetLoader.h b/SHADE_Engine/src/Assets/Libraries/Loaders/SHAssetLoader.h index 63e081af..b6b7656b 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHAssetLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHAssetLoader.h @@ -18,5 +18,6 @@ namespace SHADE struct SHAssetLoader { virtual SHAssetData* Load(AssetPath path) = 0; + virtual void Write(SHAssetData const* data, AssetPath path) = 0; }; } diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHMeshLoader.cpp b/SHADE_Engine/src/Assets/Libraries/Loaders/SHMeshLoader.cpp index 90dd58d4..52134440 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHMeshLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHMeshLoader.cpp @@ -22,6 +22,7 @@ namespace SHADE if (!file.is_open()) { SHLOG_ERROR("Unable to open SHMesh File: {}", path.string()); + return; } const std::string name{ path.stem().string() }; @@ -75,4 +76,55 @@ namespace SHADE return result; } + + void SHMeshLoader::Write(SHAssetData const* data, AssetPath path) + { + std::ofstream file{ path, std::ios::out | std::ios::binary | std::ios::trunc }; + if (!file.is_open()) + { + SHLOG_ERROR("Unable to open file for writing mesh file: {}", path.string()); + } + + auto asset = *dynamic_cast(data); + + file.write( + reinterpret_cast(&(asset.header.vertexCount)), + sizeof(uint32_t) + ); + + file.write( + reinterpret_cast(&(asset.header.indexCount)), + sizeof(uint32_t) + ); + + auto const vertexVec3Byte{ sizeof(SHVec3) * asset.header.vertexCount }; + auto const vertexVec2Byte{ sizeof(SHVec2) * asset.header.vertexCount }; + + file.write( + reinterpret_cast(asset.vertexPosition.data()), + vertexVec3Byte + ); + + file.write( + reinterpret_cast(asset.vertexTangent.data()), + vertexVec3Byte + ); + + file.write( + reinterpret_cast(asset.vertexNormal.data()), + vertexVec3Byte + ); + + file.write( + reinterpret_cast(asset.texCoords.data()), + vertexVec2Byte + ); + + file.write( + reinterpret_cast(asset.indices.data()), + sizeof(uint32_t) * asset.header.indexCount + ); + + file.close(); + } } diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHMeshLoader.h b/SHADE_Engine/src/Assets/Libraries/Loaders/SHMeshLoader.h index bf65851a..03a111ce 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHMeshLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHMeshLoader.h @@ -10,7 +10,6 @@ * of DigiPen Institute of Technology is prohibited. *****************************************************************************/ #pragma once -#include "Assets/SHAssetMacros.h" #include "Assets/Asset Types/SHMeshAsset.h" #include "SHAssetLoader.h" @@ -20,5 +19,6 @@ namespace SHADE { void LoadSHMesh(AssetPath path, SHMeshAsset& meshes) noexcept; SHAssetData* Load(AssetPath path) override; + void Write(SHAssetData const* data, AssetPath path) override; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHShaderSourceLoader.cpp b/SHADE_Engine/src/Assets/Libraries/Loaders/SHShaderSourceLoader.cpp index 824995d6..f0d9a29b 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHShaderSourceLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHShaderSourceLoader.cpp @@ -43,4 +43,27 @@ namespace SHADE return result; } + + void SHShaderSourceLoader::Write(SHAssetData const* data, AssetPath path) + { + std::ofstream file{ path, std::ios::binary | std::ios::out | std::ios::trunc }; + + auto asset = *dynamic_cast(data); + + file.write( + reinterpret_cast(&asset.shaderType), sizeof(uint8_t) + ); + + size_t const byteCount = sizeof(uint32_t) * asset.spirvBinary.size(); + + file.write( + reinterpret_cast(&byteCount), sizeof(size_t) + ); + + file.write( + reinterpret_cast(asset.spirvBinary.data()), byteCount + ); + + file.close(); + } } diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHShaderSourceLoader.h b/SHADE_Engine/src/Assets/Libraries/Loaders/SHShaderSourceLoader.h index befdade5..0a4b614f 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHShaderSourceLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHShaderSourceLoader.h @@ -11,12 +11,12 @@ #pragma once #include "Assets/Libraries/Loaders/SHAssetLoader.h" -#include "Assets/SHAssetMacros.h" namespace SHADE { struct SHShaderSourceLoader : SHAssetLoader { SHAssetData* Load(AssetPath path) override; + void Write(SHAssetData const* data, AssetPath path) override; }; } diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.cpp b/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.cpp new file mode 100644 index 00000000..60ea80f6 --- /dev/null +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.cpp @@ -0,0 +1,82 @@ +/****************************************************************************** + * \file SHTextBasedLoader.cpp + * \author Loh Xiao Qi + * \date 28 October 2022 + * \brief + * + * \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction + * or disclosure of this file or its contents without the prior + * written consent of Digipen Institute of Technology is prohibited. + ******************************************************************************/ +#include "SHpch.h" +#include "SHTextBasedLoader.h" + +#include "Assets/Asset Types/SHSceneAsset.h" +#include "Assets/Asset Types/SHPrefabAsset.h" + +#include +#include + +namespace SHADE +{ + SHAssetData* SHTextBasedLoader::Load(AssetPath path) + { + std::ifstream file{ path, std::ios::in }; + + if (!file.is_open()) + { + SHLOG_ERROR("Unable to open text File: {}", path.string()); + return nullptr; + } + std::stringstream stream; + + stream << file.rdbuf(); + + std::string content = stream.str(); + + SHAssetData* result; + + if (path.extension().string() == SCENE_EXTENSION) + { + auto data = new SHSceneAsset(); + data->name = path.stem().string(); + data->data = std::move(content); + result = data; + } + else if (path.extension().string() == PREFAB_EXTENSION) + { + auto data = new SHPrefabAsset(); + data->name = path.stem().string(); + data->data = std::move(content); + result = data; + } + + file.close(); + + return result; + } + + void SHTextBasedLoader::Write(SHAssetData const* data, AssetPath path) + { + std::ofstream file{ path, std::ios::out | std::ios::trunc }; + + if (!file.is_open()) + { + SHLOG_ERROR("Unable to open text File: {}", path.string()); + return; + } + + if (path.extension().string() == SCENE_EXTENSION) + { + auto scene = dynamic_cast(data); + file << scene->data; + } + else if (path.extension().string() == PREFAB_EXTENSION) + { + auto prefab = dynamic_cast(data); + file << prefab->data; + } + + file.close(); + } +} diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.h b/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.h new file mode 100644 index 00000000..80771058 --- /dev/null +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.h @@ -0,0 +1,21 @@ +/****************************************************************************** + * \file Header.h + * \author Loh Xiao Qi + * \date 28 October 2022 + * \brief + * + * \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction + * or disclosure of this file or its contents without the prior + * written consent of Digipen Institute of Technology is prohibited. + ******************************************************************************/ +#pragma once +#include "SHAssetLoader.h" + +namespace SHADE +{ + struct SHTextBasedLoader : SHAssetLoader + { + SHAssetData* Load(AssetPath path) override; + void Write(SHAssetData const* data, AssetPath path) override; + }; +} diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextureLoader.cpp b/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextureLoader.cpp index 74c08230..423301dd 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextureLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextureLoader.cpp @@ -17,42 +17,94 @@ namespace SHADE { - void SHTextureLoader::LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept - { - std::ifstream file{ path.string(), std::ios::in | std::ios::binary }; - if (!file.is_open()) - { - SHLOG_ERROR("Error opening SHTexture file: {}", path.string()); - } + void SHTextureLoader::LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept + { + std::ifstream file{ path.string(), std::ios::in | std::ios::binary }; + if (!file.is_open()) + { + SHLOG_ERROR("Error opening SHTexture file: {}", path.string()); + } - auto const intBytes{ sizeof(uint32_t) }; - uint32_t mipCount; + auto const intBytes{ sizeof(uint32_t) }; + uint32_t mipCount; - file.read(reinterpret_cast(&asset.numBytes), intBytes); - file.read(reinterpret_cast(&asset.width), intBytes); - file.read(reinterpret_cast(&asset.height), intBytes); - file.read(reinterpret_cast(&asset.format), sizeof(SHTexture::TextureFormat)); + file.read(reinterpret_cast(&asset.numBytes), intBytes); + file.read(reinterpret_cast(&asset.width), intBytes); + file.read(reinterpret_cast(&asset.height), intBytes); + file.read(reinterpret_cast(&asset.format), sizeof(SHTexture::TextureFormat)); - file.read(reinterpret_cast(&mipCount), intBytes); - std::vector mips(mipCount); - file.read(reinterpret_cast(mips.data()), intBytes * mipCount); + file.read(reinterpret_cast(&mipCount), intBytes); + std::vector mips(mipCount); + file.read(reinterpret_cast(mips.data()), intBytes * mipCount); - auto pixel = new SHTexture::PixelChannel[asset.numBytes]; - file.read(reinterpret_cast(pixel), asset.numBytes); + auto pixel = new SHTexture::PixelChannel[asset.numBytes]; + file.read(reinterpret_cast(pixel), asset.numBytes); - asset.mipOffsets = std::move(mips); - asset.pixelData = std::move(pixel); + asset.mipOffsets = std::move(mips); + asset.pixelData = std::move(pixel); - asset.compiled = true; - file.close(); - } + asset.compiled = true; + file.close(); + } - SHAssetData* SHTextureLoader::Load(AssetPath path) - { - auto result = new SHTextureAsset(); + SHAssetData* SHTextureLoader::Load(AssetPath path) + { + auto result = new SHTextureAsset(); - LoadSHTexture(path, *result); + LoadSHTexture(path, *result); - return result; - } + return result; + } + + void SHTextureLoader::Write(SHAssetData const* data, AssetPath path) + { + std::ofstream file{ path, std::ios::out | std::ios::binary }; + if (!file.is_open()) + { + SHLOG_ERROR("Unable to open file for writing texture file: {}", path.string()); + } + + auto asset = *dynamic_cast(data); + + constexpr auto intBytes{ sizeof(uint32_t) }; + + uint32_t const mipOffsetCount{ static_cast(asset.mipOffsets.size()) }; + + file.write( + reinterpret_cast(&asset.numBytes), + intBytes + ); + + file.write( + reinterpret_cast(&asset.width), + intBytes + ); + + file.write( + reinterpret_cast(&asset.height), + intBytes + ); + + file.write( + reinterpret_cast(&asset.format), + sizeof(SHTexture::TextureFormat) + ); + + file.write( + reinterpret_cast(&mipOffsetCount), + intBytes + ); + + file.write( + reinterpret_cast(asset.mipOffsets.data()), + intBytes * asset.mipOffsets.size() + ); + + file.write( + reinterpret_cast(asset.pixelData), + asset.numBytes + ); + + file.close(); + } } diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextureLoader.h b/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextureLoader.h index 00b060ec..27f7b844 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextureLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextureLoader.h @@ -10,8 +10,6 @@ * of DigiPen Institute of Technology is prohibited. *****************************************************************************/ #pragma once - -#include "Assets/SHAssetMacros.h" #include "Assets/Asset Types/SHTextureAsset.h" #include "SHAssetLoader.h" @@ -21,5 +19,6 @@ namespace SHADE { void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept; SHAssetData* Load(AssetPath path) override; + void Write(SHAssetData const* data, AssetPath path) override; }; } diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index 1df4e30b..ff154810 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -47,6 +47,8 @@ enum class AssetType : AssetTypeMeta SHADER_BUILT_IN, TEXTURE, MESH, + SCENE, + PREFAB, MAX_COUNT }; constexpr size_t TYPE_COUNT{ static_cast(AssetType::MAX_COUNT) }; diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 61ee09c4..06acf7de 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -16,6 +16,7 @@ #include "Libraries/Loaders/SHMeshLoader.h" #include "Libraries/Loaders/SHTextureLoader.h" #include "Libraries/Loaders/SHShaderSourceLoader.h" +#include "Libraries/Loaders/SHTextBasedLoader.h" #include "Libraries/Compilers/SHMeshCompiler.h" #include "Libraries/Compilers/SHTextureCompiler.h" @@ -353,12 +354,14 @@ namespace SHADE } } - void SHAssetManager::InitLoaders() noexcept + void SHAssetManager:: InitLoaders() noexcept { loaders[static_cast(AssetType::SHADER)] = dynamic_cast(new SHShaderSourceLoader()); loaders[static_cast(AssetType::SHADER_BUILT_IN)] = loaders[static_cast(AssetType::SHADER)]; loaders[static_cast(AssetType::TEXTURE)] = dynamic_cast(new SHTextureLoader()); loaders[static_cast(AssetType::MESH)] = dynamic_cast(new SHMeshLoader()); + loaders[static_cast(AssetType::SCENE)] = dynamic_cast(new SHTextBasedLoader()); + loaders[static_cast(AssetType::PREFAB)] = loaders[static_cast(AssetType::SCENE)]; } /**************************************************************************** diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index aa08ab9c..7521e356 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -78,7 +78,10 @@ namespace SHADE // -------------------------------------------------------------------------/ template - static std::enable_if_t, T const* const> GetData(AssetID id) noexcept; + static std::enable_if_t, T* const> GetData(AssetID id) noexcept; + + template + static std::enable_if_t, T const* const> GetConstData(AssetID id) noexcept; static std::vector GetAllDataOfType(AssetType type) noexcept; static std::vector GetAllRecordOfType(AssetType type) noexcept; diff --git a/SHADE_Engine/src/Assets/SHAssetManager.hpp b/SHADE_Engine/src/Assets/SHAssetManager.hpp index 6c420778..baf8a2f3 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.hpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.hpp @@ -4,7 +4,7 @@ namespace SHADE { template - std::enable_if_t, T const* const> SHAssetManager::GetData(AssetID id) noexcept + std::enable_if_t, T* const> SHAssetManager::GetData(AssetID id) noexcept { if (!assetData.contains(id)) { @@ -13,7 +13,7 @@ namespace SHADE if (asset.id == id) { assetData.emplace(id, LoadData(asset)); - return dynamic_cast(assetData[id]); + return dynamic_cast(assetData[id]); } } @@ -21,6 +21,27 @@ namespace SHADE return nullptr; } - return dynamic_cast(assetData[id]); + return dynamic_cast(assetData[id]); } + + template + std::enable_if_t, T const * const> SHAssetManager::GetConstData(AssetID id) noexcept + { + if (!assetData.contains(id)) + { + for (auto const& asset : assetCollection) + { + if (asset.id == id) + { + assetData.emplace(id, LoadData(asset)); + return dynamic_cast(assetData[id]); + } + } + + SHLOG_ERROR("Asset ID provided does not exist: {}", id); + return nullptr; + } + + return dynamic_cast(assetData[id]); + } } From 22b0a2f97b6740dcc45a0558896c3d280befa555 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Fri, 28 Oct 2022 21:20:59 +0800 Subject: [PATCH 03/10] Changed tabs/spacing --- SHADE_Engine/src/Assets/SHAssetManager.cpp | 184 ++++++++++----------- 1 file changed, 92 insertions(+), 92 deletions(-) diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 06acf7de..967f9a18 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -113,8 +113,8 @@ namespace SHADE { case AssetType::SHADER: case AssetType::SHADER_BUILT_IN: - folder = "Shaders/"; - break; + folder = "Shaders/"; + break; default: folder = "/"; @@ -172,16 +172,16 @@ namespace SHADE AssetID SHAssetManager::CreateAsset(AssetName name, AssetType type) noexcept { - AssetID id = GenerateAssetID(type); + AssetID id = GenerateAssetID(type); - assetCollection.emplace_back( - name, - id, - type, - GenerateNewPath(name, type) - ); - return id; - } + assetCollection.emplace_back( + name, + id, + type, + GenerateNewPath(name, type) + ); + return id; + } /**************************************************************************** * \brief Import new asset from outside editor window. * @@ -245,28 +245,28 @@ namespace SHADE return result; } - AssetID SHAssetManager::CompileAsset(AssetPath path) noexcept - { - SHAsset newAsset - { - .name = path.stem().string() - }; + AssetID SHAssetManager::CompileAsset(AssetPath path) noexcept + { + SHAsset newAsset + { + .name = path.stem().string() + }; - auto const ext{ path.extension().string() }; - if (ext == GLSL_EXTENSION.data()) - { - newAsset.path = SHShaderSourceCompiler::LoadAndCompileShader(path).value(); - newAsset.id = GenerateAssetID(AssetType::SHADER_BUILT_IN); - newAsset.type = AssetType::SHADER_BUILT_IN; - } + auto const ext{ path.extension().string() }; + if (ext == GLSL_EXTENSION.data()) + { + newAsset.path = SHShaderSourceCompiler::LoadAndCompileShader(path).value(); + newAsset.id = GenerateAssetID(AssetType::SHADER_BUILT_IN); + newAsset.type = AssetType::SHADER_BUILT_IN; + } - assetCollection.push_back(newAsset); - SHAssetMetaHandler::WriteMetaData(newAsset); + assetCollection.push_back(newAsset); + SHAssetMetaHandler::WriteMetaData(newAsset); - return newAsset.id; - } + return newAsset.id; + } - bool SHAssetManager::IsRecognised(char const* ext) noexcept + bool SHAssetManager::IsRecognised(char const* ext) noexcept { for (auto const& e : EXTENSIONS) { @@ -291,77 +291,77 @@ namespace SHADE return result; } - void SHAssetManager::CompileAll() noexcept - { - std::vector paths; + void SHAssetManager::CompileAll() noexcept + { + std::vector paths; - for (auto const& dir : std::filesystem::recursive_directory_iterator{ ASSET_ROOT }) - { - if (dir.is_regular_file()) - { - for (auto const& ext : EXTERNALS) - { - if (dir.path().extension().string() == ext.data()) - { - paths.push_back(dir.path()); - } - } - } - } + for (auto const& dir : std::filesystem::recursive_directory_iterator{ ASSET_ROOT }) + { + if (dir.is_regular_file()) + { + for (auto const& ext : EXTERNALS) + { + if (dir.path().extension().string() == ext.data()) + { + paths.push_back(dir.path()); + } + } + } + } - for (auto const& path : paths) - { - SHAsset newAsset - { - .name = path.stem().string() - }; + for (auto const& path : paths) + { + SHAsset newAsset + { + .name = path.stem().string() + }; - auto const ext{ path.extension().string() }; - if (ext == GLSL_EXTENSION.data()) - { - newAsset.path = SHShaderSourceCompiler::LoadAndCompileShader(path).value(); - newAsset.id = GenerateAssetID(AssetType::SHADER_BUILT_IN); - newAsset.type = AssetType::SHADER_BUILT_IN; - } - else if (ext == DDS_EXTENSION.data()) - { - newAsset.path = SHTextureCompiler::CompileTextureAsset(path).value(); - newAsset.id = GenerateAssetID(AssetType::TEXTURE); - newAsset.type = AssetType::TEXTURE; - } - else if (ext == GLTF_EXTENSION.data() || ext == FBX_EXTENSION.data()) - { - std::vector meshes; - std::vector anims; - SHMeshCompiler::LoadFromFile(path, meshes, anims); + auto const ext{ path.extension().string() }; + if (ext == GLSL_EXTENSION.data()) + { + newAsset.path = SHShaderSourceCompiler::LoadAndCompileShader(path).value(); + newAsset.id = GenerateAssetID(AssetType::SHADER_BUILT_IN); + newAsset.type = AssetType::SHADER_BUILT_IN; + } + else if (ext == DDS_EXTENSION.data()) + { + newAsset.path = SHTextureCompiler::CompileTextureAsset(path).value(); + newAsset.id = GenerateAssetID(AssetType::TEXTURE); + newAsset.type = AssetType::TEXTURE; + } + else if (ext == GLTF_EXTENSION.data() || ext == FBX_EXTENSION.data()) + { + std::vector meshes; + std::vector anims; + SHMeshCompiler::LoadFromFile(path, meshes, anims); - for (auto const& mesh : meshes) - { - SHAsset meshAsset{ - .name = mesh->header.name - }; - meshAsset.path = SHMeshCompiler::CompileMeshBinary(*mesh, path).value(); - meshAsset.id = GenerateAssetID(AssetType::MESH); - meshAsset.type = AssetType::MESH; - assetCollection.push_back(meshAsset); - SHAssetMetaHandler::WriteMetaData(meshAsset); - } - continue; - } + for (auto const& mesh : meshes) + { + SHAsset meshAsset{ + .name = mesh->header.name + }; + meshAsset.path = SHMeshCompiler::CompileMeshBinary(*mesh, path).value(); + meshAsset.id = GenerateAssetID(AssetType::MESH); + meshAsset.type = AssetType::MESH; + assetCollection.push_back(meshAsset); + SHAssetMetaHandler::WriteMetaData(meshAsset); + } + continue; + } - assetCollection.push_back(newAsset); - SHAssetMetaHandler::WriteMetaData(newAsset); - } - } + assetCollection.push_back(newAsset); + SHAssetMetaHandler::WriteMetaData(newAsset); + } + } - void SHAssetManager:: InitLoaders() noexcept + void SHAssetManager:: InitLoaders() noexcept { loaders[static_cast(AssetType::SHADER)] = dynamic_cast(new SHShaderSourceLoader()); loaders[static_cast(AssetType::SHADER_BUILT_IN)] = loaders[static_cast(AssetType::SHADER)]; - loaders[static_cast(AssetType::TEXTURE)] = dynamic_cast(new SHTextureLoader()); - loaders[static_cast(AssetType::MESH)] = dynamic_cast(new SHMeshLoader()); - loaders[static_cast(AssetType::SCENE)] = dynamic_cast(new SHTextBasedLoader()); - loaders[static_cast(AssetType::PREFAB)] = loaders[static_cast(AssetType::SCENE)]; + loaders[static_cast(AssetType::TEXTURE)] = dynamic_cast(new SHTextureLoader()); + loaders[static_cast(AssetType::MESH)] = dynamic_cast(new SHMeshLoader()); + loaders[static_cast(AssetType::SCENE)] = dynamic_cast(new SHTextBasedLoader()); + loaders[static_cast(AssetType::PREFAB)] = loaders[static_cast(AssetType::SCENE)]; } /**************************************************************************** @@ -369,7 +369,7 @@ namespace SHADE ****************************************************************************/ void SHAssetManager::Load() noexcept { - //CompileAll(); + //CompileAll(); InitLoaders(); BuildAssetCollection(); //LoadAllData(); From cd62dbbb2515771616c783078fa97994a9a778a4 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sat, 29 Oct 2022 11:58:14 +0800 Subject: [PATCH 04/10] Material WIP --- .../src/Assets/Libraries/Loaders/SHTextBasedLoader.cpp | 8 ++++++++ SHADE_Engine/src/Assets/SHAssetMacros.h | 1 + SHADE_Engine/src/Assets/SHAssetManager.cpp | 1 + 3 files changed, 10 insertions(+) diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.cpp b/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.cpp index 60ea80f6..0dca981e 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.cpp @@ -50,6 +50,10 @@ namespace SHADE data->data = std::move(content); result = data; } + else if (path.extension().string() == MATERIAL_EXTENSION) + { + auto data = //TODO make material class + } file.close(); @@ -76,6 +80,10 @@ namespace SHADE auto prefab = dynamic_cast(data); file << prefab->data; } + else if (path.extension().string() == MATERIAL_EXTENSION) + { + auto material = //todo + } file.close(); } diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index ff154810..91d8658a 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -49,6 +49,7 @@ enum class AssetType : AssetTypeMeta MESH, SCENE, PREFAB, + MATERIAL, MAX_COUNT }; constexpr size_t TYPE_COUNT{ static_cast(AssetType::MAX_COUNT) }; diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 967f9a18..7b75f508 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -362,6 +362,7 @@ namespace SHADE loaders[static_cast(AssetType::MESH)] = dynamic_cast(new SHMeshLoader()); loaders[static_cast(AssetType::SCENE)] = dynamic_cast(new SHTextBasedLoader()); loaders[static_cast(AssetType::PREFAB)] = loaders[static_cast(AssetType::SCENE)]; + loaders[static_cast(AssetType::MATERIAL)] = loaders[static_cast(AssetType::SCENE)]; } /**************************************************************************** From 0182c90a21e8e59904efb8b29e5b47a8a14860bd Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sat, 29 Oct 2022 14:42:38 +0800 Subject: [PATCH 05/10] Interface to create and save new assets that are internal: Prefabs, Scenes, Materials --- .../src/Assets/Asset Types/SHMaterialAsset.h | 23 +++++ .../Libraries/Loaders/SHTextBasedLoader.cpp | 9 +- SHADE_Engine/src/Assets/SHAssetMacros.h | 5 ++ SHADE_Engine/src/Assets/SHAssetManager.cpp | 86 +++++++++++++------ SHADE_Engine/src/Assets/SHAssetManager.h | 7 +- 5 files changed, 100 insertions(+), 30 deletions(-) create mode 100644 SHADE_Engine/src/Assets/Asset Types/SHMaterialAsset.h diff --git a/SHADE_Engine/src/Assets/Asset Types/SHMaterialAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHMaterialAsset.h new file mode 100644 index 00000000..a130fc07 --- /dev/null +++ b/SHADE_Engine/src/Assets/Asset Types/SHMaterialAsset.h @@ -0,0 +1,23 @@ +/****************************************************************************** + * \file SHMaterialAsset.h + * \author Loh Xiao Qi + * \date 29 October 2022 + * \brief + * + * \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction + * or disclosure of this file or its contents without the prior + * written consent of Digipen Institute of Technology is prohibited. + ******************************************************************************/ +#pragma once + +#include "Assets/Asset Types/SHAssetData.h" +#include + +namespace SHADE +{ + struct SHMaterialAsset : SHAssetData + { + std::string name; + std::string data; + }; +} diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.cpp b/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.cpp index 0dca981e..b23130f3 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.cpp @@ -13,6 +13,7 @@ #include "Assets/Asset Types/SHSceneAsset.h" #include "Assets/Asset Types/SHPrefabAsset.h" +#include "Assets/Asset Types/SHMaterialAsset.h" #include #include @@ -52,7 +53,10 @@ namespace SHADE } else if (path.extension().string() == MATERIAL_EXTENSION) { - auto data = //TODO make material class + auto data = new SHMaterialAsset(); + data->name = path.stem().string(); + data->data = std::move(content); + result = data; } file.close(); @@ -82,7 +86,8 @@ namespace SHADE } else if (path.extension().string() == MATERIAL_EXTENSION) { - auto material = //todo + auto material = dynamic_cast(data); + file << material->data; } file.close(); diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index 91d8658a..4489e807 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -61,6 +61,11 @@ constexpr std::string_view ASSET_ROOT {"Assets"}; constexpr std::string_view ASSET_ROOT {"../../Assets"}; #endif +// INTERNAL ASSET PATHS +constexpr std::string_view SCENE_FOLDER{ "/Scenes/" }; +constexpr std::string_view PREFAB_FOLDER{ "/Prefabs/" }; +constexpr std::string_view MATERIAL_FOLDER{ "/Materials/" }; + // ASSET EXTENSIONS constexpr std::string_view META_EXTENSION {".shmeta"}; diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 7b75f508..989da37b 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -148,40 +148,74 @@ namespace SHADE ****************************************************************************/ AssetID SHAssetManager::CreateNewAsset(AssetType type, AssetName name) noexcept { - AssetID id{ GenerateAssetID(type) }; - SHAsset meta; - meta.id = id; - meta.type = type; + std::string newPath{ ASSET_ROOT }; + switch (type) + { + case AssetType::PREFAB: + newPath += PREFAB_FOLDER; + break; - std::string folder; - //TODO implement folder choosing - //switch (type) - //{ - //default: - // folder = ""; - // break; - //} - AssetPath path{ std::string{ASSET_ROOT} + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) }; + case AssetType::SCENE: + newPath += SCENE_FOLDER; + break; - SHAssetMetaHandler::WriteMetaData(meta); + case AssetType::MATERIAL: + newPath += MATERIAL_FOLDER; + break; - assetCollection.push_back(meta); + default: + SHLOG_ERROR("Asset type of {} not an internal asset type, cannot be created", name); + return 0; + } + + auto id = GenerateAssetID(type); + + assetCollection.emplace_back( + name, + id, + type, + newPath + ); return id; } - AssetID SHAssetManager::CreateAsset(AssetName name, AssetType type) noexcept - { - AssetID id = GenerateAssetID(type); + void SHAssetManager::SaveAsset(AssetID id) noexcept + { + for (auto const& asset : assetCollection) + { + if (asset.id == id) + { + if ( + asset.type == AssetType::SCENE || + asset.type == AssetType::PREFAB || + asset.type == AssetType::MATERIAL + ) + { + auto const data = assetData[id]; + loaders[static_cast(asset.type)]->Write(data, asset.path); + return; + } + } + } + + SHLOG_WARNING("Asset id: {} not an internal asset type, save cannot be triggered", id); + } + + //AssetID SHAssetManager::CreateAsset(AssetName name, AssetType type) noexcept + //{ + // AssetID id = GenerateAssetID(type); + + // assetCollection.emplace_back( + // name, + // id, + // type, + // GenerateNewPath(name, type) + // ); + // return id; + //} + - assetCollection.emplace_back( - name, - id, - type, - GenerateNewPath(name, type) - ); - return id; - } /**************************************************************************** * \brief Import new asset from outside editor window. * diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index 7521e356..c5b9277e 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -59,8 +59,8 @@ namespace SHADE * \param name of resource * \return resource id generated for new asset ****************************************************************************/ - static AssetID CreateNewAsset(AssetType, AssetName) noexcept; - static AssetID CreateAsset(AssetName name, AssetType type) noexcept; + static AssetID CreateNewAsset(AssetType type, AssetName name) noexcept; + static void SaveAsset(AssetID id) noexcept; /**************************************************************************** * \brief Import new resource from outside editor window. @@ -101,6 +101,9 @@ namespace SHADE static void CompileAll() noexcept; + //TODO use this function to create asset data internall at all calls to generate id + //static AssetID CreateAsset(AssetName name, AssetType type) noexcept; + static FMOD::System* audioSystem; static std::unordered_map* audioSoundList; From 270205b0ba4a473d2444f59c990c2c4abcbbada1 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sat, 29 Oct 2022 14:50:44 +0800 Subject: [PATCH 06/10] Added line to write asset meta into file when saving Does check for data write before saving --- SHADE_Engine/src/Assets/SHAssetManager.cpp | 19 +++++++++++++++---- SHADE_Engine/src/Assets/SHAssetManager.h | 2 +- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 989da37b..90002b3d 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -180,7 +180,7 @@ namespace SHADE return id; } - void SHAssetManager::SaveAsset(AssetID id) noexcept + bool SHAssetManager::SaveAsset(AssetID id) noexcept { for (auto const& asset : assetCollection) { @@ -192,14 +192,25 @@ namespace SHADE asset.type == AssetType::MATERIAL ) { - auto const data = assetData[id]; - loaders[static_cast(asset.type)]->Write(data, asset.path); - return; + if (assetData.contains(id)) + { + auto const data = assetData.at(id); + loaders[static_cast(asset.type)]->Write(data, asset.path); + SHAssetMetaHandler::WriteMetaData(asset); + + return true; + } + + SHLOG_ERROR("Asset data has not been written into, cannot be saved: {}", + asset.path.filename().string()); + + return false; } } } SHLOG_WARNING("Asset id: {} not an internal asset type, save cannot be triggered", id); + return false; } //AssetID SHAssetManager::CreateAsset(AssetName name, AssetType type) noexcept diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index c5b9277e..28950646 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -60,7 +60,7 @@ namespace SHADE * \return resource id generated for new asset ****************************************************************************/ static AssetID CreateNewAsset(AssetType type, AssetName name) noexcept; - static void SaveAsset(AssetID id) noexcept; + static bool SaveAsset(AssetID id) noexcept; /**************************************************************************** * \brief Import new resource from outside editor window. From 219492dedd5c97a45a0cff0c7b8c5dc509f0c512 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sat, 29 Oct 2022 15:36:34 +0800 Subject: [PATCH 07/10] Changed asset collection from vector to unordered_map for better id col check Reduce use of for loops to iterate through asset collection --- SHADE_Engine/src/Assets/SHAssetManager.cpp | 91 ++++++++++++---------- SHADE_Engine/src/Assets/SHAssetManager.h | 4 +- SHADE_Engine/src/Assets/SHAssetManager.hpp | 4 +- 3 files changed, 56 insertions(+), 43 deletions(-) diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 90002b3d..78c94da7 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -10,6 +10,7 @@ #include "SHpch.h" #include #include +#include #include "SHAssetManager.h" #include "SHAssetMetaHandler.h" @@ -29,8 +30,9 @@ namespace SHADE std::vector SHAssetManager::loaders(TYPE_COUNT); - std::vector SHAssetManager::assetCollection; + std::unordered_map SHAssetManager::assetCollection; std::unordered_map SHAssetManager::assetData; + /**************************************************************************** * \brief Static function to generate asset ID. @@ -45,13 +47,7 @@ namespace SHADE result |= unique; - while (result == 0 || - std::ranges::any_of( - assetCollection.begin(), - assetCollection.end(), - [result](SHAsset const& asset) { return asset.id == result; } - ) - ) + while (result == 0 || assetCollection.contains(result)) { result = GenerateAssetID(type); } @@ -133,9 +129,17 @@ namespace SHADE * * \return const& to unordered_map ****************************************************************************/ - std::vector const& SHAssetManager::GetAllAssets() noexcept + std::vector SHAssetManager::GetAllAssets() noexcept { - return assetCollection; + std::vector result; + result.reserve(assetCollection.size()); + + for (auto const& asset : std::ranges::views::values(assetCollection)) + { + result.push_back(asset); + } + + return result; } /**************************************************************************** @@ -169,43 +173,50 @@ namespace SHADE } auto id = GenerateAssetID(type); - - assetCollection.emplace_back( + SHAsset asset{ name, id, type, newPath - ); + }; + + assetCollection.insert({ + id, + SHAsset( + name, + id, + type, + newPath + ) + }); return id; } bool SHAssetManager::SaveAsset(AssetID id) noexcept { - for (auto const& asset : assetCollection) + if (assetCollection.contains(id)) { - if (asset.id == id) + auto const& asset = assetCollection[id]; + if ( + asset.type == AssetType::SCENE || + asset.type == AssetType::PREFAB || + asset.type == AssetType::MATERIAL + ) { - if ( - asset.type == AssetType::SCENE || - asset.type == AssetType::PREFAB || - asset.type == AssetType::MATERIAL - ) + if (assetData.contains(id)) { - if (assetData.contains(id)) - { - auto const data = assetData.at(id); - loaders[static_cast(asset.type)]->Write(data, asset.path); - SHAssetMetaHandler::WriteMetaData(asset); + auto const data = assetData.at(id); + loaders[static_cast(asset.type)]->Write(data, asset.path); + SHAssetMetaHandler::WriteMetaData(asset); - return true; - } - - SHLOG_ERROR("Asset data has not been written into, cannot be saved: {}", - asset.path.filename().string()); - - return false; + return true; } + + SHLOG_ERROR("Asset data has not been written into, cannot be saved: {}", + asset.path.filename().string()); + + return false; } } @@ -249,7 +260,8 @@ namespace SHADE std::filesystem::copy(path, newPath); - assetCollection.push_back(CreateAssetFromPath(newPath)); + auto asset = CreateAssetFromPath(newPath); + assetCollection.insert({asset.id, asset}); return id; } @@ -279,7 +291,7 @@ namespace SHADE std::vector SHAssetManager::GetAllRecordOfType(AssetType type) noexcept { std::vector result; - for (auto const& asset : assetCollection) + for (auto const& asset : std::ranges::views::values(assetCollection)) { if (asset.type == type) { @@ -305,7 +317,7 @@ namespace SHADE newAsset.type = AssetType::SHADER_BUILT_IN; } - assetCollection.push_back(newAsset); + assetCollection.insert({ newAsset.id, newAsset }); SHAssetMetaHandler::WriteMetaData(newAsset); return newAsset.id; @@ -388,13 +400,13 @@ namespace SHADE meshAsset.path = SHMeshCompiler::CompileMeshBinary(*mesh, path).value(); meshAsset.id = GenerateAssetID(AssetType::MESH); meshAsset.type = AssetType::MESH; - assetCollection.push_back(meshAsset); + assetCollection.insert({ meshAsset.id, meshAsset }); SHAssetMetaHandler::WriteMetaData(meshAsset); } continue; } - assetCollection.push_back(newAsset); + assetCollection.insert({ newAsset.id, newAsset }); SHAssetMetaHandler::WriteMetaData(newAsset); } } @@ -426,7 +438,7 @@ namespace SHADE ****************************************************************************/ void SHAssetManager::LoadAllData() noexcept { - for (auto const& asset : assetCollection) + for (auto const& asset : std::ranges::views::values(assetCollection)) { SHAssetData* data = loaders[static_cast(asset.type)]->Load(asset.path); assetData.emplace(asset.id, data); @@ -457,7 +469,8 @@ namespace SHADE { if (dir.path().extension().string() == META_EXTENSION.data()) { - assetCollection.push_back(SHAssetMetaHandler::RetrieveMetaData(dir.path())); + auto asset = SHAssetMetaHandler::RetrieveMetaData(dir.path()); + assetCollection.insert({ asset.id, asset }); } } } diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index 28950646..fca38865 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -49,7 +49,7 @@ namespace SHADE * * \return const& to unordered_map ****************************************************************************/ - static std::vector const& GetAllAssets() noexcept; + static std::vector GetAllAssets() noexcept; /**************************************************************************** * \brief Create record for new resource. CAN ONLY CREATE FOR CUSTOM @@ -110,7 +110,7 @@ namespace SHADE static std::vector loaders; // For all resources - static std::vector assetCollection; + static std::unordered_map assetCollection; static std::unordered_map assetData; }; } diff --git a/SHADE_Engine/src/Assets/SHAssetManager.hpp b/SHADE_Engine/src/Assets/SHAssetManager.hpp index baf8a2f3..4f372938 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.hpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.hpp @@ -8,7 +8,7 @@ namespace SHADE { if (!assetData.contains(id)) { - for (auto const& asset : assetCollection) + for (auto const& asset : std::ranges::views::values(assetCollection)) { if (asset.id == id) { @@ -29,7 +29,7 @@ namespace SHADE { if (!assetData.contains(id)) { - for (auto const& asset : assetCollection) + for (auto const& asset : std::ranges::views::values(assetCollection)) { if (asset.id == id) { From c71a84cc59cebf14d7c91b326eff2c9ff15379fa Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sat, 29 Oct 2022 15:50:26 +0800 Subject: [PATCH 08/10] Simple file deletion --- SHADE_Engine/src/Assets/SHAssetManager.cpp | 38 +++++++++++++++++----- SHADE_Engine/src/Assets/SHAssetManager.h | 11 ++++--- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 78c94da7..96ea7d1a 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -57,11 +57,6 @@ namespace SHADE /**************************************************************************** * \brief Deallocate all memory used by asset data ****************************************************************************/ - void SHAssetManager::Unload() noexcept - { - - } - void SHAssetManager::Unload(AssetID assetId) noexcept { // TODO @@ -74,9 +69,9 @@ namespace SHADE delete loader; } - for (auto const& data : assetData) + for (auto const& data : std::ranges::views::values(assetData)) { - delete data.second; + delete data; } } @@ -224,6 +219,27 @@ namespace SHADE return false; } + bool SHAssetManager::DeleteAsset(AssetID id) noexcept + { + + if (assetCollection.contains(id)) + { + auto const& asset = assetCollection[id]; + if ( + asset.type == AssetType::SCENE || + asset.type == AssetType::PREFAB || + asset.type == AssetType::MATERIAL + ) + { + return (DeleteLocalFile(asset.path) && DeleteLocalFile(asset.path.string() + META_EXTENSION.data())); + } + SHLOG_WARNING("Asset id: {} not an internal asset type, file deletion not allowed", id); + } + + SHLOG_WARNING("Asset id does not exist, nothing was deleted: {}", id); + return false; + } + //AssetID SHAssetManager::CreateAsset(AssetName name, AssetType type) noexcept //{ // AssetID id = GenerateAssetID(type); @@ -411,7 +427,13 @@ namespace SHADE } } - void SHAssetManager:: InitLoaders() noexcept + bool SHAssetManager::DeleteLocalFile(AssetPath path) noexcept + { + //TODO Move this to dedicated library + return std::filesystem::remove(path); + } + + void SHAssetManager:: InitLoaders() noexcept { loaders[static_cast(AssetType::SHADER)] = dynamic_cast(new SHShaderSourceLoader()); loaders[static_cast(AssetType::SHADER_BUILT_IN)] = loaders[static_cast(AssetType::SHADER)]; diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index fca38865..22e92c7d 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -26,19 +26,17 @@ namespace SHADE * \brief Static function to generate resource ID. ****************************************************************************/ static AssetID GenerateAssetID(AssetType type) noexcept; - static AssetPath GenerateLocalPath(AssetPath path) noexcept; - static AssetPath GenerateNewPath(AssetName name, AssetType type); /**************************************************************************** * \brief Deallocate all memory used by resource data ****************************************************************************/ - static void Unload() noexcept; - static void Unload(AssetID assetId) noexcept; - static void Exit() noexcept; + + static void Unload(AssetID assetId) noexcept; + /**************************************************************************** * \brief Load all resources that are in the folder ****************************************************************************/ @@ -61,6 +59,7 @@ namespace SHADE ****************************************************************************/ static AssetID CreateNewAsset(AssetType type, AssetName name) noexcept; static bool SaveAsset(AssetID id) noexcept; + static bool DeleteAsset(AssetID id) noexcept; /**************************************************************************** * \brief Import new resource from outside editor window. @@ -101,6 +100,8 @@ namespace SHADE static void CompileAll() noexcept; + static bool DeleteLocalFile(AssetPath path) noexcept; + //TODO use this function to create asset data internall at all calls to generate id //static AssetID CreateAsset(AssetName name, AssetType type) noexcept; From 70533b17126773e466366a59f6aaa012dab3bace Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sat, 29 Oct 2022 15:53:15 +0800 Subject: [PATCH 09/10] Changed Application exit call to asset manager --- SHADE_Application/src/Application/SBApplication.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 53393fea..de548060 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -159,7 +159,7 @@ namespace Sandbox SHSceneManager::Exit(); SHSystemManager::Exit(); - SHAssetManager::Unload(); + SHAssetManager::Exit(); } } From 00d4d5d91053c2a1c87e1ba4697095658e3fdad8 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sun, 30 Oct 2022 03:06:18 +0800 Subject: [PATCH 10/10] Removed code that accidentally calls delete on freed memory for asset loaders --- SHADE_Engine/src/Assets/SHAssetManager.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 96ea7d1a..9890d047 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -64,10 +64,10 @@ namespace SHADE void SHAssetManager::Exit() noexcept { - for (auto const& loader : loaders) - { - delete loader; - } + delete loaders[static_cast(AssetType::SHADER)]; + delete loaders[static_cast(AssetType::TEXTURE)]; + delete loaders[static_cast(AssetType::MESH)]; + delete loaders[static_cast(AssetType::SCENE)]; for (auto const& data : std::ranges::views::values(assetData)) {