#pragma once #include #include #include #include #include #include "gcml.h" #include "stdexcept" #include // Forward-declare your Shader class class Shader; // Define types of assets enum class AssetType { TEXTURE, SHADER, SOUND, MODEL, }; // A simple struct to hold the generic pointer struct GenericAsset { void *data = nullptr; }; struct Vertex { float position[3]; float texCoord[2]; float normal[3]; }; // Define a Texture structure struct Texture { GLuint id; std::string type; std::string path; }; struct Model { std::vector vertices; std::vector indices; std::vector textures; GLuint vao, vbo, ebo; }; // The main AssetManager class AssetManager { public: AssetManager() = default; ~AssetManager() = default; using AssetVariant = std::variant; // Template function to load an asset template T loadAsset(AssetType type, const std::string &path) { // 1) Create a unique key for cache lookup std::string key = generateKey(type, path); // 2) Check if it’s already loaded auto it = m_AssetMap.find(key); if (it != m_AssetMap.end()) { // Debug: Log the variant type if (std::holds_alternative(it->second)) { return std::get(it->second); } else { throw std::runtime_error("Asset type mismatch for key: " + key); } } // 3) Not loaded yet, load from disk AssetVariant assetData = loadAssetFromDisk(type, path); if (assetData.index() == std::variant_npos) { DEBUG_PRINT("[AssetManager] Failed to load asset: %s", path.c_str()); // Replace NULL with 0 for non-pointer types if constexpr (std::is_pointer_v) { return nullptr; // For pointers } else { return 0; // For non-pointer } } // 4) Store in cache m_AssetMap[key] = assetData; // 5) Return the loaded asset return std::get(assetData); } void DebugAssetMap(); private: // Cache of already loaded assets: key = "type + path" std::unordered_map m_AssetMap; AssetVariant loadAssetFromDisk(AssetType type, const std::string &path); // Generate the unique key std::string generateKey(AssetType type, const std::string &path); };