From ca1cbe29502f673013fdca411c517e78f3c47d4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 18 Apr 2022 21:35:33 +0200 Subject: [PATCH] Platform: port Sdl2Application away from std::string. Co-authored-by: Squareys --- src/Magnum/Platform/Sdl2Application.cpp | 38 ++++++++++-------- src/Magnum/Platform/Sdl2Application.h | 39 ++++++++++++------- .../Platform/Test/Sdl2ApplicationTest.cpp | 7 +++- 3 files changed, 53 insertions(+), 31 deletions(-) diff --git a/src/Magnum/Platform/Sdl2Application.cpp b/src/Magnum/Platform/Sdl2Application.cpp index eea226204..744e338bc 100644 --- a/src/Magnum/Platform/Sdl2Application.cpp +++ b/src/Magnum/Platform/Sdl2Application.cpp @@ -159,22 +159,22 @@ Sdl2Application::Sdl2Application(const Arguments& arguments, NoCreateT): /* Save command-line arguments */ if(args.value("log") == "verbose") _verboseLog = true; - const std::string dpiScaling = args.value("dpi-scaling"); - if(dpiScaling == "default") + const Containers::StringView dpiScaling = args.value("dpi-scaling"); + if(dpiScaling == "default"_s) _commandLineDpiScalingPolicy = Implementation::Sdl2DpiScalingPolicy::Default; #ifdef CORRADE_TARGET_APPLE - else if(dpiScaling == "framebuffer") + else if(dpiScaling == "framebuffer"_s) _commandLineDpiScalingPolicy = Implementation::Sdl2DpiScalingPolicy::Framebuffer; #endif #ifndef CORRADE_TARGET_APPLE #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_ANDROID) - else if(dpiScaling == "virtual") + else if(dpiScaling == "virtual"_s) _commandLineDpiScalingPolicy = Implementation::Sdl2DpiScalingPolicy::Virtual; #endif - else if(dpiScaling == "physical") + else if(dpiScaling == "physical"_s) _commandLineDpiScalingPolicy = Implementation::Sdl2DpiScalingPolicy::Physical; #endif - else if(dpiScaling.find_first_of(" \t\n") != std::string::npos) + else if(dpiScaling.containsAny(" \t\n"_s)) _commandLineDpiScaling = args.value("dpi-scaling"); else _commandLineDpiScaling = Vector2{args.value("dpi-scaling")}; @@ -322,13 +322,15 @@ Vector2 Sdl2Application::dpiScaling(const Configuration& configuration) { #endif } -void Sdl2Application::setWindowTitle(const std::string& title) { +void Sdl2Application::setWindowTitle(const Containers::StringView title) { #ifndef CORRADE_TARGET_EMSCRIPTEN - SDL_SetWindowTitle(_window, title.data()); + SDL_SetWindowTitle(_window, + Containers::String::nullTerminatedGlobalView(title).data()); #else /* We don't have the _window because SDL_CreateWindow() doesn't exist in the SDL1/2 hybrid. But it's not used anyway, so pass nullptr there. */ - SDL_SetWindowTitle(nullptr, title.data()); + SDL_SetWindowTitle(nullptr, + Containers::String::nullTerminatedGlobalView(title).data()); #endif } @@ -743,16 +745,20 @@ Vector2i Sdl2Application::framebufferSize() const { #endif #ifdef CORRADE_TARGET_EMSCRIPTEN -void Sdl2Application::setContainerCssClass(const std::string& cssClass) { +void Sdl2Application::setContainerCssClass(const Containers::StringView cssClass) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdollar-in-identifier-extension" EM_ASM_({ /* Handle also the classic #container for backwards compatibility. We also need to preserve the mn-container otherwise next time we'd have - no way to look for it anymore. */ + no way to look for it anymore. + + Using UTF8ToString() instead of AsciiToString() as it has an + explicit size parameter and thus doesn't need a null-terminated + input, which would potentially require yet another allocation. */ (Module['canvas'].closest('.mn-container') || - document.getElementById('container')).className = (['mn-container', AsciiToString($0)]).join(' '); - }, cssClass.data()); + document.getElementById('container')).className = (['mn-container', UTF8ToString($0, $1)]).join(' '); + }, cssClass.data(), cssClass.size()); #pragma GCC diagnostic pop } #endif @@ -1201,7 +1207,7 @@ Sdl2Application::GLConfiguration::~GLConfiguration() = default; Sdl2Application::Configuration::Configuration(): #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_IOS) - _title("Magnum SDL2 Application"), + _title(Containers::String::nullTerminatedGlobalView("Magnum SDL2 Application"_s)), #endif #if !defined(CORRADE_TARGET_IOS) && !defined(CORRADE_TARGET_EMSCRIPTEN) _size{800, 600}, @@ -1212,11 +1218,11 @@ Sdl2Application::Configuration::Configuration(): Sdl2Application::Configuration::~Configuration() = default; -std::string Sdl2Application::KeyEvent::keyName(const Key key) { +Containers::StringView Sdl2Application::KeyEvent::keyName(const Key key) { return SDL_GetKeyName(SDL_Keycode(key)); } -std::string Sdl2Application::KeyEvent::keyName() const { +Containers::StringView Sdl2Application::KeyEvent::keyName() const { return keyName(_key); } diff --git a/src/Magnum/Platform/Sdl2Application.h b/src/Magnum/Platform/Sdl2Application.h index aa232c3b8..2f528644b 100644 --- a/src/Magnum/Platform/Sdl2Application.h +++ b/src/Magnum/Platform/Sdl2Application.h @@ -31,10 +31,10 @@ * @brief Class @ref Magnum::Platform::Sdl2Application, macro @ref MAGNUM_SDL2APPLICATION_MAIN() */ -#include #include #include #include +#include /** @todo PIMPL Configuration instead? */ #include "Magnum/Magnum.h" #include "Magnum/Tags.h" @@ -81,6 +81,11 @@ #pragma clang diagnostic pop #endif +#ifdef MAGNUM_BUILD_DEPRECATED +/* Some APIs used to take or return a std::string before */ +#include +#endif + #ifndef DOXYGEN_GENERATING_OUTPUT union SDL_Event; /* for anyEvent() */ #endif @@ -805,7 +810,7 @@ class Sdl2Application { * * The @p title is expected to be encoded in UTF-8. */ - void setWindowTitle(const std::string& title); + void setWindowTitle(Containers::StringView title); #if !defined(CORRADE_TARGET_EMSCRIPTEN) && (SDL_MAJOR_VERSION*1000 + SDL_MINOR_VERSION*100 + SDL_PATCHLEVEL >= 2005 || defined(DOXYGEN_GENERATING_OUTPUT)) /** @@ -853,7 +858,7 @@ class Sdl2Application { * @cb{.html}
@ce is not found. This * compatibility is scheduled to be removed in the future. */ - void setContainerCssClass(const std::string& cssClass); + void setContainerCssClass(Containers::StringView cssClass); #endif /** @@ -1819,10 +1824,13 @@ class Sdl2Application::Configuration { /** * @brief Window title * + * The returned string view is + * @relativeref{Corrade,Containers::StringViewFlag::NullTerminated} and + * is valid until the next call to @ref setTitle(). * @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten" * and @ref CORRADE_TARGET_IOS "iOS". */ - std::string title() const { return _title; } + Containers::StringView title() const { return _title; } #endif /** @@ -1840,8 +1848,8 @@ class Sdl2Application::Configuration { * application state change) using @ref setWindowTitle(). */ #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_IOS) - Configuration& setTitle(std::string title) { - _title = std::move(title); + Configuration& setTitle(const Containers::StringView title) { + _title = Containers::String::nullTerminatedGlobalView(title); return *this; } #else @@ -1954,7 +1962,7 @@ class Sdl2Application::Configuration { private: #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_IOS) - std::string _title; + Containers::String _title; #endif Vector2i _size; DpiScalingPolicy _dpiScalingPolicy; @@ -2468,10 +2476,13 @@ class Sdl2Application::KeyEvent: public Sdl2Application::InputEvent { * * Human-readable localized UTF-8 name for given @p key, intended for * displaying to the user in e.g. key binding configuration. If there - * is no name for given key, empty string is returned. - * @see @ref keyName(Key) + * is no name for given key, empty string is returned. The returned + * view is always @relativeref{Corrade,Containers::StringViewFlag::NullTerminated} + * and is valid at least until the next call to this function, to + * @ref keyName() const or to the underlying @cpp SDL_GetKeyName() @ce + * API. */ - static std::string keyName(Key key); + static Containers::StringView keyName(Key key); /** * @brief Key @@ -2486,10 +2497,12 @@ class Sdl2Application::KeyEvent: public Sdl2Application::InputEvent { * Human-readable localized UTF-8 name for the key returned by * @ref key(), intended for displaying to the user in e.g. * key binding configuration. If there is no name for that key, empty - * string is returned. - * @see @ref keyName(Key) + * string is returned. The returned string is always @relativeref{Corrade,Containers::StringViewFlag::NullTerminated} + * and is valid at least until the next call to this function, to + * @ref keyName(Key) or to the underlying @cpp SDL_GetKeyName() @ce + * API. */ - std::string keyName() const; + Containers::StringView keyName() const; /** @brief Modifiers */ Modifiers modifiers() const { return _modifiers; } diff --git a/src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp b/src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp index 0ec516e73..20513c946 100644 --- a/src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp +++ b/src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp @@ -53,6 +53,8 @@ namespace Magnum { namespace Platform { namespace Test { namespace { +using namespace Containers::Literals; + struct Sdl2ApplicationTest: Platform::Application { explicit Sdl2ApplicationTest(const Arguments& arguments); @@ -107,7 +109,7 @@ struct Sdl2ApplicationTest: Platform::Application { stopTextInput(); } else if(event.key() == KeyEvent::Key::T) { Debug{} << "setting window title"; - setWindowTitle("This is a UTF-8 Window Title™!"); + setWindowTitle("This is a UTF-8 Window Title™ and it should have no exclamation mark!!"_s.exceptSuffix(2)); } #ifndef CORRADE_TARGET_EMSCRIPTEN else if(event.key() == KeyEvent::Key::S) { @@ -181,7 +183,8 @@ Sdl2ApplicationTest::Sdl2ApplicationTest(const Arguments& arguments): Platform:: } Configuration conf; - conf.setWindowFlags(Configuration::WindowFlag::Resizable); + conf.setTitle("Window title that should have no exclamation mark!!"_s.exceptSuffix(2)) + .setWindowFlags(Configuration::WindowFlag::Resizable); if(!args.value("dpi-scaling").empty()) conf.setSize({800, 600}, args.value("dpi-scaling")); #ifndef CORRADE_TARGET_EMSCRIPTEN