From ca0a231b3505486e86d2045847464a61ed1bf123 Mon Sep 17 00:00:00 2001 From: trustytrojan Date: Wed, 1 May 2024 21:43:24 -0400 Subject: [PATCH] Add `operator bool()` to `sf::Event` for checking if the event type is not Empty --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/ISSUE_TEMPLATE/feature_request.yml | 2 +- .github/pull_request_template.md | 2 +- doc/mainpage.hpp | 2 +- examples/android/app/src/main/jni/main.cpp | 2 +- examples/island/Island.cpp | 2 +- examples/joystick/Joystick.cpp | 2 +- examples/opengl/OpenGL.cpp | 2 +- examples/shader/Shader.cpp | 2 +- examples/sound_effects/SoundEffects.cpp | 2 +- examples/stencil/Stencil.cpp | 2 +- examples/tennis/Tennis.cpp | 2 +- examples/vulkan/Vulkan.cpp | 2 +- examples/window/Window.cpp | 2 +- include/SFML/Graphics/RenderWindow.hpp | 2 +- include/SFML/Window/Clipboard.hpp | 2 +- include/SFML/Window/Event.hpp | 13 ++++++- include/SFML/Window/Window.hpp | 2 +- include/SFML/Window/WindowBase.hpp | 38 ++++++++----------- src/SFML/Window/WindowBase.cpp | 26 ++++--------- src/SFML/Window/WindowImpl.cpp | 8 ++-- src/SFML/Window/WindowImpl.hpp | 7 ++-- test/Window/Event.test.cpp | 24 ++++++++++++ test/Window/WindowBase.test.cpp | 6 +-- .../SFML/SFML App.xctemplate/main.cpp | 2 +- .../SFML/SFML CLT.xctemplate/main.cpp | 2 +- 26 files changed, 89 insertions(+), 71 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 49f871afb..69e9e25ab 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -57,7 +57,7 @@ body: while (window.isOpen()) { - for (sf::Event event; window.pollEvent(event);) + while (const auto event = window.pollEvent()) { if (event.is()) window.close(); diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index d1661aa2a..235e0360a 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -54,7 +54,7 @@ body: while (window.isOpen()) { - for (sf::Event event; window.pollEvent(event);) + while (const auto event = window.pollEvent()) { if (event.is()) window.close(); diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 4475cea18..179526f3a 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -39,7 +39,7 @@ int main() while (window.isOpen()) { - for (sf::Event event; window.pollEvent(event);) + while (const auto event = window.pollEvent()) { if (event.is()) window.close(); diff --git a/doc/mainpage.hpp b/doc/mainpage.hpp index abd0f4824..ce8b88a13 100644 --- a/doc/mainpage.hpp +++ b/doc/mainpage.hpp @@ -44,7 +44,7 @@ /// while (window.isOpen()) /// { /// // Process events -/// for (sf::Event event; window.pollEvent(event);) +/// while (const auto event = window.pollEvent()) /// { /// // Close window: exit /// if (event.is()) diff --git a/examples/android/app/src/main/jni/main.cpp b/examples/android/app/src/main/jni/main.cpp index 9e704506b..e07e9c3a4 100644 --- a/examples/android/app/src/main/jni/main.cpp +++ b/examples/android/app/src/main/jni/main.cpp @@ -113,7 +113,7 @@ int main(int argc, char* argv[]) while (window.isOpen()) { - for (sf::Event event; active ? window.pollEvent(event) : window.waitEvent(event);) + while (const auto event = active ? window.pollEvent() : window.waitEvent()) { if (event.is()) { diff --git a/examples/island/Island.cpp b/examples/island/Island.cpp index c389a3434..845bc40bd 100644 --- a/examples/island/Island.cpp +++ b/examples/island/Island.cpp @@ -179,7 +179,7 @@ int main() while (window.isOpen()) { // Handle events - for (sf::Event event; window.pollEvent(event);) + while (const auto event = window.pollEvent()) { // Window closed or escape key pressed: exit if (event.is() || (event.is() && diff --git a/examples/joystick/Joystick.cpp b/examples/joystick/Joystick.cpp index a4cf88d49..265114080 100644 --- a/examples/joystick/Joystick.cpp +++ b/examples/joystick/Joystick.cpp @@ -158,7 +158,7 @@ int main() while (window.isOpen()) { // Handle events - for (sf::Event event; window.pollEvent(event);) + while (const auto event = window.pollEvent()) { // Window closed or escape key pressed: exit if (event.is() || (event.is() && diff --git a/examples/opengl/OpenGL.cpp b/examples/opengl/OpenGL.cpp index 6e526aed2..ec0925bb4 100644 --- a/examples/opengl/OpenGL.cpp +++ b/examples/opengl/OpenGL.cpp @@ -208,7 +208,7 @@ int main() while (window.isOpen()) { // Process events - for (sf::Event event; window.pollEvent(event);) + while (const auto event = window.pollEvent()) { // Close window: exit if (event.is()) diff --git a/examples/shader/Shader.cpp b/examples/shader/Shader.cpp index 8be184c34..37a8b45ad 100644 --- a/examples/shader/Shader.cpp +++ b/examples/shader/Shader.cpp @@ -389,7 +389,7 @@ int main() while (window.isOpen()) { // Process events - for (sf::Event event; window.pollEvent(event);) + while (const auto event = window.pollEvent()) { // Close window: exit if (event.is()) diff --git a/examples/sound_effects/SoundEffects.cpp b/examples/sound_effects/SoundEffects.cpp index 79651f208..77404e4c0 100644 --- a/examples/sound_effects/SoundEffects.cpp +++ b/examples/sound_effects/SoundEffects.cpp @@ -677,7 +677,7 @@ int main() while (window.isOpen()) { // Process events - for (sf::Event event; window.pollEvent(event);) + while (const auto event = window.pollEvent()) { // Close window: exit if (event.is()) diff --git a/examples/stencil/Stencil.cpp b/examples/stencil/Stencil.cpp index e79005dbf..7af35a40c 100644 --- a/examples/stencil/Stencil.cpp +++ b/examples/stencil/Stencil.cpp @@ -40,7 +40,7 @@ int main() while (window.isOpen()) { // Handle events - for (sf::Event event; window.pollEvent(event);) + while (const auto event = window.pollEvent()) { // Window closed: exit if (event.is()) diff --git a/examples/tennis/Tennis.cpp b/examples/tennis/Tennis.cpp index 18ba7b8e8..41b05b8ef 100644 --- a/examples/tennis/Tennis.cpp +++ b/examples/tennis/Tennis.cpp @@ -115,7 +115,7 @@ int main() while (window.isOpen()) { // Handle events - for (sf::Event event; window.pollEvent(event);) + while (const auto event = window.pollEvent()) { // Window closed or escape key pressed: exit if (event.is() || (event.is() && diff --git a/examples/vulkan/Vulkan.cpp b/examples/vulkan/Vulkan.cpp index 7f026ae1f..5467e6609 100644 --- a/examples/vulkan/Vulkan.cpp +++ b/examples/vulkan/Vulkan.cpp @@ -2542,7 +2542,7 @@ public: while (window.isOpen()) { // Process events - for (sf::Event event; window.pollEvent(event);) + while (const auto event = window.pollEvent()) { // Close window: exit if (event.is()) diff --git a/examples/window/Window.cpp b/examples/window/Window.cpp index 2aaa7a446..a5394d249 100644 --- a/examples/window/Window.cpp +++ b/examples/window/Window.cpp @@ -141,7 +141,7 @@ int main() while (window.isOpen()) { // Process events - for (sf::Event event; window.pollEvent(event);) + while (const auto event = window.pollEvent()) { // Close window: exit if (event.is()) diff --git a/include/SFML/Graphics/RenderWindow.hpp b/include/SFML/Graphics/RenderWindow.hpp index 052b1c964..02fb0ef0c 100644 --- a/include/SFML/Graphics/RenderWindow.hpp +++ b/include/SFML/Graphics/RenderWindow.hpp @@ -237,7 +237,7 @@ private: /// while (window.isOpen()) /// { /// // Event processing -/// for (sf::Event event; window.pollEvent(event);) +/// while (const auto event = window.pollEvent()) /// { /// // Request for closing the window /// if (event.is()) diff --git a/include/SFML/Window/Clipboard.hpp b/include/SFML/Window/Clipboard.hpp index 0d28a2d65..d6a7f5d86 100644 --- a/include/SFML/Window/Clipboard.hpp +++ b/include/SFML/Window/Clipboard.hpp @@ -91,7 +91,7 @@ SFML_WINDOW_API void setString(const String& text); /// sf::String string = sf::Clipboard::getString(); /// /// // or use it in the event loop -/// for (sf::Event event; window.pollEvent(event);) +/// while (const auto event = window.pollEvent()) /// { /// if(event.is()) /// window.close(); diff --git a/include/SFML/Window/Event.hpp b/include/SFML/Window/Event.hpp index 1b0b2169c..e73515c73 100644 --- a/include/SFML/Window/Event.hpp +++ b/include/SFML/Window/Event.hpp @@ -276,6 +276,17 @@ 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 @@ -345,7 +356,7 @@ private: /// any of the corresponding event data. /// /// \code -/// for (sf::Event event; window.pollEvent(event);) +/// while (const auto event = window.pollEvent()) /// { /// // Request for closing the window /// if (event.is()) diff --git a/include/SFML/Window/Window.hpp b/include/SFML/Window/Window.hpp index 0ac10e663..392c5f554 100644 --- a/include/SFML/Window/Window.hpp +++ b/include/SFML/Window/Window.hpp @@ -347,7 +347,7 @@ private: /// while (window.isOpen()) /// { /// // Event processing -/// for (sf::Event event; window.pollEvent(event);) +/// while (const auto event = window.pollEvent()) /// { /// // Request for closing the window /// if (event.is()) diff --git a/include/SFML/Window/WindowBase.hpp b/include/SFML/Window/WindowBase.hpp index c1e75ce7e..acb294907 100644 --- a/include/SFML/Window/WindowBase.hpp +++ b/include/SFML/Window/WindowBase.hpp @@ -180,52 +180,46 @@ 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 false and leave \a event unmodified. - /// 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. + /// it will return an empty event. 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 - /// for (sf::Event event; window.pollEvent(event);) + /// while (const auto event = window.pollEvent()) /// { /// // process event... /// } /// \endcode /// - /// \param event Event to be returned - /// - /// \return True if an event was returned, or false if the event queue was empty + /// \return The event; will be `Empty` (convertible to `false`) if no events are pending /// /// \see waitEvent /// //////////////////////////////////////////////////////////// - [[nodiscard]] bool pollEvent(Event& event); + [[nodiscard]] Event 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. - /// After this function returns (and no error occurred), - /// the \a event object is always valid and filled properly. - /// 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. + /// it will wait until an event is received. After this function + /// returns if no error occurred, the returned event will not be + /// empty. 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 - /// sf::Event event; - /// if (window.waitEvent(event)) + /// if (const auto event = window.waitEvent()) /// { /// // process event... /// } /// \endcode /// - /// \param event Event to be returned - /// - /// \return False if any error occurred + /// \return The event /// /// \see pollEvent /// //////////////////////////////////////////////////////////// - [[nodiscard]] bool waitEvent(Event& event); + [[nodiscard]] Event waitEvent(); //////////////////////////////////////////////////////////// /// \brief Get the position of the window @@ -563,7 +557,7 @@ private: /// while (window.isOpen()) /// { /// // Event processing -/// for (sf::Event event; window.pollEvent(event);) +/// while (const auto event = window.pollEvent()) /// { /// // Request for closing the window /// if (event.is()) diff --git a/src/SFML/Window/WindowBase.cpp b/src/SFML/Window/WindowBase.cpp index b068c7b1b..f437be7fc 100644 --- a/src/SFML/Window/WindowBase.cpp +++ b/src/SFML/Window/WindowBase.cpp @@ -136,32 +136,22 @@ bool WindowBase::isOpen() const //////////////////////////////////////////////////////////// -bool WindowBase::pollEvent(Event& event) +Event WindowBase::pollEvent() { - if (m_impl && m_impl->popEvent(event, false)) - { + sf::Event event; + if (m_impl && (event = m_impl->popEvent(false))) filterEvent(event); - return true; - } - else - { - return false; - } + return event; } //////////////////////////////////////////////////////////// -bool WindowBase::waitEvent(Event& event) +Event WindowBase::waitEvent() { - if (m_impl && m_impl->popEvent(event, true)) - { + sf::Event event; + if (m_impl && (event = m_impl->popEvent(true))) filterEvent(event); - return true; - } - else - { - return false; - } + return event; } diff --git a/src/SFML/Window/WindowImpl.cpp b/src/SFML/Window/WindowImpl.cpp index e7496ed00..5825766ef 100644 --- a/src/SFML/Window/WindowImpl.cpp +++ b/src/SFML/Window/WindowImpl.cpp @@ -176,7 +176,7 @@ void WindowImpl::setMaximumSize(const std::optional& maximumSize) //////////////////////////////////////////////////////////// -bool WindowImpl::popEvent(Event& event, bool block) +Event WindowImpl::popEvent(bool block) { // If the event queue is empty, let's first check if new events are available from the OS if (m_events.empty()) @@ -202,16 +202,16 @@ bool WindowImpl::popEvent(Event& event, bool block) } } + sf::Event event; + // Pop the first event of the queue, if it is not empty if (!m_events.empty()) { event = m_events.front(); m_events.pop(); - - return true; } - return false; + return event; } diff --git a/src/SFML/Window/WindowImpl.hpp b/src/SFML/Window/WindowImpl.hpp index 4e2d3e8e0..3dbb97c14 100644 --- a/src/SFML/Window/WindowImpl.hpp +++ b/src/SFML/Window/WindowImpl.hpp @@ -128,13 +128,14 @@ public: /// The \a block parameter controls the behavior of the function /// if no event is available: if it is true then the function /// doesn't return until a new event is triggered; otherwise it - /// returns false to indicate that no event is available. + /// returns an empty event to indicate that no event is available. /// - /// \param event Event to be returned /// \param block Use true to block the thread until an event arrives /// + /// \return The event; can be `Empty` (convertible to `false`) if not blocking + /// //////////////////////////////////////////////////////////// - bool popEvent(Event& event, bool block); + Event popEvent(bool block); //////////////////////////////////////////////////////////// /// \brief Get the OS-specific handle of the window diff --git a/test/Window/Event.test.cpp b/test/Window/Event.test.cpp index 99126ca90..acedebc7b 100644 --- a/test/Window/Event.test.cpp +++ b/test/Window/Event.test.cpp @@ -19,6 +19,7 @@ TEST_CASE("[Window] sf::Event") SECTION("Default constructor") { const sf::Event event; + CHECK(!event); CHECK(event.is()); CHECK(event.getIf()); } @@ -26,6 +27,7 @@ TEST_CASE("[Window] sf::Event") 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,30 +39,36 @@ TEST_CASE("[Window] sf::Event") { sf::Event event; event = sf::Event::Closed{}; + CHECK(event); 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(); @@ -72,6 +80,7 @@ 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(); @@ -83,6 +92,7 @@ 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(); @@ -91,6 +101,7 @@ 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(); @@ -98,6 +109,7 @@ 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(); @@ -105,20 +117,24 @@ 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::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(); @@ -126,6 +142,7 @@ 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(); @@ -133,6 +150,7 @@ 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(); @@ -141,18 +159,21 @@ 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(); @@ -160,6 +181,7 @@ 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(); @@ -167,6 +189,7 @@ 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(); @@ -174,6 +197,7 @@ 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(); diff --git a/test/Window/WindowBase.test.cpp b/test/Window/WindowBase.test.cpp index c0a704598..ddb3a5ba6 100644 --- a/test/Window/WindowBase.test.cpp +++ b/test/Window/WindowBase.test.cpp @@ -105,15 +105,13 @@ TEST_CASE("[Window] sf::WindowBase", runDisplayTests()) SECTION("pollEvent()") { sf::WindowBase windowBase; - sf::Event event; - CHECK(!windowBase.pollEvent(event)); + CHECK(!windowBase.pollEvent()); } SECTION("waitEvent()") { sf::WindowBase windowBase; - sf::Event event; - CHECK(!windowBase.waitEvent(event)); + CHECK(!windowBase.waitEvent()); } SECTION("Set/get position") diff --git a/tools/xcode/templates/SFML/SFML App.xctemplate/main.cpp b/tools/xcode/templates/SFML/SFML App.xctemplate/main.cpp index fac3c5c4c..43aad693d 100644 --- a/tools/xcode/templates/SFML/SFML App.xctemplate/main.cpp +++ b/tools/xcode/templates/SFML/SFML App.xctemplate/main.cpp @@ -64,7 +64,7 @@ int main() while (window.isOpen()) { // Process events - for (sf::Event event; window.pollEvent(event);) + while (const auto event = window.pollEvent()) { // Close window: exit if (event.is()) diff --git a/tools/xcode/templates/SFML/SFML CLT.xctemplate/main.cpp b/tools/xcode/templates/SFML/SFML CLT.xctemplate/main.cpp index e3db2187f..004142237 100644 --- a/tools/xcode/templates/SFML/SFML CLT.xctemplate/main.cpp +++ b/tools/xcode/templates/SFML/SFML CLT.xctemplate/main.cpp @@ -62,7 +62,7 @@ int main() while (window.isOpen()) { // Process events - for (sf::Event event; window.pollEvent(event);) + while (const auto event = window.pollEvent()) { // Close window: exit if (event.is())