From 86c1a71a934579760c76e746cdec1ac83b28a0a8 Mon Sep 17 00:00:00 2001 From: vittorioromeo Date: Sun, 23 Jun 2024 12:30:02 +0200 Subject: [PATCH] Remove default empty state of `sf::Event` --- .github/ISSUE_TEMPLATE/bug_report.yml | 4 +- .github/ISSUE_TEMPLATE/feature_request.yml | 4 +- .github/pull_request_template.md | 4 +- doc/mainpage.hpp | 4 +- examples/android/app/src/main/jni/main.cpp | 24 +++-- examples/island/Island.cpp | 11 +-- examples/joystick/Joystick.cpp | 18 ++-- examples/opengl/OpenGL.cpp | 22 ++--- examples/raw_input/RawInput.cpp | 8 +- examples/shader/Shader.cpp | 6 +- examples/sound_effects/SoundEffects.cpp | 6 +- examples/stencil/Stencil.cpp | 4 +- examples/tennis/Tennis.cpp | 14 +-- examples/vulkan/Vulkan.cpp | 17 ++-- examples/window/Window.cpp | 17 ++-- include/SFML/Graphics/RenderWindow.hpp | 4 +- include/SFML/Window/Clipboard.hpp | 11 +-- include/SFML/Window/Event.hpp | 45 ++-------- include/SFML/Window/Window.hpp | 4 +- include/SFML/Window/WindowBase.hpp | 22 ++--- src/SFML/Window/Android/WindowImplAndroid.cpp | 40 +++------ src/SFML/Window/DRM/InputImpl.cpp | 88 ++++++++----------- src/SFML/Window/DRM/WindowImplDRM.cpp | 7 +- src/SFML/Window/WindowBase.cpp | 33 +++++-- src/SFML/Window/WindowImpl.cpp | 10 +-- src/SFML/Window/WindowImpl.hpp | 12 +-- test/Window/Event.test.cpp | 37 +------- 27 files changed, 199 insertions(+), 277 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 69e9e25ab..3159bd708 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -57,9 +57,9 @@ body: while (window.isOpen()) { - while (const auto event = window.pollEvent()) + while (const std::optional event = window.pollEvent()) { - if (event.is()) + if (event->is()) window.close(); } diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 235e0360a..de8376d11 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -54,9 +54,9 @@ body: while (window.isOpen()) { - while (const auto event = window.pollEvent()) + while (const std::optional event = window.pollEvent()) { - if (event.is()) + if (event->is()) window.close(); } diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 179526f3a..dc6753170 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -39,9 +39,9 @@ int main() while (window.isOpen()) { - while (const auto event = window.pollEvent()) + while (const std::optional event = window.pollEvent()) { - if (event.is()) + if (event->is()) window.close(); } diff --git a/doc/mainpage.hpp b/doc/mainpage.hpp index 9b444e59c..b2599e1bb 100644 --- a/doc/mainpage.hpp +++ b/doc/mainpage.hpp @@ -38,10 +38,10 @@ /// while (window.isOpen()) /// { /// // Process events -/// while (const auto event = window.pollEvent()) +/// while (const std::optional event = window.pollEvent()) /// { /// // Close window: exit -/// if (event.is()) +/// if (event->is()) /// window.close(); /// } /// diff --git a/examples/android/app/src/main/jni/main.cpp b/examples/android/app/src/main/jni/main.cpp index 18da48f89..e79609595 100644 --- a/examples/android/app/src/main/jni/main.cpp +++ b/examples/android/app/src/main/jni/main.cpp @@ -109,43 +109,41 @@ int main(int argc, char* argv[]) while (window.isOpen()) { - while (const auto event = active ? window.pollEvent() : window.waitEvent()) + while (const std::optional event = active ? window.pollEvent() : window.waitEvent()) { - if (event.is()) + if (event->is() || + (event->is() && + event->getIf()->code == sf::Keyboard::Key::Escape)) { window.close(); } - else if (const auto* keyPressed = event.getIf()) - { - if (keyPressed->code == sf::Keyboard::Key::Escape) - window.close(); - } - else if (const auto* resized = event.getIf()) + + else if (const auto* resized = event->getIf()) { const auto size = sf::Vector2f(resized->size); view.setSize(size); view.setCenter(size / 2.f); window.setView(view); } - else if (event.is()) + else if (event->is()) { background = sf::Color::Black; } - else if (event.is()) + else if (event->is()) { background = sf::Color::White; } // On Android MouseLeft/MouseEntered are (for now) triggered, // whenever the app loses or gains focus. - else if (event.is()) + else if (event->is()) { active = false; } - else if (event.is()) + else if (event->is()) { active = true; } - else if (const auto* touchBegan = event.getIf()) + else if (const auto* touchBegan = event->getIf()) { if (touchBegan->finger == 0) { diff --git a/examples/island/Island.cpp b/examples/island/Island.cpp index 401dc749b..819bd8689 100644 --- a/examples/island/Island.cpp +++ b/examples/island/Island.cpp @@ -174,20 +174,21 @@ int main() while (window.isOpen()) { // Handle events - while (const auto event = window.pollEvent()) + while (const std::optional event = window.pollEvent()) { // Window closed or escape key pressed: exit - if (event.is() || (event.is() && - event.getIf()->code == sf::Keyboard::Key::Escape)) + if (event->is() || + (event->is() && + event->getIf()->code == sf::Keyboard::Key::Escape)) { window.close(); break; } // Arrow key pressed: - if (terrainShader.has_value() && event.is()) + if (terrainShader.has_value() && event->is()) { - switch (event.getIf()->code) + switch (event->getIf()->code) { case sf::Keyboard::Key::Enter: generateTerrain(terrainStagingBuffer.data()); diff --git a/examples/joystick/Joystick.cpp b/examples/joystick/Joystick.cpp index 019a37f32..09ce372a6 100644 --- a/examples/joystick/Joystick.cpp +++ b/examples/joystick/Joystick.cpp @@ -156,36 +156,38 @@ int main() while (window.isOpen()) { // Handle events - while (const auto event = window.pollEvent()) + while (const std::optional event = window.pollEvent()) { // Window closed or escape key pressed: exit - if (event.is() || (event.is() && - event.getIf()->code == sf::Keyboard::Key::Escape)) + if (event->is() || + (event->is() && + event->getIf()->code == sf::Keyboard::Key::Escape)) { window.close(); break; } - else if (const auto* joystickButtonPressed = event.getIf()) + + if (const auto* joystickButtonPressed = event->getIf()) { // Update displayed joystick values updateValues(joystickButtonPressed->joystickId); } - else if (const auto* joystickButtonReleased = event.getIf()) + else if (const auto* joystickButtonReleased = event->getIf()) { // Update displayed joystick values updateValues(joystickButtonReleased->joystickId); } - else if (const auto* joystickMoved = event.getIf()) + else if (const auto* joystickMoved = event->getIf()) { // Update displayed joystick values updateValues(joystickMoved->joystickId); } - else if (const auto* joystickConnected = event.getIf()) + else if (const auto* joystickConnected = event->getIf()) { // Update displayed joystick values updateValues(joystickConnected->joystickId); } - else if (event.is()) + else if (event->is()) { // Reset displayed joystick values to empty for (auto& [label, joystickObject] : texts) diff --git a/examples/opengl/OpenGL.cpp b/examples/opengl/OpenGL.cpp index cd093409f..9841c06a4 100644 --- a/examples/opengl/OpenGL.cpp +++ b/examples/opengl/OpenGL.cpp @@ -201,25 +201,19 @@ int main() while (window.isOpen()) { // Process events - while (const auto event = window.pollEvent()) + while (const std::optional event = window.pollEvent()) { - // Close window: exit - if (event.is()) - { - exit = true; - window.close(); - } - - // Escape key: exit - if (const auto* keyPressed = event.getIf(); - keyPressed && keyPressed->code == sf::Keyboard::Key::Escape) + // Window closed or escape key pressed: exit + if (event->is() || + (event->is() && + event->getIf()->code == sf::Keyboard::Key::Escape)) { exit = true; window.close(); } // Return key: toggle mipmapping - if (const auto* keyPressed = event.getIf(); + if (const auto* keyPressed = event->getIf(); keyPressed && keyPressed->code == sf::Keyboard::Key::Enter) { if (mipmapEnabled) @@ -236,7 +230,7 @@ int main() } // Space key: toggle sRGB conversion - if (const auto* keyPressed = event.getIf(); + if (const auto* keyPressed = event->getIf(); keyPressed && keyPressed->code == sf::Keyboard::Key::Space) { sRgb = !sRgb; @@ -244,7 +238,7 @@ int main() } // Adjust the viewport when the window is resized - if (const auto* resized = event.getIf()) + if (const auto* resized = event->getIf()) { const sf::Vector2u textureSize = backgroundTexture.getSize(); diff --git a/examples/raw_input/RawInput.cpp b/examples/raw_input/RawInput.cpp index d514864a6..29d38a424 100644 --- a/examples/raw_input/RawInput.cpp +++ b/examples/raw_input/RawInput.cpp @@ -34,9 +34,9 @@ int main() while (window.isOpen()) { - while (const auto event = window.pollEvent()) + while (const std::optional event = window.pollEvent()) { - if (event.is()) + if (event->is()) { window.close(); break; @@ -45,10 +45,10 @@ int main() static const auto vec2ToString = [](const sf::Vector2i& vec2) { return '(' + std::to_string(vec2.x) + ", " + std::to_string(vec2.y) + ')'; }; - if (const auto* const mouseMoved = event.getIf()) + if (const auto* const mouseMoved = event->getIf()) mousePosition.setString("Mouse Position: " + vec2ToString(mouseMoved->position)); - if (const auto* const mouseMovedRaw = event.getIf()) + if (const auto* const mouseMovedRaw = event->getIf()) { log.emplace_back("Mouse Movement: " + vec2ToString(mouseMovedRaw->delta)); diff --git a/examples/shader/Shader.cpp b/examples/shader/Shader.cpp index 157eb4f8c..b618be327 100644 --- a/examples/shader/Shader.cpp +++ b/examples/shader/Shader.cpp @@ -438,16 +438,16 @@ int main() while (window.isOpen()) { // Process events - while (const auto event = window.pollEvent()) + while (const std::optional event = window.pollEvent()) { // Close window: exit - if (event.is()) + if (event->is()) { window.close(); break; } - if (const auto* keyPressed = event.getIf()) + if (const auto* keyPressed = event->getIf()) { switch (keyPressed->code) { diff --git a/examples/sound_effects/SoundEffects.cpp b/examples/sound_effects/SoundEffects.cpp index 84f83f075..260ba7505 100644 --- a/examples/sound_effects/SoundEffects.cpp +++ b/examples/sound_effects/SoundEffects.cpp @@ -1124,13 +1124,13 @@ int main() while (window.isOpen()) { // Process events - while (const auto event = window.pollEvent()) + while (const std::optional event = window.pollEvent()) { // Close window: exit - if (event.is()) + if (event->is()) window.close(); - if (const auto* keyPressed = event.getIf()) + if (const auto* keyPressed = event->getIf()) { switch (keyPressed->code) { diff --git a/examples/stencil/Stencil.cpp b/examples/stencil/Stencil.cpp index 7efd76450..643bfcd2a 100644 --- a/examples/stencil/Stencil.cpp +++ b/examples/stencil/Stencil.cpp @@ -40,10 +40,10 @@ int main() while (window.isOpen()) { // Handle events - while (const auto event = window.pollEvent()) + while (const std::optional event = window.pollEvent()) { // Window closed: exit - if (event.is()) + if (event->is()) { window.close(); break; diff --git a/examples/tennis/Tennis.cpp b/examples/tennis/Tennis.cpp index 6e7af5268..42f55b45d 100644 --- a/examples/tennis/Tennis.cpp +++ b/examples/tennis/Tennis.cpp @@ -109,19 +109,21 @@ int main() while (window.isOpen()) { // Handle events - while (const auto event = window.pollEvent()) + while (const std::optional event = window.pollEvent()) { // Window closed or escape key pressed: exit - if (event.is() || (event.is() && - event.getIf()->code == sf::Keyboard::Key::Escape)) + if (event->is() || + (event->is() && + event->getIf()->code == sf::Keyboard::Key::Escape)) { window.close(); break; } // Space key pressed: play - if ((event.is() && event.getIf()->code == sf::Keyboard::Key::Space) || - event.is()) + if ((event->is() && + event->getIf()->code == sf::Keyboard::Key::Space) || + event->is()) { if (!isPlaying) { @@ -144,7 +146,7 @@ int main() } // Window size changed, adjust view appropriately - if (event.is()) + if (event->is()) { sf::View view; view.setSize({gameWidth, gameHeight}); diff --git a/examples/vulkan/Vulkan.cpp b/examples/vulkan/Vulkan.cpp index 686f8cd62..57157f5d4 100644 --- a/examples/vulkan/Vulkan.cpp +++ b/examples/vulkan/Vulkan.cpp @@ -2544,19 +2544,18 @@ public: while (window.isOpen()) { // Process events - while (const auto event = window.pollEvent()) + while (const std::optional event = window.pollEvent()) { - // Close window: exit - if (event.is()) - window.close(); - - // Escape key: exit - if (event.is() && - event.getIf()->code == sf::Keyboard::Key::Escape) + // Window closed or escape key pressed: exit + if (event->is() || + (event->is() && + event->getIf()->code == sf::Keyboard::Key::Escape)) + { window.close(); + } // Re-create the swapchain when the window is resized - if (event.is()) + if (event->is()) swapchainOutOfDate = true; } diff --git a/examples/window/Window.cpp b/examples/window/Window.cpp index a5394d249..9f46a9af8 100644 --- a/examples/window/Window.cpp +++ b/examples/window/Window.cpp @@ -141,19 +141,18 @@ int main() while (window.isOpen()) { // Process events - while (const auto event = window.pollEvent()) + while (const std::optional event = window.pollEvent()) { - // Close window: exit - if (event.is()) + // Window closed or escape key pressed: exit + if (event->is() || + (event->is() && + event->getIf()->code == sf::Keyboard::Key::Escape)) + { window.close(); - - // Escape key: exit - if (const auto* keyPressed = event.getIf()) - if (keyPressed->code == sf::Keyboard::Key::Escape) - window.close(); + } // Resize event: adjust the viewport - if (const auto* resized = event.getIf()) + if (const auto* resized = event->getIf()) { const auto [width, height] = resized->size; glViewport(0, 0, static_cast(width), static_cast(height)); diff --git a/include/SFML/Graphics/RenderWindow.hpp b/include/SFML/Graphics/RenderWindow.hpp index a19481e14..7f39e0f83 100644 --- a/include/SFML/Graphics/RenderWindow.hpp +++ b/include/SFML/Graphics/RenderWindow.hpp @@ -237,10 +237,10 @@ private: /// while (window.isOpen()) /// { /// // Event processing -/// while (const auto event = window.pollEvent()) +/// while (const std::optional event = window.pollEvent()) /// { /// // Request for closing the window -/// if (event.is()) +/// if (event->is()) /// window.close(); /// } /// diff --git a/include/SFML/Window/Clipboard.hpp b/include/SFML/Window/Clipboard.hpp index d6a7f5d86..420cc73a0 100644 --- a/include/SFML/Window/Clipboard.hpp +++ b/include/SFML/Window/Clipboard.hpp @@ -91,18 +91,19 @@ SFML_WINDOW_API void setString(const String& text); /// sf::String string = sf::Clipboard::getString(); /// /// // or use it in the event loop -/// while (const auto event = window.pollEvent()) +/// while (const std::optional event = window.pollEvent()) /// { -/// if(event.is()) +/// if (event->is()) /// window.close(); -/// if(const auto* keyPressed = event.getIf()) +/// +/// if (const auto* keyPressed = event->getIf()) /// { /// // Using Ctrl + V to paste a string into SFML -/// if(keyPressed->control && keyPressed->code == sf::Keyboard::Key::V) +/// if (keyPressed->control && keyPressed->code == sf::Keyboard::Key::V) /// string = sf::Clipboard::getString(); /// /// // Using Ctrl + C to copy a string out of SFML -/// if(keyPressed->control && keyPressed->code == sf::Keyboard::Key::C) +/// if (keyPressed->control && keyPressed->code == sf::Keyboard::Key::C) /// sf::Clipboard::setString("Hello World!"); /// } /// } diff --git a/include/SFML/Window/Event.hpp b/include/SFML/Window/Event.hpp index a2c292fd1..0c5a1feeb 100644 --- a/include/SFML/Window/Event.hpp +++ b/include/SFML/Window/Event.hpp @@ -48,14 +48,6 @@ namespace sf class SFML_WINDOW_API Event { public: - //////////////////////////////////////////////////////////// - /// \brief Empty event - /// - //////////////////////////////////////////////////////////// - struct Empty - { - }; - //////////////////////////////////////////////////////////// /// \brief Closed event /// @@ -274,14 +266,6 @@ public: Vector3f value; //!< Current value of the sensor on the X, Y, and Z axes }; - //////////////////////////////////////////////////////////// - /// \brief Default constructor - /// - /// Sets the event to sf::Event::Empty - /// - //////////////////////////////////////////////////////////// - Event() = default; - //////////////////////////////////////////////////////////// /// \brief Construct from a given sf::Event subtype /// @@ -309,23 +293,11 @@ public: template [[nodiscard]] const T* getIf() const; - //////////////////////////////////////////////////////////// - /// \brief Check if current event type is not `Empty` - /// - /// \return True if current event type is not `Empty` - /// - //////////////////////////////////////////////////////////// - [[nodiscard]] explicit operator bool() const - { - return !is(); - } - private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - std::variant()) +/// // Window closed or escape key pressed: exit +/// if (event->is() || +/// (event->is() && +/// event->getIf()->code == sf::Keyboard::Key::Escape)) /// window.close(); /// -/// // The escape key was pressed -/// if (const auto* keyPressed = event.getIf()) -/// if (keyPressed->code == sf::Keyboard::Key::Escape) -/// window.close(); -/// /// // The window was resized -/// if (const auto* resized = event.getIf()) +/// if (const auto* resized = event->getIf()) /// doSomethingWithTheNewSize(resized->size); /// /// // etc ... diff --git a/include/SFML/Window/Window.hpp b/include/SFML/Window/Window.hpp index 392c5f554..fd16967a2 100644 --- a/include/SFML/Window/Window.hpp +++ b/include/SFML/Window/Window.hpp @@ -347,10 +347,10 @@ private: /// while (window.isOpen()) /// { /// // Event processing -/// while (const auto event = window.pollEvent()) +/// while (const std::optional event = window.pollEvent()) /// { /// // Request for closing the window -/// if (event.is()) +/// if (event->is()) /// window.close(); /// } /// diff --git a/include/SFML/Window/WindowBase.hpp b/include/SFML/Window/WindowBase.hpp index 15512cae5..f6c213e4b 100644 --- a/include/SFML/Window/WindowBase.hpp +++ b/include/SFML/Window/WindowBase.hpp @@ -181,36 +181,36 @@ public: /// \brief Pop the next event from the front of the FIFO event queue, if any, and return it /// /// This function is not blocking: if there's no pending event then - /// it will return an empty event. Note that more than one event + /// it will return a `std::nullopt`. Note that more than one event /// may be present in the event queue, thus you should always call /// this function in a loop to make sure that you process every /// pending event. /// \code - /// while (const auto event = window.pollEvent()) + /// while (const std::optional event = window.pollEvent()) /// { /// // process event... /// } /// \endcode /// - /// \return The event; will be `Empty` (convertible to `false`) if no events are pending + /// \return The event, otherwise `std::nullopt` if no events are pending /// /// \see waitEvent /// //////////////////////////////////////////////////////////// - [[nodiscard]] Event pollEvent(); + [[nodiscard]] std::optional pollEvent(); //////////////////////////////////////////////////////////// /// \brief Wait for an event and return it /// /// This function is blocking: if there's no pending event then /// it will wait until an event is received or until the provided - /// timeout elapses. After this function returns if no error nor - /// timeout occurred, the returned event will not be empty. + /// timeout elapses. Only if an error or a timeout occurs the + /// returned event will be `std::nullopt`. /// This function is typically used when you have a thread that is /// dedicated to events handling: you want to make this thread sleep /// as long as no new event is received. /// \code - /// if (const auto event = window.waitEvent()) + /// while (const std::optional event = window.waitEvent()) /// { /// // process event... /// } @@ -218,12 +218,12 @@ public: /// /// \param timeout Maximum time to wait (`Time::Zero` for infinite) /// - /// \return The event; will be `Empty` (convertible to `false`) on timeout or if window was closed + /// \return The event, otherwise `std::nullopt` on timeout or if window was closed /// /// \see pollEvent /// //////////////////////////////////////////////////////////// - [[nodiscard]] Event waitEvent(Time timeout = Time::Zero); + [[nodiscard]] std::optional waitEvent(Time timeout = Time::Zero); //////////////////////////////////////////////////////////// /// \brief Get the position of the window @@ -561,10 +561,10 @@ private: /// while (window.isOpen()) /// { /// // Event processing -/// while (const auto event = window.pollEvent()) +/// while (const std::optional event = window.pollEvent()) /// { /// // Request for closing the window -/// if (event.is()) +/// if (event->is()) /// window.close(); /// } /// diff --git a/src/SFML/Window/Android/WindowImplAndroid.cpp b/src/SFML/Window/Android/WindowImplAndroid.cpp index b49010c75..f8d4c89fe 100644 --- a/src/SFML/Window/Android/WindowImplAndroid.cpp +++ b/src/SFML/Window/Android/WindowImplAndroid.cpp @@ -462,28 +462,20 @@ int WindowImplAndroid::processKeyEvent(AInputEvent* inputEvent, ActivityStates& //////////////////////////////////////////////////////////// int WindowImplAndroid::processMotionEvent(AInputEvent* inputEvent, ActivityStates& states) { - const std::int32_t device = AInputEvent_getSource(inputEvent); - - Event event; - - if (device == AINPUT_SOURCE_MOUSE) - event = Event::MouseMoved{}; - else if (static_cast(device) & AINPUT_SOURCE_TOUCHSCREEN) - event = Event::TouchMoved{}; - - const std::size_t pointerCount = AMotionEvent_getPointerCount(inputEvent); + const std::int32_t device = AInputEvent_getSource(inputEvent); + const std::size_t pointerCount = AMotionEvent_getPointerCount(inputEvent); for (std::size_t p = 0; p < pointerCount; ++p) { const std::int32_t id = AMotionEvent_getPointerId(inputEvent, p); - int x = static_cast(AMotionEvent_getX(inputEvent, p)); - int y = static_cast(AMotionEvent_getY(inputEvent, p)); + const int x = static_cast(AMotionEvent_getX(inputEvent, p)); + const int y = static_cast(AMotionEvent_getY(inputEvent, p)); if (device == AINPUT_SOURCE_MOUSE) { const Event::MouseMoved mouseMoved{{x, y}}; - event = mouseMoved; + forwardEvent(mouseMoved); states.mousePosition = mouseMoved.position; } @@ -493,13 +485,12 @@ int WindowImplAndroid::processMotionEvent(AInputEvent* inputEvent, ActivityState continue; const Event::TouchMoved touchMoved{static_cast(id), {x, y}}; - event = touchMoved; + forwardEvent(touchMoved); states.touchEvents[id] = touchMoved.position; } - - forwardEvent(event); } + return 1; } @@ -517,45 +508,42 @@ int WindowImplAndroid::processPointerEvent(bool isDown, AInputEvent* inputEvent, int x = static_cast(AMotionEvent_getX(inputEvent, index)); int y = static_cast(AMotionEvent_getY(inputEvent, index)); - Event event; - if (isDown) { if (device == AINPUT_SOURCE_MOUSE) { - event = Event::MouseButtonPressed{button, {x, y}}; - if (id >= 0 && id < static_cast(Mouse::ButtonCount)) states.isButtonPressed[button] = true; + + forwardEvent(Event::MouseButtonPressed{button, {x, y}}); } else if (static_cast(device) & AINPUT_SOURCE_TOUCHSCREEN) { Event::TouchBegan touchBegan; touchBegan.finger = static_cast(id); touchBegan.position = {x, y}; - event = touchBegan; states.touchEvents[id] = touchBegan.position; + + forwardEvent(touchBegan); } } else { if (device == AINPUT_SOURCE_MOUSE) { - event = Event::MouseButtonReleased{button, {x, y}}; - if (id >= 0 && id < static_cast(Mouse::ButtonCount)) states.isButtonPressed[button] = false; + + forwardEvent(Event::MouseButtonReleased{button, {x, y}}); } else if (static_cast(device) & AINPUT_SOURCE_TOUCHSCREEN) { - event = Event::TouchEnded{static_cast(id), {x, y}}; - states.touchEvents.erase(id); + forwardEvent(Event::TouchEnded{static_cast(id), {x, y}}); } } - forwardEvent(event); return 1; } diff --git a/src/SFML/Window/DRM/InputImpl.cpp b/src/SFML/Window/DRM/InputImpl.cpp index bd14c71f7..2a172f027 100644 --- a/src/SFML/Window/DRM/InputImpl.cpp +++ b/src/SFML/Window/DRM/InputImpl.cpp @@ -191,7 +191,7 @@ sf::Keyboard::Key toKey(int code) { switch (code) { - // clang-format off + // clang-format off case KEY_ESC: return sf::Keyboard::Key::Escape; case KEY_1: return sf::Keyboard::Key::Num1; case KEY_2: return sf::Keyboard::Key::Num2; @@ -341,7 +341,7 @@ void processSlots() } } -bool eventProcess(sf::Event& event) +std::optional eventProcess() { const std::lock_guard lock(inputMutex); @@ -353,9 +353,10 @@ bool eventProcess(sf::Event& event) static unsigned int doDeferredText = 0; if (doDeferredText) { - event = sf::Event::TextEntered{doDeferredText}; + const auto event = sf::Event::TextEntered{doDeferredText}; + doDeferredText = 0; - return true; + return event; } ssize_t bytesRead = 0; @@ -372,13 +373,12 @@ bool eventProcess(sf::Event& event) { if (const std::optional mb = toMouseButton(inputEvent.code)) { - if (inputEvent.value) - event = sf::Event::MouseButtonPressed{*mb, mousePos}; - else - event = sf::Event::MouseButtonReleased{*mb, mousePos}; - mouseMap[*mb] = inputEvent.value; - return true; + + if (inputEvent.value) + return sf::Event::MouseButtonPressed{*mb, mousePos}; + else + return sf::Event::MouseButtonReleased{*mb, mousePos}; } else { @@ -394,8 +394,7 @@ bool eventProcess(sf::Event& event) // if (special) { - event = sf::Event::TextEntered{special}; - return true; + return sf::Event::TextEntered{special}; } } else if (kb != sf::Keyboard::Key::Unknown) @@ -410,17 +409,15 @@ bool eventProcess(sf::Event& event) keyChanged.shift = shiftDown(); keyChanged.system = systemDown(); - if (inputEvent.value) - event = sf::Event::KeyPressed{keyChanged}; - else - event = sf::Event::KeyReleased{keyChanged}; - keyMap[kb] = inputEvent.value; if (special && inputEvent.value) doDeferredText = special; - return true; + if (inputEvent.value) + return sf::Event::KeyPressed{keyChanged}; + else + return sf::Event::KeyReleased{keyChanged}; } } } @@ -443,14 +440,11 @@ bool eventProcess(sf::Event& event) sf::Event::MouseWheelScrolled mouseWheelScrolled; mouseWheelScrolled.delta = static_cast(inputEvent.value); mouseWheelScrolled.position = mousePos; - event = mouseWheelScrolled; - return true; + return mouseWheelScrolled; } - if (posChange) { - event = sf::Event::MouseMoved{mousePos}; - return true; + return sf::Event::MouseMoved{mousePos}; } } else if (inputEvent.type == EV_ABS) @@ -488,7 +482,6 @@ bool eventProcess(sf::Event& event) if ((bytesRead < 0) && (errno != EAGAIN)) sf::err() << " Error: " << std::strerror(errno) << std::endl; } - // Finally check if there is a Text event on stdin // // We only clear the ICANON flag for the time of reading @@ -510,7 +503,7 @@ bool eventProcess(sf::Event& event) if (ready > 0 && FD_ISSET(STDIN_FILENO, &readFDSet)) bytesRead = read(STDIN_FILENO, &code, 1); - if ((code == 127) || (code == 8)) // Suppress 127 (DEL) to 8 (BACKSPACE) + if ((code == 127) || (code == 8)) // Suppress127 (DEL) to 8 (BACKSPACE) code = 0; else if (code == 27) // ESC { @@ -534,22 +527,18 @@ bool eventProcess(sf::Event& event) if (code > 0) { // TODO: Proper unicode handling - event = sf::Event::TextEntered{code}; - return true; + return sf::Event::TextEntered{code}; } // No events available - return false; + return std::nullopt; } // assumes inputMutex is locked void update() { - sf::Event event; - while (eventProcess(event)) - { - pushEvent(event); - } + while (const std::optional event = eventProcess()) + pushEvent(*event); } } // namespace @@ -603,7 +592,7 @@ String getDescription(Keyboard::Scancode /* code */) } -//////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// void setVirtualKeyboardVisible(bool /*visible*/) { // Not applicable @@ -682,36 +671,35 @@ Vector2i getTouchPosition(unsigned int finger, const WindowBase& /*relativeTo*/) //////////////////////////////////////////////////////////// -bool checkEvent(Event& event) +std::optional checkEvent() { const std::lock_guard lock(inputMutex); + if (!eventQueue.empty()) { - event = eventQueue.front(); + auto event = std::make_optional(eventQueue.front()); eventQueue.pop(); - return true; + return event; } - if (eventProcess(event)) + if (const std::optional event = eventProcess()) { - return true; + return event; } - else + + // In the case of multitouch, eventProcess() could have returned false + // but added events directly to the queue. (This is ugly, but I'm not + // sure of a good way to handle generating multiple events at once.) + if (!eventQueue.empty()) { - // In the case of multitouch, eventProcess() could have returned false - // but added events directly to the queue. (This is ugly, but I'm not - // sure of a good way to handle generating multiple events at once.) - if (!eventQueue.empty()) - { - event = eventQueue.front(); - eventQueue.pop(); + auto event = std::make_optional(eventQueue.front()); + eventQueue.pop(); - return true; - } + return event; } - return false; + return std::nullopt; } diff --git a/src/SFML/Window/DRM/WindowImplDRM.cpp b/src/SFML/Window/DRM/WindowImplDRM.cpp index 205ac4bae..149ec6ff0 100644 --- a/src/SFML/Window/DRM/WindowImplDRM.cpp +++ b/src/SFML/Window/DRM/WindowImplDRM.cpp @@ -46,7 +46,7 @@ namespace InputImpl /// \return False if event queue is empty /// //////////////////////////////////////////////////////////// -bool checkEvent(Event& event); +std::optional checkEvent(); //////////////////////////////////////////////////////////// /// \brief Backup terminal configuration and disable console feedback @@ -190,9 +190,8 @@ bool WindowImplDRM::hasFocus() const void WindowImplDRM::processEvents() { - Event event; - while (InputImpl::checkEvent(event)) - pushEvent(event); + while (const std::optional event = InputImpl::checkEvent()) + pushEvent(*event); } } // namespace sf::priv diff --git a/src/SFML/Window/WindowBase.cpp b/src/SFML/Window/WindowBase.cpp index ab90f6981..a522b0cd3 100644 --- a/src/SFML/Window/WindowBase.cpp +++ b/src/SFML/Window/WindowBase.cpp @@ -43,6 +43,7 @@ #include #include +#include namespace @@ -71,7 +72,7 @@ WindowBase::WindowBase(VideoMode mode, const String& title, std::uint32_t style, //////////////////////////////////////////////////////////// WindowBase::WindowBase(VideoMode mode, const String& title, State state) { - WindowBase::create(mode, title, sf::Style::Default, state); + WindowBase::create(mode, title, Style::Default, state); } @@ -146,21 +147,35 @@ bool WindowBase::isOpen() const //////////////////////////////////////////////////////////// -Event WindowBase::pollEvent() +std::optional WindowBase::pollEvent() { - Event event; - if (m_impl && (event = m_impl->pollEvent())) - filterEvent(event); + std::optional event; // Use a single local variable for NRVO + + if (m_impl == nullptr) + return event; // Empty optional + + event = m_impl->pollEvent(); + + if (event.has_value()) + filterEvent(*event); + return event; } //////////////////////////////////////////////////////////// -Event WindowBase::waitEvent(Time timeout) +std::optional WindowBase::waitEvent(Time timeout) { - Event event; - if (m_impl && (event = m_impl->waitEvent(timeout))) - filterEvent(event); + std::optional event; // Use a single local variable for NRVO + + if (m_impl == nullptr) + return event; // Empty optional + + event = m_impl->waitEvent(timeout); + + if (event.has_value()) + filterEvent(*event); + return event; } diff --git a/src/SFML/Window/WindowImpl.cpp b/src/SFML/Window/WindowImpl.cpp index 6d813cc2d..f13e541b6 100644 --- a/src/SFML/Window/WindowImpl.cpp +++ b/src/SFML/Window/WindowImpl.cpp @@ -176,7 +176,7 @@ void WindowImpl::setMaximumSize(const std::optional& maximumSize) //////////////////////////////////////////////////////////// -Event WindowImpl::waitEvent(Time timeout) +std::optional WindowImpl::waitEvent(Time timeout) { const auto timedOut = [&, startTime = std::chrono::steady_clock::now()] { @@ -201,7 +201,7 @@ Event WindowImpl::waitEvent(Time timeout) //////////////////////////////////////////////////////////// -Event WindowImpl::pollEvent() +std::optional WindowImpl::pollEvent() { // If the event queue is empty, let's first check if new events are available from the OS if (m_events.empty()) @@ -212,13 +212,13 @@ Event WindowImpl::pollEvent() //////////////////////////////////////////////////////////// -Event WindowImpl::popEvent() +std::optional WindowImpl::popEvent() { - Event event; + std::optional event; // Use a single local variable for NRVO if (!m_events.empty()) { - event = m_events.front(); + event.emplace(m_events.front()); m_events.pop(); } diff --git a/src/SFML/Window/WindowImpl.hpp b/src/SFML/Window/WindowImpl.hpp index a36ea3ce2..19ae80ad9 100644 --- a/src/SFML/Window/WindowImpl.hpp +++ b/src/SFML/Window/WindowImpl.hpp @@ -129,10 +129,10 @@ public: /// /// \param timeout Maximum time to wait (`Time::Zero` for infinite) /// - /// \return The event on success, `Event::Empty` otherwise + /// \return The event on success, `std::nullopt` otherwise /// //////////////////////////////////////////////////////////// - [[nodiscard]] Event waitEvent(Time timeout); + [[nodiscard]] std::optional waitEvent(Time timeout); //////////////////////////////////////////////////////////// /// \brief Return the next window event, if available @@ -140,10 +140,10 @@ public: /// If there's no event available, this function calls the /// window's internal event processing function. /// - /// \return The event if available, `Event::Empty` otherwise + /// \return The event if available, `std::nullopt` otherwise /// //////////////////////////////////////////////////////////// - [[nodiscard]] Event pollEvent(); + [[nodiscard]] std::optional pollEvent(); //////////////////////////////////////////////////////////// /// \brief Get the OS-specific handle of the window @@ -334,10 +334,10 @@ private: struct JoystickStatesImpl; //////////////////////////////////////////////////////////// - /// \brief Pop the first event of the queue if available, otherwise an empty event + /// \return First event of the queue if available, `std::nullopt` otherwise /// //////////////////////////////////////////////////////////// - [[nodiscard]] Event popEvent(); + [[nodiscard]] std::optional popEvent(); //////////////////////////////////////////////////////////// /// \brief Read the joysticks state and generate the appropriate events diff --git a/test/Window/Event.test.cpp b/test/Window/Event.test.cpp index 9155a6ed6..6fa25bd57 100644 --- a/test/Window/Event.test.cpp +++ b/test/Window/Event.test.cpp @@ -8,6 +8,7 @@ TEST_CASE("[Window] sf::Event") { SECTION("Type traits") { + STATIC_CHECK(!std::is_default_constructible_v); STATIC_CHECK(std::is_copy_constructible_v); STATIC_CHECK(std::is_copy_assignable_v); STATIC_CHECK(std::is_nothrow_move_constructible_v); @@ -16,18 +17,9 @@ TEST_CASE("[Window] sf::Event") SECTION("Construction") { - SECTION("Default constructor") - { - const sf::Event event; - CHECK(!event); - CHECK(event.is()); - CHECK(event.getIf()); - } - SECTION("Template constructor") { const sf::Event event = sf::Event::Resized{{1, 2}}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& resized = *event.getIf(); @@ -37,38 +29,31 @@ TEST_CASE("[Window] sf::Event") SECTION("Assign all possible values") { - sf::Event event; - event = sf::Event::Closed{}; - CHECK(event); + sf::Event event = sf::Event::Closed{}; CHECK(event.is()); CHECK(event.getIf()); event = sf::Event::Resized{{1, 2}}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& resized = *event.getIf(); CHECK(resized.size == sf::Vector2u(1, 2)); event = sf::Event::FocusLost{}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); event = sf::Event::FocusGained{}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); event = sf::Event::TextEntered{123456}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& textEntered = *event.getIf(); CHECK(textEntered.unicode == 123456); event = sf::Event::KeyPressed{sf::Keyboard::Key::C, sf::Keyboard::Scan::C, true, true, true, true}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& keyPressed = *event.getIf(); @@ -80,7 +65,6 @@ TEST_CASE("[Window] sf::Event") CHECK(keyPressed.system); event = sf::Event::KeyReleased{sf::Keyboard::Key::D, sf::Keyboard::Scan::D, true, true, true, true}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& keyReleased = *event.getIf(); @@ -92,7 +76,6 @@ TEST_CASE("[Window] sf::Event") CHECK(keyReleased.system); event = sf::Event::MouseWheelScrolled{sf::Mouse::Wheel::Horizontal, 3.14f, {4, 5}}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& mouseWheelScrolled = *event.getIf(); @@ -101,7 +84,6 @@ TEST_CASE("[Window] sf::Event") CHECK(mouseWheelScrolled.position == sf::Vector2i(4, 5)); event = sf::Event::MouseButtonPressed{sf::Mouse::Button::Middle, {6, 7}}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& mouseButtonPressed = *event.getIf(); @@ -109,7 +91,6 @@ TEST_CASE("[Window] sf::Event") CHECK(mouseButtonPressed.position == sf::Vector2i(6, 7)); event = sf::Event::MouseButtonReleased{sf::Mouse::Button::Extra1, {8, 9}}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& mouseButtonReleased = *event.getIf(); @@ -117,31 +98,26 @@ TEST_CASE("[Window] sf::Event") CHECK(mouseButtonReleased.position == sf::Vector2i(8, 9)); event = sf::Event::MouseMoved{{4, 2}}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& mouseMoved = *event.getIf(); CHECK(mouseMoved.position == sf::Vector2i(4, 2)); event = sf::Event::MouseMovedRaw{{3, 7}}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& mouseMovedRaw = *event.getIf(); CHECK(mouseMovedRaw.delta == sf::Vector2i(3, 7)); event = sf::Event::MouseEntered{}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); event = sf::Event::MouseLeft{}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); event = sf::Event::JoystickButtonPressed{100, 200}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& joystickButtonPressed = *event.getIf(); @@ -149,7 +125,6 @@ TEST_CASE("[Window] sf::Event") CHECK(joystickButtonPressed.button == 200); event = sf::Event::JoystickButtonReleased{300, 400}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& joystickButtonReleased = *event.getIf(); @@ -157,7 +132,6 @@ TEST_CASE("[Window] sf::Event") CHECK(joystickButtonReleased.button == 400); event = sf::Event::JoystickMoved{300, sf::Joystick::Axis::Z, 1.23f}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& joystickMoved = *event.getIf(); @@ -166,21 +140,18 @@ TEST_CASE("[Window] sf::Event") CHECK(joystickMoved.position == 1.23f); event = sf::Event::JoystickConnected{42}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& joystickConnected = *event.getIf(); CHECK(joystickConnected.joystickId == 42); event = sf::Event::JoystickDisconnected{43}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& joystickDisconnected = *event.getIf(); CHECK(joystickDisconnected.joystickId == 43); event = sf::Event::TouchBegan{99, {98, 97}}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& touchBegan = *event.getIf(); @@ -188,7 +159,6 @@ TEST_CASE("[Window] sf::Event") CHECK(touchBegan.position == sf::Vector2i(98, 97)); event = sf::Event::TouchMoved{96, {95, 94}}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& touchMoved = *event.getIf(); @@ -196,7 +166,6 @@ TEST_CASE("[Window] sf::Event") CHECK(touchMoved.position == sf::Vector2i(95, 94)); event = sf::Event::TouchEnded{93, {92, 91}}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& touchEnded = *event.getIf(); @@ -204,7 +173,6 @@ TEST_CASE("[Window] sf::Event") CHECK(touchEnded.position == sf::Vector2i(92, 91)); event = sf::Event::SensorChanged{sf::Sensor::Type::Gravity, {1.2f, 3.4f, 5.6f}}; - CHECK(event); CHECK(event.is()); CHECK(event.getIf()); const auto& sensorChanged = *event.getIf(); @@ -215,7 +183,6 @@ TEST_CASE("[Window] sf::Event") SECTION("Subtypes") { // Empty structs - STATIC_CHECK(std::is_empty_v); STATIC_CHECK(std::is_empty_v); STATIC_CHECK(std::is_empty_v); STATIC_CHECK(std::is_empty_v);