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

154 lines
3.9 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_layer_stack(nullptr)
, m_input(nullptr)
, m_window(nullptr)
2022-03-07 21:57:00 +03:30
{
lt_assert(!s_Context, "Repeated singleton construction");
2022-03-07 21:57:00 +03:30
s_Context = this;
m_logger = logger::create();
log_debug_data();
2021-07-29 17:12:13 +04:30
m_instrumentor = Instrumentor::create();
m_instrumentor->begin_session("Logs/ProfileResults_Startup.json");
2021-07-29 17:12:13 +04:30
m_layer_stack = LayerStack::create();
m_input = Input::create();
m_resource_manager = ResourceManager::create();
m_window = Window::create(std::bind(&Application::on_event, this, std::placeholders::_1));
2022-03-07 21:57:00 +03:30
}
2021-05-20 10:21:08 +04:30
2022-03-07 21:57:00 +03:30
Application::~Application()
{
lt_log(trace, "Application::~Application()");
m_instrumentor->end_session(); // ProfileResults_Termination //
2022-03-07 21:57:00 +03:30
}
2021-05-20 10:21:08 +04:30
void Application::game_loop()
2022-03-07 21:57:00 +03:30
{
// check
lt_assert(!m_layer_stack->is_empty(), "layer_stack is empty");
2021-05-27 19:54:05 +04:30
2022-03-07 21:57:00 +03:30
// log debug data
m_logger->log_debug_data();
m_window->GetGfxContext()->log_debug_data();
m_window->GetGfxContext()->GetUserInterface()->log_debug_data();
2021-06-01 11:23:41 +04:30
2022-03-07 21:57:00 +03:30
// reveal window
m_window->set_visibility(true);
m_instrumentor->end_session(); // ProfileResults_GameLoop //
m_instrumentor->begin_session("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->is_closed())
2022-03-07 21:57:00 +03:30
{
{
2022-03-07 21:57:00 +03:30
// update layers
lt_profile_scope("game_loop::update");
for (auto it = m_layer_stack->begin(); it != m_layer_stack->end(); it++)
(*it)->on_update(deltaTimer.get_delta_time());
2022-03-07 21:57:00 +03:30
}
2022-03-07 21:57:00 +03:30
{
// render layers
lt_profile_scope("game_loop::Render");
m_window->GetGfxContext()->GetRenderer()->begin_frame();
for (auto it = m_layer_stack->begin(); it != m_layer_stack->end(); it++)
(*it)->on_render();
m_window->GetGfxContext()->GetRenderer()->end_frame();
2022-03-07 21:57:00 +03:30
}
2022-03-07 21:57:00 +03:30
{
// render user interface
lt_profile_scope("game_loop::UserInterface");
m_window->GetGfxContext()->GetUserInterface()->begin();
for (auto it = m_layer_stack->begin(); it != m_layer_stack->end(); it++)
(*it)->on_user_interface_update();
m_window->GetGfxContext()->GetUserInterface()->end();
2022-03-07 21:57:00 +03:30
}
2021-07-09 09:55:05 +04:30
2022-03-07 21:57:00 +03:30
{
// poll events
lt_profile_scope("game_loop::Events");
m_window->poll_events();
}
2021-05-20 10:21:08 +04:30
2022-03-07 21:57:00 +03:30
/// update delta time
deltaTimer.update();
}
m_instrumentor->end_session(); // ProfileResults_GameLoop //
m_instrumentor->begin_session("Logs/ProfileResults_Termination.json");
2022-03-07 21:57:00 +03:30
}
void Application::quit()
2022-03-07 21:57:00 +03:30
{
s_Context->m_window->close();
2022-03-07 21:57:00 +03:30
}
2021-05-27 18:55:30 +04:30
void Application::on_event(const Event &event)
2022-03-07 21:57:00 +03:30
{
// window
if (event.has_category(WindowEventCategory))
2022-03-07 21:57:00 +03:30
{
m_window->on_event(event);
if (event.get_event_type() == EventType::WindowResized)
m_window->GetGfxContext()->GetRenderer()->on_window_resize(
2025-07-05 13:28:41 +03:30
(const WindowResizedEvent &)event
);
2021-05-23 18:10:11 +04:30
}
2022-03-07 21:57:00 +03:30
// input
if (event.has_category(InputEventCategory))
2021-06-15 09:39:11 +04:30
{
m_input->on_event(event);
2022-03-07 21:57:00 +03:30
if (!m_input->is_receiving_game_events()) // 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_layer_stack->rbegin(); it != m_layer_stack->rend(); it++)
if ((*it)->on_event(event))
2022-03-07 21:57:00 +03:30
return;
}
void Application::log_debug_data()
2022-03-07 21:57:00 +03:30
{
// #todo: log more information
lt_log(info, "________________________________________");
lt_log(info, "Platform::");
lt_log(info, " OS: {}", LT_BUILD_PLATFORM);
lt_log(info, " DIR: {}", std::filesystem::current_path().generic_string());
lt_log(info, "________________________________________");
2022-03-07 21:57:00 +03:30
}
} // namespace Light