diff --git a/src/Magnum/Audio/Context.cpp b/src/Magnum/Audio/Context.cpp index 0cb5a7e7e..17434247b 100644 --- a/src/Magnum/Audio/Context.cpp +++ b/src/Magnum/Audio/Context.cpp @@ -155,11 +155,16 @@ Context::Context(const Configuration& config) { Debug() << "OpenAL version:" << versionString(); } -Context::~Context() { - CORRADE_INTERNAL_ASSERT(_current == this); +Context::Context(Context&& other) noexcept: _device{other._device}, _context{other._context}, _extensionStatus{std::move(other._extensionStatus)}, _supportedExtensions{std::move(other._supportedExtensions)} { + other._device = nullptr; + other._context = nullptr; + if(_current == &other) _current = this; +} - alcDestroyContext(_context); - alcCloseDevice(_device); +Context::~Context() { + if(_context) alcDestroyContext(_context); + if(_device) alcCloseDevice(_device); + if(_current == this) _current = nullptr; } std::vector Context::extensionStrings() const { diff --git a/src/Magnum/Audio/Context.h b/src/Magnum/Audio/Context.h index 68c5f240f..df87a83d6 100644 --- a/src/Magnum/Audio/Context.h +++ b/src/Magnum/Audio/Context.h @@ -169,6 +169,12 @@ class MAGNUM_AUDIO_EXPORT Context { explicit Context(); #endif + /** @brief Copying is not allowed */ + Context(const Context&) = delete; + + /** @brief Move constructor */ + Context(Context&& other) noexcept; + /** * @brief Destructor * @@ -176,6 +182,12 @@ class MAGNUM_AUDIO_EXPORT Context { */ ~Context(); + /** @brief Copying is not allowed */ + Context& operator=(const Context&) = delete; + + /** @brief Move assignment is not allowed */ + Context& operator=(Context&& other) = delete; + #if defined(MAGNUM_BUILD_DEPRECATED) && !defined(DOXYGEN_GENERATING_OUTPUT) CORRADE_DEPRECATED("Audio::Context::current() returns reference now") Context* operator->() { return this; } CORRADE_DEPRECATED("Audio::Context::current() returns reference now") operator Context*() { return this; } diff --git a/src/Magnum/Audio/Test/ContextALTest.cpp b/src/Magnum/Audio/Test/ContextALTest.cpp index 397c59908..26a665917 100644 --- a/src/Magnum/Audio/Test/ContextALTest.cpp +++ b/src/Magnum/Audio/Test/ContextALTest.cpp @@ -34,15 +34,45 @@ namespace Magnum { namespace Audio { namespace Test { struct ContextALTest: TestSuite::Tester { explicit ContextALTest(); + void construct(); + void constructMove(); + void extensionsString(); void isExtensionEnabled(); }; ContextALTest::ContextALTest() { - addTests({&ContextALTest::extensionsString, + addTests({&ContextALTest::construct, + &ContextALTest::constructMove, + + &ContextALTest::extensionsString, &ContextALTest::isExtensionEnabled}); } +void ContextALTest::construct() { + CORRADE_VERIFY(!Context::hasCurrent()); + + { + Context context; + CORRADE_VERIFY(Context::hasCurrent()); + CORRADE_COMPARE(&Context::current(), &context); + } + + CORRADE_VERIFY(!Context::hasCurrent()); +} + +void ContextALTest::constructMove() { + Context context; + CORRADE_COMPARE(&Context::current(), &context); + + { + Context second{std::move(context)}; + CORRADE_COMPARE(&Context::current(), &second); + } + + CORRADE_VERIFY(!Context::hasCurrent()); +} + void ContextALTest::extensionsString() { Context context; diff --git a/src/Magnum/Audio/Test/ContextTest.cpp b/src/Magnum/Audio/Test/ContextTest.cpp index bbfa70a99..e524e54af 100644 --- a/src/Magnum/Audio/Test/ContextTest.cpp +++ b/src/Magnum/Audio/Test/ContextTest.cpp @@ -34,17 +34,29 @@ namespace Magnum { namespace Audio { namespace Test { struct ContextTest: TestSuite::Tester { explicit ContextTest(); + void constructCopyMove(); + void extensions(); void debugHrtfStatus(); }; ContextTest::ContextTest() { - addTests({&ContextTest::extensions, + addTests({&ContextTest::constructCopyMove, + + &ContextTest::extensions, &ContextTest::debugHrtfStatus}); } +void ContextTest::constructCopyMove() { + /* Only move-construction allowed */ + CORRADE_VERIFY(!(std::is_constructible{})); + CORRADE_VERIFY((std::is_constructible{})); + CORRADE_VERIFY(!(std::is_assignable{})); + CORRADE_VERIFY(!(std::is_assignable{})); +} + void ContextTest::extensions() { const char* used[Implementation::ExtensionCount]{};