fix: segfault & refactor: layerstack to hold refs
This commit is contained in:
		
							parent
							
								
									25e1ee8aa0
								
							
						
					
					
						commit
						345dddcf11
					
				
					 7 changed files with 40 additions and 83 deletions
				
			
		| 
						 | 
					@ -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();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue