SP3-13 Assets Management #131
|
@ -159,7 +159,7 @@ namespace Sandbox
|
||||||
|
|
||||||
SHSceneManager::Exit();
|
SHSceneManager::Exit();
|
||||||
SHSystemManager::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
|
struct SHAssetLoader
|
||||||
{
|
{
|
||||||
virtual SHAssetData* Load(AssetPath path) = 0;
|
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())
|
if (!file.is_open())
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Unable to open SHMesh File: {}", path.string());
|
SHLOG_ERROR("Unable to open SHMesh File: {}", path.string());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string name{ path.stem().string() };
|
const std::string name{ path.stem().string() };
|
||||||
|
@ -75,4 +76,55 @@ namespace SHADE
|
||||||
|
|
||||||
return result;
|
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.
|
* of DigiPen Institute of Technology is prohibited.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "Assets/SHAssetMacros.h"
|
|
||||||
#include "Assets/Asset Types/SHMeshAsset.h"
|
#include "Assets/Asset Types/SHMeshAsset.h"
|
||||||
#include "SHAssetLoader.h"
|
#include "SHAssetLoader.h"
|
||||||
|
|
||||||
|
@ -20,5 +19,6 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
void LoadSHMesh(AssetPath path, SHMeshAsset& meshes) noexcept;
|
void LoadSHMesh(AssetPath path, SHMeshAsset& meshes) noexcept;
|
||||||
SHAssetData* Load(AssetPath path) override;
|
SHAssetData* Load(AssetPath path) override;
|
||||||
|
void Write(SHAssetData const* data, AssetPath path) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -43,4 +43,27 @@ namespace SHADE
|
||||||
|
|
||||||
return result;
|
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
|
#pragma once
|
||||||
|
|
||||||
#include "Assets/Libraries/Loaders/SHAssetLoader.h"
|
#include "Assets/Libraries/Loaders/SHAssetLoader.h"
|
||||||
#include "Assets/SHAssetMacros.h"
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
struct SHShaderSourceLoader : SHAssetLoader
|
struct SHShaderSourceLoader : SHAssetLoader
|
||||||
{
|
{
|
||||||
SHAssetData* Load(AssetPath path) override;
|
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;
|
||||||
|
};
|
||||||
|
}
|
|
@ -17,42 +17,94 @@
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
void SHTextureLoader::LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept
|
void SHTextureLoader::LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept
|
||||||
{
|
{
|
||||||
std::ifstream file{ path.string(), std::ios::in | std::ios::binary };
|
std::ifstream file{ path.string(), std::ios::in | std::ios::binary };
|
||||||
if (!file.is_open())
|
if (!file.is_open())
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Error opening SHTexture file: {}", path.string());
|
SHLOG_ERROR("Error opening SHTexture file: {}", path.string());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const intBytes{ sizeof(uint32_t) };
|
auto const intBytes{ sizeof(uint32_t) };
|
||||||
uint32_t mipCount;
|
uint32_t mipCount;
|
||||||
|
|
||||||
file.read(reinterpret_cast<char*>(&asset.numBytes), intBytes);
|
file.read(reinterpret_cast<char*>(&asset.numBytes), intBytes);
|
||||||
file.read(reinterpret_cast<char*>(&asset.width), intBytes);
|
file.read(reinterpret_cast<char*>(&asset.width), intBytes);
|
||||||
file.read(reinterpret_cast<char*>(&asset.height), intBytes);
|
file.read(reinterpret_cast<char*>(&asset.height), intBytes);
|
||||||
file.read(reinterpret_cast<char*>(&asset.format), sizeof(SHTexture::TextureFormat));
|
file.read(reinterpret_cast<char*>(&asset.format), sizeof(SHTexture::TextureFormat));
|
||||||
|
|
||||||
file.read(reinterpret_cast<char*>(&mipCount), intBytes);
|
file.read(reinterpret_cast<char*>(&mipCount), intBytes);
|
||||||
std::vector<uint32_t> mips(mipCount);
|
std::vector<uint32_t> mips(mipCount);
|
||||||
file.read(reinterpret_cast<char*>(mips.data()), intBytes * mipCount);
|
file.read(reinterpret_cast<char*>(mips.data()), intBytes * mipCount);
|
||||||
|
|
||||||
auto pixel = new SHTexture::PixelChannel[asset.numBytes];
|
auto pixel = new SHTexture::PixelChannel[asset.numBytes];
|
||||||
file.read(reinterpret_cast<char*>(pixel), asset.numBytes);
|
file.read(reinterpret_cast<char*>(pixel), asset.numBytes);
|
||||||
|
|
||||||
asset.mipOffsets = std::move(mips);
|
asset.mipOffsets = std::move(mips);
|
||||||
asset.pixelData = std::move(pixel);
|
asset.pixelData = std::move(pixel);
|
||||||
|
|
||||||
asset.compiled = true;
|
asset.compiled = true;
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
SHAssetData* SHTextureLoader::Load(AssetPath path)
|
SHAssetData* SHTextureLoader::Load(AssetPath path)
|
||||||
{
|
{
|
||||||
auto result = new SHTextureAsset();
|
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<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.
|
* of DigiPen Institute of Technology is prohibited.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Assets/SHAssetMacros.h"
|
|
||||||
#include "Assets/Asset Types/SHTextureAsset.h"
|
#include "Assets/Asset Types/SHTextureAsset.h"
|
||||||
#include "SHAssetLoader.h"
|
#include "SHAssetLoader.h"
|
||||||
|
|
||||||
|
@ -21,5 +19,6 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept;
|
void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept;
|
||||||
SHAssetData* Load(AssetPath path) override;
|
SHAssetData* Load(AssetPath path) override;
|
||||||
|
void Write(SHAssetData const* data, AssetPath path) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,5 @@ namespace SHADE
|
||||||
AssetID id;
|
AssetID id;
|
||||||
AssetType type;
|
AssetType type;
|
||||||
AssetPath path;
|
AssetPath path;
|
||||||
FolderLocation location;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -47,6 +47,9 @@ enum class AssetType : AssetTypeMeta
|
||||||
SHADER_BUILT_IN,
|
SHADER_BUILT_IN,
|
||||||
TEXTURE,
|
TEXTURE,
|
||||||
MESH,
|
MESH,
|
||||||
|
SCENE,
|
||||||
|
PREFAB,
|
||||||
|
MATERIAL,
|
||||||
MAX_COUNT
|
MAX_COUNT
|
||||||
};
|
};
|
||||||
constexpr size_t TYPE_COUNT{ static_cast<size_t>(AssetType::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"};
|
constexpr std::string_view ASSET_ROOT {"../../Assets"};
|
||||||
#endif
|
#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
|
// ASSET EXTENSIONS
|
||||||
constexpr std::string_view META_EXTENSION {".shmeta"};
|
constexpr std::string_view META_EXTENSION {".shmeta"};
|
||||||
|
|
|
@ -10,13 +10,14 @@
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <ranges>
|
||||||
#include "SHAssetManager.h"
|
#include "SHAssetManager.h"
|
||||||
#include "SHAssetMetaHandler.h"
|
#include "SHAssetMetaHandler.h"
|
||||||
#include "Filesystem/SHFileSystem.h"
|
|
||||||
|
|
||||||
#include "Libraries/Loaders/SHMeshLoader.h"
|
#include "Libraries/Loaders/SHMeshLoader.h"
|
||||||
#include "Libraries/Loaders/SHTextureLoader.h"
|
#include "Libraries/Loaders/SHTextureLoader.h"
|
||||||
#include "Libraries/Loaders/SHShaderSourceLoader.h"
|
#include "Libraries/Loaders/SHShaderSourceLoader.h"
|
||||||
|
#include "Libraries/Loaders/SHTextBasedLoader.h"
|
||||||
|
|
||||||
#include "Libraries/Compilers/SHMeshCompiler.h"
|
#include "Libraries/Compilers/SHMeshCompiler.h"
|
||||||
#include "Libraries/Compilers/SHTextureCompiler.h"
|
#include "Libraries/Compilers/SHTextureCompiler.h"
|
||||||
|
@ -29,8 +30,9 @@ namespace SHADE
|
||||||
|
|
||||||
std::vector<SHAssetLoader*> SHAssetManager::loaders(TYPE_COUNT);
|
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;
|
std::unordered_map<AssetID, SHAssetData * const> SHAssetManager::assetData;
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* \brief Static function to generate asset ID.
|
* \brief Static function to generate asset ID.
|
||||||
|
@ -45,13 +47,7 @@ namespace SHADE
|
||||||
|
|
||||||
result |= unique;
|
result |= unique;
|
||||||
|
|
||||||
while (result == 0 ||
|
while (result == 0 || assetCollection.contains(result))
|
||||||
std::ranges::any_of(
|
|
||||||
assetCollection.begin(),
|
|
||||||
assetCollection.end(),
|
|
||||||
[result](SHAsset const& asset) { return asset.id == result; }
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
result = GenerateAssetID(type);
|
result = GenerateAssetID(type);
|
||||||
}
|
}
|
||||||
|
@ -61,11 +57,6 @@ namespace SHADE
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* \brief Deallocate all memory used by asset data
|
* \brief Deallocate all memory used by asset data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void SHAssetManager::Unload() noexcept
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHAssetManager::Unload(AssetID assetId) noexcept
|
void SHAssetManager::Unload(AssetID assetId) noexcept
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -73,14 +64,14 @@ namespace SHADE
|
||||||
|
|
||||||
void SHAssetManager::Exit() noexcept
|
void SHAssetManager::Exit() noexcept
|
||||||
{
|
{
|
||||||
for (auto const& loader : loaders)
|
delete loaders[static_cast<size_t>(AssetType::SHADER)];
|
||||||
{
|
delete loaders[static_cast<size_t>(AssetType::TEXTURE)];
|
||||||
delete loader;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,8 +104,8 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
case AssetType::SHADER:
|
case AssetType::SHADER:
|
||||||
case AssetType::SHADER_BUILT_IN:
|
case AssetType::SHADER_BUILT_IN:
|
||||||
folder = "Shaders/";
|
folder = "Shaders/";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
folder = "/";
|
folder = "/";
|
||||||
|
@ -133,9 +124,17 @@ namespace SHADE
|
||||||
*
|
*
|
||||||
* \return const& to unordered_map<AssetName, AssetID>
|
* \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 SHAssetManager::CreateNewAsset(AssetType type, AssetName name) noexcept
|
||||||
{
|
{
|
||||||
AssetID id{ GenerateAssetID(type) };
|
std::string newPath{ ASSET_ROOT };
|
||||||
SHAsset meta;
|
switch (type)
|
||||||
meta.id = id;
|
{
|
||||||
meta.type = type;
|
case AssetType::PREFAB:
|
||||||
|
newPath += PREFAB_FOLDER;
|
||||||
|
break;
|
||||||
|
|
||||||
std::string folder;
|
case AssetType::SCENE:
|
||||||
//TODO implement folder choosing
|
newPath += SCENE_FOLDER;
|
||||||
//switch (type)
|
break;
|
||||||
//{
|
|
||||||
//default:
|
|
||||||
// folder = "";
|
|
||||||
// break;
|
|
||||||
//}
|
|
||||||
AssetPath path{ std::string{ASSET_ROOT} + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) };
|
|
||||||
|
|
||||||
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);
|
||||||
|
SHAsset asset{
|
||||||
|
name,
|
||||||
|
id,
|
||||||
|
type,
|
||||||
|
newPath
|
||||||
|
};
|
||||||
|
|
||||||
|
assetCollection.insert({
|
||||||
|
id,
|
||||||
|
SHAsset(
|
||||||
|
name,
|
||||||
|
id,
|
||||||
|
type,
|
||||||
|
newPath
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetID SHAssetManager::CreateAsset(AssetName name, AssetType type) noexcept
|
bool SHAssetManager::SaveAsset(AssetID id) noexcept
|
||||||
{
|
{
|
||||||
AssetID id = GenerateAssetID(type);
|
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;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
assetCollection.emplace_back(
|
|
||||||
name,
|
|
||||||
id,
|
|
||||||
type,
|
|
||||||
GenerateNewPath(name, type),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* \brief Import new asset from outside editor window.
|
* \brief Import new asset from outside editor window.
|
||||||
*
|
*
|
||||||
|
@ -205,7 +276,8 @@ namespace SHADE
|
||||||
|
|
||||||
std::filesystem::copy(path, newPath);
|
std::filesystem::copy(path, newPath);
|
||||||
|
|
||||||
assetCollection.push_back(CreateAssetFromPath(newPath));
|
auto asset = CreateAssetFromPath(newPath);
|
||||||
|
assetCollection.insert({asset.id, asset});
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
@ -235,7 +307,7 @@ namespace SHADE
|
||||||
std::vector<SHAsset> SHAssetManager::GetAllRecordOfType(AssetType type) noexcept
|
std::vector<SHAsset> SHAssetManager::GetAllRecordOfType(AssetType type) noexcept
|
||||||
{
|
{
|
||||||
std::vector<SHAsset> result;
|
std::vector<SHAsset> result;
|
||||||
for (auto const& asset : assetCollection)
|
for (auto const& asset : std::ranges::views::values(assetCollection))
|
||||||
{
|
{
|
||||||
if (asset.type == type)
|
if (asset.type == type)
|
||||||
{
|
{
|
||||||
|
@ -246,29 +318,28 @@ namespace SHADE
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetID SHAssetManager::CompileAsset(AssetPath path) noexcept
|
AssetID SHAssetManager::CompileAsset(AssetPath path) noexcept
|
||||||
{
|
{
|
||||||
SHAsset newAsset
|
SHAsset newAsset
|
||||||
{
|
{
|
||||||
.name = path.stem().string(),
|
.name = path.stem().string()
|
||||||
.location = 0
|
};
|
||||||
};
|
|
||||||
|
|
||||||
auto const ext{ path.extension().string() };
|
auto const ext{ path.extension().string() };
|
||||||
if (ext == GLSL_EXTENSION.data())
|
if (ext == GLSL_EXTENSION.data())
|
||||||
{
|
{
|
||||||
newAsset.path = SHShaderSourceCompiler::LoadAndCompileShader(path).value();
|
newAsset.path = SHShaderSourceCompiler::LoadAndCompileShader(path).value();
|
||||||
newAsset.id = GenerateAssetID(AssetType::SHADER_BUILT_IN);
|
newAsset.id = GenerateAssetID(AssetType::SHADER_BUILT_IN);
|
||||||
newAsset.type = AssetType::SHADER_BUILT_IN;
|
newAsset.type = AssetType::SHADER_BUILT_IN;
|
||||||
}
|
}
|
||||||
|
|
||||||
assetCollection.push_back(newAsset);
|
assetCollection.insert({ newAsset.id, newAsset });
|
||||||
SHAssetMetaHandler::WriteMetaData(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)
|
for (auto const& e : EXTENSIONS)
|
||||||
{
|
{
|
||||||
|
@ -289,82 +360,88 @@ namespace SHADE
|
||||||
result.type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string());
|
result.type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string());
|
||||||
result.id = GenerateAssetID(result.type);
|
result.id = GenerateAssetID(result.type);
|
||||||
result.path = path;
|
result.path = path;
|
||||||
result.location = 0;
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAssetManager::CompileAll() noexcept
|
void SHAssetManager::CompileAll() noexcept
|
||||||
|
{
|
||||||
|
std::vector<AssetPath> 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& 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<SHMeshAsset*> meshes;
|
||||||
|
std::vector<SHAnimationAsset*> 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.insert({ meshAsset.id, meshAsset });
|
||||||
|
SHAssetMetaHandler::WriteMetaData(meshAsset);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
assetCollection.insert({ newAsset.id, newAsset });
|
||||||
|
SHAssetMetaHandler::WriteMetaData(newAsset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHAssetManager::DeleteLocalFile(AssetPath path) noexcept
|
||||||
{
|
{
|
||||||
std::vector<AssetPath> paths;
|
//TODO Move this to dedicated library
|
||||||
|
return std::filesystem::remove(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(),
|
|
||||||
.location = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
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<SHMeshAsset*> meshes;
|
|
||||||
std::vector<SHAnimationAsset*> anims;
|
|
||||||
SHMeshCompiler::LoadFromFile(path, meshes, anims);
|
|
||||||
|
|
||||||
for (auto const& mesh : meshes)
|
|
||||||
{
|
|
||||||
SHAsset meshAsset{
|
|
||||||
.name = mesh->header.name,
|
|
||||||
.location = 0
|
|
||||||
};
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAssetManager::InitLoaders() noexcept
|
void SHAssetManager:: InitLoaders() noexcept
|
||||||
{
|
{
|
||||||
loaders[static_cast<size_t>(AssetType::SHADER)] = dynamic_cast<SHAssetLoader*>(new SHShaderSourceLoader());
|
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::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::TEXTURE)] = dynamic_cast<SHAssetLoader*>(new SHTextureLoader());
|
||||||
loaders[static_cast<size_t>(AssetType::MESH)] = dynamic_cast<SHAssetLoader*>(new SHMeshLoader());
|
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
|
void SHAssetManager::Load() noexcept
|
||||||
{
|
{
|
||||||
CompileAll();
|
//CompileAll();
|
||||||
InitLoaders();
|
InitLoaders();
|
||||||
BuildAssetCollection();
|
BuildAssetCollection();
|
||||||
//LoadAllData();
|
//LoadAllData();
|
||||||
|
@ -383,7 +460,7 @@ namespace SHADE
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void SHAssetManager::LoadAllData() noexcept
|
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);
|
SHAssetData* data = loaders[static_cast<size_t>(asset.type)]->Load(asset.path);
|
||||||
assetData.emplace(asset.id, data);
|
assetData.emplace(asset.id, data);
|
||||||
|
@ -414,7 +491,8 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (dir.path().extension().string() == META_EXTENSION.data())
|
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 "SHAsset.h"
|
||||||
#include "Asset Types/SHAssetData.h"
|
#include "Asset Types/SHAssetData.h"
|
||||||
#include "Assets/Libraries/Loaders/SHAssetLoader.h"
|
#include "Assets/Libraries/Loaders/SHAssetLoader.h"
|
||||||
#include <memory>
|
#include "Filesystem/SHFileSystem.h"
|
||||||
|
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
|
|
||||||
|
@ -26,19 +26,17 @@ namespace SHADE
|
||||||
* \brief Static function to generate resource ID.
|
* \brief Static function to generate resource ID.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static AssetID GenerateAssetID(AssetType type) noexcept;
|
static AssetID GenerateAssetID(AssetType type) noexcept;
|
||||||
|
|
||||||
static AssetPath GenerateLocalPath(AssetPath path) noexcept;
|
static AssetPath GenerateLocalPath(AssetPath path) noexcept;
|
||||||
|
|
||||||
static AssetPath GenerateNewPath(AssetName name, AssetType type);
|
static AssetPath GenerateNewPath(AssetName name, AssetType type);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* \brief Deallocate all memory used by resource data
|
* \brief Deallocate all memory used by resource data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void Unload() noexcept;
|
|
||||||
static void Unload(AssetID assetId) noexcept;
|
|
||||||
|
|
||||||
static void Exit() noexcept;
|
static void Exit() noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
static void Unload(AssetID assetId) noexcept;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* \brief Load all resources that are in the folder
|
* \brief Load all resources that are in the folder
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -49,7 +47,7 @@ namespace SHADE
|
||||||
*
|
*
|
||||||
* \return const& to unordered_map<AssetName, AssetID>
|
* \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
|
* \brief Create record for new resource. CAN ONLY CREATE FOR CUSTOM
|
||||||
|
@ -59,8 +57,9 @@ namespace SHADE
|
||||||
* \param name of resource
|
* \param name of resource
|
||||||
* \return resource id generated for new asset
|
* \return resource id generated for new asset
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static AssetID CreateNewAsset(AssetType, AssetName) noexcept;
|
static AssetID CreateNewAsset(AssetType type, AssetName name) noexcept;
|
||||||
static AssetID CreateAsset(AssetName name, AssetType type) noexcept;
|
static bool SaveAsset(AssetID id) noexcept;
|
||||||
|
static bool DeleteAsset(AssetID id) noexcept;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* \brief Import new resource from outside editor window.
|
* \brief Import new resource from outside editor window.
|
||||||
|
@ -78,7 +77,10 @@ namespace SHADE
|
||||||
// -------------------------------------------------------------------------/
|
// -------------------------------------------------------------------------/
|
||||||
|
|
||||||
template<typename T>
|
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<SHAssetData const*> GetAllDataOfType(AssetType type) noexcept;
|
||||||
static std::vector<SHAsset> GetAllRecordOfType(AssetType type) noexcept;
|
static std::vector<SHAsset> GetAllRecordOfType(AssetType type) noexcept;
|
||||||
|
@ -98,13 +100,18 @@ namespace SHADE
|
||||||
|
|
||||||
static void CompileAll() noexcept;
|
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 FMOD::System* audioSystem;
|
||||||
static std::unordered_map<AssetID,SHSound>* audioSoundList;
|
static std::unordered_map<AssetID,SHSound>* audioSoundList;
|
||||||
|
|
||||||
static std::vector<SHAssetLoader*> loaders;
|
static std::vector<SHAssetLoader*> loaders;
|
||||||
|
|
||||||
// For all resources
|
// For all resources
|
||||||
static std::vector<SHAsset> assetCollection;
|
static std::unordered_map<AssetID, SHAsset> assetCollection;
|
||||||
static std::unordered_map<AssetID, SHAssetData * const> assetData;
|
static std::unordered_map<AssetID, SHAssetData * const> assetData;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,16 @@
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
template<typename T>
|
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))
|
if (!assetData.contains(id))
|
||||||
{
|
{
|
||||||
for (auto const& asset : assetCollection)
|
for (auto const& asset : std::ranges::views::values(assetCollection))
|
||||||
{
|
{
|
||||||
if (asset.id == id)
|
if (asset.id == id)
|
||||||
{
|
{
|
||||||
assetData.emplace(id, LoadData(asset));
|
assetData.emplace(id, LoadData(asset));
|
||||||
return dynamic_cast<T const* const>(assetData[id]);
|
return dynamic_cast<T* const>(assetData[id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,27 @@ namespace SHADE
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dynamic_cast<T const* const>(assetData[id]);
|
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)
|
||||||
|
{
|
||||||
|
assetData.emplace(id, LoadData(asset));
|
||||||
|
return dynamic_cast<T const* const>(assetData[id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHLOG_ERROR("Asset ID provided does not exist: {}", id);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dynamic_cast<T const* const>(assetData[id]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,81 +6,39 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
char const FOLDER_MAX_COUNT {15};
|
SHFolder::SHFolder(FolderName name)
|
||||||
|
:name{ name }, subFolders(0), folded{ false }, path{""}
|
||||||
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{""}
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
return result;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHFileSystem::DeleteFolder(FolderPointer location) noexcept
|
bool SHFileSystem::DeleteFolder(FolderPointer location) noexcept
|
||||||
{
|
{
|
||||||
if (!folders.contains(location->id))
|
//TODO IMPLEMENT
|
||||||
{
|
|
||||||
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());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHFileSystem::StartupFillDirectories(FolderPath path) noexcept
|
FolderPointer SHFileSystem::BuildDirectory(FolderPath path) noexcept
|
||||||
{
|
{
|
||||||
std::queue<FolderPointer> folderQueue;
|
std::queue<FolderPointer> folderQueue;
|
||||||
|
auto result = new SHFolder("root");
|
||||||
folderQueue.push(RegisterFolder(path, 0, 0, "Root"));
|
folderQueue.push(result);
|
||||||
|
|
||||||
while (!folderQueue.empty())
|
while (!folderQueue.empty())
|
||||||
{
|
{
|
||||||
|
@ -101,59 +59,15 @@ namespace SHADE
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
FolderLocation location = folder->id;
|
std::string name = dirEntry.path().stem().string();
|
||||||
location <<= FOLDER_BIT_ALLOCATE;
|
|
||||||
location |= ++count;
|
|
||||||
|
|
||||||
std::string name = dirEntry.path().string();
|
FolderPointer newFolder{ new SHFolder(name) };
|
||||||
name = name.substr(name.find_last_of('/') + 1, name.length() - name.find_last_of('/'));
|
|
||||||
|
|
||||||
FolderPointer newFolder{ RegisterFolder(
|
|
||||||
dirEntry.path().string(),
|
|
||||||
folder->id,
|
|
||||||
location,
|
|
||||||
name)
|
|
||||||
};
|
|
||||||
|
|
||||||
folderQueue.push(newFolder);
|
folderQueue.push(newFolder);
|
||||||
folder->subFolders.push_back(newFolder);
|
folder->subFolders.push_back(newFolder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
FolderPointer SHFileSystem::GetRoot() noexcept
|
return result;
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include "SHFolder.h"
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
namespace SHADE
|
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
|
class SHFileSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static FolderLocation CreateNewFolderHere(FolderName name, FolderLocation here = 0) noexcept;
|
static FolderPointer BuildDirectory(FolderPath path) noexcept;
|
||||||
|
|
||||||
static bool DeleteFolder(FolderPointer location) noexcept;
|
|
||||||
|
|
||||||
static void StartupFillDirectories(FolderPath path) noexcept;
|
|
||||||
|
|
||||||
static FolderPointer GetRoot() noexcept;
|
|
||||||
|
|
||||||
private:
|
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;
|
friend class SHFolder;
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -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