From 0d30bb843d3aeeacae211e1d0ba3cbf5faa01cd7 Mon Sep 17 00:00:00 2001 From: ancarola Date: Sun, 3 Feb 2019 21:52:52 +0100 Subject: Create an interface to SDL events List of basic events interfaces in namespace wsdl2::event - event_t - e_key - mouse::e_mouse - mouse::e_motion - mouse::e_button - e_quit (pure SDL quit callback) - window::e_window - window::e_resize - window::e_move --- event.cpp | 100 ++++++++++++++++++++++++++--- include/event.hpp | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++--- include/video.hpp | 9 ++- video.cpp | 15 +++++ 4 files changed, 287 insertions(+), 20 deletions(-) diff --git a/event.cpp b/event.cpp index 60d432e..a6830e6 100644 --- a/event.cpp +++ b/event.cpp @@ -1,21 +1,105 @@ #include "event.hpp" - -#include +#include "video.hpp" extern "C" { #include } -wsdl2::event::event(const SDL_Event& e) { - m_event = e; +using namespace wsdl2::event; + +event_t::event_t(const SDL_Event& e) : m_event(e) {} + +event_t::event_t(const event_t& e) : m_event(e.m_event) {} + +uint32_t event_t::type() const +{ + return m_event.type; } -std::optional wsdl2::poll_event() { +std::shared_ptr poll_event() { + SDL_Event ev; +#define EV_PTR(__type__) std::make_shared(ev) + + using namespace wsdl2::event; + if (SDL_PollEvent(&ev) != 0) { - return event(ev); + + switch (ev.type) + { + + // keyboard events + case SDL_KEYUP: + return EV_PTR(e_key); + case SDL_KEYDOWN: + return EV_PTR(e_key); + + // mouse events + case SDL_MOUSEMOTION: + return EV_PTR(mouse::e_motion); + case SDL_MOUSEBUTTONDOWN: + return EV_PTR(mouse::e_button); + case SDL_MOUSEBUTTONUP: + return EV_PTR(mouse::e_button); + case SDL_MOUSEWHEEL: + return EV_PTR(mouse::e_wheel); + + // sdl quit event + case SDL_QUIT: + return EV_PTR(e_quit); + + // window events + case SDL_WINDOWEVENT: + + switch (ev.window.event) + { + case (SDL_WINDOWEVENT_MOVED): + return EV_PTR(window::e_move); + case (SDL_WINDOWEVENT_RESIZED): + return EV_PTR(window::e_resize); + case (SDL_WINDOWEVENT_SIZE_CHANGED): + return EV_PTR(window::e_resize); + default: + return EV_PTR(window::e_window); + } + } + + return nullptr; } - return std::nullopt; -} \ No newline at end of file + return nullptr; +} + + +/* + * Keyboard + */ + +e_key::action_t e_key::action() const +{ + return static_cast(sdl().type); +} + +SDL_Keycode e_key::get() const +{ + return sdl().key.keysym.sym; +} + +/* + * Mouse + */ + +mouse::action_t mouse::e_mouse::action() const +{ + return static_cast(sdl().type); +} + +mm::vec2 mouse::e_mouse::location() const +{ + // TODO + return mm::vec2({}); +} + +// TODO other structures +// diff --git a/include/event.hpp b/include/event.hpp index 9932cb8..12e898f 100644 --- a/include/event.hpp +++ b/include/event.hpp @@ -1,24 +1,189 @@ #pragma once -#include +#include "mm/mmvec.hpp" +#include extern "C" { #include } namespace wsdl2 { - class event { - public: - using type = SDL_EventType; - event(const SDL_Event& e); + // forward declaration + class window; +} - SDL_Event& sdl() { return m_event; } +namespace wsdl2::event { + + class event_t { - private: SDL_Event m_event; + + protected: + + SDL_Event& sdl() { return m_event; } + + const SDL_Event& sdl() const { return m_event; } + + public: + + event_t(const SDL_Event& e); + + // polymorphic + virtual ~event_t() {} + + // copy constructor + event_t(const event_t& e); + + uint32_t type() const; + }; + + struct e_key : public event_t + { + enum class action_t : unsigned + { + up = SDL_KEYUP, + down = SDL_KEYDOWN + }; + + using event_t::event_t; + e_key(const event_t& e) : event_t(e) {} + + action_t action() const; + + // key pressed or released + SDL_Keycode get() const; + }; + + namespace mouse { + + enum class action_t : unsigned + { + button_up = SDL_MOUSEBUTTONUP, + button_down = SDL_MOUSEBUTTONDOWN, + motion = SDL_MOUSEMOTION, + wheel = SDL_MOUSEWHEEL + }; + + struct e_mouse : public event_t + { + virtual ~e_mouse() {} + + using event_t::event_t; + e_mouse(const event_t& e) : event_t(e) {} + + action_t action() const; + + virtual mm::vec2 location() const = 0; + }; + + struct e_button : public e_mouse + { + using e_mouse::e_mouse; + e_button(const event_t& e) : e_mouse(e) {} + + enum class button_t : unsigned + { + left = SDL_BUTTON_LEFT, + middle = SDL_BUTTON_MIDDLE, + right = SDL_BUTTON_RIGHT, + x1 = SDL_BUTTON_X1, + x2 = SDL_BUTTON_X2 + }; + + mm::vec2 clicks() const; + + button_t which() const; + + virtual mm::vec2 location() const override; + }; + + struct e_motion : public e_mouse + { + using e_mouse::e_mouse; + e_motion(const event_t& e) : e_mouse(e) {} + + // delta (x, y) + mm::vec2 movement() const; + + virtual mm::vec2 location() const override; + }; + + struct e_wheel : public e_mouse + { + using e_mouse::e_mouse; + e_wheel(const event_t& e) : e_mouse(e) {} + + int horizontal() const; + int vertical() const; + + virtual mm::vec2 location() const override; + }; + + } + + struct e_quit : public event_t + { + using event_t::event_t; + e_quit(const event_t& e) : event_t(e) {} }; + namespace window { + + enum class action_t : unsigned + { + shown = SDL_WINDOWEVENT_SHOWN, + hidden = SDL_WINDOWEVENT_HIDDEN, + exposed = SDL_WINDOWEVENT_EXPOSED, + moved = SDL_WINDOWEVENT_MOVED, + resized = SDL_WINDOWEVENT_RESIZED, + size_changed = SDL_WINDOWEVENT_SIZE_CHANGED, + minimized = SDL_WINDOWEVENT_MINIMIZED, + maximized = SDL_WINDOWEVENT_MAXIMIZED, + restored = SDL_WINDOWEVENT_RESTORED, + enter = SDL_WINDOWEVENT_ENTER, + leave = SDL_WINDOWEVENT_LEAVE, + focus_gained = SDL_WINDOWEVENT_FOCUS_GAINED, + focus_lost = SDL_WINDOWEVENT_FOCUS_LOST, + close = SDL_WINDOWEVENT_CLOSE, + take_focus = SDL_WINDOWEVENT_TAKE_FOCUS, + hit_test = SDL_WINDOWEVENT_HIT_TEST + }; + + + struct e_window : public event_t + { + + using event_t::event_t; + e_window(const event_t& e) : event_t(e) {} + + // TODO, mapping sdl window id with wsdl2 object + wsdl2::window * window(); + + action_t action() const; + }; + + // window positional event + struct e_move : public e_window + { + using e_window::e_window; + e_move(const event_t& e) : e_window(e) {} + + mm::vec2 position(); + }; + + // window bound event + struct e_resize : public e_window + { + using e_window::e_window; + e_resize(const event_t& e) : e_window(e) {} + + mm::vec2 size(); + }; + } + + // TODO other handlers + + std::shared_ptr poll_event(); +} - std::optional poll_event(); -} \ No newline at end of file diff --git a/include/video.hpp b/include/video.hpp index 1d71d21..7fbf859 100644 --- a/include/video.hpp +++ b/include/video.hpp @@ -4,6 +4,7 @@ #include #include +#include #include extern "C" { @@ -236,6 +237,9 @@ namespace wsdl2 { /// a basic wrapper around a SDL window class window { + + static std::map win_map; + public: friend class renderer; @@ -261,6 +265,8 @@ namespace wsdl2 { renderer& get_renderer() { return m_renderer; } void update(); + static window * get(Uint8 id); + private: bool m_open; renderer m_renderer; @@ -269,7 +275,4 @@ namespace wsdl2 { // dirty C code SDL_Window* sdl(); }; - - - } diff --git a/video.cpp b/video.cpp index 5a5e933..e777371 100644 --- a/video.cpp +++ b/video.cpp @@ -87,6 +87,10 @@ renderer::~renderer() { /* class window */ +// existing window mapping (SDL_ID <-> window) +std::map window::win_map; + + window::window(const std::string& title, std::size_t width, std::size_t height) { // create (hidden) window m_window = SDL_CreateWindow( @@ -102,6 +106,9 @@ window::window(const std::string& title, std::size_t width, std::size_t height) throw std::runtime_error("failed to create SDL window"); } + // put into window id mapping + win_map.insert(std::pair(static_cast(SDL_GetWindowID(m_window)), this)); + m_renderer.create_sdl_renderer(m_window); // other attributes @@ -134,7 +141,14 @@ bool window::is_visible() { return SDL_WINDOW_SHOWN & SDL_GetWindowFlags(m_window); } +window * window::get(Uint8 id) +{ + auto it = win_map.find(id); + return (it != win_map.end()) ? it->second : 0; +} + void window::update() { + m_renderer.clear(); m_renderer.present(); } @@ -150,3 +164,4 @@ SDL_Window * window::sdl() { return m_window; } + -- cgit v1.2.1