Files
OpenVulkano/openVulkanoCpp/Host/GraphicsAppManager.cpp

204 lines
5.1 KiB
C++

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "GraphicsAppManager.hpp"
#include "Base/IPlatform.hpp"
#include "Base/Logger.hpp"
#include "Base/FrameMetadata.hpp"
#include "PlatformProducer.hpp"
#include <chrono>
#include <thread>
#include <stdexcept>
namespace openVulkanoCpp
{
GraphicsAppManager::GraphicsAppManager(openVulkanoCpp::IGraphicsApp* app, RenderAPI::RenderApi renderApi)
: app(app), renderApi(renderApi)
{
Utils::SetThreadName("Main");
Logger::SetupLogger();
if (!app)
{
constexpr auto msg = "The app must not be null!";
Logger::MANAGER->error(msg);
throw std::runtime_error(msg);
}
platform = std::unique_ptr<IPlatform>(PlatformProducer::CreatePlatform(renderApi));
window = platform->MakeWindow();
renderer = std::unique_ptr<IRenderer>(PlatformProducer::CreateRenderManager(renderApi));
app->SetGraphicsAppManager(this);
window->SetWindowHandler(this);
}
GraphicsAppManager::GraphicsAppManager(IGraphicsApp* app, IWindow* window, RenderAPI::RenderApi renderApi)
: app(app), renderApi(renderApi)
{
Utils::SetThreadName("Main");
Logger::SetupLogger();
if (!app)
{
constexpr auto msg = "The app must not be null!";
Logger::MANAGER->error(msg);
throw std::runtime_error(msg);
}
//platform = std::unique_ptr<IPlatform>(PlatformProducer::CreatePlatform(renderApi));
this->window = window;
renderer = std::unique_ptr<IRenderer>(PlatformProducer::CreateRenderManager(renderApi));
app->SetGraphicsAppManager(this);
window->SetWindowHandler(this);
}
GraphicsAppManager::~GraphicsAppManager() noexcept
{
if (windowTitleFormat.empty()) return;
ShutDown();
}
void GraphicsAppManager::Stop()
{
running = false;
Logger::MANAGER->info("Graphics application stopped");
}
void GraphicsAppManager::Pause()
{
paused = true;
frameTimer.Stop();
Logger::MANAGER->info("Graphics application paused");
}
void GraphicsAppManager::Resume()
{
paused = false;
frameTimer.Start();
Logger::MANAGER->info("Graphics application resumed");
}
void GraphicsAppManager::Run()
{
running = true;
StartUp();
frameTimer.Reset();
Loop(); // Runs the rendering loop
ShutDown();
}
void GraphicsAppManager::StartUp()
{
try
{
Logger::MANAGER->info("Initializing ...");
app->Init();
if (platform) platform->Init();
window->Init(renderApi);
//TODO restore window settings if there are any set
renderer->Init(static_cast<IGraphicsAppManager*>(this), window);
windowTitleFormat = app->GetAppName() + " " + static_cast<std::string>(app->GetAppVersion()) + " - " + renderer->GetMainRenderDeviceName() + " - {:.1f} fps ({:.1f} ms)";
Logger::MANAGER->info("Initialized");
}
catch (std::exception& e)
{
Logger::MANAGER->error("Failed to initiate: {0}", e.what());
running = false;
#ifdef DEBUG
throw e;
#endif
}
}
void GraphicsAppManager::Loop()
{
while (running)
{
LoopTick();
}
}
void GraphicsAppManager::LoopTick()
{
if (platform) platform->Tick();
if (paused)
{ // The rendering is paused
// No need to burn cpu time if the app is paused
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
else
{
app->Tick();
renderer->Tick();
frameTimer.Tick();
UpdateFps();
CURRENT_FRAME.frameId = frameCount;
CURRENT_FRAME.frameTime = frameTimer.GetTickSeconds();
}
}
void GraphicsAppManager::ShutDown()
{
Logger::MANAGER->info("Shutting down ...");
app->Close();
renderer->Close();
window->Close();
if (platform) platform->Close();
windowTitleFormat = "";
Logger::MANAGER->info("Shutdown complete");
}
void GraphicsAppManager::UpdateFps()
{
frameCount++;
fpsTimer += frameTimer.GetTickSeconds();
if(fpsTimer > 1.0f)
{
avgFps = static_cast<float>(frameCount - lastFrameCount) / fpsTimer;
avgFrameTime = (1 / avgFps) * 1000.0f;
lastFrameCount = frameCount;
fpsTimer = 0;
if (window->HasTitle())
{
window->SetTitle(fmt::format(windowTitleFormat, avgFps, avgFrameTime));
}
}
}
void GraphicsAppManager::OnWindowMinimize(openVulkanoCpp::IWindow* window)
{
if (window != this->window) return;
Pause();
}
void GraphicsAppManager::OnWindowRestore(openVulkanoCpp::IWindow* window)
{
if (window != this->window) return;
Resume();
}
void GraphicsAppManager::OnWindowFocusLost(IWindow* window)
{}
void GraphicsAppManager::OnWindowFocusGained(IWindow* window)
{}
void GraphicsAppManager::OnWindowMove(IWindow* window, int posX, int posY)
{
//TODO save window pos
}
void GraphicsAppManager::OnWindowResize(openVulkanoCpp::IWindow* window, const uint32_t newWidth, const uint32_t newHeight)
{
if(window != this->window) return;
if (window->GetWidth() != newWidth || window->GetHeight() != newHeight) window->SetSize(newWidth, newHeight);
renderer->Resize(newWidth, newHeight);
}
void GraphicsAppManager::OnWindowClose(openVulkanoCpp::IWindow* window)
{
window->SetWindowHasBeenDestroyed();
if (window != this->window) return;
Stop();
}
}