fix: segfault & refactor: layerstack to hold refs

This commit is contained in:
light7734 2025-07-06 17:45:40 +03:30
parent 25e1ee8aa0
commit 345dddcf11
Signed by: light7734
GPG key ID: 8C30176798F1A6BA
7 changed files with 40 additions and 83 deletions

View file

@ -28,11 +28,11 @@ protected:
Scope<Window> m_window; Scope<Window> m_window;
private: private:
static Application *s_instance;
void on_event(const Event &event); void on_event(const Event &event);
void log_debug_data(); void log_debug_data();
Scope<LayerStack> m_layer_stack;
}; };
extern Light::Scope<Application> create_application(); extern Light::Scope<Application> create_application();

View file

@ -7,7 +7,7 @@ namespace Light {
class Layer; class Layer;
class Event; class Event;
class LayerStack /* singleton */ class LayerStack
{ {
public: public:
static auto instance() -> LayerStack & static auto instance() -> LayerStack &
@ -16,21 +16,18 @@ public:
return instance; return instance;
} }
~LayerStack(); template<typename Layer_T, typename... Args>
// #todo: is this needed?
template<typename t, typename... Args>
static void emplace_layer(Args &&...args) static void emplace_layer(Args &&...args)
{ {
instance().attach_layer_impl(new t((args)...)); instance().attach_layer_impl(create_ref<Layer_T>(std::forward<Args>(args)...));
} }
static void attach_layer(Layer *layer) static void attach_layer(Ref<Layer> layer)
{ {
instance().attach_layer_impl(layer); instance().attach_layer_impl(std::move(layer));
} }
static void detach_layer(Layer *layer) static void detach_layer(const Ref<Layer> &layer)
{ {
instance().detach_layer_impl(layer); instance().detach_layer_impl(layer);
} }
@ -40,38 +37,34 @@ public:
return m_layers.empty(); return m_layers.empty();
} }
auto begin() -> std::vector<Layer *>::iterator auto begin() -> std::vector<Ref<Layer>>::iterator
{ {
return m_layers.begin(); return m_layers.begin();
} }
auto end() -> std::vector<Layer *>::iterator auto end() -> std::vector<Ref<Layer>>::iterator
{ {
return m_layers.end(); return m_layers.end();
} }
auto rbegin() -> std::vector<Layer *>::reverse_iterator auto rbegin() -> std::vector<Ref<Layer>>::reverse_iterator
{ {
return m_layers.rbegin(); return m_layers.rbegin();
} }
auto rend() -> std::vector<Layer *>::reverse_iterator auto rend() -> std::vector<Ref<Layer>>::reverse_iterator
{ {
return m_layers.rend(); return m_layers.rend();
} }
private: private:
std::vector<Layer *> m_layers; std::vector<Ref<Layer>> m_layers;
std::vector<Layer *>::iterator m_begin;
std::vector<Layer *>::iterator m_end;
LayerStack() = default; LayerStack() = default;
void attach_layer_impl(Layer *layer); void attach_layer_impl(Ref<Layer> layer);
void detach_layer_impl(Layer *layer); void detach_layer_impl(const Ref<Layer> &layer);
}; };
} // namespace Light } // namespace Light

View file

@ -12,11 +12,12 @@
namespace Light { namespace Light {
Application *Application::s_instance = nullptr;
Application::Application(): m_window(nullptr) Application::Application(): m_window(nullptr)
{ {
static auto constructed = false; lt_assert(!s_instance, "Application constructed twice");
lt_assert(!constructed, "Application constructed twice"); s_instance = this;
constructed = true;
log_debug_data(); log_debug_data();
@ -34,7 +35,7 @@ Application::~Application()
void Application::game_loop() void Application::game_loop()
{ {
// check // check
lt_assert(!m_layer_stack->is_empty(), "layer_stack is empty"); lt_assert(!LayerStack::instance().is_empty(), "layer_stack is empty");
// log debug data // log debug data
m_window->get_graphics_context()->log_debug_data(); m_window->get_graphics_context()->log_debug_data();
@ -54,7 +55,7 @@ void Application::game_loop()
// update layers // update layers
lt_profile_scope("game_loop::update"); lt_profile_scope("game_loop::update");
for (auto &it : *m_layer_stack) for (auto &it : LayerStack::instance())
{ {
it->on_update(delta_timer.get_delta_time()); it->on_update(delta_timer.get_delta_time());
} }
@ -65,7 +66,7 @@ void Application::game_loop()
lt_profile_scope("game_loop::Render"); lt_profile_scope("game_loop::Render");
m_window->get_graphics_context()->get_renderer()->begin_frame(); m_window->get_graphics_context()->get_renderer()->begin_frame();
for (auto &it : *m_layer_stack) for (auto &it : LayerStack::instance())
{ {
it->on_render(); it->on_render();
} }
@ -78,7 +79,7 @@ void Application::game_loop()
lt_profile_scope("game_loop::UserInterface"); lt_profile_scope("game_loop::UserInterface");
m_window->get_graphics_context()->get_user_interface()->begin(); m_window->get_graphics_context()->get_user_interface()->begin();
for (auto &it : *m_layer_stack) for (auto &it : LayerStack::instance())
{ {
it->on_user_interface_update(); it->on_user_interface_update();
} }
@ -102,7 +103,7 @@ void Application::game_loop()
void Application::quit() void Application::quit()
{ {
/** TODO: fix quitting procedure */ s_instance->m_window->close();
} }
void Application::on_event(const Event &event) void Application::on_event(const Event &event)
@ -131,7 +132,7 @@ void Application::on_event(const Event &event)
} }
} }
for (auto &it : std::ranges::reverse_view(*m_layer_stack)) for (auto &it : std::ranges::reverse_view(LayerStack::instance()))
{ {
if (it->on_event(event)) if (it->on_event(event))
{ {

View file

@ -123,7 +123,7 @@ void Input::on_event(const Event &inputEvent)
if (m_user_interface_events) if (m_user_interface_events)
{ {
io.KeysDown[event.get_key()] = true; // io.AddKeyEvent(event.get_key(), true);
// if (event.get_key() == Key::BackSpace) // if (event.get_key() == Key::BackSpace)
// io.AddInputCharacter(Key::BackSpace); // io.AddInputCharacter(Key::BackSpace);
} }
@ -141,7 +141,7 @@ void Input::on_event(const Event &inputEvent)
if (m_user_interface_events) if (m_user_interface_events)
{ {
io.KeysDown[event.get_key()] = false; // io.AddKeyEvent(event.get_key(), false);
} }
return; return;

View file

@ -7,32 +7,16 @@
namespace Light { namespace Light {
LayerStack::~LayerStack() void LayerStack::attach_layer_impl(Ref<Layer> layer)
{ {
for (auto *layer : m_layers) log_trc("Attaching [{}]", layer->get_name());
{ m_layers.emplace_back(std::move(layer));
delete layer;
}
} }
void LayerStack::attach_layer_impl(Layer *layer) void LayerStack::detach_layer_impl(const Ref<Layer> &layer)
{ {
// #todo: handle attaching layer inside a for loop log_trc("Detaching [{}]", layer->get_name());
m_layers.push_back(layer);
m_begin = m_layers.begin();
m_end = m_layers.end();
log_trc("Attached [{}]", layer->get_name());
}
void LayerStack::detach_layer_impl(Layer *layer)
{
// #todo: handle detaching layer inside a for loop
m_layers.erase(std::find(m_layers.begin(), m_layers.end(), layer)); m_layers.erase(std::find(m_layers.begin(), m_layers.end(), layer));
m_begin = m_layers.begin();
m_end = m_layers.end();
log_trc("Detached [{}]", layer->get_name());
} }
} // namespace Light } // namespace Light

View file

@ -12,8 +12,8 @@
#include <engine/events/mouse.hpp> #include <engine/events/mouse.hpp>
#include <engine/graphics/graphics_context.hpp> #include <engine/graphics/graphics_context.hpp>
#include <engine/input/key_codes.hpp> #include <engine/input/key_codes.hpp>
#include <utility>
#include <imgui.h> #include <imgui.h>
#include <utility>
namespace Light { namespace Light {
@ -75,9 +75,12 @@ void UserInterface::init(GLFWwindow *windowHandle, Ref<SharedContext> sharedCont
io.ConfigFlags |= ImGuiBackendFlags_RendererHasViewports; io.ConfigFlags |= ImGuiBackendFlags_RendererHasViewports;
// #todo: handle this in a better way // #todo: handle this in a better way
if (std::filesystem::exists("user_gui_layout.ini")) { if (std::filesystem::exists("user_gui_layout.ini"))
{
io.IniFilename = "user_gui_layout.ini"; io.IniFilename = "user_gui_layout.ini";
} else { }
else
{
io.IniFilename = "default_gui_layout.ini"; io.IniFilename = "default_gui_layout.ini";
} }
@ -86,30 +89,6 @@ void UserInterface::init(GLFWwindow *windowHandle, Ref<SharedContext> sharedCont
platform_implementation(windowHandle, std::move(sharedContext)); platform_implementation(windowHandle, std::move(sharedContext));
// keyboard map
io.KeyMap[ImGuiKey_Tab] = Key::Tab;
io.KeyMap[ImGuiKey_LeftArrow] = Key::LeftArrow;
io.KeyMap[ImGuiKey_RightArrow] = Key::RightArrow;
io.KeyMap[ImGuiKey_UpArrow] = Key::UpArrow;
io.KeyMap[ImGuiKey_DownArrow] = Key::DownArrow;
io.KeyMap[ImGuiKey_PageUp] = Key::PageUp;
io.KeyMap[ImGuiKey_PageDown] = Key::PageDown;
io.KeyMap[ImGuiKey_Home] = Key::Home;
io.KeyMap[ImGuiKey_End] = Key::end;
io.KeyMap[ImGuiKey_Insert] = Key::Insert;
io.KeyMap[ImGuiKey_Delete] = Key::Delete;
io.KeyMap[ImGuiKey_Backspace] = Key::BackSpace;
io.KeyMap[ImGuiKey_Space] = Key::Space;
io.KeyMap[ImGuiKey_Enter] = Key::Enter;
io.KeyMap[ImGuiKey_Escape] = Key::Escape;
io.KeyMap[ImGuiKey_KeyPadEnter] = Key::Enter;
io.KeyMap[ImGuiKey_A] = Key::A;
io.KeyMap[ImGuiKey_C] = Key::C;
io.KeyMap[ImGuiKey_V] = Key::V;
io.KeyMap[ImGuiKey_X] = Key::X;
io.KeyMap[ImGuiKey_Y] = Key::Y;
io.KeyMap[ImGuiKey_Z] = Key::Z;
io.Fonts->AddFontFromFileTTF("data/assets/fonts/open_sans/OpenSans-Bold.ttf", 18.0f); io.Fonts->AddFontFromFileTTF("data/assets/fonts/open_sans/OpenSans-Bold.ttf", 18.0f);
io.FontDefault = io.Fonts->AddFontFromFileTTF( io.FontDefault = io.Fonts->AddFontFromFileTTF(
"data/assets/fonts/open_sans/OpenSans-Regular.ttf", "data/assets/fonts/open_sans/OpenSans-Regular.ttf",

View file

@ -23,7 +23,7 @@ public:
m_window->set_properties(properties); m_window->set_properties(properties);
// Attach the sandbox layer // Attach the sandbox layer
LayerStack::emplace_layer<EditorLayer>(("MirrorLayer")); LayerStack::emplace_layer<EditorLayer>("MirrorLayer");
} }
}; };