#include "window.h" #include #include namespace Donut { static bool s_glfw_initialized = false; static uint32_t s_glfw_window_count = 0; Window::Window(const std::string& title, int width, int height) : m_title(title), m_width(width), m_height(height), m_is_closed(false) { init(); } Window::~Window() { shutdown(); } void Window::init() { if (!s_glfw_initialized) { int success = glfwInit(); if (!success) { std::cout << "Could not initialize GLFW!" << std::endl; return; } s_glfw_initialized = true; } m_window = glfwCreateWindow(m_width, m_height, m_title.c_str(), nullptr, nullptr); if (!m_window) { std::cout << "Could not create GLFW window!" << std::endl; glfwTerminate(); return; } glfwMakeContextCurrent(m_window); glfwSetWindowUserPointer(m_window, this); glfwSetErrorCallback(glfw_error_callback); glfwSetWindowCloseCallback(m_window, glfw_window_close_callback); glfwSetWindowSizeCallback(m_window, glfw_window_size_callback); glfwSetWindowFocusCallback(m_window, glfw_window_focus_callback); glfwSetWindowPosCallback(m_window, glfw_window_pos_callback); glfwSetKeyCallback(m_window, glfw_key_callback); glfwSetCharCallback(m_window, glfw_char_callback); glfwSetMouseButtonCallback(m_window, glfw_mouse_button_callback); glfwSetScrollCallback(m_window, glfw_mouse_scroll_callback); glfwSetCursorPosCallback(m_window, glfw_cursor_pos_callback); s_glfw_window_count++; } void Window::shutdown() { glfwDestroyWindow(m_window); s_glfw_window_count--; if (s_glfw_window_count == 0) { glfwTerminate(); s_glfw_initialized = false; } } void Window::on_update() const { glfwPollEvents(); glfwSwapBuffers(m_window); } bool Window::should_close() const { return glfwWindowShouldClose(m_window) || m_is_closed; } void Window::glfw_error_callback(int error, const char* description) { std::cout << "GLFW Error (" << error << "): " << description << std::endl; } void Window::glfw_window_close_callback(GLFWwindow* window) { Window* win = static_cast(glfwGetWindowUserPointer(window)); WindowCloseEvent event; win->m_event_handler.on_event(event); } void Window::glfw_window_size_callback(GLFWwindow* window, int width, int height) { Window* win = static_cast(glfwGetWindowUserPointer(window)); win->m_width = width; win->m_height = height; WindowResizeEvent event(width, height); win->m_event_handler.on_event(event); } void Window::glfw_window_focus_callback(GLFWwindow* window, int focused) { Window* win = static_cast(glfwGetWindowUserPointer(window)); if (focused) { WindowFocusEvent event; win->m_event_handler.on_event(event); } else { WindowLostFocusEvent event; win->m_event_handler.on_event(event); } } void Window::glfw_window_pos_callback(GLFWwindow* window, int xpos, int ypos) { Window* win = static_cast(glfwGetWindowUserPointer(window)); WindowMovedEvent event(xpos, ypos); win->m_event_handler.on_event(event); } void Window::glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { Window* win = static_cast(glfwGetWindowUserPointer(window)); switch (action) { case GLFW_PRESS: { KeyPressedEvent event(key, false); win->m_event_handler.on_event(event); } break; case GLFW_RELEASE: { KeyReleasedEvent event(key); win->m_event_handler.on_event(event); } break; case GLFW_REPEAT: { KeyPressedEvent event(key, true); win->m_event_handler.on_event(event); } break; } } void Window::glfw_char_callback(GLFWwindow* window, unsigned int keycode) { Window* win = static_cast(glfwGetWindowUserPointer(window)); KeyTypedEvent event(keycode); win->m_event_handler.on_event(event); } void Window::glfw_mouse_button_callback(GLFWwindow* window, int button, int action, int mods) { Window* win = static_cast(glfwGetWindowUserPointer(window)); switch (action) { case GLFW_PRESS: { MouseButtonPressedEvent event(button); win->m_event_handler.on_event(event); } break; case GLFW_RELEASE: { MouseButtonReleasedEvent event(button); win->m_event_handler.on_event(event); break; } } } void Window::glfw_mouse_scroll_callback(GLFWwindow* window, double x_offset, double y_offset) { Window* win = static_cast(glfwGetWindowUserPointer(window)); MouseScrolledEvent event((float)x_offset, (float)y_offset); win->m_event_handler.on_event(event); } void Window::glfw_cursor_pos_callback(GLFWwindow* window, double x_pos, double y_pos) { Window* win = static_cast(glfwGetWindowUserPointer(window)); MouseMovedEvent event((float)x_pos, (float)y_pos); win->m_event_handler.on_event(event); } }