diff --git a/src/controllers/bulk/bulkcontroller.cpp b/src/controllers/bulk/bulkcontroller.cpp index 05fff956e39..242b59f9a2d 100644 --- a/src/controllers/bulk/bulkcontroller.cpp +++ b/src/controllers/bulk/bulkcontroller.cpp @@ -99,14 +99,7 @@ QString BulkController::mappingExtension() { } void BulkController::setMapping(std::shared_ptr pMapping) { - VERIFY_OR_DEBUG_ASSERT(pMapping.use_count() == 1) { - return; - } - auto pDowncastedMapping = std::dynamic_pointer_cast(pMapping); - VERIFY_OR_DEBUG_ASSERT(pDowncastedMapping) { - return; - } - m_pMapping = pDowncastedMapping; + m_pMapping = downcastAndTakeOwnership(std::move(pMapping)); } std::shared_ptr BulkController::cloneMapping() { diff --git a/src/controllers/controller.h b/src/controllers/controller.h index cf22a10b935..6d764bb4a9c 100644 --- a/src/controllers/controller.h +++ b/src/controllers/controller.h @@ -79,6 +79,23 @@ class Controller : public QObject { void stopLearning(); protected: + template + std::shared_ptr downcastAndTakeOwnership( + std::shared_ptr&& pMapping) { + // Controller cannot take ownership if pMapping is referenced elsewhere because + // the controller polling thread needs exclusive accesses to the non-thread safe + // LegacyControllerMapping. + // Trying to cast a std::shared_ptr to a std::unique_ptr is not worth the trouble. + VERIFY_OR_DEBUG_ASSERT(pMapping.use_count() == 1) { + return nullptr; + } + auto pDowncastedMapping = std::dynamic_pointer_cast(pMapping); + VERIFY_OR_DEBUG_ASSERT(pDowncastedMapping) { + return nullptr; + } + return pDowncastedMapping; + } + // The length parameter is here for backwards compatibility for when scripts // were required to specify it. virtual void send(const QList& data, unsigned int length = 0); diff --git a/src/controllers/hid/hidcontroller.cpp b/src/controllers/hid/hidcontroller.cpp index 535185b3d14..8ac1a2b29a4 100644 --- a/src/controllers/hid/hidcontroller.cpp +++ b/src/controllers/hid/hidcontroller.cpp @@ -39,14 +39,7 @@ QString HidController::mappingExtension() { } void HidController::setMapping(std::shared_ptr pMapping) { - VERIFY_OR_DEBUG_ASSERT(pMapping.use_count() == 1) { - return; - } - auto pDowncastedMapping = std::dynamic_pointer_cast(pMapping); - VERIFY_OR_DEBUG_ASSERT(pDowncastedMapping) { - return; - } - m_pMapping = pDowncastedMapping; + m_pMapping = downcastAndTakeOwnership(std::move(pMapping)); } std::shared_ptr HidController::cloneMapping() { diff --git a/src/controllers/midi/midicontroller.cpp b/src/controllers/midi/midicontroller.cpp index ad3bc3be9d4..4c8b601f0de 100644 --- a/src/controllers/midi/midicontroller.cpp +++ b/src/controllers/midi/midicontroller.cpp @@ -31,14 +31,7 @@ QString MidiController::mappingExtension() { } void MidiController::setMapping(std::shared_ptr pMapping) { - VERIFY_OR_DEBUG_ASSERT(pMapping.use_count() == 1) { - return; - } - auto pDowncastedMapping = std::dynamic_pointer_cast(pMapping); - VERIFY_OR_DEBUG_ASSERT(pDowncastedMapping) { - return; - } - m_pMapping = pDowncastedMapping; + m_pMapping = downcastAndTakeOwnership(std::move(pMapping)); } std::shared_ptr MidiController::cloneMapping() {