Add Asset system
- Add Abstract Asset class which defines Assets - Add AssetManager class to keep track of all the Asset - Add AssetFile class to cache the asset without loading it - Add UUID class to uniquely identify assets - Add MetaFile class to load meta asset files
This commit is contained in:
@@ -166,6 +166,9 @@
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\copium\asset\Asset.cpp" />
|
||||
<ClCompile Include="src\copium\asset\AssetFile.cpp" />
|
||||
<ClCompile Include="src\copium\asset\AssetManager.cpp" />
|
||||
<ClCompile Include="src\copium\buffer\RendererVertexBuffer.cpp" />
|
||||
<ClCompile Include="src\copium\core\Application.cpp" />
|
||||
<ClCompile Include="src\copium\buffer\Buffer.cpp" />
|
||||
@@ -184,6 +187,7 @@
|
||||
<ClCompile Include="src\copium\sampler\DepthAttachment.cpp" />
|
||||
<ClCompile Include="src\copium\pipeline\DescriptorPool.cpp" />
|
||||
<ClCompile Include="src\copium\pipeline\DescriptorSet.cpp" />
|
||||
<ClCompile Include="src\copium\util\RuntimeException.cpp" />
|
||||
<ClCompile Include="src\copium\util\FileSystem.cpp" />
|
||||
<ClCompile Include="src\copium\buffer\Framebuffer.cpp" />
|
||||
<ClCompile Include="src\copium\sampler\Image.cpp" />
|
||||
@@ -198,14 +202,21 @@
|
||||
<ClCompile Include="src\copium\core\SwapChain.cpp" />
|
||||
<ClCompile Include="src\copium\sampler\Texture2D.cpp" />
|
||||
<ClCompile Include="src\copium\pipeline\ShaderReflector.cpp" />
|
||||
<ClCompile Include="src\copium\util\MetaFile.cpp" />
|
||||
<ClCompile Include="src\copium\util\StringUtil.cpp" />
|
||||
<ClCompile Include="src\copium\util\Timer.cpp" />
|
||||
<ClCompile Include="src\copium\buffer\UniformBuffer.cpp" />
|
||||
<ClCompile Include="src\copium\mesh\Vertex.cpp" />
|
||||
<ClCompile Include="src\copium\buffer\VertexBuffer.cpp" />
|
||||
<ClCompile Include="src\copium\pipeline\VertexDescriptor.cpp" />
|
||||
<ClCompile Include="src\copium\mesh\VertexPassthrough.cpp" />
|
||||
<ClCompile Include="src\copium\util\UUID.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\copium\asset\Asset.h" />
|
||||
<ClInclude Include="src\copium\asset\AssetFile.h" />
|
||||
<ClInclude Include="src\copium\asset\AssetManager.h" />
|
||||
<ClInclude Include="src\copium\asset\AssetMeta.h" />
|
||||
<ClInclude Include="src\copium\buffer\RendererVertexBuffer.h" />
|
||||
<ClInclude Include="src\copium\core\Device.h" />
|
||||
<ClInclude Include="src\copium\core\Vulkan.h" />
|
||||
@@ -224,6 +235,7 @@
|
||||
<ClInclude Include="src\copium\core\DebugMessenger.h" />
|
||||
<ClInclude Include="src\copium\pipeline\DescriptorSet.h" />
|
||||
<ClInclude Include="src\copium\pipeline\DescriptorPool.h" />
|
||||
<ClInclude Include="src\copium\util\RuntimeException.h" />
|
||||
<ClInclude Include="src\copium\util\FileSystem.h" />
|
||||
<ClInclude Include="src\copium\buffer\Framebuffer.h" />
|
||||
<ClInclude Include="src\copium\sampler\Image.h" />
|
||||
@@ -239,14 +251,19 @@
|
||||
<ClInclude Include="src\copium\core\QueueFamilies.h" />
|
||||
<ClInclude Include="src\copium\core\SwapChain.h" />
|
||||
<ClInclude Include="src\copium\pipeline\ShaderReflector.h" />
|
||||
<ClInclude Include="src\copium\util\MetaFile.h" />
|
||||
<ClInclude Include="src\copium\util\StringUtil.h" />
|
||||
<ClInclude Include="src\copium\util\Timer.h" />
|
||||
<ClInclude Include="src\copium\mesh\Vertex.h" />
|
||||
<ClInclude Include="src\copium\buffer\VertexBuffer.h" />
|
||||
<ClInclude Include="src\copium\pipeline\VertexDescriptor.h" />
|
||||
<ClInclude Include="src\copium\util\UUID.h" />
|
||||
<ClInclude Include="src\copium\util\VulkanException.h" />
|
||||
<ClInclude Include="src\copium\mesh\VertexPassthrough.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="assets\fox.meta" />
|
||||
<None Include="assets\fox2.meta" />
|
||||
<None Include="res\shaders\passthrough.frag" />
|
||||
<None Include="res\shaders\passthrough.vert" />
|
||||
<None Include="res\shaders\renderer.frag" />
|
||||
|
||||
@@ -129,6 +129,27 @@
|
||||
<ClCompile Include="src\copium\pipeline\ShaderBinding.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\copium\util\UUID.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\copium\asset\AssetManager.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\copium\util\MetaFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\copium\util\StringUtil.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\copium\asset\Asset.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\copium\asset\AssetFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\copium\util\RuntimeException.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\copium\sampler\DepthAttachment.h">
|
||||
@@ -248,6 +269,30 @@
|
||||
<ClInclude Include="src\copium\pipeline\ShaderBinding.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\copium\util\UUID.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\copium\asset\AssetMeta.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\copium\util\MetaFile.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\copium\util\StringUtil.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\copium\asset\Asset.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\copium\asset\AssetManager.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\copium\asset\AssetFile.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\copium\util\RuntimeException.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="res\shaders\shader.frag" />
|
||||
@@ -256,5 +301,7 @@
|
||||
<None Include="res\shaders\passthrough.vert" />
|
||||
<None Include="res\shaders\renderer.frag" />
|
||||
<None Include="res\shaders\renderer.vert" />
|
||||
<None Include="assets\fox.meta" />
|
||||
<None Include="assets\fox2.meta" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,3 @@
|
||||
[Texture2D]
|
||||
filepath=res/textures/texture.png
|
||||
uuid=f49a5284-d666-0982-95ca-cf68cc3d4f45
|
||||
@@ -0,0 +1,3 @@
|
||||
[Texture2D]
|
||||
filepath=res/textures/texture2.png
|
||||
uuid=0964e525-22c3-4d25-d5c6-a162965f6e8d
|
||||
@@ -0,0 +1,41 @@
|
||||
#include "copium/asset/Asset.h"
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
Asset::Asset(AssetType type)
|
||||
{
|
||||
metaData.type = type;
|
||||
}
|
||||
|
||||
Asset::~Asset() = default;
|
||||
|
||||
AssetHandle Asset::GetHandle() const
|
||||
{
|
||||
return metaData.handle;
|
||||
}
|
||||
|
||||
AssetType Asset::GetType() const
|
||||
{
|
||||
return metaData.type;
|
||||
}
|
||||
|
||||
const std::string& Asset::GetName() const
|
||||
{
|
||||
return metaData.name;
|
||||
}
|
||||
|
||||
UUID Asset::GetUUID() const
|
||||
{
|
||||
return metaData.uuid;
|
||||
}
|
||||
|
||||
bool Asset::isRuntime() const
|
||||
{
|
||||
return metaData.isRuntime;
|
||||
}
|
||||
|
||||
Asset::operator AssetHandle() const
|
||||
{
|
||||
return metaData.handle;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "copium/asset/AssetMeta.h"
|
||||
#include "copium/util/MetaFile.h"
|
||||
#include "copium/util/UUID.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
|
||||
class Asset
|
||||
{
|
||||
friend class AssetManager;
|
||||
public:
|
||||
Asset(AssetType type);
|
||||
virtual ~Asset();
|
||||
|
||||
AssetHandle GetHandle() const;
|
||||
AssetType GetType() const;
|
||||
const std::string& GetName() const;
|
||||
UUID GetUUID() const;
|
||||
bool isRuntime() const;
|
||||
|
||||
operator AssetHandle() const;
|
||||
|
||||
private:
|
||||
AssetMeta metaData;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#include "copium/asset/AssetFile.h"
|
||||
|
||||
#include "copium/util/FileSystem.h"
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
AssetFile::AssetFile(const std::string& path)
|
||||
: path{path}
|
||||
{
|
||||
Load();
|
||||
}
|
||||
|
||||
bool AssetFile::NeedReload() const
|
||||
{
|
||||
return dateModified < FileSystem::DateModified(path);
|
||||
}
|
||||
|
||||
void AssetFile::Load()
|
||||
{
|
||||
const std::vector<std::pair<std::string, AssetType>> strToType{{"Texture2D", AssetType::Texture2D}};
|
||||
MetaFile metaFile{path};
|
||||
for (auto&& [str, type] : strToType)
|
||||
{
|
||||
if (!metaFile.HasMetaClass(str))
|
||||
continue;
|
||||
|
||||
Load(metaFile, str, type);
|
||||
return;
|
||||
}
|
||||
CP_ABORT("Load : Unknown Asset type");
|
||||
}
|
||||
|
||||
const std::string& AssetFile::GetPath() const
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
UUID AssetFile::GetUUID() const
|
||||
{
|
||||
return uuid;
|
||||
}
|
||||
|
||||
void AssetFile::Load(const MetaFile& metaFile, const std::string& className, AssetType assetType)
|
||||
{
|
||||
const MetaFileClass& metaClass = metaFile.GetMetaClass(className);
|
||||
uuid = UUID{metaClass.GetValue("uuid")};
|
||||
type = assetType;
|
||||
dateModified = FileSystem::DateModified(path);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "copium/asset/AssetMeta.h"
|
||||
#include "copium/util/MetaFile.h"
|
||||
#include "copium/util/UUID.h"
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
class AssetFile
|
||||
{
|
||||
private:
|
||||
std::string path;
|
||||
AssetType type;
|
||||
UUID uuid;
|
||||
int64_t dateModified;
|
||||
|
||||
public:
|
||||
AssetFile(const std::string& path);
|
||||
|
||||
bool NeedReload() const;
|
||||
void Load();
|
||||
|
||||
const std::string& GetPath() const;
|
||||
UUID GetUUID() const;
|
||||
private:
|
||||
void Load(const MetaFile& metaFile, const std::string& className, AssetType assetType);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
#include "copium/asset/AssetManager.h"
|
||||
|
||||
#include "copium/sampler/Texture2D.h"
|
||||
#include "copium/util/Common.h"
|
||||
#include "copium/util/MetaFile.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
std::vector<std::string> AssetManager::assetDirs;
|
||||
std::map<AssetHandle, std::unique_ptr<Asset>> AssetManager::assets;
|
||||
std::map<std::string, AssetHandle> AssetManager::pathToAssetCache;
|
||||
std::map<std::string, AssetHandle> AssetManager::nameToAssetCache;
|
||||
std::vector<AssetFile> AssetManager::cachedAssetFiles;
|
||||
AssetHandle AssetManager::assetHandle = 1;
|
||||
AssetHandle AssetManager::runtimeAssetHandle = (1 << 31) + 1;
|
||||
|
||||
void AssetManager::RegisterAssetDir(std::string assetDir)
|
||||
{
|
||||
if (assetDir.back() == '/')
|
||||
assetDir.pop_back();
|
||||
assetDirs.emplace_back(assetDir);
|
||||
for (std::filesystem::recursive_directory_iterator it(assetDir), end; it != end; ++it)
|
||||
{
|
||||
if (std::filesystem::is_directory(it->path()))
|
||||
continue;
|
||||
std::filesystem::path assetDirPath{assetDir};
|
||||
cachedAssetFiles.emplace_back(assetDir + "/" + std::filesystem::absolute(it->path()).string().substr(std::filesystem::absolute(assetDirPath).string().size()).c_str());
|
||||
}
|
||||
UUID uuid{};
|
||||
CP_INFO(uuid.ToString().c_str());
|
||||
}
|
||||
|
||||
void AssetManager::UnregisterAssetDir(std::string assetDir)
|
||||
{
|
||||
if (assetDir.back() == '/')
|
||||
assetDir.pop_back();
|
||||
|
||||
for (auto it = assetDirs.begin(); it != assetDirs.end(); ++it)
|
||||
{
|
||||
if (*it == assetDir)
|
||||
{
|
||||
assetDirs.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Asset& AssetManager::GetAsset(AssetHandle handle)
|
||||
{
|
||||
auto it = assets.find(handle);
|
||||
CP_ASSERT(it != assets.end(), "GetAsset : Asset not loaded");
|
||||
return *it->second.get();
|
||||
}
|
||||
|
||||
Asset& AssetManager::LoadAsset(const std::string& assetPath)
|
||||
{
|
||||
CP_DEBUG("LoadAsset : Loading Asset: %s", assetPath.c_str());
|
||||
|
||||
for (auto& dir : assetDirs)
|
||||
{
|
||||
std::string path = dir + "/" + assetPath;
|
||||
auto it = pathToAssetCache.find(path);
|
||||
if (it != pathToAssetCache.end())
|
||||
return *assets.find(it->second)->second.get();
|
||||
|
||||
std::ifstream file{path};
|
||||
if (!file.good())
|
||||
continue;
|
||||
|
||||
MetaFile metaFile{path};
|
||||
if (metaFile.HasMetaClass("Texture2D"))
|
||||
{
|
||||
return CreateAsset<Texture2D>(metaFile, "Texture2D");
|
||||
}
|
||||
CP_ABORT("LoadAsset : Unknown Asset type: %s/%s", dir.c_str(), assetPath.c_str());
|
||||
}
|
||||
CP_ABORT("LoadAsset : Unknown Asset: %s", assetPath.c_str());
|
||||
}
|
||||
|
||||
|
||||
Asset& AssetManager::LoadAsset(const UUID& uuid)
|
||||
{
|
||||
CP_DEBUG("LoadAsset : Loading uuid Asset: %s", uuid.ToString().c_str());
|
||||
for (auto&& assetFile : cachedAssetFiles)
|
||||
{
|
||||
if (assetFile.GetUUID() != uuid)
|
||||
continue;
|
||||
|
||||
if (assetFile.NeedReload())
|
||||
assetFile.Load();
|
||||
|
||||
if (assetFile.GetUUID() != uuid)
|
||||
continue;
|
||||
|
||||
CP_DEBUG("LoadAsset : Loading Asset: %s", assetFile.GetPath().c_str());
|
||||
auto it = pathToAssetCache.find(assetFile.GetPath());
|
||||
if (it != pathToAssetCache.end())
|
||||
return *assets.find(it->second)->second.get();
|
||||
|
||||
MetaFile metaFile{assetFile.GetPath()};
|
||||
if (metaFile.HasMetaClass("Texture2D"))
|
||||
{
|
||||
return CreateAsset<Texture2D>(metaFile, "Texture2D");
|
||||
}
|
||||
CP_ABORT("LoadAsset : Unknown Asset type: %s", assetFile.GetPath().c_str());
|
||||
}
|
||||
CP_ABORT("LoadAsset : Asset not found with uuid=%s", uuid.ToString().c_str());
|
||||
// TODO: Reload the assetCache to see if a new file has appeared with that uuid
|
||||
}
|
||||
|
||||
void AssetManager::UnloadAsset(AssetHandle handle)
|
||||
{
|
||||
auto it = assets.find(handle);
|
||||
CP_ASSERT(it != assets.end(), "UnloadAsset : Asset not loaded");
|
||||
|
||||
if (it->second->isRuntime())
|
||||
nameToAssetCache.erase(it->second->GetName());
|
||||
else
|
||||
pathToAssetCache.erase(it->second->GetName());
|
||||
assets.erase(it);
|
||||
}
|
||||
|
||||
void AssetManager::Cleanup()
|
||||
{
|
||||
if (assets.empty())
|
||||
return;
|
||||
CP_WARN("Cleanup : Cleaning up %d loaded assets", assets.size());
|
||||
assets.clear();
|
||||
nameToAssetCache.clear();
|
||||
pathToAssetCache.clear();
|
||||
}
|
||||
|
||||
Asset& AssetManager::RegisterRuntimeAsset(const std::string& name, std::unique_ptr<Asset>&& asset)
|
||||
{
|
||||
auto it = nameToAssetCache.find(name);
|
||||
CP_ASSERT(it == nameToAssetCache.end(), "RegistedRuntimeAsset : Asset already exists: %s", name);
|
||||
|
||||
AssetHandle handle = runtimeAssetHandle++;
|
||||
Asset* asset2 = assets.emplace(handle, std::move(asset)).first->second.get();
|
||||
asset2->metaData.handle = handle;
|
||||
asset2->metaData.name = name;
|
||||
asset2->metaData.uuid = UUID();
|
||||
asset2->metaData.isRuntime = true;
|
||||
nameToAssetCache.emplace(name, handle);
|
||||
return *asset2;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Asset& AssetManager::CreateAsset(const MetaFile& metaFile, const std::string& metaFileClass)
|
||||
{
|
||||
AssetHandle handle = assetHandle++;
|
||||
pathToAssetCache.emplace(metaFile.GetFilePath(), handle);
|
||||
Asset& asset = *assets.emplace(handle, std::make_unique<T>(metaFile)).first->second.get();
|
||||
asset.metaData.handle = handle;
|
||||
asset.metaData.name = metaFile.GetFilePath();
|
||||
asset.metaData.uuid = UUID{metaFile.GetMetaClass(metaFileClass).GetValue("uuid")};
|
||||
asset.metaData.isRuntime = false;
|
||||
return asset;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include "copium/asset/Asset.h"
|
||||
#include "copium/asset/AssetFile.h"
|
||||
#include "copium/util/Common.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
class AssetManager
|
||||
{
|
||||
CP_STATIC_CLASS(AssetManager);
|
||||
private:
|
||||
static std::vector<std::string> assetDirs;
|
||||
static std::map<AssetHandle, std::unique_ptr<Asset>> assets;
|
||||
|
||||
static std::map<std::string, AssetHandle> pathToAssetCache;
|
||||
static std::map<std::string, AssetHandle> nameToAssetCache;
|
||||
static AssetHandle assetHandle;
|
||||
static AssetHandle runtimeAssetHandle;
|
||||
|
||||
static std::vector<AssetFile> cachedAssetFiles; // TODO: Make a set?
|
||||
public:
|
||||
static void RegisterAssetDir(std::string assetDir);
|
||||
static void UnregisterAssetDir(std::string assetDir);
|
||||
static Asset& GetAsset(AssetHandle handle);
|
||||
static Asset& LoadAsset(const std::string& assetPath);
|
||||
static Asset& LoadAsset(const UUID& uuid);
|
||||
static void UnloadAsset(AssetHandle handle);
|
||||
static Asset& RegisterRuntimeAsset(const std::string& name, std::unique_ptr<Asset>&& asset);
|
||||
static void Cleanup();
|
||||
|
||||
template <typename AssetT>
|
||||
static AssetT& LoadAsset(const std::string& assetPath)
|
||||
{
|
||||
AssetT* asset = dynamic_cast<AssetT*>(&LoadAsset(assetPath));
|
||||
CP_ASSERT(asset, "LoadAsset : Invalid Asset cast");
|
||||
return *asset;
|
||||
}
|
||||
|
||||
template <typename AssetT>
|
||||
static AssetT& LoadAsset(const UUID& uuid)
|
||||
{
|
||||
AssetT* asset = dynamic_cast<AssetT*>(&LoadAsset(uuid));
|
||||
CP_ASSERT(asset, "LoadAsset : Invalid Asset cast");
|
||||
return *asset;
|
||||
}
|
||||
|
||||
template <typename AssetT>
|
||||
static AssetT& GetAsset(AssetHandle handle)
|
||||
{
|
||||
Asset& asset = GetAsset(handle);
|
||||
AssetT* assetT = dynamic_cast<AssetT*>(&asset);
|
||||
CP_ASSERT(assetT, "GetAsset : Invalid Asset cast");
|
||||
return *assetT;
|
||||
}
|
||||
|
||||
template <typename AssetT>
|
||||
static AssetT& RegisterRuntimeAsset(const std::string& name, std::unique_ptr<AssetT>&& assetT)
|
||||
{
|
||||
AssetT* ptr = assetT.release();
|
||||
Asset& asset = RegisterRuntimeAsset(name, std::unique_ptr<Asset>((Asset*)ptr));
|
||||
return *(AssetT*)&asset;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
static Asset& CreateAsset(const MetaFile& metaFile, const std::string& metaFileClass);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "copium/util/UUID.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
enum class AssetType
|
||||
{
|
||||
Pipeline,
|
||||
Texture2D,
|
||||
Sound,
|
||||
};
|
||||
using AssetHandle = uint64_t;
|
||||
|
||||
struct AssetMeta
|
||||
{
|
||||
AssetHandle handle;
|
||||
AssetType type;
|
||||
std::string name;
|
||||
UUID uuid;
|
||||
bool isRuntime;
|
||||
};
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "copium/core/Vulkan.h"
|
||||
#include "copium/mesh/Vertex.h"
|
||||
#include "copium/mesh/VertexPassthrough.h"
|
||||
#include "copium/asset/AssetManager.h"
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
@@ -49,6 +50,8 @@ namespace Copium
|
||||
Application::~Application()
|
||||
{
|
||||
vkDeviceWaitIdle(Vulkan::GetDevice());
|
||||
AssetManager::UnloadAsset(texture2D);
|
||||
AssetManager::UnloadAsset(texture2D2);
|
||||
}
|
||||
|
||||
bool Application::Update()
|
||||
@@ -81,8 +84,8 @@ namespace Copium
|
||||
|
||||
void Application::InitializeTextureSampler()
|
||||
{
|
||||
texture2D = std::make_unique<Texture2D>("res/textures/texture.png");
|
||||
texture2D2 = std::make_unique<Texture2D>("res/textures/texture2.png");
|
||||
texture2D = AssetManager::LoadAsset("fox.meta");
|
||||
texture2D2 = AssetManager::LoadAsset("fox2.meta");
|
||||
}
|
||||
|
||||
void Application::InitializeDescriptorSets()
|
||||
@@ -90,7 +93,7 @@ namespace Copium
|
||||
descriptorPool = std::make_unique<DescriptorPool>();
|
||||
|
||||
descriptorSet = graphicsPipeline->CreateDescriptorSet(*descriptorPool, 0);
|
||||
descriptorSet->SetSampler(*texture2D, 1);
|
||||
descriptorSet->SetSampler(AssetManager::GetAsset<Texture2D>(texture2D), 1);
|
||||
|
||||
descriptorSetPassthrough = graphicsPipelinePassthrough->CreateDescriptorSet(*descriptorPool, 0);
|
||||
descriptorSetPassthrough->SetSampler(framebuffer->GetColorAttachment(), 0);
|
||||
@@ -144,8 +147,8 @@ namespace Copium
|
||||
renderer->Quad(glm::vec2{-1 + x * 0.2 + 0.05, -1 + y * 0.2 + 0.05}, glm::vec2{0.1, 0.1}, glm::vec3{x * 0.1, y * 0.1, 1.0});
|
||||
}
|
||||
}
|
||||
renderer->Quad(glm::vec2{-0.9, -0.4}, glm::vec2{0.8, 0.8}, *texture2D);
|
||||
renderer->Quad(glm::vec2{ 0.1, -0.4}, glm::vec2{0.8, 0.8}, *texture2D2);
|
||||
renderer->Quad(glm::vec2{-0.9, -0.4}, glm::vec2{0.8, 0.8}, AssetManager::GetAsset<Texture2D>(texture2D));
|
||||
renderer->Quad(glm::vec2{ 0.1, -0.4}, glm::vec2{0.8, 0.8}, AssetManager::GetAsset<Texture2D>(texture2D2));
|
||||
renderer->End();
|
||||
|
||||
framebuffer->Unbind(*commandBuffer);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "copium/asset/AssetMeta.h"
|
||||
#include "copium/buffer/Framebuffer.h"
|
||||
#include "copium/mesh/Mesh.h"
|
||||
#include "copium/pipeline/DescriptorPool.h"
|
||||
#include "copium/pipeline/DescriptorSet.h"
|
||||
#include "copium/pipeline/Pipeline.h"
|
||||
#include "copium/renderer/Renderer.h"
|
||||
#include "copium/sampler/Texture2D.h"
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
@@ -16,8 +16,8 @@ namespace Copium
|
||||
private:
|
||||
std::unique_ptr<Renderer> renderer;
|
||||
std::unique_ptr<Framebuffer> framebuffer;
|
||||
std::unique_ptr<Texture2D> texture2D;
|
||||
std::unique_ptr<Texture2D> texture2D2;
|
||||
AssetHandle texture2D;
|
||||
AssetHandle texture2D2;
|
||||
std::unique_ptr<DescriptorPool> descriptorPool;
|
||||
std::unique_ptr<DescriptorSet> descriptorSet;
|
||||
std::unique_ptr<DescriptorSet> descriptorSetPassthrough;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "copium/core/Vulkan.h"
|
||||
|
||||
#include "copium/asset/AssetManager.h"
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
std::unique_ptr<Instance> Vulkan::instance;
|
||||
@@ -10,13 +12,19 @@ namespace Copium
|
||||
void Vulkan::Initialize()
|
||||
{
|
||||
instance = std::make_unique<Instance>("Copium Engine");
|
||||
window = std::make_unique<Window>( "Copium Engine", 1920, 1080, Window::Mode::Windowed);
|
||||
window = std::make_unique<Window>("Copium Engine", 1920, 1080, Window::Mode::Windowed);
|
||||
device = std::make_unique<Device>();
|
||||
swapChain = std::make_unique<SwapChain>();
|
||||
|
||||
// TODO: Make the working directory always be relative to the assets folder
|
||||
// By looking at where the executable is, since that should always be in the bin folder (it currently isn't though)
|
||||
AssetManager::RegisterAssetDir("assets/");
|
||||
}
|
||||
|
||||
void Vulkan::Destroy()
|
||||
{
|
||||
AssetManager::UnregisterAssetDir("assets/");
|
||||
AssetManager::Cleanup();
|
||||
swapChain.reset();
|
||||
device.reset();
|
||||
window.reset();
|
||||
|
||||
@@ -5,9 +5,13 @@
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
int main()
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
CP_ASSERT(glfwInit() == GLFW_TRUE, "main : Failed to initialize the glfw context");
|
||||
for (int i = 0; i < argc; i++)
|
||||
{
|
||||
CP_INFO(argv[i]);
|
||||
}
|
||||
|
||||
Copium::Vulkan::Initialize();
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "copium/renderer/Renderer.h"
|
||||
|
||||
#include "copium/asset/AssetManager.h"
|
||||
#include "copium/core/Vulkan.h"
|
||||
#include "copium/pipeline/PipelineCreator.h"
|
||||
#include "copium/renderer/RendererVertex.h"
|
||||
@@ -14,13 +15,18 @@ namespace Copium
|
||||
Renderer::Renderer(VkRenderPass renderPass)
|
||||
: descriptorPool{},
|
||||
ibo{MAX_NUM_INDICES},
|
||||
emptyTexture{{0, 0, 0, 255}, 1, 1},
|
||||
samplers{MAX_NUM_TEXTURES, &emptyTexture}
|
||||
emptyTexture{AssetManager::RegisterRuntimeAsset("empty", std::make_unique<Texture2D>(std::vector<uint8_t>{0, 0, 0, 255}, 1, 1))},
|
||||
samplers{MAX_NUM_TEXTURES, &AssetManager::GetAsset<Texture2D>(emptyTexture)}
|
||||
{
|
||||
InitializeIndexBuffer();
|
||||
InitializeGraphicsPipeline(renderPass);
|
||||
}
|
||||
|
||||
Renderer::~Renderer()
|
||||
{
|
||||
AssetManager::UnloadAsset(emptyTexture);
|
||||
}
|
||||
|
||||
void Renderer::Quad(const glm::vec2& pos, const glm::vec2& size, const glm::vec3& color)
|
||||
{
|
||||
AllocateQuad();
|
||||
@@ -144,7 +150,7 @@ namespace Copium
|
||||
void Renderer::NextBatch()
|
||||
{
|
||||
batchIndex++;
|
||||
std::fill(samplers.begin(), samplers.end(), &emptyTexture);
|
||||
std::fill(samplers.begin(), samplers.end(), &AssetManager::GetAsset<Texture2D>(emptyTexture));
|
||||
if (batchIndex >= batches.size())
|
||||
{
|
||||
batches.emplace_back(std::make_unique<Batch>(*graphicsPipeline, descriptorPool, MAX_NUM_VERTICES, samplers));
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Copium
|
||||
private:
|
||||
DescriptorPool descriptorPool;
|
||||
IndexBuffer ibo;
|
||||
Texture2D emptyTexture;
|
||||
AssetHandle emptyTexture;
|
||||
std::unique_ptr<Pipeline> graphicsPipeline;
|
||||
std::vector<std::unique_ptr<Batch>> batches;
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Copium
|
||||
void* mappedVertexBuffer;
|
||||
public:
|
||||
Renderer(VkRenderPass renderPass);
|
||||
~Renderer();
|
||||
|
||||
void Quad(const glm::vec2& from, const glm::vec2& to, const glm::vec3& color = glm::vec3{1, 1, 1});
|
||||
void Quad(const glm::vec2& from, const glm::vec2& to, const Sampler& sampler, const glm::vec2& texCoord1 = glm::vec2{0, 0}, const glm::vec2& texCoord2 = glm::vec2{1, 1});
|
||||
|
||||
@@ -5,17 +5,20 @@
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb/stb_image.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
Texture2D::Texture2D(const std::string& filename)
|
||||
: Sampler{}
|
||||
Texture2D::Texture2D(const MetaFile& metaFile)
|
||||
: Sampler{}, Asset{AssetType::Texture2D}
|
||||
{
|
||||
CP_DEBUG("Texture2D : Loading texture file: %s", filename.c_str());
|
||||
InitializeTextureImageFromFile(filename);
|
||||
const std::string& filepath = metaFile.GetMetaClass("Texture2D").GetValue("filepath");
|
||||
CP_DEBUG("Texture2D : Loading texture file: %s", filepath.c_str());
|
||||
InitializeTextureImageFromFile(filepath);
|
||||
}
|
||||
|
||||
Texture2D::Texture2D(const std::vector<uint8_t>& rgbaData, int width, int height)
|
||||
: Sampler{}
|
||||
: Sampler{}, Asset{AssetType::Texture2D}
|
||||
{
|
||||
CP_ASSERT(rgbaData.size() == width * height * 4, "rgbaData has invalid size, should be equal to width * height * 4 (%d) actually is %d", width * height * 4, rgbaData.size());
|
||||
InitializeTextureImageFromData((void*)rgbaData.data(), width, height);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "copium/asset/Asset.h"
|
||||
#include "copium/buffer/CommandBufferScoped.h"
|
||||
#include "copium/sampler/Image.h"
|
||||
#include "copium/sampler/Sampler.h"
|
||||
@@ -9,7 +10,7 @@
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
class Texture2D final : public Sampler
|
||||
class Texture2D final : public Sampler, public Asset
|
||||
{
|
||||
CP_DELETE_COPY_AND_MOVE_CTOR(Texture2D);
|
||||
private:
|
||||
@@ -17,7 +18,7 @@ namespace Copium
|
||||
VkDeviceMemory imageMemory;
|
||||
VkImageView imageView;
|
||||
public:
|
||||
Texture2D(const std::string& filename);
|
||||
Texture2D(const MetaFile& metaFile);
|
||||
Texture2D(const std::vector<uint8_t>& rgbaData, int width, int height);
|
||||
~Texture2D() override;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "copium/util/RuntimeException.h"
|
||||
#include "copium/util/VulkanException.h"
|
||||
|
||||
#include <iostream>
|
||||
@@ -11,30 +12,31 @@
|
||||
#define CP_TERM_CLEAR "\033[0m"
|
||||
|
||||
#define CP_DEBUG(format, ...) std::cout << CP_TERM_GRAY << "[DBG] " << Copium::String::Format(format, __VA_ARGS__) << CP_TERM_CLEAR << std::endl
|
||||
#define CP_INFO(format, ...) std::cout << "[INF] " << Copium::String::Format(format, __VA_ARGS__) << std::endl
|
||||
#define CP_INFO(format, ...) std::cout << "[INF] " << Copium::String::Format(format, __VA_ARGS__) << std::endl
|
||||
#define CP_WARN(format, ...) std::cout << CP_TERM_YELLOW << "[WRN] " << Copium::String::Format(format, __VA_ARGS__) << CP_TERM_CLEAR << std::endl
|
||||
#define CP_ERR(format, ...) std::cout << CP_TERM_RED << "[ERR] " << Copium::String::Format(format, __VA_ARGS__) << CP_TERM_CLEAR << std::endl
|
||||
|
||||
// Continue traces, will not print the [XXX] tag before the log
|
||||
#define CP_DEBUG_CONT(format, ...) std::cout << CP_TERM_GRAY << " " << Copium::String::Format(format, __VA_ARGS__) << CP_TERM_CLEAR << std::endl
|
||||
#define CP_INFO_CONT(format, ...) std::cout << " " << Copium::String::Format(format, __VA_ARGS__) << std::endl
|
||||
#define CP_INFO_CONT(format, ...) std::cout << " " << Copium::String::Format(format, __VA_ARGS__) << std::endl
|
||||
#define CP_WARN_CONT(format, ...) std::cout << CP_TERM_YELLOW << " " << Copium::String::Format(format, __VA_ARGS__) << CP_TERM_CLEAR << std::endl
|
||||
#define CP_ERR_CONT(format, ...) std::cout << CP_TERM_RED << " " << Copium::String::Format(format, __VA_ARGS__) << CP_TERM_CLEAR << std::endl
|
||||
|
||||
#define CP_UNIMPLEMENTED() CP_WARN("%s is unimplemented", __FUNCTION__)
|
||||
#define CP_ABORT(format, ...) \
|
||||
do \
|
||||
{ \
|
||||
CP_ERR(format, __VA_ARGS__); \
|
||||
throw std::runtime_error(Copium::String::Format(format, __VA_ARGS__)); \
|
||||
CP_ERR("Aborted at %s:%d", __FILE__, __LINE__); \
|
||||
CP_ERR_CONT(format, __VA_ARGS__); \
|
||||
throw Copium::RuntimeException(Copium::String::Format(format, __VA_ARGS__)); \
|
||||
} while(false)
|
||||
#define CP_ASSERT(Function, format, ...) \
|
||||
do \
|
||||
{ \
|
||||
if(!(Function)) \
|
||||
{ \
|
||||
CP_ERR(format, __VA_ARGS__); \
|
||||
throw std::runtime_error(Copium::String::Format(format, __VA_ARGS__)); \
|
||||
CP_ERR("Assertion failed at %s:%d", __FILE__, __LINE__); \
|
||||
CP_ERR_CONT(format, __VA_ARGS__); \
|
||||
throw Copium::RuntimeException(Copium::String::Format(format, __VA_ARGS__)); \
|
||||
} \
|
||||
} while(false)
|
||||
#define CP_VK_ASSERT(Function, format, ...) \
|
||||
@@ -42,11 +44,15 @@
|
||||
{ \
|
||||
if(Function != VK_SUCCESS) \
|
||||
{ \
|
||||
CP_ERR(format, __VA_ARGS__); \
|
||||
throw VulkanException(Copium::String::Format(format, __VA_ARGS__)); \
|
||||
CP_ERR("Assertion failed at %s:%d", __FILE__, __LINE__); \
|
||||
CP_ERR_CONT(format, __VA_ARGS__); \
|
||||
throw Copium::VulkanException(Copium::String::Format(format, __VA_ARGS__)); \
|
||||
} \
|
||||
} while(false)
|
||||
|
||||
#define CP_UNIMPLEMENTED() CP_WARN("%s is unimplemented", __FUNCTION__)
|
||||
#define CP_ABORT_UNIMPLEMENTED() CP_ABORT("%s is unimplemented", __FUNCTION__)
|
||||
|
||||
#define CP_STATIC_CLASS(ClassName)\
|
||||
ClassName() = delete
|
||||
#define CP_DELETE_COPY_AND_MOVE_CTOR(ClassName) \
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
#include "copium/util/MetaFile.h"
|
||||
|
||||
#include "copium/util/Common.h"
|
||||
#include "copium/util/StringUtil.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
std::string MetaFileClass::GetValue(const std::string& key, const std::string& val) const
|
||||
{
|
||||
auto it = values.find(key);
|
||||
if(it != values.end())
|
||||
return it->second;
|
||||
return val;
|
||||
}
|
||||
|
||||
bool MetaFileClass::HasValue(const std::string& key) const
|
||||
{
|
||||
return values.find(key) != values.end();
|
||||
}
|
||||
|
||||
const std::string& MetaFileClass::GetValue(const std::string& key) const
|
||||
{
|
||||
auto it = values.find(key);
|
||||
CP_ASSERT(it != values.end(), "GetValue : Value does not exist: %s", key.c_str());
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const std::map<std::string, std::string>& MetaFileClass::GetValues() const
|
||||
{
|
||||
return values;
|
||||
}
|
||||
|
||||
void MetaFileClass::AddValue(const std::string& key, const std::string& val)
|
||||
{
|
||||
values.emplace(key, val);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, const MetaFileClass& file)
|
||||
{
|
||||
for(auto value : file.GetValues())
|
||||
{
|
||||
stream << value.first << "=" << value.second << std::endl;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
MetaFile::MetaFile() {}
|
||||
MetaFile::MetaFile(const std::string& filepath)
|
||||
: filepath{filepath}
|
||||
{
|
||||
std::ifstream stream(filepath);
|
||||
|
||||
CP_ASSERT(stream.is_open(), "MetaFile : Could not find meta file: %s", filepath.c_str());
|
||||
LoadMetaFile(stream);
|
||||
}
|
||||
|
||||
MetaFile::MetaFile(std::istream& stream)
|
||||
{
|
||||
LoadMetaFile(stream);
|
||||
}
|
||||
|
||||
bool MetaFile::HasMetaClass(const std::string& className) const
|
||||
{
|
||||
return classes.find(className) != classes.end();
|
||||
}
|
||||
|
||||
MetaFileClass& MetaFile::GetMetaClass(const std::string& className)
|
||||
{
|
||||
auto it = classes.find(className);
|
||||
CP_ASSERT(it != classes.end(), "GetMetaClass : class does not exist: %s", className.c_str());
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const MetaFileClass& MetaFile::GetMetaClass(const std::string& className) const
|
||||
{
|
||||
auto it = classes.find(className);
|
||||
CP_ASSERT(it != classes.end(), "GetMetaClass : class does not exist: ", className.c_str());
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const std::string& MetaFile::GetFilePath() const
|
||||
{
|
||||
return filepath;
|
||||
}
|
||||
|
||||
void MetaFile::AddMetaClass(const std::string& name, const MetaFileClass& metaClass)
|
||||
{
|
||||
classes[name] = metaClass;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, const MetaFile& file)
|
||||
{
|
||||
for(auto metaClass : file.classes)
|
||||
{
|
||||
stream << "[" << metaClass.first << "]" << std::endl;
|
||||
stream << metaClass.second;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
std::istream& operator>>(std::istream& stream, MetaFile& file)
|
||||
{
|
||||
file.classes.clear();
|
||||
file.LoadMetaFile(stream);
|
||||
return stream;
|
||||
}
|
||||
|
||||
void MetaFile::LoadMetaFile(std::istream& stream)
|
||||
{
|
||||
std::string currentClass = "";
|
||||
auto metaClassIt = classes.end();
|
||||
std::string line;
|
||||
while(std::getline(stream, line))
|
||||
{
|
||||
std::string_view trimmedLine = StringUtil::Trim(line);
|
||||
if(trimmedLine.empty())
|
||||
continue;
|
||||
|
||||
if(trimmedLine == "---")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(trimmedLine.front() == '[' && trimmedLine.back() == ']' )
|
||||
{
|
||||
currentClass = StringUtil::Trim(line);
|
||||
currentClass = currentClass.substr(1, currentClass.size() - 2);
|
||||
metaClassIt = classes.find(currentClass);
|
||||
CP_ASSERT(metaClassIt == classes.end(), "LoadMetaFile : Meta file contains two of the same class: %s", currentClass.c_str());
|
||||
metaClassIt = classes.emplace(currentClass, MetaFileClass{}).first;
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t pos = line.find("=");
|
||||
if(pos == std::string::npos)
|
||||
{
|
||||
CP_WARN("LoadMetaFile : Meta file line does not contain \'=\'");
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string_view key = StringUtil::Trim(std::string_view(line.c_str(), pos));
|
||||
std::string_view value = StringUtil::Trim(std::string_view(line.c_str() + pos + 1));
|
||||
if(key.length() == 0)
|
||||
{
|
||||
CP_WARN("LoadMetaFile : MetaFile key is empty");
|
||||
continue;
|
||||
}
|
||||
|
||||
CP_ASSERT(metaClassIt != classes.end(), "LoadMetaFile : No meta file header specified: ", filepath.c_str());
|
||||
auto res = metaClassIt->second.values.emplace(key, value);
|
||||
if(!res.second)
|
||||
{
|
||||
CP_WARN("LoadMetaFile : Meta file key is defined twice: %s", std::string(key).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<MetaFile> MetaFile::ReadList(const std::string& file)
|
||||
{
|
||||
std::vector<MetaFile> metaFiles;
|
||||
std::ifstream stream{file};
|
||||
if(stream)
|
||||
{
|
||||
MetaFile meta;
|
||||
while(!stream.eof())
|
||||
{
|
||||
MetaFile meta{};
|
||||
stream >> meta;
|
||||
if(meta.classes.empty())
|
||||
continue;
|
||||
metaFiles.emplace_back(meta);
|
||||
}
|
||||
return metaFiles;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
class MetaFileClass
|
||||
{
|
||||
friend class MetaFile;
|
||||
private:
|
||||
std::map<std::string, std::string> values;
|
||||
|
||||
public:
|
||||
MetaFileClass() {}
|
||||
MetaFileClass(const std::map<std::string, std::string>& values)
|
||||
: values{values}
|
||||
{}
|
||||
std::string GetValue(const std::string& key, const std::string& val) const;
|
||||
bool HasValue(const std::string& key) const;
|
||||
const std::string& GetValue(const std::string& key) const;
|
||||
const std::map<std::string, std::string>& GetValues() const;
|
||||
|
||||
void AddValue(const std::string& key, const std::string& val);
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& stream, const MetaFileClass& file);
|
||||
};
|
||||
|
||||
class MetaFile
|
||||
{
|
||||
private:
|
||||
std::string filepath;
|
||||
std::map<std::string, MetaFileClass> classes; // map<class, map<variable, value>>
|
||||
|
||||
public:
|
||||
MetaFile();
|
||||
MetaFile(const std::string& filepath);
|
||||
MetaFile(std::istream& stream);
|
||||
|
||||
bool HasMetaClass(const std::string& className) const;
|
||||
MetaFileClass& GetMetaClass(const std::string& className);
|
||||
const MetaFileClass& GetMetaClass(const std::string& className) const;
|
||||
const std::string& GetFilePath() const;
|
||||
|
||||
void AddMetaClass(const std::string& name, const MetaFileClass& metaClass);
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& stream, const MetaFile& file);
|
||||
friend std::istream& operator>>(std::istream& stream, MetaFile& file);
|
||||
|
||||
static std::vector<MetaFile> ReadList(const std::string& file);
|
||||
private:
|
||||
void LoadMetaFile(std::istream& stream);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "copium/util/RuntimeException.h"
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
RuntimeException::RuntimeException(const std::string& str)
|
||||
: errorMessage{str}
|
||||
{}
|
||||
|
||||
const std::string& RuntimeException::GetErrorMessage() const
|
||||
{
|
||||
return errorMessage;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
class RuntimeException
|
||||
{
|
||||
private:
|
||||
std::string errorMessage;
|
||||
public:
|
||||
RuntimeException(const std::string& str);
|
||||
|
||||
const std::string& GetErrorMessage() const;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "copium/util/StringUtil.h"
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
size_t StringUtil::GetTrimStartPos(const std::string_view& str)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while(pos < str.size() && (str[pos] == ' ' || str[pos] == '\t'))
|
||||
pos++;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
size_t StringUtil::GetTrimEndPos(const std::string_view& str)
|
||||
{
|
||||
if(str.empty())
|
||||
return 0;
|
||||
size_t pos = str.size() - 1;
|
||||
while(pos > 0 && (str[pos] == ' ' || str[pos] == '\t'))
|
||||
pos--;
|
||||
return pos;
|
||||
}
|
||||
|
||||
std::string_view StringUtil::Trim(const std::string_view& str)
|
||||
{
|
||||
size_t start = GetTrimStartPos(str);
|
||||
size_t end = GetTrimEndPos(str);
|
||||
if(start == str.size() || start > end)
|
||||
return "";
|
||||
return std::string_view(str.data() + start, end - start + 1);
|
||||
}
|
||||
|
||||
std::string_view StringUtil::Trim(const std::string& str)
|
||||
{
|
||||
return Trim(std::string_view(str));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "copium/util/Common.h"
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
|
||||
class StringUtil
|
||||
{
|
||||
CP_STATIC_CLASS(StringUtil);
|
||||
|
||||
public:
|
||||
static std::string_view Trim(const std::string& str);
|
||||
static std::string_view Trim(const std::string_view& str);
|
||||
private:
|
||||
static size_t GetTrimStartPos(const std::string_view& str);
|
||||
static size_t GetTrimEndPos(const std::string_view& str);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
#include "copium/util/UUID.h"
|
||||
|
||||
#include "copium/util/Common.h"
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
|
||||
std::random_device UUID::randomDevice{};
|
||||
std::mt19937 UUID::randomGenerator{randomDevice()};
|
||||
std::uniform_int_distribution<uint64_t> UUID::randomDistribution{std::numeric_limits<uint64_t>::min(), std::numeric_limits<uint64_t>::max()};
|
||||
|
||||
UUID::UUID()
|
||||
: msb{randomDistribution(randomGenerator)}, lsb{randomDistribution(randomGenerator)}
|
||||
{}
|
||||
|
||||
UUID::UUID(uint64_t msb, uint64_t lsb)
|
||||
: msb{msb}, lsb{lsb}
|
||||
{}
|
||||
|
||||
UUID::UUID(const std::string& uuidString)
|
||||
: msb{0}, lsb{0}
|
||||
{
|
||||
CP_ASSERT(uuidString.size() == 36, "UUID : Invalid UUID string size: %s", uuidString.c_str());
|
||||
for (int i = 0; i < 18; i++)
|
||||
{
|
||||
if (i == 8 || i == 13) // skip "-"
|
||||
continue;
|
||||
msb <<= 4;
|
||||
msb |= HexToDec(uuidString[i]);
|
||||
}
|
||||
for (int i = 19; i < 36; i++)
|
||||
{
|
||||
if (i == 23) // skip "-"
|
||||
continue;
|
||||
lsb <<= 4;
|
||||
lsb |= HexToDec(uuidString[i]);
|
||||
}
|
||||
}
|
||||
|
||||
std::string UUID::ToString() const
|
||||
{
|
||||
std::string string;
|
||||
string.reserve(36);
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
if (i == 8 || i == 12) string.push_back('-');
|
||||
string.push_back(DecToHex((msb >> (60 - i * 4)) & 0xf));
|
||||
}
|
||||
string.push_back('-');
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
if (i == 4) string.push_back('-');
|
||||
string.push_back(DecToHex((lsb >> (60 - i * 4)) & 0xf));
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
bool UUID::operator==(const UUID& rhs)
|
||||
{
|
||||
return msb == rhs.msb && lsb == rhs.lsb;
|
||||
}
|
||||
|
||||
bool UUID::operator!=(const UUID& rhs)
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
bool UUID::operator<(const UUID& rhs)
|
||||
{
|
||||
if (msb != rhs.msb)
|
||||
return msb < rhs.msb;
|
||||
return lsb < rhs.lsb;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const UUID& uuid)
|
||||
{
|
||||
return os << uuid.ToString();
|
||||
}
|
||||
|
||||
uint8_t UUID::HexToDec(char c) const
|
||||
{
|
||||
if (c >= '0' && c <= '9') return c - '0';
|
||||
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
||||
CP_ABORT("HexToDec : Invalid char value: %c (%d)", c, (int)c);
|
||||
}
|
||||
|
||||
char UUID::DecToHex(uint8_t nibble) const
|
||||
{
|
||||
if (nibble >= 0 && nibble <= 9) return '0' + nibble;
|
||||
if (nibble >= 10 && nibble <= 15) return 'a' + nibble - 10;
|
||||
CP_ABORT("DecToHex : Invalid nibble value: %d", (int)nibble);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
class UUID
|
||||
{
|
||||
private:
|
||||
uint64_t msb;
|
||||
uint64_t lsb;
|
||||
static std::random_device randomDevice;
|
||||
static std::mt19937 randomGenerator;
|
||||
static std::uniform_int_distribution<uint64_t> randomDistribution;
|
||||
public:
|
||||
UUID();
|
||||
UUID(uint64_t msb, uint64_t lsb);
|
||||
// Format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
UUID(const std::string& uuidString);
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
bool operator==(const UUID& rhs);
|
||||
bool operator!=(const UUID& rhs);
|
||||
bool operator<(const UUID& rhs);
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const UUID& uuid);
|
||||
|
||||
private:
|
||||
uint8_t HexToDec(char c) const;
|
||||
char DecToHex(uint8_t byte) const;
|
||||
};
|
||||
}
|
||||
@@ -1,14 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "copium/util/RuntimeException.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
class VulkanException : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
VulkanException(const std::string& str)
|
||||
: runtime_error{str.c_str()}
|
||||
{}
|
||||
};
|
||||
class VulkanException : public RuntimeException
|
||||
{
|
||||
public:
|
||||
VulkanException(const std::string& str)
|
||||
: RuntimeException{str}
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user