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>
|
2025-07-06 16:30:38 +03:30
|
|
|
#include <ranges>
|
2021-07-01 19:25:46 +04:30
|
|
|
|
2021-05-20 10:21:08 +04:30
|
|
|
namespace Light {
|
|
|
|
|
2025-07-06 17:23:28 +03:30
|
|
|
Application::Application(): m_window(nullptr)
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
2025-07-06 17:23:28 +03:30
|
|
|
static auto constructed = false;
|
|
|
|
lt_assert(!constructed, "Application constructed twice");
|
|
|
|
constructed = true;
|
2021-10-02 08:51:54 +03:30
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
log_debug_data();
|
2021-07-29 17:12:13 +04:30
|
|
|
|
2025-07-06 16:52:50 +03:30
|
|
|
Light::Instrumentor::begin_session("Logs/ProfileResults_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)); });
|
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
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
void Application::game_loop()
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
|
|
|
// check
|
2025-07-05 15:36:53 +03:30
|
|
|
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
|
2025-07-06 14:02:50 +03:30
|
|
|
m_window->get_graphics_context()->log_debug_data();
|
|
|
|
m_window->get_graphics_context()->get_user_interface()->log_debug_data();
|
2021-06-01 11:23:41 +04:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
// reveal window
|
2025-07-05 15:36:53 +03:30
|
|
|
m_window->set_visibility(true);
|
2021-06-14 10:01:28 +04:30
|
|
|
|
2025-07-06 17:23:28 +03:30
|
|
|
Instrumentor::end_session();
|
|
|
|
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 */
|
2025-07-06 14:02:50 +03:30
|
|
|
auto delta_timer = DeltaTimer {};
|
2025-07-05 15:36:53 +03:30
|
|
|
while (!m_window->is_closed())
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
2021-05-23 21:25:31 +04:30
|
|
|
{
|
2022-03-07 21:57:00 +03:30
|
|
|
// update layers
|
2025-07-05 15:36:53 +03:30
|
|
|
lt_profile_scope("game_loop::update");
|
2021-07-12 15:20:47 +04:30
|
|
|
|
2025-07-06 17:23:28 +03:30
|
|
|
for (auto &it : *m_layer_stack)
|
|
|
|
{
|
2025-07-06 16:52:50 +03:30
|
|
|
it->on_update(delta_timer.get_delta_time());
|
2025-07-06 17:23:28 +03:30
|
|
|
}
|
2022-03-07 21:57:00 +03:30
|
|
|
}
|
2021-07-21 15:14:22 +04:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
|
|
|
// render layers
|
2025-07-05 15:36:53 +03:30
|
|
|
lt_profile_scope("game_loop::Render");
|
2025-07-06 14:02:50 +03:30
|
|
|
m_window->get_graphics_context()->get_renderer()->begin_frame();
|
2021-07-21 15:14:22 +04:30
|
|
|
|
2025-07-06 17:23:28 +03:30
|
|
|
for (auto &it : *m_layer_stack)
|
|
|
|
{
|
2025-07-06 16:52:50 +03:30
|
|
|
it->on_render();
|
2025-07-06 17:23:28 +03:30
|
|
|
}
|
2021-07-12 15:20:47 +04:30
|
|
|
|
2025-07-06 14:02:50 +03:30
|
|
|
m_window->get_graphics_context()->get_renderer()->end_frame();
|
2022-03-07 21:57:00 +03:30
|
|
|
}
|
2021-07-21 15:14:22 +04:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
|
|
|
// render user interface
|
2025-07-05 15:36:53 +03:30
|
|
|
lt_profile_scope("game_loop::UserInterface");
|
2025-07-06 14:02:50 +03:30
|
|
|
m_window->get_graphics_context()->get_user_interface()->begin();
|
2021-07-21 15:14:22 +04:30
|
|
|
|
2025-07-06 17:23:28 +03:30
|
|
|
for (auto &it : *m_layer_stack)
|
|
|
|
{
|
2025-07-06 16:52:50 +03:30
|
|
|
it->on_user_interface_update();
|
2025-07-06 17:23:28 +03:30
|
|
|
}
|
2021-07-12 15:20:47 +04:30
|
|
|
|
2025-07-06 14:02:50 +03:30
|
|
|
m_window->get_graphics_context()->get_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
|
2025-07-05 15:36:53 +03:30
|
|
|
lt_profile_scope("game_loop::Events");
|
|
|
|
m_window->poll_events();
|
2021-05-23 21:25:31 +04:30
|
|
|
}
|
2021-05-20 10:21:08 +04:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
/// update delta time
|
2025-07-06 14:02:50 +03:30
|
|
|
delta_timer.update();
|
2021-10-02 08:51:54 +03:30
|
|
|
}
|
|
|
|
|
2025-07-06 17:23:28 +03:30
|
|
|
Instrumentor::end_session();
|
|
|
|
Instrumentor::begin_session("Logs/ProfileResults_Termination.json");
|
2022-03-07 21:57:00 +03:30
|
|
|
}
|
2021-07-14 00:17:30 +04:30
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
void Application::quit()
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
2025-07-06 17:23:28 +03:30
|
|
|
/** TODO: fix quitting procedure */
|
2022-03-07 21:57:00 +03:30
|
|
|
}
|
2021-05-27 18:55:30 +04:30
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
void Application::on_event(const Event &event)
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
|
|
|
// window
|
2025-07-05 15:36:53 +03:30
|
|
|
if (event.has_category(WindowEventCategory))
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
2025-07-05 15:36:53 +03:30
|
|
|
m_window->on_event(event);
|
2021-07-21 20:03:39 +04:30
|
|
|
|
2025-07-06 17:23:28 +03:30
|
|
|
if (event.get_event_type() == EventType::WindowResized)
|
|
|
|
{
|
2025-07-06 14:02:50 +03:30
|
|
|
m_window->get_graphics_context()->get_renderer()->on_window_resize(
|
2025-07-05 13:28:41 +03:30
|
|
|
(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
|
2025-07-05 15:36:53 +03:30
|
|
|
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
|
|
|
}
|
|
|
|
|
2025-07-06 16:30:38 +03:30
|
|
|
for (auto &it : std::ranges::reverse_view(*m_layer_stack))
|
|
|
|
{
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2025-07-05 15:36:53 +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
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Light
|