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;
private:
static Application *s_instance;
void on_event(const Event &event);
void log_debug_data();
Scope<LayerStack> m_layer_stack;
};
extern Light::Scope<Application> create_application();

View file

@ -7,7 +7,7 @@ namespace Light {
class Layer;
class Event;
class LayerStack /* singleton */
class LayerStack
{
public:
static auto instance() -> LayerStack &
@ -16,21 +16,18 @@ public:
return instance;
}
~LayerStack();
// #todo: is this needed?
template<typename t, typename... Args>
template<typename Layer_T, typename... 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);
}
@ -40,38 +37,34 @@ public:
return m_layers.empty();
}
auto begin() -> std::vector<Layer *>::iterator
auto begin() -> std::vector<Ref<Layer>>::iterator
{
return m_layers.begin();
}
auto end() -> std::vector<Layer *>::iterator
auto end() -> std::vector<Ref<Layer>>::iterator
{
return m_layers.end();
}
auto rbegin() -> std::vector<Layer *>::reverse_iterator
auto rbegin() -> std::vector<Ref<Layer>>::reverse_iterator
{
return m_layers.rbegin();
}
auto rend() -> std::vector<Layer *>::reverse_iterator
auto rend() -> std::vector<Ref<Layer>>::reverse_iterator
{
return m_layers.rend();
}
private:
std::vector<Layer *> m_layers;
std::vector<Layer *>::iterator m_begin;
std::vector<Layer *>::iterator m_end;
std::vector<Ref<Layer>> m_layers;
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

View file

@ -12,11 +12,12 @@
namespace Light {
Application *Application::s_instance = nullptr;
Application::Application(): m_window(nullptr)
{
static auto constructed = false;
lt_assert(!constructed, "Application constructed twice");
constructed = true;
lt_assert(!s_instance, "Application constructed twice");
s_instance = this;
log_debug_data();
@ -34,7 +35,7 @@ Application::~Application()
void Application::game_loop()
{
// 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
m_window->get_graphics_context()->log_debug_data();
@ -54,7 +55,7 @@ void Application::game_loop()
// update layers
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());
}
@ -65,7 +66,7 @@ void Application::game_loop()
lt_profile_scope("game_loop::Render");
m_window->get_graphics_context()->get_renderer()->begin_frame();
for (auto &it : *m_layer_stack)
for (auto &it : LayerStack::instance())
{
it->on_render();
}
@ -78,7 +79,7 @@ void Application::game_loop()
lt_profile_scope("game_loop::UserInterface");
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();
}
@ -102,7 +103,7 @@ void Application::game_loop()
void Application::quit()
{
/** TODO: fix quitting procedure */
s_instance->m_window->close();
}
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))
{

View file

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

View file

@ -7,32 +7,16 @@
namespace Light {
LayerStack::~LayerStack()
void LayerStack::attach_layer_impl(Ref<Layer> layer)
{
for (auto *layer : m_layers)
{
delete layer;
}
log_trc("Attaching [{}]", layer->get_name());
m_layers.emplace_back(std::move(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
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
log_trc("Detaching [{}]", layer->get_name());
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

View file

@ -12,8 +12,8 @@
#include <engine/events/mouse.hpp>
#include <engine/graphics/graphics_context.hpp>
#include <engine/input/key_codes.hpp>
#include <utility>
#include <imgui.h>
#include <utility>
namespace Light {
@ -75,41 +75,20 @@ void UserInterface::init(GLFWwindow *windowHandle, Ref<SharedContext> sharedCont
io.ConfigFlags |= ImGuiBackendFlags_RendererHasViewports;
// #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";
} else {
}
else
{
io.IniFilename = "default_gui_layout.ini";
}
}
// style
ImGui::StyleColorsDark();
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.FontDefault = io.Fonts->AddFontFromFileTTF(
"data/assets/fonts/open_sans/OpenSans-Regular.ttf",

View file

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