Create-Engine/src/src/core/utils/AssetManager.h

176 lines
4.3 KiB
C++

#pragma once
#include <string>
#include <unordered_map>
#include <memory>
#include <future>
#include <yaml-cpp/yaml.h>
#include "../types/vec2.h"
#include <GL/glew.h>
#include <string_view>
#include "miniaudio.h"
using UAssetID = uint64_t;
class Object;
#define ASSET_TEXTURE "ASSET_TEXTURE"
#define ASSET_AUDIO "ASSET_AUDIO"
#define ASSET_FONT "ASSET_FONT"
#define ASSET_SHADER "ASSET_SHADER"
#define ASSET_SCRIPT "ASSET_SCRIPT"
#define ASSET_SCENE "ASSET_SCENE"
#define ASSET_VIDEO "ASSET_VIDEO"
#define ASSET_PREFAB "ASSET_PREFAB"
#define ASSET_UNKNOWN "ASSET_UNKNOWN"
#define ASSET_TYPE_LIST \
X(Image) \
X(Audio) \
X(Font) \
X(Prefab) \
X(Shader) \
X(Script) \
X(Scene) \
X(Video) \
X(Unknown)
enum class AssetType
{
#define X(name) name,
ASSET_TYPE_LIST
#undef X
};
inline const char *AssetTypeToString(AssetType type)
{
switch (type)
{
#define X(name) \
case AssetType::name: \
return #name;
ASSET_TYPE_LIST
#undef X
default:
return "Unknown";
}
}
inline AssetType StringToAssetType(const std::string_view str)
{
static const std::unordered_map<std::string_view, AssetType> map = {
#define X(name) {#name, AssetType::name},
ASSET_TYPE_LIST
#undef X
};
auto it = map.find(str);
return it != map.end() ? it->second : AssetType::Unknown;
}
struct AssetInfo
{
uint64_t uaid = 0;
std::string path;
std::string filename;
std::string filetype;
AssetType type = AssetType::Image;
std::string hash;
std::time_t lastModified = 0;
bool loaded = false;
virtual ~AssetInfo() = default;
virtual void Save(YAML::Emitter &out) const = 0;
virtual void Load(const YAML::Node &node) = 0;
};
struct ImageAssetInfo : public AssetInfo
{
core::types::Vec2 size = {0, 0};
int channels = 4;
std::string format = "GL_RGBA";
GLuint textureID = 0;
ImageAssetInfo() { type = AssetType::Image; }
void Save(YAML::Emitter &out) const override;
void Load(const YAML::Node &node) override;
};
struct AudioAssetInfo : public AssetInfo
{
ma_sound *sound = nullptr;
AudioAssetInfo() { type = AssetType::Audio; }
void Save(YAML::Emitter &out) const override;
void Load(const YAML::Node &node) override;
};
struct FontAssetInfo : public AssetInfo
{
GLuint atlasTextureID = 0;
int atlasWidth = 0;
int atlasHeight = 0;
FontAssetInfo();
void Save(YAML::Emitter &out) const override;
void Load(const YAML::Node &node) override;
};
struct PrefabAssetInfo : public AssetInfo
{
YAML::Node prefabYAML;
std::shared_ptr<Object> prefabRoot = nullptr;
std::string prefabName = "Unnamed Prefab";
PrefabAssetInfo();
~PrefabAssetInfo() override
{
prefabRoot.reset();
}
std::shared_ptr<Object> Instantiate() const;
void Save(YAML::Emitter &out) const override;
void Load(const YAML::Node &node) override;
void ReloadFromYAML();
};
const char *MiniaudioResultToString(ma_result result);
class AssetManager
{
public:
static void Init();
static void LoadAssetAsync(const std::string &path, AssetType type);
static const AssetInfo *GetAssetByID(uint64_t uaid);
static const AssetInfo *GetAssetByPath(const std::string &path);
static const std::unordered_map<uint64_t, std::shared_ptr<AssetInfo>> &GetAllAssets();
static void UnloadAsset(uint64_t uaid);
static void ClearAllAssets();
static void Save(YAML::Emitter &out);
static void Load(const YAML::Node &node);
static uint64_t GenerateUAID();
static std::string GetFileExtension(const std::string& filepath);
static AssetType AssetTypeFromExtension(std::string ext);
static AssetType AssetTypeFromPath(const std::string& filepath);
private:
static std::unordered_map<uint64_t, std::shared_ptr<AssetInfo>> s_Assets;
static std::unordered_map<std::string, uint64_t> s_PathToUAID;
static uint64_t s_NextUAID;
static void LoadImageInternal(const std::string &path, uint64_t uaid);
static void LoadAudioInternal(const std::string &path, uint64_t uaid);
static void LoadPrefabInternal(const std::string &path, uint64_t uaid);
static void LoadFontInternal(const std::string &path, uint64_t uaid);
};