SP3-13 Assets Management #131
|
@ -159,7 +159,7 @@ namespace Sandbox
|
|||
|
||||
SHSceneManager::Exit();
|
||||
SHSystemManager::Exit();
|
||||
SHAssetManager::Unload();
|
||||
SHAssetManager::Exit();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 <string>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
struct SHMaterialAsset : SHAssetData
|
||||
{
|
||||
std::string name;
|
||||
std::string data;
|
||||
};
|
||||
}
|
|
@ -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 <string>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
struct SHPrefabAsset : SHAssetData
|
||||
{
|
||||
std::string name;
|
||||
std::string data;
|
||||
};
|
||||
}
|
|
@ -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 <string>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
struct SHSceneAsset : SHAssetData
|
||||
{
|
||||
std::string name;
|
||||
std::string data;
|
||||
};
|
||||
}
|
|
@ -18,5 +18,6 @@ namespace SHADE
|
|||
struct SHAssetLoader
|
||||
{
|
||||
virtual SHAssetData* Load(AssetPath path) = 0;
|
||||
virtual void Write(SHAssetData const* data, AssetPath path) = 0;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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<SHMeshAsset const*>(data);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(&(asset.header.vertexCount)),
|
||||
sizeof(uint32_t)
|
||||
);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<const char*>(&(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<char const*>(asset.vertexPosition.data()),
|
||||
vertexVec3Byte
|
||||
);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(asset.vertexTangent.data()),
|
||||
vertexVec3Byte
|
||||
);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(asset.vertexNormal.data()),
|
||||
vertexVec3Byte
|
||||
);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(asset.texCoords.data()),
|
||||
vertexVec2Byte
|
||||
);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(asset.indices.data()),
|
||||
sizeof(uint32_t) * asset.header.indexCount
|
||||
);
|
||||
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
|
@ -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<SHShaderAsset const*>(data);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(&asset.shaderType), sizeof(uint8_t)
|
||||
);
|
||||
|
||||
size_t const byteCount = sizeof(uint32_t) * asset.spirvBinary.size();
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(&byteCount), sizeof(size_t)
|
||||
);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(asset.spirvBinary.data()), byteCount
|
||||
);
|
||||
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/******************************************************************************
|
||||
* \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 "Assets/Asset Types/SHMaterialAsset.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
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;
|
||||
}
|
||||
else if (path.extension().string() == MATERIAL_EXTENSION)
|
||||
{
|
||||
auto data = new SHMaterialAsset();
|
||||
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<SHSceneAsset const*>(data);
|
||||
file << scene->data;
|
||||
}
|
||||
else if (path.extension().string() == PREFAB_EXTENSION)
|
||||
{
|
||||
auto prefab = dynamic_cast<SHPrefabAsset const*>(data);
|
||||
file << prefab->data;
|
||||
}
|
||||
else if (path.extension().string() == MATERIAL_EXTENSION)
|
||||
{
|
||||
auto material = dynamic_cast<SHMaterialAsset const*>(data);
|
||||
file << material->data;
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
}
|
|
@ -55,4 +55,56 @@ namespace SHADE
|
|||
|
||||
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<SHTextureAsset const*>(data);
|
||||
|
||||
constexpr auto intBytes{ sizeof(uint32_t) };
|
||||
|
||||
uint32_t const mipOffsetCount{ static_cast<uint32_t>(asset.mipOffsets.size()) };
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(&asset.numBytes),
|
||||
intBytes
|
||||
);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(&asset.width),
|
||||
intBytes
|
||||
);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(&asset.height),
|
||||
intBytes
|
||||
);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(&asset.format),
|
||||
sizeof(SHTexture::TextureFormat)
|
||||
);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(&mipOffsetCount),
|
||||
intBytes
|
||||
);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(asset.mipOffsets.data()),
|
||||
intBytes * asset.mipOffsets.size()
|
||||
);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(asset.pixelData),
|
||||
asset.numBytes
|
||||
);
|
||||
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -23,6 +23,5 @@ namespace SHADE
|
|||
AssetID id;
|
||||
AssetType type;
|
||||
AssetPath path;
|
||||
FolderLocation location;
|
||||
};
|
||||
}
|
|
@ -47,6 +47,9 @@ enum class AssetType : AssetTypeMeta
|
|||
SHADER_BUILT_IN,
|
||||
TEXTURE,
|
||||
MESH,
|
||||
SCENE,
|
||||
PREFAB,
|
||||
MATERIAL,
|
||||
MAX_COUNT
|
||||
};
|
||||
constexpr size_t TYPE_COUNT{ static_cast<size_t>(AssetType::MAX_COUNT) };
|
||||
|
@ -58,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"};
|
||||
|
|
|
@ -10,13 +10,14 @@
|
|||
#include "SHpch.h"
|
||||
#include <random>
|
||||
#include <chrono>
|
||||
#include <ranges>
|
||||
#include "SHAssetManager.h"
|
||||
#include "SHAssetMetaHandler.h"
|
||||
#include "Filesystem/SHFileSystem.h"
|
||||
|
||||
#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"
|
||||
|
@ -29,9 +30,10 @@ namespace SHADE
|
|||
|
||||
std::vector<SHAssetLoader*> SHAssetManager::loaders(TYPE_COUNT);
|
||||
|
||||
std::vector<SHAsset> SHAssetManager::assetCollection;
|
||||
std::unordered_map<AssetID, SHAsset> SHAssetManager::assetCollection;
|
||||
std::unordered_map<AssetID, SHAssetData * const> 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);
|
||||
}
|
||||
|
@ -61,11 +57,6 @@ namespace SHADE
|
|||
/****************************************************************************
|
||||
* \brief Deallocate all memory used by asset data
|
||||
****************************************************************************/
|
||||
void SHAssetManager::Unload() noexcept
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SHAssetManager::Unload(AssetID assetId) noexcept
|
||||
{
|
||||
// TODO
|
||||
|
@ -73,14 +64,14 @@ namespace SHADE
|
|||
|
||||
void SHAssetManager::Exit() noexcept
|
||||
{
|
||||
for (auto const& loader : loaders)
|
||||
{
|
||||
delete loader;
|
||||
}
|
||||
delete loaders[static_cast<size_t>(AssetType::SHADER)];
|
||||
delete loaders[static_cast<size_t>(AssetType::TEXTURE)];
|
||||
delete loaders[static_cast<size_t>(AssetType::MESH)];
|
||||
delete loaders[static_cast<size_t>(AssetType::SCENE)];
|
||||
|
||||
for (auto const& data : assetData)
|
||||
for (auto const& data : std::ranges::views::values(assetData))
|
||||
{
|
||||
delete data.second;
|
||||
delete data;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,9 +124,17 @@ namespace SHADE
|
|||
*
|
||||
* \return const& to unordered_map<AssetName, AssetID>
|
||||
****************************************************************************/
|
||||
std::vector<SHAsset> const& SHAssetManager::GetAllAssets() noexcept
|
||||
std::vector<SHAsset> SHAssetManager::GetAllAssets() noexcept
|
||||
{
|
||||
return assetCollection;
|
||||
std::vector<SHAsset> result;
|
||||
result.reserve(assetCollection.size());
|
||||
|
||||
for (auto const& asset : std::ranges::views::values(assetCollection))
|
||||
{
|
||||
result.push_back(asset);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -148,41 +147,113 @@ 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);
|
||||
|
||||
return id;
|
||||
default:
|
||||
SHLOG_ERROR("Asset type of {} not an internal asset type, cannot be created", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AssetID SHAssetManager::CreateAsset(AssetName name, AssetType type) noexcept
|
||||
{
|
||||
AssetID id = GenerateAssetID(type);
|
||||
|
||||
assetCollection.emplace_back(
|
||||
auto id = GenerateAssetID(type);
|
||||
SHAsset asset{
|
||||
name,
|
||||
id,
|
||||
type,
|
||||
GenerateNewPath(name, type),
|
||||
0
|
||||
);
|
||||
newPath
|
||||
};
|
||||
|
||||
assetCollection.insert({
|
||||
id,
|
||||
SHAsset(
|
||||
name,
|
||||
id,
|
||||
type,
|
||||
newPath
|
||||
)
|
||||
});
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
bool SHAssetManager::SaveAsset(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
|
||||
)
|
||||
{
|
||||
if (assetData.contains(id))
|
||||
{
|
||||
auto const data = assetData.at(id);
|
||||
loaders[static_cast<size_t>(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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// assetCollection.emplace_back(
|
||||
// name,
|
||||
// id,
|
||||
// type,
|
||||
// GenerateNewPath(name, type)
|
||||
// );
|
||||
// return id;
|
||||
//}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* \brief Import new asset from outside editor window.
|
||||
*
|
||||
|
@ -205,7 +276,8 @@ namespace SHADE
|
|||
|
||||
std::filesystem::copy(path, newPath);
|
||||
|
||||
assetCollection.push_back(CreateAssetFromPath(newPath));
|
||||
auto asset = CreateAssetFromPath(newPath);
|
||||
assetCollection.insert({asset.id, asset});
|
||||
|
||||
return id;
|
||||
}
|
||||
|
@ -235,7 +307,7 @@ namespace SHADE
|
|||
std::vector<SHAsset> SHAssetManager::GetAllRecordOfType(AssetType type) noexcept
|
||||
{
|
||||
std::vector<SHAsset> result;
|
||||
for (auto const& asset : assetCollection)
|
||||
for (auto const& asset : std::ranges::views::values(assetCollection))
|
||||
{
|
||||
if (asset.type == type)
|
||||
{
|
||||
|
@ -250,8 +322,7 @@ namespace SHADE
|
|||
{
|
||||
SHAsset newAsset
|
||||
{
|
||||
.name = path.stem().string(),
|
||||
.location = 0
|
||||
.name = path.stem().string()
|
||||
};
|
||||
|
||||
auto const ext{ path.extension().string() };
|
||||
|
@ -262,7 +333,7 @@ namespace SHADE
|
|||
newAsset.type = AssetType::SHADER_BUILT_IN;
|
||||
}
|
||||
|
||||
assetCollection.push_back(newAsset);
|
||||
assetCollection.insert({ newAsset.id, newAsset });
|
||||
SHAssetMetaHandler::WriteMetaData(newAsset);
|
||||
|
||||
return newAsset.id;
|
||||
|
@ -289,7 +360,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 +386,7 @@ namespace SHADE
|
|||
{
|
||||
SHAsset newAsset
|
||||
{
|
||||
.name = path.stem().string(),
|
||||
.location = 0
|
||||
.name = path.stem().string()
|
||||
};
|
||||
|
||||
auto const ext{ path.extension().string() };
|
||||
|
@ -342,29 +411,37 @@ 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);
|
||||
meshAsset.type = AssetType::MESH;
|
||||
assetCollection.push_back(meshAsset);
|
||||
//SHAssetMetaHandler::WriteMetaData(meshAsset);
|
||||
assetCollection.insert({ meshAsset.id, meshAsset });
|
||||
SHAssetMetaHandler::WriteMetaData(meshAsset);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
assetCollection.push_back(newAsset);
|
||||
//SHAssetMetaHandler::WriteMetaData(newAsset);
|
||||
assetCollection.insert({ newAsset.id, newAsset });
|
||||
SHAssetMetaHandler::WriteMetaData(newAsset);
|
||||
}
|
||||
}
|
||||
|
||||
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<size_t>(AssetType::SHADER)] = dynamic_cast<SHAssetLoader*>(new SHShaderSourceLoader());
|
||||
loaders[static_cast<size_t>(AssetType::SHADER_BUILT_IN)] = loaders[static_cast<size_t>(AssetType::SHADER)];
|
||||
loaders[static_cast<size_t>(AssetType::TEXTURE)] = dynamic_cast<SHAssetLoader*>(new SHTextureLoader());
|
||||
loaders[static_cast<size_t>(AssetType::MESH)] = dynamic_cast<SHAssetLoader*>(new SHMeshLoader());
|
||||
loaders[static_cast<size_t>(AssetType::SCENE)] = dynamic_cast<SHAssetLoader*>(new SHTextBasedLoader());
|
||||
loaders[static_cast<size_t>(AssetType::PREFAB)] = loaders[static_cast<size_t>(AssetType::SCENE)];
|
||||
loaders[static_cast<size_t>(AssetType::MATERIAL)] = loaders[static_cast<size_t>(AssetType::SCENE)];
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -372,7 +449,7 @@ namespace SHADE
|
|||
****************************************************************************/
|
||||
void SHAssetManager::Load() noexcept
|
||||
{
|
||||
CompileAll();
|
||||
//CompileAll();
|
||||
InitLoaders();
|
||||
BuildAssetCollection();
|
||||
//LoadAllData();
|
||||
|
@ -383,7 +460,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<size_t>(asset.type)]->Load(asset.path);
|
||||
assetData.emplace(asset.id, data);
|
||||
|
@ -414,7 +491,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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "SHAsset.h"
|
||||
#include "Asset Types/SHAssetData.h"
|
||||
#include "Assets/Libraries/Loaders/SHAssetLoader.h"
|
||||
#include <memory>
|
||||
#include "Filesystem/SHFileSystem.h"
|
||||
|
||||
#include "SH_API.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
|
||||
****************************************************************************/
|
||||
|
@ -49,7 +47,7 @@ namespace SHADE
|
|||
*
|
||||
* \return const& to unordered_map<AssetName, AssetID>
|
||||
****************************************************************************/
|
||||
static std::vector<SHAsset> const& GetAllAssets() noexcept;
|
||||
static std::vector<SHAsset> GetAllAssets() noexcept;
|
||||
|
||||
/****************************************************************************
|
||||
* \brief Create record for new resource. CAN ONLY CREATE FOR CUSTOM
|
||||
|
@ -59,8 +57,9 @@ 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 bool SaveAsset(AssetID id) noexcept;
|
||||
static bool DeleteAsset(AssetID id) noexcept;
|
||||
|
||||
/****************************************************************************
|
||||
* \brief Import new resource from outside editor window.
|
||||
|
@ -78,7 +77,10 @@ namespace SHADE
|
|||
// -------------------------------------------------------------------------/
|
||||
|
||||
template<typename T>
|
||||
static std::enable_if_t<std::is_base_of_v<SHAssetData, T>, T const* const> GetData(AssetID id) noexcept;
|
||||
static std::enable_if_t<std::is_base_of_v<SHAssetData, T>, T* const> GetData(AssetID id) noexcept;
|
||||
|
||||
template<typename T>
|
||||
static std::enable_if_t<std::is_base_of_v<SHAssetData, T>, T const* const> GetConstData(AssetID id) noexcept;
|
||||
|
||||
static std::vector<SHAssetData const*> GetAllDataOfType(AssetType type) noexcept;
|
||||
static std::vector<SHAsset> GetAllRecordOfType(AssetType type) noexcept;
|
||||
|
@ -98,13 +100,18 @@ 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;
|
||||
|
||||
static FMOD::System* audioSystem;
|
||||
static std::unordered_map<AssetID,SHSound>* audioSoundList;
|
||||
|
||||
static std::vector<SHAssetLoader*> loaders;
|
||||
|
||||
// For all resources
|
||||
static std::vector<SHAsset> assetCollection;
|
||||
static std::unordered_map<AssetID, SHAsset> assetCollection;
|
||||
static std::unordered_map<AssetID, SHAssetData * const> assetData;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -4,11 +4,32 @@
|
|||
namespace SHADE
|
||||
{
|
||||
template<typename T>
|
||||
std::enable_if_t<std::is_base_of_v<SHAssetData, T>, T const* const> SHAssetManager::GetData(AssetID id) noexcept
|
||||
std::enable_if_t<std::is_base_of_v<SHAssetData, T>, T* const> SHAssetManager::GetData(AssetID id) noexcept
|
||||
{
|
||||
if (!assetData.contains(id))
|
||||
{
|
||||
for (auto const& asset : assetCollection)
|
||||
for (auto const& asset : std::ranges::views::values(assetCollection))
|
||||
{
|
||||
if (asset.id == id)
|
||||
{
|
||||
assetData.emplace(id, LoadData(asset));
|
||||
return dynamic_cast<T* const>(assetData[id]);
|
||||
}
|
||||
}
|
||||
|
||||
SHLOG_ERROR("Asset ID provided does not exist: {}", id);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return dynamic_cast<T* const>(assetData[id]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::enable_if_t<std::is_base_of_v<SHAssetData, T>, T const * const> SHAssetManager::GetConstData(AssetID id) noexcept
|
||||
{
|
||||
if (!assetData.contains(id))
|
||||
{
|
||||
for (auto const& asset : std::ranges::views::values(assetCollection))
|
||||
{
|
||||
if (asset.id == id)
|
||||
{
|
||||
|
|
|
@ -6,81 +6,39 @@
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
char const FOLDER_MAX_COUNT {15};
|
||||
|
||||
std::unordered_map<FolderLocation, std::unique_ptr<SHFolder>> 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)
|
||||
for (auto const& folder : parent->subFolders)
|
||||
{
|
||||
if (!folders.contains(0))
|
||||
if (name == folder->name)
|
||||
{
|
||||
folders[0] = std::make_unique<SHFolder>(0, "root");
|
||||
SHLOG_ERROR("Unable to create subfolder {} at {} as it already exists", name, folder->name);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
|
||||
auto result = new SHFolder(name);
|
||||
parent->subFolders.push_back(result);
|
||||
|
||||
if (count >= FOLDER_MAX_COUNT)
|
||||
{
|
||||
SHLOG_ERROR("Max subfolder reached: {}\n", name);
|
||||
}
|
||||
|
||||
auto const location = static_cast<FolderLocation>(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<FolderCounter>(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<FolderPointer> 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<SHFolder>(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<SHFolder>(location, name);
|
||||
folders[location]->path = path;
|
||||
folders[parent]->subFolders.push_back(folders[location].get());
|
||||
|
||||
return folders[location].get();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#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<FolderPointer> subFolders;
|
||||
std::vector<SHFile> 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<FolderLocation, std::unique_ptr<SHFolder>> 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;
|
||||
};
|
||||
}
|
|
@ -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 <string>
|
||||
#include <vector>
|
||||
#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<FolderPointer> subFolders;
|
||||
std::vector<SHFile> files;
|
||||
|
||||
bool folded;
|
||||
|
||||
FolderPointer CreateSubFolderHere(FolderName name);
|
||||
|
||||
private:
|
||||
FolderPath path;
|
||||
friend class SHFileSystem;
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue