Remove default empty state of sf::Event

This commit is contained in:
vittorioromeo 2024-06-23 12:30:02 +02:00 committed by Vittorio Romeo
parent db245a440f
commit 86c1a71a93
27 changed files with 199 additions and 277 deletions

View File

@ -57,9 +57,9 @@ body:
while (window.isOpen()) while (window.isOpen())
{ {
while (const auto event = window.pollEvent()) while (const std::optional event = window.pollEvent())
{ {
if (event.is<sf::Event::Closed>()) if (event->is<sf::Event::Closed>())
window.close(); window.close();
} }

View File

@ -54,9 +54,9 @@ body:
while (window.isOpen()) while (window.isOpen())
{ {
while (const auto event = window.pollEvent()) while (const std::optional event = window.pollEvent())
{ {
if (event.is<sf::Event::Closed>()) if (event->is<sf::Event::Closed>())
window.close(); window.close();
} }

View File

@ -39,9 +39,9 @@ int main()
while (window.isOpen()) while (window.isOpen())
{ {
while (const auto event = window.pollEvent()) while (const std::optional event = window.pollEvent())
{ {
if (event.is<sf::Event::Closed>()) if (event->is<sf::Event::Closed>())
window.close(); window.close();
} }

View File

@ -38,10 +38,10 @@
/// while (window.isOpen()) /// while (window.isOpen())
/// { /// {
/// // Process events /// // Process events
/// while (const auto event = window.pollEvent()) /// while (const std::optional event = window.pollEvent())
/// { /// {
/// // Close window: exit /// // Close window: exit
/// if (event.is<sf::Event::Closed>()) /// if (event->is<sf::Event::Closed>())
/// window.close(); /// window.close();
/// } /// }
/// ///

View File

@ -109,43 +109,41 @@ int main(int argc, char* argv[])
while (window.isOpen()) 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<sf::Event::Closed>()) if (event->is<sf::Event::Closed>() ||
(event->is<sf::Event::KeyPressed>() &&
event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
{ {
window.close(); window.close();
} }
else if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>())
{ else if (const auto* resized = event->getIf<sf::Event::Resized>())
if (keyPressed->code == sf::Keyboard::Key::Escape)
window.close();
}
else if (const auto* resized = event.getIf<sf::Event::Resized>())
{ {
const auto size = sf::Vector2f(resized->size); const auto size = sf::Vector2f(resized->size);
view.setSize(size); view.setSize(size);
view.setCenter(size / 2.f); view.setCenter(size / 2.f);
window.setView(view); window.setView(view);
} }
else if (event.is<sf::Event::FocusLost>()) else if (event->is<sf::Event::FocusLost>())
{ {
background = sf::Color::Black; background = sf::Color::Black;
} }
else if (event.is<sf::Event::FocusGained>()) else if (event->is<sf::Event::FocusGained>())
{ {
background = sf::Color::White; background = sf::Color::White;
} }
// On Android MouseLeft/MouseEntered are (for now) triggered, // On Android MouseLeft/MouseEntered are (for now) triggered,
// whenever the app loses or gains focus. // whenever the app loses or gains focus.
else if (event.is<sf::Event::MouseLeft>()) else if (event->is<sf::Event::MouseLeft>())
{ {
active = false; active = false;
} }
else if (event.is<sf::Event::MouseEntered>()) else if (event->is<sf::Event::MouseEntered>())
{ {
active = true; active = true;
} }
else if (const auto* touchBegan = event.getIf<sf::Event::TouchBegan>()) else if (const auto* touchBegan = event->getIf<sf::Event::TouchBegan>())
{ {
if (touchBegan->finger == 0) if (touchBegan->finger == 0)
{ {

View File

@ -174,20 +174,21 @@ int main()
while (window.isOpen()) while (window.isOpen())
{ {
// Handle events // Handle events
while (const auto event = window.pollEvent()) while (const std::optional event = window.pollEvent())
{ {
// Window closed or escape key pressed: exit // Window closed or escape key pressed: exit
if (event.is<sf::Event::Closed>() || (event.is<sf::Event::KeyPressed>() && if (event->is<sf::Event::Closed>() ||
event.getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape)) (event->is<sf::Event::KeyPressed>() &&
event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
{ {
window.close(); window.close();
break; break;
} }
// Arrow key pressed: // Arrow key pressed:
if (terrainShader.has_value() && event.is<sf::Event::KeyPressed>()) if (terrainShader.has_value() && event->is<sf::Event::KeyPressed>())
{ {
switch (event.getIf<sf::Event::KeyPressed>()->code) switch (event->getIf<sf::Event::KeyPressed>()->code)
{ {
case sf::Keyboard::Key::Enter: case sf::Keyboard::Key::Enter:
generateTerrain(terrainStagingBuffer.data()); generateTerrain(terrainStagingBuffer.data());

View File

@ -156,36 +156,38 @@ int main()
while (window.isOpen()) while (window.isOpen())
{ {
// Handle events // Handle events
while (const auto event = window.pollEvent()) while (const std::optional event = window.pollEvent())
{ {
// Window closed or escape key pressed: exit // Window closed or escape key pressed: exit
if (event.is<sf::Event::Closed>() || (event.is<sf::Event::KeyPressed>() && if (event->is<sf::Event::Closed>() ||
event.getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape)) (event->is<sf::Event::KeyPressed>() &&
event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
{ {
window.close(); window.close();
break; break;
} }
else if (const auto* joystickButtonPressed = event.getIf<sf::Event::JoystickButtonPressed>())
if (const auto* joystickButtonPressed = event->getIf<sf::Event::JoystickButtonPressed>())
{ {
// Update displayed joystick values // Update displayed joystick values
updateValues(joystickButtonPressed->joystickId); updateValues(joystickButtonPressed->joystickId);
} }
else if (const auto* joystickButtonReleased = event.getIf<sf::Event::JoystickButtonReleased>()) else if (const auto* joystickButtonReleased = event->getIf<sf::Event::JoystickButtonReleased>())
{ {
// Update displayed joystick values // Update displayed joystick values
updateValues(joystickButtonReleased->joystickId); updateValues(joystickButtonReleased->joystickId);
} }
else if (const auto* joystickMoved = event.getIf<sf::Event::JoystickMoved>()) else if (const auto* joystickMoved = event->getIf<sf::Event::JoystickMoved>())
{ {
// Update displayed joystick values // Update displayed joystick values
updateValues(joystickMoved->joystickId); updateValues(joystickMoved->joystickId);
} }
else if (const auto* joystickConnected = event.getIf<sf::Event::JoystickConnected>()) else if (const auto* joystickConnected = event->getIf<sf::Event::JoystickConnected>())
{ {
// Update displayed joystick values // Update displayed joystick values
updateValues(joystickConnected->joystickId); updateValues(joystickConnected->joystickId);
} }
else if (event.is<sf::Event::JoystickDisconnected>()) else if (event->is<sf::Event::JoystickDisconnected>())
{ {
// Reset displayed joystick values to empty // Reset displayed joystick values to empty
for (auto& [label, joystickObject] : texts) for (auto& [label, joystickObject] : texts)

View File

@ -201,25 +201,19 @@ int main()
while (window.isOpen()) while (window.isOpen())
{ {
// Process events // Process events
while (const auto event = window.pollEvent()) while (const std::optional event = window.pollEvent())
{ {
// Close window: exit // Window closed or escape key pressed: exit
if (event.is<sf::Event::Closed>()) if (event->is<sf::Event::Closed>() ||
{ (event->is<sf::Event::KeyPressed>() &&
exit = true; event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
window.close();
}
// Escape key: exit
if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>();
keyPressed && keyPressed->code == sf::Keyboard::Key::Escape)
{ {
exit = true; exit = true;
window.close(); window.close();
} }
// Return key: toggle mipmapping // Return key: toggle mipmapping
if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>(); if (const auto* keyPressed = event->getIf<sf::Event::KeyPressed>();
keyPressed && keyPressed->code == sf::Keyboard::Key::Enter) keyPressed && keyPressed->code == sf::Keyboard::Key::Enter)
{ {
if (mipmapEnabled) if (mipmapEnabled)
@ -236,7 +230,7 @@ int main()
} }
// Space key: toggle sRGB conversion // Space key: toggle sRGB conversion
if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>(); if (const auto* keyPressed = event->getIf<sf::Event::KeyPressed>();
keyPressed && keyPressed->code == sf::Keyboard::Key::Space) keyPressed && keyPressed->code == sf::Keyboard::Key::Space)
{ {
sRgb = !sRgb; sRgb = !sRgb;
@ -244,7 +238,7 @@ int main()
} }
// Adjust the viewport when the window is resized // Adjust the viewport when the window is resized
if (const auto* resized = event.getIf<sf::Event::Resized>()) if (const auto* resized = event->getIf<sf::Event::Resized>())
{ {
const sf::Vector2u textureSize = backgroundTexture.getSize(); const sf::Vector2u textureSize = backgroundTexture.getSize();

View File

@ -34,9 +34,9 @@ int main()
while (window.isOpen()) while (window.isOpen())
{ {
while (const auto event = window.pollEvent()) while (const std::optional event = window.pollEvent())
{ {
if (event.is<sf::Event::Closed>()) if (event->is<sf::Event::Closed>())
{ {
window.close(); window.close();
break; break;
@ -45,10 +45,10 @@ int main()
static const auto vec2ToString = [](const sf::Vector2i& vec2) static const auto vec2ToString = [](const sf::Vector2i& vec2)
{ return '(' + std::to_string(vec2.x) + ", " + std::to_string(vec2.y) + ')'; }; { return '(' + std::to_string(vec2.x) + ", " + std::to_string(vec2.y) + ')'; };
if (const auto* const mouseMoved = event.getIf<sf::Event::MouseMoved>()) if (const auto* const mouseMoved = event->getIf<sf::Event::MouseMoved>())
mousePosition.setString("Mouse Position: " + vec2ToString(mouseMoved->position)); mousePosition.setString("Mouse Position: " + vec2ToString(mouseMoved->position));
if (const auto* const mouseMovedRaw = event.getIf<sf::Event::MouseMovedRaw>()) if (const auto* const mouseMovedRaw = event->getIf<sf::Event::MouseMovedRaw>())
{ {
log.emplace_back("Mouse Movement: " + vec2ToString(mouseMovedRaw->delta)); log.emplace_back("Mouse Movement: " + vec2ToString(mouseMovedRaw->delta));

View File

@ -438,16 +438,16 @@ int main()
while (window.isOpen()) while (window.isOpen())
{ {
// Process events // Process events
while (const auto event = window.pollEvent()) while (const std::optional event = window.pollEvent())
{ {
// Close window: exit // Close window: exit
if (event.is<sf::Event::Closed>()) if (event->is<sf::Event::Closed>())
{ {
window.close(); window.close();
break; break;
} }
if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>()) if (const auto* keyPressed = event->getIf<sf::Event::KeyPressed>())
{ {
switch (keyPressed->code) switch (keyPressed->code)
{ {

View File

@ -1124,13 +1124,13 @@ int main()
while (window.isOpen()) while (window.isOpen())
{ {
// Process events // Process events
while (const auto event = window.pollEvent()) while (const std::optional event = window.pollEvent())
{ {
// Close window: exit // Close window: exit
if (event.is<sf::Event::Closed>()) if (event->is<sf::Event::Closed>())
window.close(); window.close();
if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>()) if (const auto* keyPressed = event->getIf<sf::Event::KeyPressed>())
{ {
switch (keyPressed->code) switch (keyPressed->code)
{ {

View File

@ -40,10 +40,10 @@ int main()
while (window.isOpen()) while (window.isOpen())
{ {
// Handle events // Handle events
while (const auto event = window.pollEvent()) while (const std::optional event = window.pollEvent())
{ {
// Window closed: exit // Window closed: exit
if (event.is<sf::Event::Closed>()) if (event->is<sf::Event::Closed>())
{ {
window.close(); window.close();
break; break;

View File

@ -109,19 +109,21 @@ int main()
while (window.isOpen()) while (window.isOpen())
{ {
// Handle events // Handle events
while (const auto event = window.pollEvent()) while (const std::optional event = window.pollEvent())
{ {
// Window closed or escape key pressed: exit // Window closed or escape key pressed: exit
if (event.is<sf::Event::Closed>() || (event.is<sf::Event::KeyPressed>() && if (event->is<sf::Event::Closed>() ||
event.getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape)) (event->is<sf::Event::KeyPressed>() &&
event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
{ {
window.close(); window.close();
break; break;
} }
// Space key pressed: play // Space key pressed: play
if ((event.is<sf::Event::KeyPressed>() && event.getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Space) || if ((event->is<sf::Event::KeyPressed>() &&
event.is<sf::Event::TouchBegan>()) event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Space) ||
event->is<sf::Event::TouchBegan>())
{ {
if (!isPlaying) if (!isPlaying)
{ {
@ -144,7 +146,7 @@ int main()
} }
// Window size changed, adjust view appropriately // Window size changed, adjust view appropriately
if (event.is<sf::Event::Resized>()) if (event->is<sf::Event::Resized>())
{ {
sf::View view; sf::View view;
view.setSize({gameWidth, gameHeight}); view.setSize({gameWidth, gameHeight});

View File

@ -2544,19 +2544,18 @@ public:
while (window.isOpen()) while (window.isOpen())
{ {
// Process events // Process events
while (const auto event = window.pollEvent()) while (const std::optional event = window.pollEvent())
{ {
// Close window: exit // Window closed or escape key pressed: exit
if (event.is<sf::Event::Closed>()) if (event->is<sf::Event::Closed>() ||
window.close(); (event->is<sf::Event::KeyPressed>() &&
event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
// Escape key: exit {
if (event.is<sf::Event::KeyPressed>() &&
event.getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape)
window.close(); window.close();
}
// Re-create the swapchain when the window is resized // Re-create the swapchain when the window is resized
if (event.is<sf::Event::Resized>()) if (event->is<sf::Event::Resized>())
swapchainOutOfDate = true; swapchainOutOfDate = true;
} }

View File

@ -141,19 +141,18 @@ int main()
while (window.isOpen()) while (window.isOpen())
{ {
// Process events // Process events
while (const auto event = window.pollEvent()) while (const std::optional event = window.pollEvent())
{ {
// Close window: exit // Window closed or escape key pressed: exit
if (event.is<sf::Event::Closed>()) if (event->is<sf::Event::Closed>() ||
(event->is<sf::Event::KeyPressed>() &&
event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
{
window.close(); window.close();
}
// Escape key: exit
if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>())
if (keyPressed->code == sf::Keyboard::Key::Escape)
window.close();
// Resize event: adjust the viewport // Resize event: adjust the viewport
if (const auto* resized = event.getIf<sf::Event::Resized>()) if (const auto* resized = event->getIf<sf::Event::Resized>())
{ {
const auto [width, height] = resized->size; const auto [width, height] = resized->size;
glViewport(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height)); glViewport(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height));

View File

@ -237,10 +237,10 @@ private:
/// while (window.isOpen()) /// while (window.isOpen())
/// { /// {
/// // Event processing /// // Event processing
/// while (const auto event = window.pollEvent()) /// while (const std::optional event = window.pollEvent())
/// { /// {
/// // Request for closing the window /// // Request for closing the window
/// if (event.is<sf::Event::Closed>()) /// if (event->is<sf::Event::Closed>())
/// window.close(); /// window.close();
/// } /// }
/// ///

View File

@ -91,18 +91,19 @@ SFML_WINDOW_API void setString(const String& text);
/// sf::String string = sf::Clipboard::getString(); /// sf::String string = sf::Clipboard::getString();
/// ///
/// // or use it in the event loop /// // or use it in the event loop
/// while (const auto event = window.pollEvent()) /// while (const std::optional event = window.pollEvent())
/// { /// {
/// if(event.is<sf::Event::Closed>()) /// if (event->is<sf::Event::Closed>())
/// window.close(); /// window.close();
/// if(const auto* keyPressed = event.getIf<sf::Event::KeyPressed>()) ///
/// if (const auto* keyPressed = event->getIf<sf::Event::KeyPressed>())
/// { /// {
/// // Using Ctrl + V to paste a string into SFML /// // 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(); /// string = sf::Clipboard::getString();
/// ///
/// // Using Ctrl + C to copy a string out of SFML /// // 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!"); /// sf::Clipboard::setString("Hello World!");
/// } /// }
/// } /// }

View File

@ -48,14 +48,6 @@ namespace sf
class SFML_WINDOW_API Event class SFML_WINDOW_API Event
{ {
public: public:
////////////////////////////////////////////////////////////
/// \brief Empty event
///
////////////////////////////////////////////////////////////
struct Empty
{
};
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Closed event /// \brief Closed event
/// ///
@ -274,14 +266,6 @@ public:
Vector3f value; //!< Current value of the sensor on the X, Y, and Z axes 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 /// \brief Construct from a given sf::Event subtype
/// ///
@ -309,23 +293,11 @@ public:
template <typename T> template <typename T>
[[nodiscard]] const T* getIf() const; [[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<Empty>();
}
private: private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::variant<Empty, std::variant<Closed,
Closed,
Resized, Resized,
FocusLost, FocusLost,
FocusGained, FocusGained,
@ -390,19 +362,16 @@ private:
/// any of the corresponding event data. /// any of the corresponding event data.
/// ///
/// \code /// \code
/// while (const auto event = window.pollEvent()) /// while (const std::optional event = window.pollEvent())
/// { /// {
/// // Request for closing the window /// // Window closed or escape key pressed: exit
/// if (event.is<sf::Event::Closed>()) /// if (event->is<sf::Event::Closed>() ||
/// (event->is<sf::Event::KeyPressed>() &&
/// event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
/// window.close(); /// window.close();
/// ///
/// // The escape key was pressed
/// if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>())
/// if (keyPressed->code == sf::Keyboard::Key::Escape)
/// window.close();
///
/// // The window was resized /// // The window was resized
/// if (const auto* resized = event.getIf<sf::Event::Resized>()) /// if (const auto* resized = event->getIf<sf::Event::Resized>())
/// doSomethingWithTheNewSize(resized->size); /// doSomethingWithTheNewSize(resized->size);
/// ///
/// // etc ... /// // etc ...

View File

@ -347,10 +347,10 @@ private:
/// while (window.isOpen()) /// while (window.isOpen())
/// { /// {
/// // Event processing /// // Event processing
/// while (const auto event = window.pollEvent()) /// while (const std::optional event = window.pollEvent())
/// { /// {
/// // Request for closing the window /// // Request for closing the window
/// if (event.is<sf::Event::Closed>()) /// if (event->is<sf::Event::Closed>())
/// window.close(); /// window.close();
/// } /// }
/// ///

View File

@ -181,36 +181,36 @@ public:
/// \brief Pop the next event from the front of the FIFO event queue, if any, and return it /// \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 /// 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 /// may be present in the event queue, thus you should always call
/// this function in a loop to make sure that you process every /// this function in a loop to make sure that you process every
/// pending event. /// pending event.
/// \code /// \code
/// while (const auto event = window.pollEvent()) /// while (const std::optional event = window.pollEvent())
/// { /// {
/// // process event... /// // process event...
/// } /// }
/// \endcode /// \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 /// \see waitEvent
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] Event pollEvent(); [[nodiscard]] std::optional<Event> pollEvent();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Wait for an event and return it /// \brief Wait for an event and return it
/// ///
/// This function is blocking: if there's no pending event then /// This function is blocking: if there's no pending event then
/// it will wait until an event is received or until the provided /// it will wait until an event is received or until the provided
/// timeout elapses. After this function returns if no error nor /// timeout elapses. Only if an error or a timeout occurs the
/// timeout occurred, the returned event will not be empty. /// returned event will be `std::nullopt`.
/// This function is typically used when you have a thread that is /// This function is typically used when you have a thread that is
/// dedicated to events handling: you want to make this thread sleep /// dedicated to events handling: you want to make this thread sleep
/// as long as no new event is received. /// as long as no new event is received.
/// \code /// \code
/// if (const auto event = window.waitEvent()) /// while (const std::optional event = window.waitEvent())
/// { /// {
/// // process event... /// // process event...
/// } /// }
@ -218,12 +218,12 @@ public:
/// ///
/// \param timeout Maximum time to wait (`Time::Zero` for infinite) /// \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 /// \see pollEvent
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] Event waitEvent(Time timeout = Time::Zero); [[nodiscard]] std::optional<Event> waitEvent(Time timeout = Time::Zero);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Get the position of the window /// \brief Get the position of the window
@ -561,10 +561,10 @@ private:
/// while (window.isOpen()) /// while (window.isOpen())
/// { /// {
/// // Event processing /// // Event processing
/// while (const auto event = window.pollEvent()) /// while (const std::optional event = window.pollEvent())
/// { /// {
/// // Request for closing the window /// // Request for closing the window
/// if (event.is<sf::Event::Closed>()) /// if (event->is<sf::Event::Closed>())
/// window.close(); /// window.close();
/// } /// }
/// ///

View File

@ -462,28 +462,20 @@ int WindowImplAndroid::processKeyEvent(AInputEvent* inputEvent, ActivityStates&
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
int WindowImplAndroid::processMotionEvent(AInputEvent* inputEvent, ActivityStates& states) int WindowImplAndroid::processMotionEvent(AInputEvent* inputEvent, ActivityStates& states)
{ {
const std::int32_t device = AInputEvent_getSource(inputEvent); const std::int32_t device = AInputEvent_getSource(inputEvent);
const std::size_t pointerCount = AMotionEvent_getPointerCount(inputEvent);
Event event;
if (device == AINPUT_SOURCE_MOUSE)
event = Event::MouseMoved{};
else if (static_cast<std::uint32_t>(device) & AINPUT_SOURCE_TOUCHSCREEN)
event = Event::TouchMoved{};
const std::size_t pointerCount = AMotionEvent_getPointerCount(inputEvent);
for (std::size_t p = 0; p < pointerCount; ++p) for (std::size_t p = 0; p < pointerCount; ++p)
{ {
const std::int32_t id = AMotionEvent_getPointerId(inputEvent, p); const std::int32_t id = AMotionEvent_getPointerId(inputEvent, p);
int x = static_cast<int>(AMotionEvent_getX(inputEvent, p)); const int x = static_cast<int>(AMotionEvent_getX(inputEvent, p));
int y = static_cast<int>(AMotionEvent_getY(inputEvent, p)); const int y = static_cast<int>(AMotionEvent_getY(inputEvent, p));
if (device == AINPUT_SOURCE_MOUSE) if (device == AINPUT_SOURCE_MOUSE)
{ {
const Event::MouseMoved mouseMoved{{x, y}}; const Event::MouseMoved mouseMoved{{x, y}};
event = mouseMoved; forwardEvent(mouseMoved);
states.mousePosition = mouseMoved.position; states.mousePosition = mouseMoved.position;
} }
@ -493,13 +485,12 @@ int WindowImplAndroid::processMotionEvent(AInputEvent* inputEvent, ActivityState
continue; continue;
const Event::TouchMoved touchMoved{static_cast<unsigned int>(id), {x, y}}; const Event::TouchMoved touchMoved{static_cast<unsigned int>(id), {x, y}};
event = touchMoved; forwardEvent(touchMoved);
states.touchEvents[id] = touchMoved.position; states.touchEvents[id] = touchMoved.position;
} }
forwardEvent(event);
} }
return 1; return 1;
} }
@ -517,45 +508,42 @@ int WindowImplAndroid::processPointerEvent(bool isDown, AInputEvent* inputEvent,
int x = static_cast<int>(AMotionEvent_getX(inputEvent, index)); int x = static_cast<int>(AMotionEvent_getX(inputEvent, index));
int y = static_cast<int>(AMotionEvent_getY(inputEvent, index)); int y = static_cast<int>(AMotionEvent_getY(inputEvent, index));
Event event;
if (isDown) if (isDown)
{ {
if (device == AINPUT_SOURCE_MOUSE) if (device == AINPUT_SOURCE_MOUSE)
{ {
event = Event::MouseButtonPressed{button, {x, y}};
if (id >= 0 && id < static_cast<int>(Mouse::ButtonCount)) if (id >= 0 && id < static_cast<int>(Mouse::ButtonCount))
states.isButtonPressed[button] = true; states.isButtonPressed[button] = true;
forwardEvent(Event::MouseButtonPressed{button, {x, y}});
} }
else if (static_cast<unsigned int>(device) & AINPUT_SOURCE_TOUCHSCREEN) else if (static_cast<unsigned int>(device) & AINPUT_SOURCE_TOUCHSCREEN)
{ {
Event::TouchBegan touchBegan; Event::TouchBegan touchBegan;
touchBegan.finger = static_cast<unsigned int>(id); touchBegan.finger = static_cast<unsigned int>(id);
touchBegan.position = {x, y}; touchBegan.position = {x, y};
event = touchBegan;
states.touchEvents[id] = touchBegan.position; states.touchEvents[id] = touchBegan.position;
forwardEvent(touchBegan);
} }
} }
else else
{ {
if (device == AINPUT_SOURCE_MOUSE) if (device == AINPUT_SOURCE_MOUSE)
{ {
event = Event::MouseButtonReleased{button, {x, y}};
if (id >= 0 && id < static_cast<int>(Mouse::ButtonCount)) if (id >= 0 && id < static_cast<int>(Mouse::ButtonCount))
states.isButtonPressed[button] = false; states.isButtonPressed[button] = false;
forwardEvent(Event::MouseButtonReleased{button, {x, y}});
} }
else if (static_cast<std::uint32_t>(device) & AINPUT_SOURCE_TOUCHSCREEN) else if (static_cast<std::uint32_t>(device) & AINPUT_SOURCE_TOUCHSCREEN)
{ {
event = Event::TouchEnded{static_cast<unsigned int>(id), {x, y}};
states.touchEvents.erase(id); states.touchEvents.erase(id);
forwardEvent(Event::TouchEnded{static_cast<unsigned int>(id), {x, y}});
} }
} }
forwardEvent(event);
return 1; return 1;
} }

View File

@ -191,7 +191,7 @@ sf::Keyboard::Key toKey(int code)
{ {
switch (code) switch (code)
{ {
// clang-format off // clang-format off
case KEY_ESC: return sf::Keyboard::Key::Escape; case KEY_ESC: return sf::Keyboard::Key::Escape;
case KEY_1: return sf::Keyboard::Key::Num1; case KEY_1: return sf::Keyboard::Key::Num1;
case KEY_2: return sf::Keyboard::Key::Num2; case KEY_2: return sf::Keyboard::Key::Num2;
@ -341,7 +341,7 @@ void processSlots()
} }
} }
bool eventProcess(sf::Event& event) std::optional<sf::Event> eventProcess()
{ {
const std::lock_guard lock(inputMutex); const std::lock_guard lock(inputMutex);
@ -353,9 +353,10 @@ bool eventProcess(sf::Event& event)
static unsigned int doDeferredText = 0; static unsigned int doDeferredText = 0;
if (doDeferredText) if (doDeferredText)
{ {
event = sf::Event::TextEntered{doDeferredText}; const auto event = sf::Event::TextEntered{doDeferredText};
doDeferredText = 0; doDeferredText = 0;
return true; return event;
} }
ssize_t bytesRead = 0; ssize_t bytesRead = 0;
@ -372,13 +373,12 @@ bool eventProcess(sf::Event& event)
{ {
if (const std::optional<sf::Mouse::Button> mb = toMouseButton(inputEvent.code)) if (const std::optional<sf::Mouse::Button> mb = toMouseButton(inputEvent.code))
{ {
if (inputEvent.value)
event = sf::Event::MouseButtonPressed{*mb, mousePos};
else
event = sf::Event::MouseButtonReleased{*mb, mousePos};
mouseMap[*mb] = inputEvent.value; mouseMap[*mb] = inputEvent.value;
return true;
if (inputEvent.value)
return sf::Event::MouseButtonPressed{*mb, mousePos};
else
return sf::Event::MouseButtonReleased{*mb, mousePos};
} }
else else
{ {
@ -394,8 +394,7 @@ bool eventProcess(sf::Event& event)
// //
if (special) if (special)
{ {
event = sf::Event::TextEntered{special}; return sf::Event::TextEntered{special};
return true;
} }
} }
else if (kb != sf::Keyboard::Key::Unknown) else if (kb != sf::Keyboard::Key::Unknown)
@ -410,17 +409,15 @@ bool eventProcess(sf::Event& event)
keyChanged.shift = shiftDown(); keyChanged.shift = shiftDown();
keyChanged.system = systemDown(); keyChanged.system = systemDown();
if (inputEvent.value)
event = sf::Event::KeyPressed{keyChanged};
else
event = sf::Event::KeyReleased{keyChanged};
keyMap[kb] = inputEvent.value; keyMap[kb] = inputEvent.value;
if (special && inputEvent.value) if (special && inputEvent.value)
doDeferredText = special; 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; sf::Event::MouseWheelScrolled mouseWheelScrolled;
mouseWheelScrolled.delta = static_cast<float>(inputEvent.value); mouseWheelScrolled.delta = static_cast<float>(inputEvent.value);
mouseWheelScrolled.position = mousePos; mouseWheelScrolled.position = mousePos;
event = mouseWheelScrolled; return mouseWheelScrolled;
return true;
} }
if (posChange) if (posChange)
{ {
event = sf::Event::MouseMoved{mousePos}; return sf::Event::MouseMoved{mousePos};
return true;
} }
} }
else if (inputEvent.type == EV_ABS) else if (inputEvent.type == EV_ABS)
@ -488,7 +482,6 @@ bool eventProcess(sf::Event& event)
if ((bytesRead < 0) && (errno != EAGAIN)) if ((bytesRead < 0) && (errno != EAGAIN))
sf::err() << " Error: " << std::strerror(errno) << std::endl; sf::err() << " Error: " << std::strerror(errno) << std::endl;
} }
// Finally check if there is a Text event on stdin // Finally check if there is a Text event on stdin
// //
// We only clear the ICANON flag for the time of reading // 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)) if (ready > 0 && FD_ISSET(STDIN_FILENO, &readFDSet))
bytesRead = read(STDIN_FILENO, &code, 1); 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; code = 0;
else if (code == 27) // ESC else if (code == 27) // ESC
{ {
@ -534,22 +527,18 @@ bool eventProcess(sf::Event& event)
if (code > 0) if (code > 0)
{ {
// TODO: Proper unicode handling // TODO: Proper unicode handling
event = sf::Event::TextEntered{code}; return sf::Event::TextEntered{code};
return true;
} }
// No events available // No events available
return false; return std::nullopt;
} }
// assumes inputMutex is locked // assumes inputMutex is locked
void update() void update()
{ {
sf::Event event; while (const std::optional event = eventProcess())
while (eventProcess(event)) pushEvent(*event);
{
pushEvent(event);
}
} }
} // namespace } // namespace
@ -603,7 +592,7 @@ String getDescription(Keyboard::Scancode /* code */)
} }
//////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
void setVirtualKeyboardVisible(bool /*visible*/) void setVirtualKeyboardVisible(bool /*visible*/)
{ {
// Not applicable // Not applicable
@ -682,36 +671,35 @@ Vector2i getTouchPosition(unsigned int finger, const WindowBase& /*relativeTo*/)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool checkEvent(Event& event) std::optional<Event> checkEvent()
{ {
const std::lock_guard lock(inputMutex); const std::lock_guard lock(inputMutex);
if (!eventQueue.empty()) if (!eventQueue.empty())
{ {
event = eventQueue.front(); auto event = std::make_optional(eventQueue.front());
eventQueue.pop(); 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 auto event = std::make_optional(eventQueue.front());
// but added events directly to the queue. (This is ugly, but I'm not eventQueue.pop();
// sure of a good way to handle generating multiple events at once.)
if (!eventQueue.empty())
{
event = eventQueue.front();
eventQueue.pop();
return true; return event;
}
} }
return false; return std::nullopt;
} }

View File

@ -46,7 +46,7 @@ namespace InputImpl
/// \return False if event queue is empty /// \return False if event queue is empty
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool checkEvent(Event& event); std::optional<Event> checkEvent();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Backup terminal configuration and disable console feedback /// \brief Backup terminal configuration and disable console feedback
@ -190,9 +190,8 @@ bool WindowImplDRM::hasFocus() const
void WindowImplDRM::processEvents() void WindowImplDRM::processEvents()
{ {
Event event; while (const std::optional event = InputImpl::checkEvent())
while (InputImpl::checkEvent(event)) pushEvent(*event);
pushEvent(event);
} }
} // namespace sf::priv } // namespace sf::priv

View File

@ -43,6 +43,7 @@
#include <vector> #include <vector>
#include <cassert> #include <cassert>
#include <cstdlib>
namespace 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::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<Event> WindowBase::pollEvent()
{ {
Event event; std::optional<sf::Event> event; // Use a single local variable for NRVO
if (m_impl && (event = m_impl->pollEvent()))
filterEvent(event); if (m_impl == nullptr)
return event; // Empty optional
event = m_impl->pollEvent();
if (event.has_value())
filterEvent(*event);
return event; return event;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Event WindowBase::waitEvent(Time timeout) std::optional<Event> WindowBase::waitEvent(Time timeout)
{ {
Event event; std::optional<sf::Event> event; // Use a single local variable for NRVO
if (m_impl && (event = m_impl->waitEvent(timeout)))
filterEvent(event); if (m_impl == nullptr)
return event; // Empty optional
event = m_impl->waitEvent(timeout);
if (event.has_value())
filterEvent(*event);
return event; return event;
} }

View File

@ -176,7 +176,7 @@ void WindowImpl::setMaximumSize(const std::optional<Vector2u>& maximumSize)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Event WindowImpl::waitEvent(Time timeout) std::optional<Event> WindowImpl::waitEvent(Time timeout)
{ {
const auto timedOut = [&, startTime = std::chrono::steady_clock::now()] const auto timedOut = [&, startTime = std::chrono::steady_clock::now()]
{ {
@ -201,7 +201,7 @@ Event WindowImpl::waitEvent(Time timeout)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Event WindowImpl::pollEvent() std::optional<Event> WindowImpl::pollEvent()
{ {
// If the event queue is empty, let's first check if new events are available from the OS // If the event queue is empty, let's first check if new events are available from the OS
if (m_events.empty()) if (m_events.empty())
@ -212,13 +212,13 @@ Event WindowImpl::pollEvent()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Event WindowImpl::popEvent() std::optional<Event> WindowImpl::popEvent()
{ {
Event event; std::optional<Event> event; // Use a single local variable for NRVO
if (!m_events.empty()) if (!m_events.empty())
{ {
event = m_events.front(); event.emplace(m_events.front());
m_events.pop(); m_events.pop();
} }

View File

@ -129,10 +129,10 @@ public:
/// ///
/// \param timeout Maximum time to wait (`Time::Zero` for infinite) /// \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<Event> waitEvent(Time timeout);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Return the next window event, if available /// \brief Return the next window event, if available
@ -140,10 +140,10 @@ public:
/// If there's no event available, this function calls the /// If there's no event available, this function calls the
/// window's internal event processing function. /// 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<Event> pollEvent();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Get the OS-specific handle of the window /// \brief Get the OS-specific handle of the window
@ -334,10 +334,10 @@ private:
struct JoystickStatesImpl; 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<Event> popEvent();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Read the joysticks state and generate the appropriate events /// \brief Read the joysticks state and generate the appropriate events

View File

@ -8,6 +8,7 @@ TEST_CASE("[Window] sf::Event")
{ {
SECTION("Type traits") SECTION("Type traits")
{ {
STATIC_CHECK(!std::is_default_constructible_v<sf::Event>);
STATIC_CHECK(std::is_copy_constructible_v<sf::Event>); STATIC_CHECK(std::is_copy_constructible_v<sf::Event>);
STATIC_CHECK(std::is_copy_assignable_v<sf::Event>); STATIC_CHECK(std::is_copy_assignable_v<sf::Event>);
STATIC_CHECK(std::is_nothrow_move_constructible_v<sf::Event>); STATIC_CHECK(std::is_nothrow_move_constructible_v<sf::Event>);
@ -16,18 +17,9 @@ TEST_CASE("[Window] sf::Event")
SECTION("Construction") SECTION("Construction")
{ {
SECTION("Default constructor")
{
const sf::Event event;
CHECK(!event);
CHECK(event.is<sf::Event::Empty>());
CHECK(event.getIf<sf::Event::Empty>());
}
SECTION("Template constructor") SECTION("Template constructor")
{ {
const sf::Event event = sf::Event::Resized{{1, 2}}; const sf::Event event = sf::Event::Resized{{1, 2}};
CHECK(event);
CHECK(event.is<sf::Event::Resized>()); CHECK(event.is<sf::Event::Resized>());
CHECK(event.getIf<sf::Event::Resized>()); CHECK(event.getIf<sf::Event::Resized>());
const auto& resized = *event.getIf<sf::Event::Resized>(); const auto& resized = *event.getIf<sf::Event::Resized>();
@ -37,38 +29,31 @@ TEST_CASE("[Window] sf::Event")
SECTION("Assign all possible values") SECTION("Assign all possible values")
{ {
sf::Event event; sf::Event event = sf::Event::Closed{};
event = sf::Event::Closed{};
CHECK(event);
CHECK(event.is<sf::Event::Closed>()); CHECK(event.is<sf::Event::Closed>());
CHECK(event.getIf<sf::Event::Closed>()); CHECK(event.getIf<sf::Event::Closed>());
event = sf::Event::Resized{{1, 2}}; event = sf::Event::Resized{{1, 2}};
CHECK(event);
CHECK(event.is<sf::Event::Resized>()); CHECK(event.is<sf::Event::Resized>());
CHECK(event.getIf<sf::Event::Resized>()); CHECK(event.getIf<sf::Event::Resized>());
const auto& resized = *event.getIf<sf::Event::Resized>(); const auto& resized = *event.getIf<sf::Event::Resized>();
CHECK(resized.size == sf::Vector2u(1, 2)); CHECK(resized.size == sf::Vector2u(1, 2));
event = sf::Event::FocusLost{}; event = sf::Event::FocusLost{};
CHECK(event);
CHECK(event.is<sf::Event::FocusLost>()); CHECK(event.is<sf::Event::FocusLost>());
CHECK(event.getIf<sf::Event::FocusLost>()); CHECK(event.getIf<sf::Event::FocusLost>());
event = sf::Event::FocusGained{}; event = sf::Event::FocusGained{};
CHECK(event);
CHECK(event.is<sf::Event::FocusGained>()); CHECK(event.is<sf::Event::FocusGained>());
CHECK(event.getIf<sf::Event::FocusGained>()); CHECK(event.getIf<sf::Event::FocusGained>());
event = sf::Event::TextEntered{123456}; event = sf::Event::TextEntered{123456};
CHECK(event);
CHECK(event.is<sf::Event::TextEntered>()); CHECK(event.is<sf::Event::TextEntered>());
CHECK(event.getIf<sf::Event::TextEntered>()); CHECK(event.getIf<sf::Event::TextEntered>());
const auto& textEntered = *event.getIf<sf::Event::TextEntered>(); const auto& textEntered = *event.getIf<sf::Event::TextEntered>();
CHECK(textEntered.unicode == 123456); CHECK(textEntered.unicode == 123456);
event = sf::Event::KeyPressed{sf::Keyboard::Key::C, sf::Keyboard::Scan::C, true, true, true, true}; event = sf::Event::KeyPressed{sf::Keyboard::Key::C, sf::Keyboard::Scan::C, true, true, true, true};
CHECK(event);
CHECK(event.is<sf::Event::KeyPressed>()); CHECK(event.is<sf::Event::KeyPressed>());
CHECK(event.getIf<sf::Event::KeyPressed>()); CHECK(event.getIf<sf::Event::KeyPressed>());
const auto& keyPressed = *event.getIf<sf::Event::KeyPressed>(); const auto& keyPressed = *event.getIf<sf::Event::KeyPressed>();
@ -80,7 +65,6 @@ TEST_CASE("[Window] sf::Event")
CHECK(keyPressed.system); CHECK(keyPressed.system);
event = sf::Event::KeyReleased{sf::Keyboard::Key::D, sf::Keyboard::Scan::D, true, true, true, true}; event = sf::Event::KeyReleased{sf::Keyboard::Key::D, sf::Keyboard::Scan::D, true, true, true, true};
CHECK(event);
CHECK(event.is<sf::Event::KeyReleased>()); CHECK(event.is<sf::Event::KeyReleased>());
CHECK(event.getIf<sf::Event::KeyReleased>()); CHECK(event.getIf<sf::Event::KeyReleased>());
const auto& keyReleased = *event.getIf<sf::Event::KeyReleased>(); const auto& keyReleased = *event.getIf<sf::Event::KeyReleased>();
@ -92,7 +76,6 @@ TEST_CASE("[Window] sf::Event")
CHECK(keyReleased.system); CHECK(keyReleased.system);
event = sf::Event::MouseWheelScrolled{sf::Mouse::Wheel::Horizontal, 3.14f, {4, 5}}; event = sf::Event::MouseWheelScrolled{sf::Mouse::Wheel::Horizontal, 3.14f, {4, 5}};
CHECK(event);
CHECK(event.is<sf::Event::MouseWheelScrolled>()); CHECK(event.is<sf::Event::MouseWheelScrolled>());
CHECK(event.getIf<sf::Event::MouseWheelScrolled>()); CHECK(event.getIf<sf::Event::MouseWheelScrolled>());
const auto& mouseWheelScrolled = *event.getIf<sf::Event::MouseWheelScrolled>(); const auto& mouseWheelScrolled = *event.getIf<sf::Event::MouseWheelScrolled>();
@ -101,7 +84,6 @@ TEST_CASE("[Window] sf::Event")
CHECK(mouseWheelScrolled.position == sf::Vector2i(4, 5)); CHECK(mouseWheelScrolled.position == sf::Vector2i(4, 5));
event = sf::Event::MouseButtonPressed{sf::Mouse::Button::Middle, {6, 7}}; event = sf::Event::MouseButtonPressed{sf::Mouse::Button::Middle, {6, 7}};
CHECK(event);
CHECK(event.is<sf::Event::MouseButtonPressed>()); CHECK(event.is<sf::Event::MouseButtonPressed>());
CHECK(event.getIf<sf::Event::MouseButtonPressed>()); CHECK(event.getIf<sf::Event::MouseButtonPressed>());
const auto& mouseButtonPressed = *event.getIf<sf::Event::MouseButtonPressed>(); const auto& mouseButtonPressed = *event.getIf<sf::Event::MouseButtonPressed>();
@ -109,7 +91,6 @@ TEST_CASE("[Window] sf::Event")
CHECK(mouseButtonPressed.position == sf::Vector2i(6, 7)); CHECK(mouseButtonPressed.position == sf::Vector2i(6, 7));
event = sf::Event::MouseButtonReleased{sf::Mouse::Button::Extra1, {8, 9}}; event = sf::Event::MouseButtonReleased{sf::Mouse::Button::Extra1, {8, 9}};
CHECK(event);
CHECK(event.is<sf::Event::MouseButtonReleased>()); CHECK(event.is<sf::Event::MouseButtonReleased>());
CHECK(event.getIf<sf::Event::MouseButtonReleased>()); CHECK(event.getIf<sf::Event::MouseButtonReleased>());
const auto& mouseButtonReleased = *event.getIf<sf::Event::MouseButtonReleased>(); const auto& mouseButtonReleased = *event.getIf<sf::Event::MouseButtonReleased>();
@ -117,31 +98,26 @@ TEST_CASE("[Window] sf::Event")
CHECK(mouseButtonReleased.position == sf::Vector2i(8, 9)); CHECK(mouseButtonReleased.position == sf::Vector2i(8, 9));
event = sf::Event::MouseMoved{{4, 2}}; event = sf::Event::MouseMoved{{4, 2}};
CHECK(event);
CHECK(event.is<sf::Event::MouseMoved>()); CHECK(event.is<sf::Event::MouseMoved>());
CHECK(event.getIf<sf::Event::MouseMoved>()); CHECK(event.getIf<sf::Event::MouseMoved>());
const auto& mouseMoved = *event.getIf<sf::Event::MouseMoved>(); const auto& mouseMoved = *event.getIf<sf::Event::MouseMoved>();
CHECK(mouseMoved.position == sf::Vector2i(4, 2)); CHECK(mouseMoved.position == sf::Vector2i(4, 2));
event = sf::Event::MouseMovedRaw{{3, 7}}; event = sf::Event::MouseMovedRaw{{3, 7}};
CHECK(event);
CHECK(event.is<sf::Event::MouseMovedRaw>()); CHECK(event.is<sf::Event::MouseMovedRaw>());
CHECK(event.getIf<sf::Event::MouseMovedRaw>()); CHECK(event.getIf<sf::Event::MouseMovedRaw>());
const auto& mouseMovedRaw = *event.getIf<sf::Event::MouseMovedRaw>(); const auto& mouseMovedRaw = *event.getIf<sf::Event::MouseMovedRaw>();
CHECK(mouseMovedRaw.delta == sf::Vector2i(3, 7)); CHECK(mouseMovedRaw.delta == sf::Vector2i(3, 7));
event = sf::Event::MouseEntered{}; event = sf::Event::MouseEntered{};
CHECK(event);
CHECK(event.is<sf::Event::MouseEntered>()); CHECK(event.is<sf::Event::MouseEntered>());
CHECK(event.getIf<sf::Event::MouseEntered>()); CHECK(event.getIf<sf::Event::MouseEntered>());
event = sf::Event::MouseLeft{}; event = sf::Event::MouseLeft{};
CHECK(event);
CHECK(event.is<sf::Event::MouseLeft>()); CHECK(event.is<sf::Event::MouseLeft>());
CHECK(event.getIf<sf::Event::MouseLeft>()); CHECK(event.getIf<sf::Event::MouseLeft>());
event = sf::Event::JoystickButtonPressed{100, 200}; event = sf::Event::JoystickButtonPressed{100, 200};
CHECK(event);
CHECK(event.is<sf::Event::JoystickButtonPressed>()); CHECK(event.is<sf::Event::JoystickButtonPressed>());
CHECK(event.getIf<sf::Event::JoystickButtonPressed>()); CHECK(event.getIf<sf::Event::JoystickButtonPressed>());
const auto& joystickButtonPressed = *event.getIf<sf::Event::JoystickButtonPressed>(); const auto& joystickButtonPressed = *event.getIf<sf::Event::JoystickButtonPressed>();
@ -149,7 +125,6 @@ TEST_CASE("[Window] sf::Event")
CHECK(joystickButtonPressed.button == 200); CHECK(joystickButtonPressed.button == 200);
event = sf::Event::JoystickButtonReleased{300, 400}; event = sf::Event::JoystickButtonReleased{300, 400};
CHECK(event);
CHECK(event.is<sf::Event::JoystickButtonReleased>()); CHECK(event.is<sf::Event::JoystickButtonReleased>());
CHECK(event.getIf<sf::Event::JoystickButtonReleased>()); CHECK(event.getIf<sf::Event::JoystickButtonReleased>());
const auto& joystickButtonReleased = *event.getIf<sf::Event::JoystickButtonReleased>(); const auto& joystickButtonReleased = *event.getIf<sf::Event::JoystickButtonReleased>();
@ -157,7 +132,6 @@ TEST_CASE("[Window] sf::Event")
CHECK(joystickButtonReleased.button == 400); CHECK(joystickButtonReleased.button == 400);
event = sf::Event::JoystickMoved{300, sf::Joystick::Axis::Z, 1.23f}; event = sf::Event::JoystickMoved{300, sf::Joystick::Axis::Z, 1.23f};
CHECK(event);
CHECK(event.is<sf::Event::JoystickMoved>()); CHECK(event.is<sf::Event::JoystickMoved>());
CHECK(event.getIf<sf::Event::JoystickMoved>()); CHECK(event.getIf<sf::Event::JoystickMoved>());
const auto& joystickMoved = *event.getIf<sf::Event::JoystickMoved>(); const auto& joystickMoved = *event.getIf<sf::Event::JoystickMoved>();
@ -166,21 +140,18 @@ TEST_CASE("[Window] sf::Event")
CHECK(joystickMoved.position == 1.23f); CHECK(joystickMoved.position == 1.23f);
event = sf::Event::JoystickConnected{42}; event = sf::Event::JoystickConnected{42};
CHECK(event);
CHECK(event.is<sf::Event::JoystickConnected>()); CHECK(event.is<sf::Event::JoystickConnected>());
CHECK(event.getIf<sf::Event::JoystickConnected>()); CHECK(event.getIf<sf::Event::JoystickConnected>());
const auto& joystickConnected = *event.getIf<sf::Event::JoystickConnected>(); const auto& joystickConnected = *event.getIf<sf::Event::JoystickConnected>();
CHECK(joystickConnected.joystickId == 42); CHECK(joystickConnected.joystickId == 42);
event = sf::Event::JoystickDisconnected{43}; event = sf::Event::JoystickDisconnected{43};
CHECK(event);
CHECK(event.is<sf::Event::JoystickDisconnected>()); CHECK(event.is<sf::Event::JoystickDisconnected>());
CHECK(event.getIf<sf::Event::JoystickDisconnected>()); CHECK(event.getIf<sf::Event::JoystickDisconnected>());
const auto& joystickDisconnected = *event.getIf<sf::Event::JoystickDisconnected>(); const auto& joystickDisconnected = *event.getIf<sf::Event::JoystickDisconnected>();
CHECK(joystickDisconnected.joystickId == 43); CHECK(joystickDisconnected.joystickId == 43);
event = sf::Event::TouchBegan{99, {98, 97}}; event = sf::Event::TouchBegan{99, {98, 97}};
CHECK(event);
CHECK(event.is<sf::Event::TouchBegan>()); CHECK(event.is<sf::Event::TouchBegan>());
CHECK(event.getIf<sf::Event::TouchBegan>()); CHECK(event.getIf<sf::Event::TouchBegan>());
const auto& touchBegan = *event.getIf<sf::Event::TouchBegan>(); const auto& touchBegan = *event.getIf<sf::Event::TouchBegan>();
@ -188,7 +159,6 @@ TEST_CASE("[Window] sf::Event")
CHECK(touchBegan.position == sf::Vector2i(98, 97)); CHECK(touchBegan.position == sf::Vector2i(98, 97));
event = sf::Event::TouchMoved{96, {95, 94}}; event = sf::Event::TouchMoved{96, {95, 94}};
CHECK(event);
CHECK(event.is<sf::Event::TouchMoved>()); CHECK(event.is<sf::Event::TouchMoved>());
CHECK(event.getIf<sf::Event::TouchMoved>()); CHECK(event.getIf<sf::Event::TouchMoved>());
const auto& touchMoved = *event.getIf<sf::Event::TouchMoved>(); const auto& touchMoved = *event.getIf<sf::Event::TouchMoved>();
@ -196,7 +166,6 @@ TEST_CASE("[Window] sf::Event")
CHECK(touchMoved.position == sf::Vector2i(95, 94)); CHECK(touchMoved.position == sf::Vector2i(95, 94));
event = sf::Event::TouchEnded{93, {92, 91}}; event = sf::Event::TouchEnded{93, {92, 91}};
CHECK(event);
CHECK(event.is<sf::Event::TouchEnded>()); CHECK(event.is<sf::Event::TouchEnded>());
CHECK(event.getIf<sf::Event::TouchEnded>()); CHECK(event.getIf<sf::Event::TouchEnded>());
const auto& touchEnded = *event.getIf<sf::Event::TouchEnded>(); const auto& touchEnded = *event.getIf<sf::Event::TouchEnded>();
@ -204,7 +173,6 @@ TEST_CASE("[Window] sf::Event")
CHECK(touchEnded.position == sf::Vector2i(92, 91)); CHECK(touchEnded.position == sf::Vector2i(92, 91));
event = sf::Event::SensorChanged{sf::Sensor::Type::Gravity, {1.2f, 3.4f, 5.6f}}; event = sf::Event::SensorChanged{sf::Sensor::Type::Gravity, {1.2f, 3.4f, 5.6f}};
CHECK(event);
CHECK(event.is<sf::Event::SensorChanged>()); CHECK(event.is<sf::Event::SensorChanged>());
CHECK(event.getIf<sf::Event::SensorChanged>()); CHECK(event.getIf<sf::Event::SensorChanged>());
const auto& sensorChanged = *event.getIf<sf::Event::SensorChanged>(); const auto& sensorChanged = *event.getIf<sf::Event::SensorChanged>();
@ -215,7 +183,6 @@ TEST_CASE("[Window] sf::Event")
SECTION("Subtypes") SECTION("Subtypes")
{ {
// Empty structs // Empty structs
STATIC_CHECK(std::is_empty_v<sf::Event::Empty>);
STATIC_CHECK(std::is_empty_v<sf::Event::Closed>); STATIC_CHECK(std::is_empty_v<sf::Event::Closed>);
STATIC_CHECK(std::is_empty_v<sf::Event::FocusLost>); STATIC_CHECK(std::is_empty_v<sf::Event::FocusLost>);
STATIC_CHECK(std::is_empty_v<sf::Event::FocusGained>); STATIC_CHECK(std::is_empty_v<sf::Event::FocusGained>);