Add non-const overload of Event::visit

This commit is contained in:
vittorioromeo 2025-01-20 16:24:04 +01:00 committed by Vittorio Romeo
parent 0e37e6dfee
commit 18393ea5cb
4 changed files with 58 additions and 10 deletions

View File

@ -338,6 +338,17 @@ public:
template <typename TEventSubtype> template <typename TEventSubtype>
[[nodiscard]] const TEventSubtype* getIf() const; [[nodiscard]] const TEventSubtype* getIf() const;
////////////////////////////////////////////////////////////
/// \brief Apply a visitor to the event
///
/// \param visitor The visitor to apply
///
/// \return The result of applying the visitor to the event
///
////////////////////////////////////////////////////////////
template <typename T>
decltype(auto) visit(T&& visitor);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Apply a visitor to the event /// \brief Apply a visitor to the event
/// ///

View File

@ -78,6 +78,14 @@ const TEventSubtype* Event::getIf() const
} }
////////////////////////////////////////////////////////////
template <typename T>
decltype(auto) Event::visit(T&& visitor)
{
return std::visit(std::forward<T>(visitor), m_data);
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename T> template <typename T>
decltype(auto) Event::visit(T&& visitor) const decltype(auto) Event::visit(T&& visitor) const

View File

@ -68,7 +68,7 @@ void WindowBase::handleEvents(Ts&&... handlers) // NOLINT(cppcoreguidelines-miss
// NOLINTNEXTLINE(misc-const-correctness) // NOLINTNEXTLINE(misc-const-correctness)
priv::OverloadSet overloadSet{std::forward<Ts>(handlers)..., [](const priv::DelayOverloadResolution&) { /* ignore */ }}; priv::OverloadSet overloadSet{std::forward<Ts>(handlers)..., [](const priv::DelayOverloadResolution&) { /* ignore */ }};
while (const std::optional event = pollEvent()) while (std::optional event = pollEvent())
event->visit(overloadSet); event->visit(overloadSet);
} }

View File

@ -9,17 +9,22 @@ namespace
{ {
struct struct
{ {
std::string_view operator()(const sf::Event::Closed&) const std::string_view operator()(sf::Event::Closed&) const
{ {
return "Closed"; return "Closed (non-const)";
} }
std::string_view operator()(const sf::Event::Resized&) const std::string_view operator()(const sf::Event::Closed&) const
{
return "Closed (const)";
}
std::string_view operator()(sf::Event::Resized&) const
{ {
return "Resized"; return "Resized";
} }
std::string_view operator()(const sf::Event::KeyPressed&) const std::string_view operator()(sf::Event::KeyPressed) const
{ {
return "KeyPressed"; return "KeyPressed";
} }
@ -306,10 +311,34 @@ TEST_CASE("[Window] sf::Event")
SECTION("visit()") SECTION("visit()")
{ {
CHECK(sf::Event(sf::Event::Closed{}).visit(visitor) == "Closed"); SECTION("Non-const")
CHECK(sf::Event(sf::Event::Resized{}).visit(visitor) == "Resized"); {
CHECK(sf::Event(sf::Event::FocusLost{}).visit(visitor) == "Other"); sf::Event closed = sf::Event::Closed{};
CHECK(sf::Event(sf::Event::FocusGained{}).visit(visitor) == "Other"); CHECK(closed.visit(visitor) == "Closed (non-const)");
CHECK(sf::Event(sf::Event::KeyPressed{}).visit(visitor) == "KeyPressed");
sf::Event resized = sf::Event::Resized{};
CHECK(resized.visit(visitor) == "Resized");
sf::Event keyPressed = sf::Event::KeyPressed{};
CHECK(keyPressed.visit(visitor) == "KeyPressed");
sf::Event focusLost = sf::Event::FocusLost{};
CHECK(focusLost.visit(visitor) == "Other");
}
SECTION("Const")
{
const sf::Event closed = sf::Event::Closed{};
CHECK(closed.visit(visitor) == "Closed (const)");
const sf::Event resized = sf::Event::Resized{};
CHECK(resized.visit(visitor) == "Other"); // Cannot use non-const reference callback
const sf::Event keyPressed = sf::Event::KeyPressed{};
CHECK(keyPressed.visit(visitor) == "KeyPressed");
const sf::Event focusLost = sf::Event::FocusLost{};
CHECK(focusLost.visit(visitor) == "Other");
}
} }
} }