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

198 lines
4.6 KiB
C++
Raw Normal View History

#include <asset_manager/asset_manager.hpp>
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/layer/layer.hpp>
#include <engine/time/timer.hpp>
#include <input/events/event.hpp>
#include <input/events/keyboard.hpp>
#include <input/events/window.hpp>
2025-07-10 13:43:04 +03:30
#include <debug/assertions.hpp>
2025-07-06 16:30:38 +03:30
#include <ranges>
#include <renderer/blender.hpp>
#include <renderer/graphics_context.hpp>
#include <renderer/render_command.hpp>
#include <renderer/renderer.hpp>
#include <ui/ui.hpp>
2025-07-11 00:05:48 +03:30
namespace lt {
2021-05-20 10:21:08 +04:30
Application *Application::s_instance = nullptr;
2025-07-06 17:23:28 +03:30
Application::Application(): m_window(nullptr)
2022-03-07 21:57:00 +03:30
{
lt_assert(!s_instance, "Application constructed twice");
s_instance = this;
log_debug_data();
2021-07-29 17:12:13 +04:30
2025-07-11 00:05:48 +03:30
lt::Instrumentor::begin_session("data/logs/profile_startup.json");
2021-07-29 17:12:13 +04:30
2025-07-06 17:23:28 +03:30
m_window = Window::create([this](auto &&PH1) { on_event(std::forward<decltype(PH1)>(PH1)); });
// create graphics context
m_graphics_context = GraphicsContext::create(
GraphicsAPI::OpenGL,
(GLFWwindow *)m_window->get_handle()
);
AssetManager::load_shader(
"LT_ENGINE_RESOURCES_TEXTURE_SHADER",
"data/assets/shaders/texture/vs.asset",
"data/assets/shaders/texture/ps.asset"
);
AssetManager::load_shader(
"LT_ENGINE_RESOURCES_TINTED_TEXTURE_SHADER",
"data/assets/shaders/tinted_texture/vs.asset",
"data/assets/shaders/tinted_texture/ps.asset"
);
AssetManager::load_shader(
"LT_ENGINE_RESOURCES_QUAD_SHADER",
"data/assets/shaders/quads/vs.asset",
"data/assets/shaders/quads/ps.asset"
);
m_renderer = Renderer::create(
(GLFWwindow *)m_window->get_handle(),
m_graphics_context->get_shared_context(),
Renderer::CreateInfo {
.quad_renderer_shader = AssetManager::get_shader("LT_ENGINE_RESOURCES_QUAD_SHADER"),
.texture_renderer_shader = AssetManager::get_shader("LT_ENGINE_RESOURCES_TEXTURE_SHADER"
),
.tinted_texture_renderer_shader = AssetManager::get_shader("LT_ENGINE_RESOURCES_TINTED_"
"TEXTURE_SHADER"),
}
);
lt_assert(m_graphics_context, "lWindow::lWindow: failed to create 'GraphicsContext'");
m_user_interface = UserInterface::create(
(GLFWwindow *)m_window->get_handle(),
m_graphics_context->get_shared_context()
);
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()
{
2025-07-06 16:30:38 +03:30
log_trc("Application::~Application()");
2025-07-06 17:23:28 +03:30
Instrumentor::end_session();
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(!LayerStack::instance().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_graphics_context->log_debug_data();
m_user_interface->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);
2025-07-06 17:23:28 +03:30
Instrumentor::end_session();
2025-07-07 15:15:26 +03:30
Instrumentor::begin_session("data/logs/profile_game_loop.json");
2021-07-09 09:55:05 +04:30
2022-03-07 21:57:00 +03:30
/* game loop */
2025-07-07 15:13:05 +03:30
auto timer = Timer {};
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 : LayerStack::instance())
2025-07-06 17:23:28 +03:30
{
2025-07-07 15:13:05 +03:30
it->on_update(timer.get_elapsed_time());
2025-07-06 17:23:28 +03:30
}
2025-07-07 15:13:05 +03:30
// TODO: each layer should have their own "delta time"
timer.reset();
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_renderer->begin_frame();
for (auto &it : LayerStack::instance())
2025-07-06 17:23:28 +03:30
{
2025-07-06 16:52:50 +03:30
it->on_render();
2025-07-06 17:23:28 +03:30
}
m_renderer->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_user_interface->begin();
for (auto &it : LayerStack::instance())
2025-07-06 17:23:28 +03:30
{
2025-07-06 16:52:50 +03:30
it->on_user_interface_update();
2025-07-06 17:23:28 +03:30
}
m_user_interface->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();
}
}
2025-07-06 17:23:28 +03:30
Instrumentor::end_session();
2025-07-07 15:15:26 +03:30
Instrumentor::begin_session("data/logs/profile_cleanup.json");
2022-03-07 21:57:00 +03:30
}
void Application::quit()
2022-03-07 21:57:00 +03:30
{
s_instance->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);
2025-07-06 17:23:28 +03:30
if (event.get_event_type() == EventType::WindowResized)
{
m_renderer->on_window_resize(dynamic_cast<const WindowResizedEvent &>(event));
2025-07-06 17:23:28 +03:30
}
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
{
2025-07-06 17:23:28 +03:30
Input::instance().on_event(event);
2022-03-07 21:57:00 +03:30
2025-07-06 17:23:28 +03:30
if (!Input::instance().is_receiving_game_events())
2025-07-06 16:30:38 +03:30
{
2022-03-07 21:57:00 +03:30
return;
2025-07-06 16:30:38 +03:30
}
2021-06-15 09:39:11 +04:30
}
for (auto &it : std::ranges::reverse_view(LayerStack::instance()))
2025-07-06 16:30:38 +03:30
{
if (it->on_event(event))
{
2022-03-07 21:57:00 +03:30
return;
2025-07-06 16:30:38 +03:30
}
}
2022-03-07 21:57:00 +03:30
}
void Application::log_debug_data()
2022-03-07 21:57:00 +03:30
{
2025-07-06 16:30:38 +03:30
log_inf("Platform::");
log_inf(" Platform name: {}", constants::platform_name);
log_inf(" Platform identifier: {}", std::to_underlying(constants::platform));
log_inf(" CWD: {}", std::filesystem::current_path().generic_string());
2022-03-07 21:57:00 +03:30
}
2025-07-11 00:05:48 +03:30
} // namespace lt