├── README.md ├── inlcude └── event_manager.hpp └── src └── main.cpp /README.md: -------------------------------------------------------------------------------- 1 | # SFML-EventManager 2 | 3 | Little helper to allow callbacks based event management with [SFML](https://github.com/SFML/SFML) 4 | 5 | ## Installation 6 | 7 | ### 1. Clone repo ❤️ 8 | 9 | ### 2. Include header 10 | ```cpp 11 | #include "event_manager.hpp" 12 | ``` 13 | 14 | ## Usage 15 | 16 | ### 1. Declare your callbacks 17 | ```cpp 18 | // Instanciate an events manager 19 | sfev::EventManager evm(window); 20 | ``` 21 | ```cpp 22 | // Add a close callback 23 | evm.addEventCallback(sf::Event::EventType::Closed, [&](const sf::Event&) {window.close(); }); 24 | ``` 25 | 26 | Example of Mouse and Keyboard events handling 27 | ```cpp 28 | using cEvent = const sf::Event&; 29 | 30 | // Add Key event callback 31 | evm.addKeyPressedCallback(sf::Keyboard::A, [&](cEvent) {std::cout << "A Pressed" << std::endl; }); 32 | evm.addKeyReleasedCallback(sf::Keyboard::A, [&](cEvent) {std::cout << "A released" << std::endl; }); 33 | 34 | // Add Mouse button event callback 35 | evm.addMousePressedCallback(sf::Mouse::Left, [&](cEvent) {std::cout << "Mouse LEFT pressed" << std::endl; }); 36 | evm.addMouseReleasedCallback(sf::Mouse::Left, [&](cEvent) {std::cout << "Mouse LEFT released" << std::endl; }); 37 | 38 | // Add another Mouse button event callback 39 | evm.addMousePressedCallback(sf::Mouse::Right, [&](cEvent) {std::cout << "Mouse RIGHT pressed" << std::endl; }); 40 | evm.addMouseReleasedCallback(sf::Mouse::Right, [&](cEvent) {std::cout << "Mouse RIGHT released" << std::endl; }); 41 | ``` 42 | 43 | ### 2. Enjoy clean events pooling loop 44 | ```cpp 45 | while (window.isOpen()) 46 | { 47 | // Clean and peaceful 48 | evm.processEvents(); 49 | 50 | window.clear(); 51 | ... 52 | window.display(); 53 | } 54 | ``` 55 | 56 | ## Technical details 57 | 58 | The callback is a ```std::function``` so you can pass any callable object with this signature. 59 | -------------------------------------------------------------------------------- /inlcude/event_manager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace sfev 8 | { 9 | 10 | // Helper using for shorter types 11 | using EventCallback = std::function; 12 | 13 | template 14 | using EventCallbackMap = std::unordered_map; 15 | 16 | using CstEv = const sf::Event&; 17 | 18 | 19 | /* 20 | This class handles subtyped events like keyboard or mouse events 21 | The unpack function allows to get relevant information from the processed event 22 | */ 23 | template 24 | class SubTypeManager 25 | { 26 | public: 27 | SubTypeManager(std::function unpack) : 28 | m_unpack(unpack) 29 | {} 30 | 31 | ~SubTypeManager() = default; 32 | 33 | void processEvent(const sf::Event& event) const 34 | { 35 | T sub_value = m_unpack(event); 36 | auto it(m_callmap.find(sub_value)); 37 | if (it != m_callmap.end()) { 38 | // Call its associated callback 39 | (it->second)(event); 40 | } 41 | } 42 | 43 | void addCallback(const T& sub_value, EventCallback callback) 44 | { 45 | m_callmap[sub_value] = callback; 46 | } 47 | 48 | private: 49 | EventCallbackMap m_callmap; 50 | std::function m_unpack; 51 | }; 52 | 53 | 54 | class EventMap 55 | { 56 | public: 57 | EventMap(bool use_builtin_helpers = true) 58 | : m_key_pressed_manager([](const sf::Event& event) {return event.key.code; }) 59 | , m_key_released_manager([](const sf::Event& event) {return event.key.code; }) 60 | , m_mouse_pressed_manager([](const sf::Event& event) {return event.mouseButton.button; }) 61 | , m_mouse_released_manager([](const sf::Event& event) {return event.mouseButton.button; }) 62 | { 63 | if (use_builtin_helpers) { 64 | // Register key events built in callbacks 65 | this->addEventCallback(sf::Event::EventType::KeyPressed, [&](const sf::Event& event) {m_key_pressed_manager.processEvent(event); }); 66 | this->addEventCallback(sf::Event::EventType::KeyReleased, [&](const sf::Event& event) {m_key_released_manager.processEvent(event); }); 67 | this->addEventCallback(sf::Event::EventType::MouseButtonPressed, [&](const sf::Event& event) {m_mouse_pressed_manager.processEvent(event); }); 68 | this->addEventCallback(sf::Event::EventType::MouseButtonReleased, [&](const sf::Event& event) {m_mouse_released_manager.processEvent(event); }); 69 | } 70 | } 71 | 72 | // Attaches new callback to an event 73 | void addEventCallback(sf::Event::EventType type, EventCallback callback) 74 | { 75 | m_events_callmap[type] = callback; 76 | } 77 | 78 | // Adds a key pressed callback 79 | void addKeyPressedCallback(sf::Keyboard::Key key_code, EventCallback callback) 80 | { 81 | m_key_pressed_manager.addCallback(key_code, callback); 82 | } 83 | 84 | // Adds a key released callback 85 | void addKeyReleasedCallback(sf::Keyboard::Key key_code, EventCallback callback) 86 | { 87 | m_key_released_manager.addCallback(key_code, callback); 88 | } 89 | 90 | // Adds a mouse pressed callback 91 | void addMousePressedCallback(sf::Mouse::Button button, EventCallback callback) 92 | { 93 | m_mouse_pressed_manager.addCallback(button, callback); 94 | } 95 | 96 | // Adds a mouse released callback 97 | void addMouseReleasedCallback(sf::Mouse::Button button, EventCallback callback) 98 | { 99 | m_mouse_released_manager.addCallback(button, callback); 100 | } 101 | 102 | // Runs the callback associated with an event 103 | void executeCallback(const sf::Event& e, EventCallback fallback = nullptr) const 104 | { 105 | auto it(m_events_callmap.find(e.type)); 106 | if (it != m_events_callmap.end()) { 107 | // Call its associated callback 108 | (it->second)(e); 109 | } else if (fallback) { 110 | fallback(e); 111 | } 112 | } 113 | 114 | // Removes a callback 115 | void removeCallback(sf::Event::EventType type) 116 | { 117 | // If event type is registred 118 | auto it(m_events_callmap.find(type)); 119 | if (it != m_events_callmap.end()) { 120 | // Remove its associated callback 121 | m_events_callmap.erase(it); 122 | } 123 | } 124 | 125 | private: 126 | SubTypeManager m_key_pressed_manager; 127 | SubTypeManager m_key_released_manager; 128 | SubTypeManager m_mouse_pressed_manager; 129 | SubTypeManager m_mouse_released_manager; 130 | EventCallbackMap m_events_callmap; 131 | }; 132 | 133 | 134 | /* 135 | This class handles any type of event and call its associated callbacks if any. 136 | To process key event in a more convenient way its using a KeyManager 137 | */ 138 | class EventManager 139 | { 140 | public: 141 | EventManager(sf::Window& window, bool use_builtin_helpers) : 142 | m_window(window), 143 | m_event_map(use_builtin_helpers) 144 | { 145 | } 146 | 147 | // Calls events' attached callbacks 148 | void processEvents(EventCallback fallback = nullptr) const 149 | { 150 | // Iterate over events 151 | sf::Event event; 152 | while (m_window.pollEvent(event)) { 153 | m_event_map.executeCallback(event, fallback); 154 | } 155 | } 156 | 157 | // Attaches new callback to an event 158 | void addEventCallback(sf::Event::EventType type, EventCallback callback) 159 | { 160 | m_event_map.addEventCallback(type, callback); 161 | } 162 | 163 | // Removes a callback 164 | void removeCallback(sf::Event::EventType type) 165 | { 166 | m_event_map.removeCallback(type); 167 | } 168 | 169 | // Adds a key pressed callback 170 | void addKeyPressedCallback(sf::Keyboard::Key key, EventCallback callback) 171 | { 172 | m_event_map.addKeyPressedCallback(key, callback); 173 | } 174 | 175 | // Adds a key released callback 176 | void addKeyReleasedCallback(sf::Keyboard::Key key, EventCallback callback) 177 | { 178 | m_event_map.addKeyReleasedCallback(key, callback); 179 | } 180 | 181 | // Adds a mouse pressed callback 182 | void addMousePressedCallback(sf::Mouse::Button button, EventCallback callback) 183 | { 184 | m_event_map.addMousePressedCallback(button, callback); 185 | } 186 | 187 | // Adds a mouse released callback 188 | void addMouseReleasedCallback(sf::Mouse::Button button, EventCallback callback) 189 | { 190 | m_event_map.addMouseReleasedCallback(button, callback); 191 | } 192 | 193 | sf::Window& getWindow() 194 | { 195 | return m_window; 196 | } 197 | 198 | sf::Vector2f getFloatMousePosition() const 199 | { 200 | const sf::Vector2i mouse_position = sf::Mouse::getPosition(m_window); 201 | return { static_cast(mouse_position.x), static_cast(mouse_position.y) }; 202 | } 203 | 204 | sf::Vector2i getMousePosition() const 205 | { 206 | return sf::Mouse::getPosition(m_window); 207 | } 208 | 209 | private: 210 | sf::Window& m_window; 211 | EventMap m_event_map; 212 | }; 213 | 214 | } // End namespace 215 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "event_manager.hpp" 3 | #include 4 | 5 | int main() 6 | { 7 | sf::RenderWindow window(sf::VideoMode(200, 200), "Test window"); 8 | 9 | sfev::EventManager evm(window); 10 | evm.addEventCallback(sf::Event::EventType::Closed, [&](const sf::Event&) {window.close(); }); 11 | evm.addKeyPressedCallback(sf::Keyboard::A, [&](const sf::Event&) {std::cout << "A Pressed" << std::endl; }); 12 | evm.addKeyReleasedCallback(sf::Keyboard::A, [&](const sf::Event&) {std::cout << "A released" << std::endl; }); 13 | 14 | evm.addMousePressedCallback(sf::Mouse::Button::Left, [&](const sf::Event&) {std::cout << "LEFT Mouse button pressed" << std::endl; }); 15 | evm.addMouseReleasedCallback(sf::Mouse::Button::Left, [&](const sf::Event&) {std::cout << "LEFT Mouse button released" << std::endl; }); 16 | 17 | evm.addMousePressedCallback(sf::Mouse::Button::Right, [&](const sf::Event&) {std::cout << "RIGHT Mouse button pressed" << std::endl; }); 18 | evm.addMouseReleasedCallback(sf::Mouse::Button::Right, [&](const sf::Event&) {std::cout << "RIGHT Mouse button released" << std::endl; }); 19 | 20 | while (window.isOpen()) 21 | { 22 | evm.processEvents(); 23 | 24 | window.clear(); 25 | window.display(); 26 | } 27 | 28 | return 0; 29 | } --------------------------------------------------------------------------------