#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]; }; struct Model { std::vector vertices; std::vector indices; GLuint vao; GLuint vbo; GLuint ebo; GLuint textureID; Model() : vao(0), vbo(0), ebo(0), textureID(0) {} }; // 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); };