#pragma once #include #include #include #include #include "debug_line.h" #include "gfx.h" #include "resource_manager.h" namespace engine { class Window; // forward-dec class InputManager; // forward-dec class Renderer; // forward-dec class SceneManager; // forward-dec struct AppConfiguration { bool enable_frame_limiter; }; class Application { private: std::unique_ptr m_window; std::unique_ptr m_input_manager; std::unique_ptr m_renderer; std::unique_ptr m_scene_manager; std::unordered_map> m_resource_managers{}; std::filesystem::path m_resources_path; AppConfiguration m_configuration; public: const char* const app_name; const char* const app_version; std::vector debug_lines{}; public: Application(const char* app_name, const char* app_version, gfx::GraphicsSettings graphics_settings, AppConfiguration configuration); Application(const Application&) = delete; ~Application(); Application& operator=(const Application&) = delete; template void registerResourceManager(); template std::shared_ptr addResource(const std::string& name, std::unique_ptr&& resource); template std::shared_ptr getResource(const std::string& name); void gameLoop(); void setFrameLimiter(bool on) { m_configuration.enable_frame_limiter = on; } Window* getWindow() { return m_window.get(); } InputManager* getInputManager() { return m_input_manager.get(); } SceneManager* getSceneManager() { return m_scene_manager.get(); } Renderer* getRenderer() { return m_renderer.get(); } std::string getResourcePath(const std::string relative_path) const { return (m_resources_path / relative_path).string(); } private: template ResourceManager* getResourceManager(); }; template void Application::registerResourceManager() { size_t hash = typeid(T).hash_code(); assert(m_resource_managers.contains(hash) == false && "Registering resource manager type more than once."); m_resource_managers.emplace(hash, std::make_unique>()); } template std::shared_ptr Application::addResource(const std::string& name, std::unique_ptr&& resource) { auto resource_manager = getResourceManager(); return resource_manager->Add(name, std::move(resource)); } template std::shared_ptr Application::getResource(const std::string& name) { auto resource_manager = getResourceManager(); return resource_manager->Get(name); } template ResourceManager* Application::getResourceManager() { size_t hash = typeid(T).hash_code(); auto it = m_resource_managers.find(hash); if (it == m_resource_managers.end()) { throw std::runtime_error("Cannot find resource manager."); } auto ptr = it->second.get(); auto casted_ptr = dynamic_cast*>(ptr); assert(casted_ptr != nullptr); return casted_ptr; } } // namespace engine