light/modules/engine/src/core/application.cpp

154 lines
3.8 KiB
C++
Raw Normal View History

2025-07-05 13:28:41 +03:30
#include <engine/core/application.hpp>
#include <engine/core/window.hpp>
#include <engine/debug/instrumentor.hpp>
#include <engine/events/event.hpp>
#include <engine/graphics/graphics_context.hpp>
#include <engine/graphics/render_command.hpp>
#include <engine/graphics/renderer.hpp>
#include <engine/layer/layer.hpp>
#include <engine/time/timer.hpp>
#include <engine/user_interface/user_interface.hpp>
2021-05-20 10:21:08 +04:30
namespace Light {
2025-07-05 13:28:41 +03:30
Application *Application::s_Context = nullptr;
2025-07-05 13:28:41 +03:30
Application::Application()
: m_Instrumentor(nullptr)
, m_LayerStack(nullptr)
, m_Input(nullptr)
, m_Window(nullptr)
2022-03-07 21:57:00 +03:30
{
ASSERT(!s_Context, "Repeated singleton construction");
s_Context = this;
2022-03-07 21:57:00 +03:30
m_Logger = Logger::Create();
LogDebugData();
2021-07-29 17:12:13 +04:30
2022-03-07 21:57:00 +03:30
m_Instrumentor = Instrumentor::Create();
m_Instrumentor->BeginSession("Logs/ProfileResults_Startup.json");
2021-07-29 17:12:13 +04:30
2022-03-07 21:57:00 +03:30
m_LayerStack = LayerStack::Create();
2025-07-05 13:28:41 +03:30
m_Input = Input::Create();
2022-03-07 21:57:00 +03:30
m_ResourceManager = ResourceManager::Create();
2022-03-07 21:57:00 +03:30
m_Window = Window::Create(std::bind(&Application::OnEvent, this, std::placeholders::_1));
}
2021-05-20 10:21:08 +04:30
2022-03-07 21:57:00 +03:30
Application::~Application()
{
LOG(trace, "Application::~Application()");
m_Instrumentor->EndSession(); // ProfileResults_Termination //
}
2021-05-20 10:21:08 +04:30
2022-03-07 21:57:00 +03:30
void Application::GameLoop()
{
// check
ASSERT(!m_LayerStack->IsEmpty(), "LayerStack is empty");
2021-05-27 19:54:05 +04:30
2022-03-07 21:57:00 +03:30
// log debug data
m_Logger->LogDebugData();
m_Window->GetGfxContext()->LogDebugData();
m_Window->GetGfxContext()->GetUserInterface()->LogDebugData();
2021-06-01 11:23:41 +04:30
2022-03-07 21:57:00 +03:30
// reveal window
m_Window->SetVisibility(true);
2022-03-07 21:57:00 +03:30
m_Instrumentor->EndSession(); // ProfileResults_GameLoop //
m_Instrumentor->BeginSession("Logs/ProfileResults_GameLoop.json");
2021-07-09 09:55:05 +04:30
2022-03-07 21:57:00 +03:30
/* game loop */
DeltaTimer deltaTimer;
while (!m_Window->IsClosed())
{
{
2022-03-07 21:57:00 +03:30
// update layers
LT_PROFILE_SCOPE("GameLoop::Update");
2022-03-07 21:57:00 +03:30
for (auto it = m_LayerStack->begin(); it != m_LayerStack->end(); it++)
(*it)->OnUpdate(deltaTimer.GetDeltaTime());
}
2022-03-07 21:57:00 +03:30
{
// render layers
LT_PROFILE_SCOPE("GameLoop::Render");
m_Window->GetGfxContext()->GetRenderer()->BeginFrame();
2022-03-07 21:57:00 +03:30
for (auto it = m_LayerStack->begin(); it != m_LayerStack->end(); it++)
(*it)->OnRender();
2022-03-07 21:57:00 +03:30
m_Window->GetGfxContext()->GetRenderer()->EndFrame();
}
2022-03-07 21:57:00 +03:30
{
// render user interface
LT_PROFILE_SCOPE("GameLoop::UserInterface");
m_Window->GetGfxContext()->GetUserInterface()->Begin();
2022-03-07 21:57:00 +03:30
for (auto it = m_LayerStack->begin(); it != m_LayerStack->end(); it++)
(*it)->OnUserInterfaceUpdate();
2022-03-07 21:57:00 +03:30
m_Window->GetGfxContext()->GetUserInterface()->End();
}
2021-07-09 09:55:05 +04:30
2022-03-07 21:57:00 +03:30
{
// poll events
LT_PROFILE_SCOPE("GameLoop::Events");
m_Window->PollEvents();
}
2021-05-20 10:21:08 +04:30
2022-03-07 21:57:00 +03:30
/// update delta time
deltaTimer.Update();
}
2022-03-07 21:57:00 +03:30
m_Instrumentor->EndSession(); // ProfileResults_GameLoop //
m_Instrumentor->BeginSession("Logs/ProfileResults_Termination.json");
}
2022-03-07 21:57:00 +03:30
void Application::Quit()
{
s_Context->m_Window->Close();
}
2021-05-27 18:55:30 +04:30
2025-07-05 13:28:41 +03:30
void Application::OnEvent(const Event &event)
2022-03-07 21:57:00 +03:30
{
// window
if (event.HasCategory(WindowEventCategory))
{
m_Window->OnEvent(event);
2022-03-07 21:57:00 +03:30
if (event.GetEventType() == EventType::WindowResized)
2025-07-05 13:28:41 +03:30
m_Window->GetGfxContext()->GetRenderer()->OnWindowResize(
(const WindowResizedEvent &)event
);
2021-05-23 18:10:11 +04:30
}
2022-03-07 21:57:00 +03:30
// input
if (event.HasCategory(InputEventCategory))
2021-06-15 09:39:11 +04:30
{
2022-03-07 21:57:00 +03:30
m_Input->OnEvent(event);
2025-07-05 13:28:41 +03:30
if (!m_Input->IsReceivingGameEvents()) // return if the event is an input event and 'Input'
// has disabled the game events
2022-03-07 21:57:00 +03:30
return;
2021-06-15 09:39:11 +04:30
}
2022-03-07 21:57:00 +03:30
/* layers */
for (auto it = m_LayerStack->rbegin(); it != m_LayerStack->rend(); it++)
if ((*it)->OnEvent(event))
return;
}
void Application::LogDebugData()
{
// #todo: log more information
LOG(info, "________________________________________");
LOG(info, "Platform::");
LOG(info, " OS: {}", LT_BUILD_PLATFORM);
LOG(info, " DIR: {}", std::filesystem::current_path().generic_string());
LOG(info, "________________________________________");
}
} // namespace Light