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 (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();
}

View File

@ -54,9 +54,9 @@ body:
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();
}

View File

@ -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<sf::Event::Closed>())
if (event->is<sf::Event::Closed>())
window.close();
}

View File

@ -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<sf::Event::Closed>())
/// if (event->is<sf::Event::Closed>())
/// window.close();
/// }
///

View File

@ -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<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();
}
else if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>())
{
if (keyPressed->code == sf::Keyboard::Key::Escape)
window.close();
}
else if (const auto* resized = event.getIf<sf::Event::Resized>())
else if (const auto* resized = event->getIf<sf::Event::Resized>())
{
const auto size = sf::Vector2f(resized->size);
view.setSize(size);
view.setCenter(size / 2.f);
window.setView(view);
}
else if (event.is<sf::Event::FocusLost>())
else if (event->is<sf::Event::FocusLost>())
{
background = sf::Color::Black;
}
else if (event.is<sf::Event::FocusGained>())
else if (event->is<sf::Event::FocusGained>())
{
background = sf::Color::White;
}
// On Android MouseLeft/MouseEntered are (for now) triggered,
// whenever the app loses or gains focus.
else if (event.is<sf::Event::MouseLeft>())
else if (event->is<sf::Event::MouseLeft>())
{
active = false;
}
else if (event.is<sf::Event::MouseEntered>())
else if (event->is<sf::Event::MouseEntered>())
{
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)
{

View File

@ -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<sf::Event::Closed>() || (event.is<sf::Event::KeyPressed>() &&
event.getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
if (event->is<sf::Event::Closed>() ||
(event->is<sf::Event::KeyPressed>() &&
event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
{
window.close();
break;
}
// 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:
generateTerrain(terrainStagingBuffer.data());

View File

@ -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<sf::Event::Closed>() || (event.is<sf::Event::KeyPressed>() &&
event.getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
if (event->is<sf::Event::Closed>() ||
(event->is<sf::Event::KeyPressed>() &&
event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
{
window.close();
break;
}
else if (const auto* joystickButtonPressed = event.getIf<sf::Event::JoystickButtonPressed>())
if (const auto* joystickButtonPressed = event->getIf<sf::Event::JoystickButtonPressed>())
{
// Update displayed joystick values
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
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
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
updateValues(joystickConnected->joystickId);
}
else if (event.is<sf::Event::JoystickDisconnected>())
else if (event->is<sf::Event::JoystickDisconnected>())
{
// Reset displayed joystick values to empty
for (auto& [label, joystickObject] : texts)

View File

@ -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<sf::Event::Closed>())
{
exit = true;
window.close();
}
// Escape key: exit
if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>();
keyPressed && keyPressed->code == sf::Keyboard::Key::Escape)
// Window closed or escape key pressed: exit
if (event->is<sf::Event::Closed>() ||
(event->is<sf::Event::KeyPressed>() &&
event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
{
exit = true;
window.close();
}
// 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)
{
if (mipmapEnabled)
@ -236,7 +230,7 @@ int main()
}
// 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)
{
sRgb = !sRgb;
@ -244,7 +238,7 @@ int main()
}
// 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();

View File

@ -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<sf::Event::Closed>())
if (event->is<sf::Event::Closed>())
{
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<sf::Event::MouseMoved>())
if (const auto* const mouseMoved = event->getIf<sf::Event::MouseMoved>())
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));

View File

@ -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<sf::Event::Closed>())
if (event->is<sf::Event::Closed>())
{
window.close();
break;
}
if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>())
if (const auto* keyPressed = event->getIf<sf::Event::KeyPressed>())
{
switch (keyPressed->code)
{

View File

@ -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<sf::Event::Closed>())
if (event->is<sf::Event::Closed>())
window.close();
if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>())
if (const auto* keyPressed = event->getIf<sf::Event::KeyPressed>())
{
switch (keyPressed->code)
{

View File

@ -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<sf::Event::Closed>())
if (event->is<sf::Event::Closed>())
{
window.close();
break;

View File

@ -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<sf::Event::Closed>() || (event.is<sf::Event::KeyPressed>() &&
event.getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
if (event->is<sf::Event::Closed>() ||
(event->is<sf::Event::KeyPressed>() &&
event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
{
window.close();
break;
}
// Space key pressed: play
if ((event.is<sf::Event::KeyPressed>() && event.getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Space) ||
event.is<sf::Event::TouchBegan>())
if ((event->is<sf::Event::KeyPressed>() &&
event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Space) ||
event->is<sf::Event::TouchBegan>())
{
if (!isPlaying)
{
@ -144,7 +146,7 @@ int main()
}
// Window size changed, adjust view appropriately
if (event.is<sf::Event::Resized>())
if (event->is<sf::Event::Resized>())
{
sf::View view;
view.setSize({gameWidth, gameHeight});

View File

@ -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<sf::Event::Closed>())
window.close();
// Escape key: exit
if (event.is<sf::Event::KeyPressed>() &&
event.getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape)
// Window closed or escape key pressed: exit
if (event->is<sf::Event::Closed>() ||
(event->is<sf::Event::KeyPressed>() &&
event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
{
window.close();
}
// Re-create the swapchain when the window is resized
if (event.is<sf::Event::Resized>())
if (event->is<sf::Event::Resized>())
swapchainOutOfDate = true;
}

View File

@ -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<sf::Event::Closed>())
// Window closed or escape key pressed: exit
if (event->is<sf::Event::Closed>() ||
(event->is<sf::Event::KeyPressed>() &&
event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
{
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
if (const auto* resized = event.getIf<sf::Event::Resized>())
if (const auto* resized = event->getIf<sf::Event::Resized>())
{
const auto [width, height] = resized->size;
glViewport(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height));

View File

@ -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<sf::Event::Closed>())
/// if (event->is<sf::Event::Closed>())
/// window.close();
/// }
///

View File

@ -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<sf::Event::Closed>())
/// if (event->is<sf::Event::Closed>())
/// 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
/// 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!");
/// }
/// }

View File

@ -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 <typename T>
[[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:
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
std::variant<Empty,
Closed,
std::variant<Closed,
Resized,
FocusLost,
FocusGained,
@ -390,19 +362,16 @@ private:
/// any of the corresponding event data.
///
/// \code
/// while (const auto event = window.pollEvent())
/// while (const std::optional event = window.pollEvent())
/// {
/// // Request for closing the window
/// if (event.is<sf::Event::Closed>())
/// // Window closed or escape key pressed: exit
/// if (event->is<sf::Event::Closed>() ||
/// (event->is<sf::Event::KeyPressed>() &&
/// event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
/// 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
/// if (const auto* resized = event.getIf<sf::Event::Resized>())
/// if (const auto* resized = event->getIf<sf::Event::Resized>())
/// doSomethingWithTheNewSize(resized->size);
///
/// // etc ...

View File

@ -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<sf::Event::Closed>())
/// if (event->is<sf::Event::Closed>())
/// 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
///
/// 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<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 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<Event> 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<sf::Event::Closed>())
/// if (event->is<sf::Event::Closed>())
/// window.close();
/// }
///

View File

@ -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<std::uint32_t>(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<int>(AMotionEvent_getX(inputEvent, p));
int y = static_cast<int>(AMotionEvent_getY(inputEvent, p));
const int x = static_cast<int>(AMotionEvent_getX(inputEvent, p));
const int y = static_cast<int>(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<unsigned int>(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<int>(AMotionEvent_getX(inputEvent, index));
int y = static_cast<int>(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<int>(Mouse::ButtonCount))
states.isButtonPressed[button] = true;
forwardEvent(Event::MouseButtonPressed{button, {x, y}});
}
else if (static_cast<unsigned int>(device) & AINPUT_SOURCE_TOUCHSCREEN)
{
Event::TouchBegan touchBegan;
touchBegan.finger = static_cast<unsigned int>(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<int>(Mouse::ButtonCount))
states.isButtonPressed[button] = false;
forwardEvent(Event::MouseButtonReleased{button, {x, y}});
}
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);
forwardEvent(Event::TouchEnded{static_cast<unsigned int>(id), {x, y}});
}
}
forwardEvent(event);
return 1;
}

View File

@ -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<sf::Event> 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<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;
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<float>(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<Event> 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;
}

View File

@ -46,7 +46,7 @@ namespace InputImpl
/// \return False if event queue is empty
///
////////////////////////////////////////////////////////////
bool checkEvent(Event& event);
std::optional<Event> 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

View File

@ -43,6 +43,7 @@
#include <vector>
#include <cassert>
#include <cstdlib>
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<Event> WindowBase::pollEvent()
{
Event event;
if (m_impl && (event = m_impl->pollEvent()))
filterEvent(event);
std::optional<sf::Event> 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<Event> WindowBase::waitEvent(Time timeout)
{
Event event;
if (m_impl && (event = m_impl->waitEvent(timeout)))
filterEvent(event);
std::optional<sf::Event> 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;
}

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()]
{
@ -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 (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())
{
event = m_events.front();
event.emplace(m_events.front());
m_events.pop();
}

View File

@ -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<Event> 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<Event> 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<Event> popEvent();
////////////////////////////////////////////////////////////
/// \brief Read the joysticks state and generate the appropriate events

View File

@ -8,6 +8,7 @@ TEST_CASE("[Window] sf::Event")
{
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_assignable_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("Default constructor")
{
const sf::Event event;
CHECK(!event);
CHECK(event.is<sf::Event::Empty>());
CHECK(event.getIf<sf::Event::Empty>());
}
SECTION("Template constructor")
{
const sf::Event event = sf::Event::Resized{{1, 2}};
CHECK(event);
CHECK(event.is<sf::Event::Resized>());
CHECK(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")
{
sf::Event event;
event = sf::Event::Closed{};
CHECK(event);
sf::Event event = sf::Event::Closed{};
CHECK(event.is<sf::Event::Closed>());
CHECK(event.getIf<sf::Event::Closed>());
event = sf::Event::Resized{{1, 2}};
CHECK(event);
CHECK(event.is<sf::Event::Resized>());
CHECK(event.getIf<sf::Event::Resized>());
const auto& resized = *event.getIf<sf::Event::Resized>();
CHECK(resized.size == sf::Vector2u(1, 2));
event = sf::Event::FocusLost{};
CHECK(event);
CHECK(event.is<sf::Event::FocusLost>());
CHECK(event.getIf<sf::Event::FocusLost>());
event = sf::Event::FocusGained{};
CHECK(event);
CHECK(event.is<sf::Event::FocusGained>());
CHECK(event.getIf<sf::Event::FocusGained>());
event = sf::Event::TextEntered{123456};
CHECK(event);
CHECK(event.is<sf::Event::TextEntered>());
CHECK(event.getIf<sf::Event::TextEntered>());
const auto& textEntered = *event.getIf<sf::Event::TextEntered>();
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<sf::Event::KeyPressed>());
CHECK(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);
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.getIf<sf::Event::KeyReleased>());
const auto& keyReleased = *event.getIf<sf::Event::KeyReleased>();
@ -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<sf::Event::MouseWheelScrolled>());
CHECK(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));
event = sf::Event::MouseButtonPressed{sf::Mouse::Button::Middle, {6, 7}};
CHECK(event);
CHECK(event.is<sf::Event::MouseButtonPressed>());
CHECK(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));
event = sf::Event::MouseButtonReleased{sf::Mouse::Button::Extra1, {8, 9}};
CHECK(event);
CHECK(event.is<sf::Event::MouseButtonReleased>());
CHECK(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));
event = sf::Event::MouseMoved{{4, 2}};
CHECK(event);
CHECK(event.is<sf::Event::MouseMoved>());
CHECK(event.getIf<sf::Event::MouseMoved>());
const auto& mouseMoved = *event.getIf<sf::Event::MouseMoved>();
CHECK(mouseMoved.position == sf::Vector2i(4, 2));
event = sf::Event::MouseMovedRaw{{3, 7}};
CHECK(event);
CHECK(event.is<sf::Event::MouseMovedRaw>());
CHECK(event.getIf<sf::Event::MouseMovedRaw>());
const auto& mouseMovedRaw = *event.getIf<sf::Event::MouseMovedRaw>();
CHECK(mouseMovedRaw.delta == sf::Vector2i(3, 7));
event = sf::Event::MouseEntered{};
CHECK(event);
CHECK(event.is<sf::Event::MouseEntered>());
CHECK(event.getIf<sf::Event::MouseEntered>());
event = sf::Event::MouseLeft{};
CHECK(event);
CHECK(event.is<sf::Event::MouseLeft>());
CHECK(event.getIf<sf::Event::MouseLeft>());
event = sf::Event::JoystickButtonPressed{100, 200};
CHECK(event);
CHECK(event.is<sf::Event::JoystickButtonPressed>());
CHECK(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);
event = sf::Event::JoystickButtonReleased{300, 400};
CHECK(event);
CHECK(event.is<sf::Event::JoystickButtonReleased>());
CHECK(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);
event = sf::Event::JoystickMoved{300, sf::Joystick::Axis::Z, 1.23f};
CHECK(event);
CHECK(event.is<sf::Event::JoystickMoved>());
CHECK(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);
event = sf::Event::JoystickConnected{42};
CHECK(event);
CHECK(event.is<sf::Event::JoystickConnected>());
CHECK(event.getIf<sf::Event::JoystickConnected>());
const auto& joystickConnected = *event.getIf<sf::Event::JoystickConnected>();
CHECK(joystickConnected.joystickId == 42);
event = sf::Event::JoystickDisconnected{43};
CHECK(event);
CHECK(event.is<sf::Event::JoystickDisconnected>());
CHECK(event.getIf<sf::Event::JoystickDisconnected>());
const auto& joystickDisconnected = *event.getIf<sf::Event::JoystickDisconnected>();
CHECK(joystickDisconnected.joystickId == 43);
event = sf::Event::TouchBegan{99, {98, 97}};
CHECK(event);
CHECK(event.is<sf::Event::TouchBegan>());
CHECK(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));
event = sf::Event::TouchMoved{96, {95, 94}};
CHECK(event);
CHECK(event.is<sf::Event::TouchMoved>());
CHECK(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));
event = sf::Event::TouchEnded{93, {92, 91}};
CHECK(event);
CHECK(event.is<sf::Event::TouchEnded>());
CHECK(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));
event = sf::Event::SensorChanged{sf::Sensor::Type::Gravity, {1.2f, 3.4f, 5.6f}};
CHECK(event);
CHECK(event.is<sf::Event::SensorChanged>());
CHECK(event.getIf<sf::Event::SensorChanged>());
const auto& sensorChanged = *event.getIf<sf::Event::SensorChanged>();
@ -215,7 +183,6 @@ TEST_CASE("[Window] sf::Event")
SECTION("Subtypes")
{
// 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::FocusLost>);
STATIC_CHECK(std::is_empty_v<sf::Event::FocusGained>);