From b6696e9f30e2225f006ec750682ceddd1eecabec Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Sat, 21 Sep 2024 19:52:05 +0200 Subject: [PATCH 01/20] refactor: remove unused and unmaintained ThreadCpuTimer --- CMakeLists.txt | 1 - src/util/threadcputimer.cpp | 115 ------------------------------------ src/util/threadcputimer.h | 15 ----- src/util/time.h | 2 - 4 files changed, 133 deletions(-) delete mode 100644 src/util/threadcputimer.cpp delete mode 100644 src/util/threadcputimer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 72a7897de61..a30e5650ed5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1200,7 +1200,6 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL src/util/tapfilter.cpp src/util/task.cpp src/util/taskmonitor.cpp - src/util/threadcputimer.cpp src/util/time.cpp src/util/timer.cpp src/util/valuetransformer.cpp diff --git a/src/util/threadcputimer.cpp b/src/util/threadcputimer.cpp deleted file mode 100644 index a40cb7b021a..00000000000 --- a/src/util/threadcputimer.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include "util/threadcputimer.h" - -#if defined(__APPLE__) -#include -#include -#include -#elif defined(__UNIX__) -#include -#include -#elif defined(_WIN32) -#include -#endif - - -////////////////////////////// Unix ////////////////////////////// -#if defined(Q_OS_UNIX) - -#if (_POSIX_THREAD_CPUTIME-0 != 0) -static const bool threadCpuTimeChecked = true; -static const bool threadCpuTimeAvailable = _POSIX_THREAD_CPUTIME > 0; -#else -static int threadCpuTimeChecked = false; -static int threadCpuTimeAvailable = false; -#endif - -#ifdef Q_CC_GNU -# define is_likely(x) __builtin_expect((x), 1) -#else -# define is_likely(x) (x) -#endif -#define load_acquire(x) ((volatile const int&)(x)) -#define store_release(x,v) ((volatile int&)(x) = (v)) - -static void unixCheckClockType() -{ -#if (_POSIX_THREAD_CPUTIME-0 == 0) - if (is_likely(load_acquire(threadCpuTimeChecked))) { - return; - } - -# if defined(_SC_THREAD_CPUTIME) - // detect if the system support monotonic timers - long x = sysconf(_SC_THREAD_CPUTIME); - store_release(threadCpuTimeAvailable, x >= 200112L); -# endif - - store_release(threadCpuTimeChecked, true); -#endif -} - -static inline void do_gettime(qint64 *sec, qint64 *frac) -{ -#if (_POSIX_MONOTONIC_CLOCK-0 >= 0) - unixCheckClockType(); - if (is_likely(threadCpuTimeAvailable)) { - timespec ts; - clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); - *sec = ts.tv_sec; - *frac = ts.tv_nsec; - return; - } -#else - Q_UNUSED(threadCpuTimeChecked); - Q_UNUSED(threadCpuTimeAvailable); - Q_UNUSED(unixCheckClockType); -#endif - *sec = 0; - *frac = 0; -} - -void ThreadCpuTimer::start() -{ - do_gettime(&t1, &t2); -} - -mixxx::Duration ThreadCpuTimer::elapsed() const -{ - qint64 sec, frac; - do_gettime(&sec, &frac); - sec = sec - t1; - frac = frac - t2; - - return mixxx::Duration::fromNanos(sec * Q_INT64_C(1000000000) + frac); -} - -mixxx::Duration ThreadCpuTimer::restart() -{ - qint64 sec, frac; - sec = t1; - frac = t2; - do_gettime(&t1, &t2); - sec = t1 - sec; - frac = t2 - frac; - return mixxx::Duration::fromNanos(sec * Q_INT64_C(1000000000) + frac); -} - -////////////////////////////// Default ////////////////////////////// -#else - -// default implementation (no hi-perf timer) does nothing -void ThreadCpuTimer::start() -{ -} - -mixxx::Duration ThreadCpuTimer::elapsed() const -{ - return mixxx::Duration::fromNanos(0); -} - -mixxx::Duration ThreadCpuTimer::restart() -{ - return mixxx::Duration::fromNanos(0); -} - -#endif diff --git a/src/util/threadcputimer.h b/src/util/threadcputimer.h deleted file mode 100644 index bb8c3922f3e..00000000000 --- a/src/util/threadcputimer.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "util/duration.h" - -class ThreadCpuTimer { - public: - void start(); - mixxx::Duration elapsed() const; - mixxx::Duration restart(); - private: -#if defined(Q_OS_UNIX) - qint64 t1; - qint64 t2; -#endif -}; diff --git a/src/util/time.h b/src/util/time.h index 87dad6d7b85..8c13566b701 100644 --- a/src/util/time.h +++ b/src/util/time.h @@ -4,13 +4,11 @@ #include "util/duration.h" #include "util/performancetimer.h" -#include "util/threadcputimer.h" namespace mixxx { class Time { using LLTIMER = PerformanceTimer; - // using LLTIMER = ThreadCpuTimer; public: using rep = LLTIMER::ClockT::rep; From ba9b7e879b390c2ca66093d8b2ecdf53f9074fe0 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Sat, 21 Sep 2024 20:03:54 +0200 Subject: [PATCH 02/20] refactor: slim down valuetransformer.h and auto memory management --- src/skin/legacy/legacyskinparser.cpp | 5 +- src/util/valuetransformer.cpp | 144 +++++++++++++++++++++------ src/util/valuetransformer.h | 90 ++--------------- src/widget/whotcuebutton.cpp | 1 + src/widget/wpushbutton.cpp | 1 + src/widget/wpushbutton.h | 2 +- src/widget/wslidercomposed.cpp | 1 + 7 files changed, 129 insertions(+), 115 deletions(-) diff --git a/src/skin/legacy/legacyskinparser.cpp b/src/skin/legacy/legacyskinparser.cpp index 4f401341259..81757e19711 100644 --- a/src/skin/legacy/legacyskinparser.cpp +++ b/src/skin/legacy/legacyskinparser.cpp @@ -10,6 +10,7 @@ #include #include "control/controlobject.h" +#include "control/controlpushbutton.h" #include "controllers/controllerlearningeventfilter.h" #include "controllers/controllermanager.h" #include "controllers/keyboard/keyboardeventfilter.h" @@ -2306,7 +2307,9 @@ void LegacySkinParser::setupConnections(const QDomNode& node, WBaseWidget* pWidg ValueTransformer* pTransformer = nullptr; QDomElement transform = m_pContext->selectElement(con, "Transform"); if (!transform.isNull()) { - pTransformer = ValueTransformer::parseFromXml(transform, *m_pContext); + pTransformer = + ValueTransformer::parseFromXml(transform, *m_pContext) + .get(); // TODO don't leak here } QString property; diff --git a/src/util/valuetransformer.cpp b/src/util/valuetransformer.cpp index 60c60fe08b0..eeff1ca0cb9 100644 --- a/src/util/valuetransformer.cpp +++ b/src/util/valuetransformer.cpp @@ -1,14 +1,94 @@ #include "util/valuetransformer.h" -ValueTransformer::ValueTransformer() { -} +#include +#include +#include +#include + +#include "skin/legacy/skincontext.h" + +class TransformNode { + public: + TransformNode() { + } + virtual ~TransformNode() { + } -void ValueTransformer::addTransformer(TransformNode* pTransformer) { - m_transformers.append(pTransformer); + virtual double transform(double argument) const = 0; + virtual double transformInverse(double argument) const = 0; +}; + +namespace { + +class TransformAdd : public TransformNode { + public: + TransformAdd(double addend) + : m_addend(addend) { + } + + double transform(double argument) const override { + return argument + m_addend; + } + + double transformInverse(double argument) const override { + return argument - m_addend; + } + + private: + double m_addend; +}; + +class TransformInvert : public TransformNode { + public: + double transform(double argument) const override { + return -argument; + } + + double transformInverse(double argument) const override { + return -argument; + } +}; + +class TransformNot : public TransformNode { + public: + double transform(double argument) const override { + return !static_cast(argument); + } + + double transformInverse(double argument) const override { + return !static_cast(argument); + } +}; + +class TransformIsEqual : public TransformNode { + public: + TransformIsEqual(double compareValue) + : m_compareValue(compareValue) { + } + + double transform(double argument) const override { + return argument == m_compareValue; + } + + double transformInverse(double argument) const override { + if (argument > 0.0) { + return m_compareValue; + } + return 0.0; + } + + private: + double m_compareValue; +}; + +} // namespace + +void ValueTransformer::addTransformer(std::unique_ptr pTransformer) { + m_transformers.push_back(std::move(pTransformer)); } double ValueTransformer::transform(double argument) const { - foreach (const TransformNode* pNode, m_transformers) { + for (const auto& pNode : m_transformers) { argument = pNode->transform(argument); } return argument; @@ -16,20 +96,29 @@ double ValueTransformer::transform(double argument) const { double ValueTransformer::transformInverse(double argument) const { for (int i = m_transformers.size() - 1; i >= 0; --i) { - const TransformNode* pNode = m_transformers[i]; - argument = pNode->transformInverse(argument); + argument = m_transformers[i]->transformInverse(argument); } return argument; } // static -ValueTransformer* ValueTransformer::parseFromXml(const QDomElement& transformElement, - const SkinContext& context) { +std::unique_ptr ValueTransformer::parseFromXml( + const QDomElement& transformElement, const SkinContext& context) { if (transformElement.isNull() || !transformElement.hasChildNodes()) { return nullptr; } - ValueTransformer* pTransformer = new ValueTransformer(); + auto pTransformer = std::unique_ptr(new ValueTransformer()); + + auto maybeAddFromElement = [&](auto element) { + QString valueStr = context.nodeToString(element); + bool ok = false; + double value = valueStr.toDouble(&ok); + if (ok) { + pTransformer->addTransformer(std::make_unique(value)); + } + }; + QDomNodeList children = transformElement.childNodes(); for (int i = 0; i < children.count(); ++i) { QDomNode node = children.at(i); @@ -38,32 +127,21 @@ ValueTransformer* ValueTransformer::parseFromXml(const QDomElement& transformEle } QDomElement element = node.toElement(); - if (element.nodeName() == "Invert") { - pTransformer->addTransformer(new TransformInvert()); - } else if (element.nodeName() == "Add") { - QString value = context.nodeToString(element); - bool ok = false; - double addend = value.toDouble(&ok); - if (ok) { - pTransformer->addTransformer(new TransformAdd(addend)); - } - } else if (element.nodeName() == "Not") { - pTransformer->addTransformer(new TransformNot()); - } else if (element.nodeName() == "IsEqual") { - QString value = context.nodeToString(element); - bool ok = false; - double compareValue = value.toDouble(&ok); - if (ok) { - pTransformer->addTransformer(new TransformIsEqual(compareValue)); - } + QString name = element.nodeName(); + if (name == "Invert") { + pTransformer->addTransformer(std::make_unique()); + } else if (name == "Add") { + maybeAddFromElement.operator()(element); + } else if (name == "Not") { + pTransformer->addTransformer(std::make_unique()); + } else if (name == "IsEqual") { + maybeAddFromElement.operator()(element); } } return pTransformer; } -ValueTransformer::~ValueTransformer() { - foreach (TransformNode* node, m_transformers) { - delete node; - } -} +ValueTransformer::ValueTransformer() = default; + +ValueTransformer::~ValueTransformer() = default; diff --git a/src/util/valuetransformer.h b/src/util/valuetransformer.h index e3069ff2e91..5f824ce3b27 100644 --- a/src/util/valuetransformer.h +++ b/src/util/valuetransformer.h @@ -1,95 +1,25 @@ #pragma once -#include -#include +#include +#include -#include "skin/legacy/skincontext.h" - -class TransformNode { - public: - TransformNode() {} - virtual ~TransformNode() {} - - virtual double transform(double argument) const = 0; - virtual double transformInverse(double argument) const = 0; -}; - -class TransformAdd : public TransformNode { - public: - TransformAdd(double addend) : m_addend(addend) {} - - double transform(double argument) const { - return argument + m_addend; - } - - double transformInverse(double argument) const { - return argument - m_addend; - } - - private: - double m_addend; -}; - -class TransformInvert : public TransformNode { - public: - TransformInvert() {} - - double transform(double argument) const { - return -argument; - } - - double transformInverse(double argument) const { - return -argument; - } -}; - -class TransformNot : public TransformNode { - public: - TransformNot() {} - - double transform(double argument) const { - return !static_cast(argument); - } - - double transformInverse(double argument) const { - return !static_cast(argument); - } -}; - -class TransformIsEqual : public TransformNode { - public: - TransformIsEqual(double compareValue) : - m_compareValue(compareValue) { - } - - double transform(double argument) const { - return argument == m_compareValue; - } - - double transformInverse(double argument) const { - if (argument > 0.0) { - return m_compareValue; - } - return 0.0; - } - - private: - double m_compareValue; -}; +class SkinContext; +class TransformNode; +class QDomElement; class ValueTransformer { public: ~ValueTransformer(); + double transform(double argument) const; double transformInverse(double argument) const; - static ValueTransformer* parseFromXml(const QDomElement& transformElement, + static std::unique_ptr parseFromXml(const QDomElement& transformElement, const SkinContext& context); private: - ValueTransformer(); - - void addTransformer(TransformNode* pTransformer); + ValueTransformer(); // only accessible from parseFromXml, not deleted + void addTransformer(std::unique_ptr pTransformer); - QList m_transformers; + std::vector> m_transformers; }; diff --git a/src/widget/whotcuebutton.cpp b/src/widget/whotcuebutton.cpp index 0e91f1812ad..b37a7874364 100644 --- a/src/widget/whotcuebutton.cpp +++ b/src/widget/whotcuebutton.cpp @@ -4,6 +4,7 @@ #include "mixer/playerinfo.h" #include "moc_whotcuebutton.cpp" +#include "skin/legacy/skincontext.h" #include "track/track.h" #include "widget/controlwidgetconnection.h" diff --git a/src/widget/wpushbutton.cpp b/src/widget/wpushbutton.cpp index 5cc3c188203..07f81be7d5d 100644 --- a/src/widget/wpushbutton.cpp +++ b/src/widget/wpushbutton.cpp @@ -11,6 +11,7 @@ #include "control/controlobject.h" #include "control/controlpushbutton.h" #include "moc_wpushbutton.cpp" +#include "skin/legacy/skincontext.h" #include "util/debug.h" #include "widget/controlwidgetconnection.h" #include "widget/wpixmapstore.h" diff --git a/src/widget/wpushbutton.h b/src/widget/wpushbutton.h index 1e4ff3ddf09..94fbad7e6b4 100644 --- a/src/widget/wpushbutton.h +++ b/src/widget/wpushbutton.h @@ -5,7 +5,7 @@ #include #include -#include "control/controlpushbutton.h" +#include "control/controlbuttonmode.h" #include "util/fpclassify.h" #include "util/performancetimer.h" #include "widget/wpixmapstore.h" diff --git a/src/widget/wslidercomposed.cpp b/src/widget/wslidercomposed.cpp index 52c6c0c60d8..e6eef93cf87 100644 --- a/src/widget/wslidercomposed.cpp +++ b/src/widget/wslidercomposed.cpp @@ -6,6 +6,7 @@ #include #include "moc_wslidercomposed.cpp" +#include "skin/legacy/skincontext.h" #include "util/debug.h" #include "widget/controlwidgetconnection.h" #include "widget/wpixmapstore.h" From 534d6c4550cbf194631c56664e9abe445fc4e7a7 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Sat, 21 Sep 2024 20:28:43 +0200 Subject: [PATCH 03/20] refactor: fix some transient dependencies on util/math.h --- src/analyzer/analyzerwaveform.h | 26 +++++++++---------- src/database/schemamanager.cpp | 5 +++- .../backends/builtin/compressoreffect.cpp | 2 ++ .../backends/builtin/distortioneffect.h | 2 +- src/effects/backends/builtin/phasereffect.cpp | 1 + .../backends/builtin/pitchshifteffect.cpp | 1 + src/encoder/encodersndfileflac.cpp | 7 ++--- src/engine/enginesidechaincompressor.cpp | 4 ++- src/preferences/broadcastprofile.cpp | 6 ++++- src/sources/audiosource.cpp | 2 +- src/sources/readaheadframebuffer.cpp | 10 +++---- src/util/readaheadsamplebuffer.cpp | 8 +++--- .../renderers/waveformwidgetrenderer.h | 2 +- 13 files changed, 45 insertions(+), 31 deletions(-) diff --git a/src/analyzer/analyzerwaveform.h b/src/analyzer/analyzerwaveform.h index 4771cc50993..ccdafd5242d 100644 --- a/src/analyzer/analyzerwaveform.h +++ b/src/analyzer/analyzerwaveform.h @@ -46,16 +46,16 @@ struct WaveformStride { inline void store(WaveformData* data) { for (int i = 0; i < ChannelCount; ++i) { WaveformData& datum = *(data + i); - datum.filtered.all = static_cast(math_min(255.0, + datum.filtered.all = static_cast(std::min(255.0, m_postScaleConversion * m_overallData[i] + 0.5)); - datum.filtered.low = static_cast(math_min(255.0, + datum.filtered.low = static_cast(std::min(255.0, m_postScaleConversion * m_filteredData[i][Low] + 0.5)); - datum.filtered.mid = static_cast(math_min(255.0, + datum.filtered.mid = static_cast(std::min(255.0, m_postScaleConversion * m_filteredData[i][Mid] + 0.5)); - datum.filtered.high = static_cast(math_min(255.0, + datum.filtered.high = static_cast(std::min(255.0, m_postScaleConversion * m_filteredData[i][High] + 0.5)); for (int stemIdx = 0; stemIdx < m_stemCount; stemIdx++) { - datum.stems[stemIdx] = static_cast(math_min(255.0, + datum.stems[stemIdx] = static_cast(std::min(255.0, m_postScaleConversion * m_stemData[i][stemIdx] + 0.5)); } } @@ -78,17 +78,17 @@ struct WaveformStride { if (m_averageDivisor) { for (int i = 0; i < ChannelCount; ++i) { WaveformData& datum = *(data + i); - datum.filtered.all = static_cast(math_min(255.0, + datum.filtered.all = static_cast(std::min(255.0, m_postScaleConversion * m_averageOverallData[i] / m_averageDivisor + 0.5)); - datum.filtered.low = static_cast(math_min(255.0, + datum.filtered.low = static_cast(std::min(255.0, m_postScaleConversion * m_averageFilteredData[i][Low] / m_averageDivisor + 0.5)); - datum.filtered.mid = static_cast(math_min(255.0, + datum.filtered.mid = static_cast(std::min(255.0, m_postScaleConversion * m_averageFilteredData[i][Mid] / m_averageDivisor + 0.5)); - datum.filtered.high = static_cast(math_min(255.0, + datum.filtered.high = static_cast(std::min(255.0, m_postScaleConversion * m_averageFilteredData[i][High] / m_averageDivisor + 0.5)); @@ -97,13 +97,13 @@ struct WaveformStride { // This is the case if The Overview Waveform has more samples than the detailed waveform for (int i = 0; i < ChannelCount; ++i) { WaveformData& datum = *(data + i); - datum.filtered.all = static_cast(math_min(255.0, + datum.filtered.all = static_cast(std::min(255.0, m_postScaleConversion * m_overallData[i] + 0.5)); - datum.filtered.low = static_cast(math_min(255.0, + datum.filtered.low = static_cast(std::min(255.0, m_postScaleConversion * m_filteredData[i][Low] + 0.5)); - datum.filtered.mid = static_cast(math_min(255.0, + datum.filtered.mid = static_cast(std::min(255.0, m_postScaleConversion * m_filteredData[i][Mid] + 0.5)); - datum.filtered.high = static_cast(math_min(255.0, + datum.filtered.high = static_cast(std::min(255.0, m_postScaleConversion * m_filteredData[i][High] + 0.5)); } } diff --git a/src/database/schemamanager.cpp b/src/database/schemamanager.cpp index a17dc47e9a3..5f0ef182918 100644 --- a/src/database/schemamanager.cpp +++ b/src/database/schemamanager.cpp @@ -1,11 +1,14 @@ #include "database/schemamanager.h" +#include +#include +#include + #include "util/assert.h" #include "util/db/fwdsqlquery.h" #include "util/db/sqltransaction.h" #include "util/logger.h" #include "util/math.h" -#include "util/optional.h" #include "util/xml.h" namespace { diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index cea9b622f4b..311256fd2ad 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -1,5 +1,7 @@ #include "effects/backends/builtin/compressoreffect.h" +#include "util/math.h" + namespace { // Auto make up time is empirically selected parameter, which is good enough for most cases constexpr double defaultMakeUpAttackMs = 150; diff --git a/src/effects/backends/builtin/distortioneffect.h b/src/effects/backends/builtin/distortioneffect.h index 70dd90cae16..00e077dc7d6 100644 --- a/src/effects/backends/builtin/distortioneffect.h +++ b/src/effects/backends/builtin/distortioneffect.h @@ -91,7 +91,7 @@ class DistortionEffect : public EffectProcessorImpl { pState->m_previousMakeUpGain = gain; // Crossfade - CSAMPLE crossfadeParam = math_min(driveParam / ModeParams::crossfadeEndParam, 1.f); + CSAMPLE crossfadeParam = std::min(driveParam / ModeParams::crossfadeEndParam, 1.f); SampleUtil::applyRampingGain(pOutput, pState->m_crossfadeParameter, crossfadeParam, diff --git a/src/effects/backends/builtin/phasereffect.cpp b/src/effects/backends/builtin/phasereffect.cpp index 709d23d09a8..74f0c4b4e6f 100644 --- a/src/effects/backends/builtin/phasereffect.cpp +++ b/src/effects/backends/builtin/phasereffect.cpp @@ -2,6 +2,7 @@ #include "effects/backends/effectmanifest.h" #include "engine/effects/engineeffectparameter.h" +#include "util/math.h" namespace { constexpr unsigned int updateCoef = 32; diff --git a/src/effects/backends/builtin/pitchshifteffect.cpp b/src/effects/backends/builtin/pitchshifteffect.cpp index 4d5dbd726c5..1df0d7165ae 100644 --- a/src/effects/backends/builtin/pitchshifteffect.cpp +++ b/src/effects/backends/builtin/pitchshifteffect.cpp @@ -6,6 +6,7 @@ #include "effects/backends/effectmanifest.h" #include "engine/effects/engineeffectparameter.h" +#include "util/math.h" #include "util/sample.h" namespace { diff --git a/src/encoder/encodersndfileflac.cpp b/src/encoder/encodersndfileflac.cpp index 7fb40d8e88f..00637f0b15f 100644 --- a/src/encoder/encodersndfileflac.cpp +++ b/src/encoder/encodersndfileflac.cpp @@ -1,6 +1,7 @@ #include "encoder/encodersndfileflac.h" #include +#include #include "encoder/encoderflacsettings.h" @@ -13,14 +14,14 @@ void convertFloat32ToIntFormat(int* pDest, const CSAMPLE* pSrc, SINT numSamples, if (format & SF_FORMAT_PCM_16) { // note: LOOP VECTORIZED" for (SINT i = 0; i < numSamples; ++i) { - pDest[i] = static_cast(math_clamp(pSrc[i] * kFloatToIntConversionFactor, + pDest[i] = static_cast(std::clamp(pSrc[i] * kFloatToIntConversionFactor, static_cast(static_cast(INT_MIN & 0xFFFF0000)), static_cast(static_cast(INT_MAX & 0xFFFF0000)))); } } else if (format & SF_FORMAT_PCM_24) { // note: LOOP VECTORIZED" for (SINT i = 0; i < numSamples; ++i) { - pDest[i] = static_cast(math_clamp(pSrc[i] * kFloatToIntConversionFactor, + pDest[i] = static_cast(std::clamp(pSrc[i] * kFloatToIntConversionFactor, static_cast(static_cast(INT_MIN & 0xFFFFFF00)), static_cast(static_cast(INT_MAX & 0xFFFFFF00)))); } @@ -62,7 +63,7 @@ void EncoderSndfileFlac::encodeBuffer(const CSAMPLE* pBuffer, const int iBufferS if (m_pClampBuffer) { SINT numSamplesLeft = iBufferSize; while (numSamplesLeft > 0) { - const SINT numSamplesToWrite = math_min(numSamplesLeft, kEncBufferSize); + const SINT numSamplesToWrite = std::min(numSamplesLeft, kEncBufferSize); convertFloat32ToIntFormat(m_pClampBuffer.get(), pBuffer, numSamplesToWrite, diff --git a/src/engine/enginesidechaincompressor.cpp b/src/engine/enginesidechaincompressor.cpp index 7ff4cb1b043..829b72fbc4a 100644 --- a/src/engine/enginesidechaincompressor.cpp +++ b/src/engine/enginesidechaincompressor.cpp @@ -1,6 +1,8 @@ +#include "engine/enginesidechaincompressor.h" + #include -#include "engine/enginesidechaincompressor.h" +#include "util/assert.h" EngineSideChainCompressor::EngineSideChainCompressor(const QString& group) : m_compressRatio(1.0), diff --git a/src/preferences/broadcastprofile.cpp b/src/preferences/broadcastprofile.cpp index b2d354561ad..e2e2ab2ede0 100644 --- a/src/preferences/broadcastprofile.cpp +++ b/src/preferences/broadcastprofile.cpp @@ -1,3 +1,8 @@ +#include "preferences/broadcastprofile.h" + +#include +#include +#include #include #include #include @@ -16,7 +21,6 @@ using namespace QKeychain; #endif // __QTKEYCHAIN__ #include "broadcast/defs_broadcast.h" -#include "broadcastprofile.h" #include "defs_urls.h" #include "errordialoghandler.h" #include "moc_broadcastprofile.cpp" diff --git a/src/sources/audiosource.cpp b/src/sources/audiosource.cpp index 2b3d7525fee..6d4df8397b4 100644 --- a/src/sources/audiosource.cpp +++ b/src/sources/audiosource.cpp @@ -193,7 +193,7 @@ bool AudioSource::verifyReadable() { // Counterexample: The broken FAAD version 2.9.1 is able to open a file // but then fails to decode any sample frames. const SINT numSampleFrames = - math_min(kVerifyReadableMaxFrameCount, frameIndexRange().length()); + std::min(kVerifyReadableMaxFrameCount, frameIndexRange().length()); SampleBuffer sampleBuffer( m_signalInfo.frames2samples(numSampleFrames)); WritableSampleFrames writableSampleFrames( diff --git a/src/sources/readaheadframebuffer.cpp b/src/sources/readaheadframebuffer.cpp index 8613aac9c3d..838c2434728 100644 --- a/src/sources/readaheadframebuffer.cpp +++ b/src/sources/readaheadframebuffer.cpp @@ -288,7 +288,7 @@ WritableSampleFrames ReadAheadFrameBuffer::consumeAndFillBuffer( // Detect and handle unexpected discontinuities: Overlap if (inputRange.start() < outputRange.start()) { const auto overlapRange = IndexRange::between( - math_max(inputRange.start(), minOutputIndex), + std::max(inputRange.start(), minOutputIndex), outputRange.start()); DEBUG_ASSERT( overlapRange.orientation() != @@ -313,7 +313,7 @@ WritableSampleFrames ReadAheadFrameBuffer::consumeAndFillBuffer( } if (!isEmpty() && inputRange.start() < writeIndex()) { const auto overlapRange = IndexRange::between( - math_max(inputRange.start(), readIndex()), + std::max(inputRange.start(), readIndex()), writeIndex()); DEBUG_ASSERT( overlapRange.orientation() != @@ -340,7 +340,7 @@ WritableSampleFrames ReadAheadFrameBuffer::consumeAndFillBuffer( const auto precedingRange = IndexRange::between( inputRange.start(), - math_min(outputRange.start(), inputRange.end())); + std::min(outputRange.start(), inputRange.end())); #if VERBOSE_DEBUG_LOG kLogger.debug() << "Discarding input data" @@ -363,7 +363,7 @@ WritableSampleFrames ReadAheadFrameBuffer::consumeAndFillBuffer( const auto gapRange = IndexRange::between( outputRange.start(), - math_min(inputRange.start(), outputRange.end())); + std::min(inputRange.start(), outputRange.end())); DEBUG_ASSERT( gapRange.orientation() != IndexRange::Orientation::Backward); @@ -390,7 +390,7 @@ WritableSampleFrames ReadAheadFrameBuffer::consumeAndFillBuffer( const auto copyableFrameRange = IndexRange::between( outputRange.start(), - math_min(inputRange.end(), outputRange.end())); + std::min(inputRange.end(), outputRange.end())); DEBUG_ASSERT(copyableFrameRange.orientation() != IndexRange::Orientation::Backward); if (copyableFrameRange.orientation() == IndexRange::Orientation::Forward) { #if VERBOSE_DEBUG_LOG diff --git a/src/util/readaheadsamplebuffer.cpp b/src/util/readaheadsamplebuffer.cpp index 5e047d0822d..36ec6dd181d 100644 --- a/src/util/readaheadsamplebuffer.cpp +++ b/src/util/readaheadsamplebuffer.cpp @@ -53,7 +53,7 @@ void ReadAheadSampleBuffer::clear() { void ReadAheadSampleBuffer::adjustCapacity(SINT capacity) { DEBUG_ASSERT_CLASS_INVARIANT_ReadAheadSampleBuffer; - SINT newCapacity = math_max(readableLength(), capacity); + SINT newCapacity = std::max(readableLength(), capacity); if (newCapacity != this->capacity()) { ReadAheadSampleBuffer tmp(*this, newCapacity); swap(tmp); @@ -65,7 +65,7 @@ void ReadAheadSampleBuffer::adjustCapacity(SINT capacity) { SampleBuffer::WritableSlice ReadAheadSampleBuffer::growForWriting(SINT maxWriteLength) { DEBUG_ASSERT_CLASS_INVARIANT_ReadAheadSampleBuffer; - const SINT tailLength = math_min(maxWriteLength, writableLength()); + const SINT tailLength = std::min(maxWriteLength, writableLength()); const SampleBuffer::WritableSlice tailSlice( m_sampleBuffer, m_readableRange.end(), tailLength); m_readableRange.growBack(tailLength); @@ -77,7 +77,7 @@ SampleBuffer::WritableSlice ReadAheadSampleBuffer::growForWriting(SINT maxWriteL SINT ReadAheadSampleBuffer::shrinkAfterWriting(SINT maxShrinkLength) { DEBUG_ASSERT_CLASS_INVARIANT_ReadAheadSampleBuffer; - const SINT shrinkLength = math_min(maxShrinkLength, readableLength()); + const SINT shrinkLength = std::min(maxShrinkLength, readableLength()); m_readableRange.shrinkBack(shrinkLength); // If the buffer has become empty reset the write head back to the start // of the available memory @@ -92,7 +92,7 @@ SINT ReadAheadSampleBuffer::shrinkAfterWriting(SINT maxShrinkLength) { SampleBuffer::ReadableSlice ReadAheadSampleBuffer::shrinkForReading(SINT maxReadLength) { DEBUG_ASSERT_CLASS_INVARIANT_ReadAheadSampleBuffer; - const SINT headLength = math_min(maxReadLength, readableLength()); + const SINT headLength = std::min(maxReadLength, readableLength()); const SampleBuffer::ReadableSlice headSlice( m_sampleBuffer, m_readableRange.start(), headLength); m_readableRange.shrinkFront(headLength); diff --git a/src/waveform/renderers/waveformwidgetrenderer.h b/src/waveform/renderers/waveformwidgetrenderer.h index 47cd21b67a6..c99833a39ee 100644 --- a/src/waveform/renderers/waveformwidgetrenderer.h +++ b/src/waveform/renderers/waveformwidgetrenderer.h @@ -181,7 +181,7 @@ class WaveformWidgetRenderer { void setPlayMarkerPosition(double newPos) { VERIFY_OR_DEBUG_ASSERT(newPos >= 0.0 && newPos <= 1.0) { - newPos = math_clamp(newPos, 0.0, 1.0); + newPos = std::clamp(newPos, 0.0, 1.0); } m_playMarkerPosition = newPos; } From 152e344b2d829295b9ee579427c49189c652f6f5 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Sat, 21 Sep 2024 20:33:15 +0200 Subject: [PATCH 04/20] refactor: convert static-only member classes to namespaces --- src/util/regex.h | 26 +++++++++++++------------- src/util/rescaler.h | 33 ++++++++++++++------------------- src/util/rlimit.h | 13 +++++++------ 3 files changed, 34 insertions(+), 38 deletions(-) diff --git a/src/util/regex.h b/src/util/regex.h index e3c59368d45..73fa32485e5 100644 --- a/src/util/regex.h +++ b/src/util/regex.h @@ -1,5 +1,7 @@ #pragma once +#include // for qt version checking + // QRegularExpression::escape was introduced in Qt 5.15. #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) #include @@ -9,21 +11,19 @@ #include #include -class RegexUtils { - public: - static QString fileExtensionsRegex(QStringList extensions) { - // Escape every extension appropriately - for (int i = 0; i < extensions.size(); ++i) { +namespace RegexUtils { + +inline QString fileExtensionsRegex(QStringList extensions) { + // Escape every extension appropriately + for (int i = 0; i < extensions.size(); ++i) { #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) - extensions[i] = QRegularExpression::escape(extensions[i]); + extensions[i] = QRegularExpression::escape(extensions[i]); #else - extensions[i] = QRegExp::escape(extensions[i]); + extensions[i] = QRegExp::escape(extensions[i]); #endif - } - // Turn the list into a "\\.(jpg|gif|etc)$" style regex string - return QString("\\.(%1)$").arg(extensions.join("|")); } + // Turn the list into a "\\.(jpg|gif|etc)$" style regex string + return QStringLiteral("\\.(%1)$").arg(extensions.join('|')); +} - private: - RegexUtils() {} -}; +} // namespace RegexUtils diff --git a/src/util/rescaler.h b/src/util/rescaler.h index c0d6bb9f367..51460dd8311 100644 --- a/src/util/rescaler.h +++ b/src/util/rescaler.h @@ -1,22 +1,17 @@ #pragma once -class RescalerUtils { - public: +namespace RescalerUtils { +// converts a value on a linear scale to a 1/x scale staring at 1 +inline double linearToOneByX(double in, double inMin, double inMax, double outMax) { + double outRange = outMax - 1; + double inRange = inMax - inMin; + return outMax / (((inMax - in) / inRange * outRange) + 1); +} - // converts a value on a linear scale to a 1/x scale staring at 1 - static double linearToOneByX(double in, double inMin, double inMax, double outMax) { - double outRange = outMax - 1; - double inRange = inMax - inMin; - return outMax / (((inMax - in) / inRange * outRange) + 1); - } - - // converts value on a 1/x scale starting by 1 to a linear scale - static double oneByXToLinear(double in, double inMax, double outMin, double outMax) { - double outRange = outMax - outMin; - double inRange = inMax - 1; - return outMax - (((inMax / in) - 1) / inRange * outRange); - } - - private: - RescalerUtils() {} -}; +// converts value on a 1/x scale starting by 1 to a linear scale +inline double oneByXToLinear(double in, double inMax, double outMin, double outMax) { + double outRange = outMax - outMin; + double inRange = inMax - 1; + return outMax - (((inMax / in) - 1) / inRange * outRange); +} +}; // namespace RescalerUtils diff --git a/src/util/rlimit.h b/src/util/rlimit.h index 1f8b50ea6ec..8030517071f 100644 --- a/src/util/rlimit.h +++ b/src/util/rlimit.h @@ -2,11 +2,12 @@ #ifdef __LINUX__ -class RLimit { - public: - static unsigned int getCurRtPrio(); - static unsigned int getMaxRtPrio(); - static bool isRtPrioAllowed(); -}; +namespace RLimit { + +unsigned int getCurRtPrio(); +unsigned int getMaxRtPrio(); +bool isRtPrioAllowed(); + +} // namespace RLimit #endif // __LINUX__ From 448ca200212cf84072d6e487e297c6a359674cb0 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Sat, 21 Sep 2024 20:36:44 +0200 Subject: [PATCH 05/20] refactor: slim down font.h --- CMakeLists.txt | 1 + src/util/font.cpp | 84 +++++++++++++++++++++++++++++++++++++++++++++ src/util/font.h | 87 +++-------------------------------------------- 3 files changed, 89 insertions(+), 83 deletions(-) create mode 100644 src/util/font.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a30e5650ed5..66721940f74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1174,6 +1174,7 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL src/util/fileaccess.cpp src/util/fileinfo.cpp src/util/filename.cpp + src/util/font.cpp src/util/imagefiledata.cpp src/util/imagefiledata.cpp src/util/imageutils.cpp diff --git a/src/util/font.cpp b/src/util/font.cpp new file mode 100644 index 00000000000..26cc6cee894 --- /dev/null +++ b/src/util/font.cpp @@ -0,0 +1,84 @@ +#include "util/font.h" + +#include +#include +#include +#include + +#include "util/cmdlineargs.h" + +namespace { + +bool addFont(const QString& path) { + int result = QFontDatabase::addApplicationFont(path); + if (result == -1) { + qWarning() << "Failed to add font:" << path; + return false; + } + + // In developer mode, spit out all the families / styles / sizes + // supported by the new font. + if (CmdlineArgs::Instance().getDeveloper()) { +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QFontDatabase database; +#endif + QStringList pointSizesStr; + const QStringList families = QFontDatabase::applicationFontFamilies(result); + for (const QString& family : families) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + const QStringList styles = QFontDatabase::styles(family); +#else + const QStringList styles = database.styles(family); +#endif + for (const QString& style : styles) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + const QList pointSizes = QFontDatabase::pointSizes(family, style); +#else + const QList pointSizes = database.pointSizes(family, style); +#endif + pointSizesStr.clear(); + pointSizesStr.reserve(pointSizes.count()); + for (int point : pointSizes) { + pointSizesStr.append(QString::number(point)); + } + qDebug() << "FONT LOADED family:" << family + << "style:" << style + << "point sizes:" << pointSizesStr.join(","); + } + } + } + return true; +} + +} // namespace + +void FontUtils::initializeFonts(const QString& resourcePath) { + QDir fontsDir(resourcePath); + if (!fontsDir.cd("fonts")) { +#ifdef __LINUX__ + // If the fonts already have been installed via the package + // manager, this is okay. We currently have no way to verify that + // though. + qDebug() +#else + qWarning() +#endif + << "No fonts directory found in" << resourcePath; + return; + } + + QList files = fontsDir.entryInfoList( + QDir::NoDotAndDotDot | QDir::Files | QDir::Readable); + for (const QFileInfo& file : files) { + const QString& path = file.filePath(); + + // Skip text files (e.g. license files). For all others we let Qt tell + // us whether the font format is supported since there is no way to + // check other than adding. + if (path.endsWith(".txt", Qt::CaseInsensitive)) { + continue; + } + + addFont(path); + } +} diff --git a/src/util/font.h b/src/util/font.h index 42bb21f4701..dc47956809f 100644 --- a/src/util/font.h +++ b/src/util/font.h @@ -1,86 +1,7 @@ #pragma once -#include -#include -#include -#include +class QString; -#include "util/cmdlineargs.h" - -class FontUtils { - public: - static void initializeFonts(const QString& resourcePath) { - QDir fontsDir(resourcePath); - if (!fontsDir.cd("fonts")) { -#ifdef __LINUX__ - // If the fonts already have been installed via the package - // manager, this is okay. We currently have no way to verify that - // though. - qDebug() -#else - qWarning() -#endif - << "No fonts directory found in" << resourcePath; - return; - } - - QList files = fontsDir.entryInfoList( - QDir::NoDotAndDotDot | QDir::Files | QDir::Readable); - foreach (const QFileInfo& file, files) { - const QString& path = file.filePath(); - - // Skip text files (e.g. license files). For all others we let Qt tell - // us whether the font format is supported since there is no way to - // check other than adding. - if (path.endsWith(".txt", Qt::CaseInsensitive)) { - continue; - } - - addFont(path); - } - } - - static bool addFont(const QString& path) { - int result = QFontDatabase::addApplicationFont(path); - if (result == -1) { - qWarning() << "Failed to add font:" << path; - return false; - } - - // In developer mode, spit out all the families / styles / sizes - // supported by the new font. - if (CmdlineArgs::Instance().getDeveloper()) { -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - QFontDatabase database; -#endif - QStringList pointSizesStr; - const QStringList families = QFontDatabase::applicationFontFamilies(result); - for (const QString& family : families) { -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - const QStringList styles = QFontDatabase::styles(family); -#else - const QStringList styles = database.styles(family); -#endif - for (const QString& style : styles) { -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - const QList pointSizes = QFontDatabase::pointSizes(family, style); -#else - const QList pointSizes = database.pointSizes(family, style); -#endif - pointSizesStr.clear(); - pointSizesStr.reserve(pointSizes.count()); - for (int point : pointSizes) { - pointSizesStr.append(QString::number(point)); - } - qDebug() << "FONT LOADED family:" << family - << "style:" << style - << "point sizes:" << pointSizesStr.join(","); - } - } - } - return true; - } - - private: - FontUtils() {} -}; +namespace FontUtils { +void initializeFonts(const QString& resourcePath); +} // namespace FontUtils From 07877a1f9c21e5cd72eb765e18de330e6a69dc97 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Sat, 21 Sep 2024 20:37:44 +0200 Subject: [PATCH 06/20] refactor: remove unused atomic utility functions from util/qatomic.h --- src/util/compatibility/qatomic.h | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/src/util/compatibility/qatomic.h b/src/util/compatibility/qatomic.h index 20dc6004e3c..d1120ed6f8a 100644 --- a/src/util/compatibility/qatomic.h +++ b/src/util/compatibility/qatomic.h @@ -9,24 +9,9 @@ // Until the minimum required Qt version of Mixxx is increased some utility // functions that work independently of the Qt version are needed. -template -inline T atomicLoadAcquire(const QAtomicInteger& atomicInt) { -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - return atomicInt.loadAcquire(); -#else - return atomicInt.load(); -#endif -} - -template -inline T* atomicLoadAcquire(const QAtomicPointer& atomicPtr) { -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - return atomicPtr.loadAcquire(); -#else - return atomicPtr.load(); -#endif -} +#define DEPRECATED_QATOMIC_OPS /// Deprecated, use the corresponding member function directly +DEPRECATED_QATOMIC_OPS template inline T atomicLoadRelaxed(const QAtomicInteger& atomicInt) { #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) @@ -36,6 +21,7 @@ inline T atomicLoadRelaxed(const QAtomicInteger& atomicInt) { #endif } +DEPRECATED_QATOMIC_OPS template inline T* atomicLoadRelaxed(const QAtomicPointer& atomicPtr) { #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) @@ -45,15 +31,7 @@ inline T* atomicLoadRelaxed(const QAtomicPointer& atomicPtr) { #endif } -template -inline void atomicStoreRelaxed(QAtomicInteger& atomicInt, T newValue) { -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - atomicInt.storeRelaxed(newValue); -#else - atomicInt.store(newValue); -#endif -} - +DEPRECATED_QATOMIC_OPS template inline void atomicStoreRelaxed(QAtomicPointer& atomicPtr, T* newValue) { #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) @@ -62,3 +40,5 @@ inline void atomicStoreRelaxed(QAtomicPointer& atomicPtr, T* newValue) { atomicPtr.store(newValue); #endif } + +#undef DEPRECATED_QATOMIC_OPS From 7849fa43e6d05ee8b457b2236193e81aa25a6052 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Sat, 21 Sep 2024 20:39:01 +0200 Subject: [PATCH 07/20] refactor: remove util/math.h dependency from util/types.h --- src/util/types.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/util/types.h b/src/util/types.h index c026e38fdb1..d4a6194f2e3 100644 --- a/src/util/types.h +++ b/src/util/types.h @@ -1,10 +1,9 @@ #pragma once +#include #include #include -#include "util/math.h" - // Signed integer type for POT array indices, sizes and pointer // arithmetic. Its size (32-/64-bit) depends on the CPU architecture. // This should be used for all CSAMLE operations since it is fast and @@ -25,28 +24,29 @@ constexpr SAMPLE SAMPLE_MAXIMUM = SHRT_MAX; // amplitude of 1.0. No min/max constants here to // emphasize the symmetric value range of CSAMPLE // data! -typedef float CSAMPLE; +using CSAMPLE = float; constexpr CSAMPLE CSAMPLE_ZERO = 0.0f; constexpr CSAMPLE CSAMPLE_ONE = 1.0f; constexpr CSAMPLE CSAMPLE_PEAK = CSAMPLE_ONE; +static_assert(sizeof(CSAMPLE) == 4); // 32 bits == 4 bytes // Limits the range of a CSAMPLE value to [-CSAMPLE_PEAK, CSAMPLE_PEAK]. -inline -CSAMPLE CSAMPLE_clamp(CSAMPLE in) { - return math_clamp(in, -CSAMPLE_PEAK, CSAMPLE_PEAK); +constexpr CSAMPLE CSAMPLE_clamp(CSAMPLE in) { + static_assert(-CSAMPLE_PEAK <= CSAMPLE_PEAK); + return std::clamp(in, -CSAMPLE_PEAK, CSAMPLE_PEAK); } // Gain values for weighted calculations of CSAMPLE // data in the range [0.0, 1.0]. Same data type as // CSAMPLE to avoid type conversions in calculations. -typedef CSAMPLE CSAMPLE_GAIN; +using CSAMPLE_GAIN = CSAMPLE; constexpr float CSAMPLE_GAIN_ZERO = CSAMPLE_ZERO; constexpr float CSAMPLE_GAIN_ONE = CSAMPLE_ONE; constexpr float CSAMPLE_GAIN_MIN = CSAMPLE_GAIN_ZERO; constexpr float CSAMPLE_GAIN_MAX = CSAMPLE_GAIN_ONE; // Limits the range of a CSAMPLE_GAIN value to [CSAMPLE_GAIN_MIN, CSAMPLE_GAIN_MAX]. -inline -CSAMPLE_GAIN CSAMPLE_GAIN_clamp(CSAMPLE_GAIN in) { - return math_clamp(in, CSAMPLE_GAIN_MIN, CSAMPLE_GAIN_MAX); +constexpr CSAMPLE_GAIN CSAMPLE_GAIN_clamp(CSAMPLE_GAIN in) { + static_assert(CSAMPLE_GAIN_MIN <= CSAMPLE_GAIN_MAX); + return std::clamp(in, CSAMPLE_GAIN_MIN, CSAMPLE_GAIN_MAX); } From 79e75064c5df8704b268b57ecbbf815ae105ceb3 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Sat, 21 Sep 2024 20:41:04 +0200 Subject: [PATCH 08/20] refactor: slim down util/xml.h * convert class to namespace * replace unecessary includes with forward decls * replace `NULL` and `0` with `nullptr` --- src/util/xml.cpp | 7 ++- src/util/xml.h | 117 ++++++++++++++++++++++++----------------------- 2 files changed, 65 insertions(+), 59 deletions(-) diff --git a/src/util/xml.cpp b/src/util/xml.cpp index ccfee0fb986..264d5218d2c 100644 --- a/src/util/xml.cpp +++ b/src/util/xml.cpp @@ -1,7 +1,12 @@ +#include "util/xml.h" + +#include +#include +#include #include +#include #include -#include "util/xml.h" #include "errordialoghandler.h" int XmlParse::selectNodeInt(const QDomNode& nodeHeader, diff --git a/src/util/xml.h b/src/util/xml.h index 5bbb4196680..3218c6c9de6 100644 --- a/src/util/xml.h +++ b/src/util/xml.h @@ -1,60 +1,61 @@ #pragma once -#include -#include -#include - -class XmlParse { - public: - // Searches for and returns a node named sNode in the children of - // nodeHeader. Returns a null QDomNode if one is not found. - static QDomNode selectNode(const QDomNode& nodeHeader, - const QString& sNode); - - // Searches for and returns an element named sNode in the children of - // nodeHeader. Returns a null QDomElement if one is not found. - static QDomElement selectElement(const QDomNode& nodeHeader, - const QString& sNode); - - // Searches for an element named sNode in the children of nodeHeader and - // parses the text value of its children as an integer. Returns 0 if sNode - // is not found in nodeHeader's children. - static int selectNodeInt(const QDomNode& nodeHeader, - const QString& sNode, bool* ok = 0); - - // Searches for an element named sNode in the children of nodeHeader and - // parses the text value of its children as a float. Returns 0.0f if sNode - // is not found in nodeHeader's children. - static float selectNodeFloat(const QDomNode& nodeHeader, - const QString& sNode, bool* ok = 0); - - // Searches for an element named sNode in the children of nodeHeader and - // parses the text value of its children as a double. Returns 0.0 if sNode - // is not found in nodeHeader's children. - static double selectNodeDouble(const QDomNode& nodeHeader, - const QString& sNode, bool* ok = 0); - - // Searches for an element named sNode in the children of nodeHeader and - // parses the text value of its children as a bool. Returns false if sNode - // is not found in nodeHeader's children. - static bool selectNodeBool(const QDomNode& nodeHeader, - const QString& sNode); - - // Searches for an element named sNode in the children of nodeHeader and - // returns the text value of its children. Returns the empty string if sNode - // is not found in nodeHeader's children. - static QString selectNodeQString(const QDomNode& nodeHeader, - const QString& sNode); - - // Open an XML file. - static QDomElement openXMLFile(const QString& path, const QString& name); - - // Add an element named elementName to the provided header element with a - // child text node with the value textValue. Returns the created element. - static QDomElement addElement(QDomDocument& document, QDomElement& header, - const QString& elementName, const QString& textValue); - - private: - XmlParse() {} - ~XmlParse() {} -}; +class QDomNode; +class QString; +class QDomElement; +class QDomDocument; + +namespace XmlParse { +// Searches for and returns a node named sNode in the children of +// nodeHeader. Returns a null QDomNode if one is not found. +QDomNode selectNode(const QDomNode& nodeHeader, + const QString& sNode); + +// Searches for and returns an element named sNode in the children of +// nodeHeader. Returns a null QDomElement if one is not found. +QDomElement selectElement(const QDomNode& nodeHeader, + const QString& sNode); + +// Searches for an element named sNode in the children of nodeHeader and +// parses the text value of its children as an integer. Returns 0 if sNode +// is not found in nodeHeader's children. +int selectNodeInt(const QDomNode& nodeHeader, + const QString& sNode, + bool* ok = nullptr); + +// Searches for an element named sNode in the children of nodeHeader and +// parses the text value of its children as a float. Returns 0.0f if sNode +// is not found in nodeHeader's children. +float selectNodeFloat(const QDomNode& nodeHeader, + const QString& sNode, + bool* ok = nullptr); + +// Searches for an element named sNode in the children of nodeHeader and +// parses the text value of its children as a double. Returns 0.0 if sNode +// is not found in nodeHeader's children. +double selectNodeDouble(const QDomNode& nodeHeader, + const QString& sNode, + bool* ok = nullptr); + +// Searches for an element named sNode in the children of nodeHeader and +// parses the text value of its children as a bool. Returns false if sNode +// is not found in nodeHeader's children. +bool selectNodeBool(const QDomNode& nodeHeader, + const QString& sNode); + +// Searches for an element named sNode in the children of nodeHeader and +// returns the text value of its children. Returns the empty string if sNode +// is not found in nodeHeader's children. +QString selectNodeQString(const QDomNode& nodeHeader, + const QString& sNode); + +// Open an XML file. +QDomElement openXMLFile(const QString& path, const QString& name); + +// Add an element named elementName to the provided header element with a +// child text node with the value textValue. Returns the created element. +QDomElement addElement(QDomDocument& document, + QDomElement& header, + const QString& elementName, + const QString& textValue); +} // namespace XmlParse From 2109be21828abd16f8506aeba84991d1468cc7eb Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Sun, 22 Sep 2024 15:52:38 +0200 Subject: [PATCH 09/20] refactor: simplify Rotary (jog) filter drastically. --- src/engine/controls/ratecontrol.cpp | 13 +--- src/util/rotary.cpp | 105 +++++----------------------- src/util/rotary.h | 39 ++--------- 3 files changed, 26 insertions(+), 131 deletions(-) diff --git a/src/engine/controls/ratecontrol.cpp b/src/engine/controls/ratecontrol.cpp index 8e1c065ccda..e036eb16ab8 100644 --- a/src/engine/controls/ratecontrol.cpp +++ b/src/engine/controls/ratecontrol.cpp @@ -165,19 +165,8 @@ RateControl::RateControl(const QString& group, m_pJog = new ControlObject(ConfigKey(group, "jog")); - m_pJogFilter = new Rotary(); // FIXME: This should be dependent on sample rate/block size or something - m_pJogFilter->setFilterLength(25); - -// // Update Internal Settings -// // Set Pitchbend Mode -// m_eRateRampMode = static_cast( -// getConfig()->getValue(ConfigKey("[Controls]","RateRamp"), -// static_cast(RampMode::Stepping))); - -// // Set the Sensitivity -// m_iRateRampSensitivity = -// getConfig()->getValueString(ConfigKey("[Controls]","RateRampSensitivity")).toInt(); + m_pJogFilter = new Rotary(25); m_pSyncMode = new ControlProxy(group, "sync_mode", this); } diff --git a/src/util/rotary.cpp b/src/util/rotary.cpp index 45f3054d91a..a83431ebd40 100644 --- a/src/util/rotary.cpp +++ b/src/util/rotary.cpp @@ -1,93 +1,24 @@ #include "util/rotary.h" -#include - -constexpr int kiRotaryFilterMaxLen = 50; - -Rotary::Rotary() - : m_iFilterLength(kiRotaryFilterMaxLen), - m_iFilterPos(0), - m_pFilter(m_iFilterLength), - m_dCalibration(1.0), - m_dLastValue(0.0), - m_iCalibrationCount(0) { - for (int i = 0; i < m_iFilterLength; ++i) { - m_pFilter[i] = 0.; - } -} +#include /* Note: There's probably a bug in this function (or this class) somewhere. - The filter function seems to be the cause of the "drifting" bug in the Hercules stuff. - What happens is that filter() gets called to do some magic to a value that's returned - from the Hercules device, and that magic adds "momentum" to it's motion (ie. it doesn't - stop dead when you stop spinning the jog wheels.) The problem with this "magic" is that - when herculeslinux.cpp passes the filtered value off to the wheel ControlObject (or what - have you), the ControlObject's internal value never goes back to zero properly. - - Albert (March 13, 2007) - */ -double Rotary::filter(double dValue) { - // Update filter buffer - m_pFilter[m_iFilterPos] = dValue/m_dCalibration; - m_iFilterPos = (m_iFilterPos+1)%m_iFilterLength; - - double dMagnitude = 0.; - for (int i=0; i kiRotaryFilterMaxLen) { - m_iFilterLength = kiRotaryFilterMaxLen; - } else if (i < 1) { - m_iFilterLength = 1; - } else { - m_iFilterLength = i; - } -} - -int Rotary::getFilterLength() { - return m_iFilterLength; + m_filterHistory.enqueue(v); + return std::accumulate(std::cbegin(m_filterHistory), + std::cend(m_filterHistory), + 0) / + static_cast(m_filterHistory.size()); } diff --git a/src/util/rotary.h b/src/util/rotary.h index 52c73264223..cc1c2f53349 100644 --- a/src/util/rotary.h +++ b/src/util/rotary.h @@ -1,40 +1,15 @@ #pragma once -#include +#include +// Simple moving average class Rotary { public: - Rotary(); - - // Start calibration measurement - void calibrateStart(); - // End calibration measurement - double calibrateEnd(); - // Set calibration - void setCalibration(double c); - // Get calibration - double getCalibration(); + Rotary(qsizetype filterLength) + : m_filterHistory(QList(filterLength, 0.0)){}; // Low pass filtered rotary event - double filter(double dValue); - // Hard set event value - double fillBuffer(double dValue); - // Collect calibration data - void calibrate(double dValue); - // Set filter length - void setFilterLength(int i); - // Get filter length - int getFilterLength(); + double filter(double value); - protected: - // Length of filter - int m_iFilterLength; - // Update position in filter - int m_iFilterPos; - // Pointer to rotary filter buffer - std::vector m_pFilter; - // Calibration value - double m_dCalibration; - // Last value - double m_dLastValue; - int m_iCalibrationCount; + private: + QQueue m_filterHistory; }; From 0e4dd46b05734aa8fbb99b38eb98a43ca879e177 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Sun, 22 Sep 2024 16:07:29 +0200 Subject: [PATCH 10/20] chore: mark `DISALLOW_COPY_AND_ASSIGN` macro as deprecated --- src/util/class.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/util/class.h b/src/util/class.h index 793a7726faa..415a0edd8a2 100644 --- a/src/util/class.h +++ b/src/util/class.h @@ -1,7 +1,9 @@ #pragma once -// A macro to disallow the copy constructor and operator= functions -// This should be used in the private: declarations for a class +// DEPRECATED: Instead rely on "the rule of zero". See +// https://en.cppreference.com/w/cpp/language/rule_of_three#Rule_of_zero +// See also: Cpp Core Guidelines C.20, C.21 & C.22 as well as the clang-tidy rule +// `modernize-use-equals-delete` #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName&) = delete; \ void operator=(const TypeName&) = delete; From 923310d20fc910fa5b0f367d973c96417075b0c1 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Sun, 22 Sep 2024 16:27:44 +0200 Subject: [PATCH 11/20] refactor: cleanup SemanticVersion --- src/util/semanticversion.cpp | 30 ++++++++-------------- src/util/semanticversion.h | 48 ++++++++++++++++++++---------------- 2 files changed, 37 insertions(+), 41 deletions(-) diff --git a/src/util/semanticversion.cpp b/src/util/semanticversion.cpp index 3e0053f18f4..39e7bbe81b2 100644 --- a/src/util/semanticversion.cpp +++ b/src/util/semanticversion.cpp @@ -1,37 +1,27 @@ #include "util/semanticversion.h" #include +#include +#include namespace { - -QRegularExpression regex("(?\\d+)\\.(?\\d+)\\.(?\\d+)"); +// thread local because SemanticVersion constructors below accesses it mutably. +// making it thread_local should avoid a datarace without having to introduce locking. +thread_local QRegularExpression regex( + QStringLiteral("(?\\d+)\\.(?\\d+)\\.(?\\d+)")); } // anonymous namespace namespace mixxx { -SemanticVersion::SemanticVersion(unsigned int majorVersion, - unsigned int minorVersion, - unsigned int patchVersion) - : majorVersion(majorVersion), - minorVersion(minorVersion), - patchVersion(patchVersion) { -} - SemanticVersion::SemanticVersion(const QString& versionString) - : majorVersion(0), - minorVersion(0), - patchVersion(0) { + : SemanticVersion() { QRegularExpressionMatch match = regex.match(versionString); if (match.hasMatch()) { - majorVersion = match.captured(QStringLiteral("major")).toUInt(); - minorVersion = match.captured(QStringLiteral("minor")).toUInt(); - patchVersion = match.captured(QStringLiteral("patch")).toUInt(); + majorVersion = match.capturedView(QStringView(u"major")).toUInt(); + minorVersion = match.capturedView(QStringView(u"minor")).toUInt(); + patchVersion = match.capturedView(QStringView(u"patch")).toUInt(); } } -bool SemanticVersion::isValid() const { - return !(majorVersion == 0 && minorVersion == 0 && patchVersion == 0); -} - } // namespace mixxx diff --git a/src/util/semanticversion.h b/src/util/semanticversion.h index 9ef99cf2d9a..b7eb1ae3a2e 100644 --- a/src/util/semanticversion.h +++ b/src/util/semanticversion.h @@ -1,38 +1,44 @@ #pragma once -#include -#include +#include + +class QString; namespace mixxx { // "major" and "minor" clash with symbols in glibc, so use more verbose variable names. class SemanticVersion { public: - SemanticVersion(unsigned int majorVersion, + constexpr SemanticVersion(unsigned int majorVersion, unsigned int minorVersion, - unsigned int patchVersion); + unsigned int patchVersion) + : majorVersion(majorVersion), + minorVersion(minorVersion), + patchVersion(patchVersion) { + } + SemanticVersion(const QString& versionString); - bool isValid() const; + constexpr bool isValid() const { + return !(majorVersion == 0 && minorVersion == 0 && patchVersion == 0); + } - unsigned int majorVersion, minorVersion, patchVersion; -}; + friend constexpr std::strong_ordering operator<=>( + const SemanticVersion&, const SemanticVersion&) noexcept; -inline bool operator<(const SemanticVersion& a, const SemanticVersion& b) { - return std::tie(a.majorVersion, a.minorVersion, a.patchVersion) < - std::tie(b.majorVersion, b.minorVersion, b.patchVersion); -} + // Do not change the order because the synthesized comparison operators + // depend on it! + unsigned int majorVersion; + unsigned int minorVersion; + unsigned int patchVersion; -inline bool operator>(const SemanticVersion& a, const SemanticVersion& b) { - return b < a; -} - -inline bool operator<=(const SemanticVersion& a, const SemanticVersion& b) { - return !(a > b); -} + private: + // you should not be able to create an invalid version easily from the outside + constexpr SemanticVersion() + : SemanticVersion(0, 0, 0){}; +}; -inline bool operator>=(const SemanticVersion& a, const SemanticVersion& b) { - return !(a < b); -} +constexpr std::strong_ordering operator<=>( + const SemanticVersion&, const SemanticVersion&) noexcept = default; } // namespace mixxx From ad841da32992a59dff65aaea499c6ae290b799e9 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Sun, 22 Sep 2024 16:34:52 +0200 Subject: [PATCH 12/20] refactor: modernize `TaskWatcher` and mark deprecated --- src/util/task.cpp | 6 +----- src/util/task.h | 7 +++++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/util/task.cpp b/src/util/task.cpp index 6b4906e20a8..6a437fb27df 100644 --- a/src/util/task.cpp +++ b/src/util/task.cpp @@ -3,13 +3,9 @@ #include #include "moc_task.cpp" -#include "util/compatibility/qatomic.h" - -TaskWatcher::TaskWatcher(QObject* pParent) : QObject(pParent) { -} TaskWatcher::~TaskWatcher() { - if (atomicLoadRelaxed(m_activeTasks) > 0) { + if (m_activeTasks.loadRelaxed() > 0) { qWarning() << "TaskWatcher destroyed before all tasks were done."; } } diff --git a/src/util/task.h b/src/util/task.h index 4fae197e74b..908e2317e0c 100644 --- a/src/util/task.h +++ b/src/util/task.h @@ -5,11 +5,14 @@ // Waits for a number of tasks to complete and emits allTasksDone() once all are // complete. +// Deprecated: This is just a unnecessarily heavy counter. You should probably refrain +// from using this in new code in favor of appropriate QtConcurrent primitives. class TaskWatcher : public QObject { Q_OBJECT public: - TaskWatcher(QObject* pParent=NULL); - virtual ~TaskWatcher(); + TaskWatcher(QObject* pParent = nullptr) + : QObject(pParent){}; + ~TaskWatcher() override; // Increment the number of active tasks by one and watch pTask for // doneSignal. This should be called before the task starts to prevent a From ec0c12dc21a4af204f3f86dfce8cdddd774f1e11 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Sun, 22 Sep 2024 16:36:18 +0200 Subject: [PATCH 13/20] refactor: slim down trace.h --- src/util/trace.h | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/src/util/trace.h b/src/util/trace.h index 4c9615bb867..09b07eb42a1 100644 --- a/src/util/trace.h +++ b/src/util/trace.h @@ -11,8 +11,7 @@ class Trace { public: - Trace(const char* tag, const char* arg=NULL, - bool writeToStdout=false, bool time=true) + Trace(const char* tag, const char* arg = nullptr, bool writeToStdout = false, bool time = true) : m_writeToStdout(writeToStdout), m_time(time) { if (writeToStdout || CmdlineArgs::Instance().getDeveloper()) { @@ -20,15 +19,6 @@ class Trace { } } - Trace(const char* tag, int arg, - bool writeToStdout=false, bool time=true) - : m_writeToStdout(writeToStdout), - m_time(time) { - if (writeToStdout || CmdlineArgs::Instance().getDeveloper()) { - initialize(tag, QString::number(arg)); - } - } - Trace(const char* tag, const QString& arg, bool writeToStdout=false, bool time=true) : m_writeToStdout(writeToStdout), @@ -38,7 +28,7 @@ class Trace { } } - virtual ~Trace() { + ~Trace() { // Proxy for whether initialize was called. if (m_tag.isEmpty()) { return; @@ -86,16 +76,7 @@ class Trace { } QString m_tag; - const bool m_writeToStdout, m_time; PerformanceTimer m_timer; - -}; - -class DebugTrace : public Trace { - public: - DebugTrace(const char* tag, bool time=true) - : Trace(tag, "", CmdlineArgs::Instance().getDeveloper(), time) { - } - virtual ~DebugTrace() { - } + bool m_writeToStdout; + bool m_time; }; From ec5108967605c2c4b271b067638b461a99efcbf4 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Mon, 23 Sep 2024 14:11:28 +0200 Subject: [PATCH 14/20] refactor: make Autopan `RampedSample` constexpr, fix cmath abs --- src/effects/backends/builtin/autopaneffect.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/effects/backends/builtin/autopaneffect.h b/src/effects/backends/builtin/autopaneffect.h index 50dd2f7d228..4994ea0e1a7 100644 --- a/src/effects/backends/builtin/autopaneffect.h +++ b/src/effects/backends/builtin/autopaneffect.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "effects/backends/effectprocessor.h" #include "engine/filters/enginefilterpansingle.h" @@ -13,27 +14,25 @@ // somewhere else (I hear clicks when I change the period of flanger for example). class RampedSample { public: - inline RampedSample() + constexpr RampedSample() : ramped(false), maxDifference(1.0f), currentValue(0), initialized(false) { } - virtual ~RampedSample(){}; - - inline void setRampingThreshold(const float newMaxDifference) { + constexpr void setRampingThreshold(float newMaxDifference) { maxDifference = newMaxDifference; } - inline void setWithRampingApplied(const float newValue) { + constexpr void setWithRampingApplied(float newValue) { if (!initialized) { currentValue = newValue; initialized = true; } else { float difference = newValue - currentValue; - if (fabs(difference) > maxDifference) { - currentValue += difference / fabs(difference) * maxDifference; + if (abs(difference) > maxDifference) { + currentValue += difference / abs(difference) * maxDifference; ramped = true; } else { currentValue = newValue; @@ -42,7 +41,7 @@ class RampedSample { } } - inline operator float() { + constexpr operator float() { return currentValue; } From 7578cfaf14fcb054f4f8dd210fcabcd2a30f1c7c Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Fri, 4 Oct 2024 18:34:42 +0200 Subject: [PATCH 15/20] refactor: optimize Rotary Jog filter (moving arithm. average) --- src/util/rotary.cpp | 29 ++++++++++++++++++++--------- src/util/rotary.h | 17 ++++++++++++++--- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/util/rotary.cpp b/src/util/rotary.cpp index a83431ebd40..63b63e764fe 100644 --- a/src/util/rotary.cpp +++ b/src/util/rotary.cpp @@ -2,6 +2,24 @@ #include +Rotary::index_type Rotary::nextIndex(Rotary::index_type i) { + if (++i >= m_filterHistory.size()) { + return 0; + } + return i; +} + +void Rotary::append(double v) { + m_filterHistory[nextIndex(m_headIndex)] = v; +} + +double Rotary::calculate() const { + return std::accumulate(std::cbegin(m_filterHistory), + std::cend(m_filterHistory), + 0) / + static_cast(m_filterHistory.size()); +} + /* Note: There's probably a bug in this function (or this class) somewhere. The filter function seems to be the cause of the "drifting" bug in the Hercules stuff. What happens is that filter() gets called to do some magic to a value that's returned @@ -12,13 +30,6 @@ - Albert (March 13, 2007) */ double Rotary::filter(double v) { - // don't grow the list if we're already at capacity. - if (m_filterHistory.size() == m_filterHistory.capacity()) { - m_filterHistory.dequeue(); - } - m_filterHistory.enqueue(v); - return std::accumulate(std::cbegin(m_filterHistory), - std::cend(m_filterHistory), - 0) / - static_cast(m_filterHistory.size()); + append(v); + return calculate(); } diff --git a/src/util/rotary.h b/src/util/rotary.h index cc1c2f53349..b191a74c525 100644 --- a/src/util/rotary.h +++ b/src/util/rotary.h @@ -1,15 +1,26 @@ #pragma once -#include +#include + +#include "util/assert.h" // Simple moving average class Rotary { + using Buffer = std::vector; + using index_type = Buffer::size_type; + public: Rotary(qsizetype filterLength) - : m_filterHistory(QList(filterLength, 0.0)){}; + : m_filterHistory(filterLength, 0.0) { + DEBUG_ASSERT(filterLength > 0); + }; // Low pass filtered rotary event double filter(double value); private: - QQueue m_filterHistory; + index_type nextIndex(index_type); + void append(double v); + double calculate() const; + Buffer m_filterHistory; + index_type m_headIndex; }; From 4100f309b0ec2d5a0e4d47108d64aefce10d9e20 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Wed, 9 Oct 2024 11:46:25 +0200 Subject: [PATCH 16/20] fixup! refactor: slim down valuetransformer.h and auto memory management --- src/skin/legacy/legacyskinparser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/skin/legacy/legacyskinparser.cpp b/src/skin/legacy/legacyskinparser.cpp index 81757e19711..09b7306cf43 100644 --- a/src/skin/legacy/legacyskinparser.cpp +++ b/src/skin/legacy/legacyskinparser.cpp @@ -2309,7 +2309,7 @@ void LegacySkinParser::setupConnections(const QDomNode& node, WBaseWidget* pWidg if (!transform.isNull()) { pTransformer = ValueTransformer::parseFromXml(transform, *m_pContext) - .get(); // TODO don't leak here + .release(); // TODO don't leak here } QString property; From 0698a5be1476cf8156e284bc8affd61730409d33 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Wed, 9 Oct 2024 11:49:00 +0200 Subject: [PATCH 17/20] fixup! refactor: remove unused atomic utility functions from util/qatomic.h --- src/util/compatibility/qatomic.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/util/compatibility/qatomic.h b/src/util/compatibility/qatomic.h index d1120ed6f8a..9b140eaf18a 100644 --- a/src/util/compatibility/qatomic.h +++ b/src/util/compatibility/qatomic.h @@ -9,9 +9,6 @@ // Until the minimum required Qt version of Mixxx is increased some utility // functions that work independently of the Qt version are needed. -#define DEPRECATED_QATOMIC_OPS /// Deprecated, use the corresponding member function directly - -DEPRECATED_QATOMIC_OPS template inline T atomicLoadRelaxed(const QAtomicInteger& atomicInt) { #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) @@ -21,7 +18,6 @@ inline T atomicLoadRelaxed(const QAtomicInteger& atomicInt) { #endif } -DEPRECATED_QATOMIC_OPS template inline T* atomicLoadRelaxed(const QAtomicPointer& atomicPtr) { #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) @@ -31,7 +27,6 @@ inline T* atomicLoadRelaxed(const QAtomicPointer& atomicPtr) { #endif } -DEPRECATED_QATOMIC_OPS template inline void atomicStoreRelaxed(QAtomicPointer& atomicPtr, T* newValue) { #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) @@ -40,5 +35,3 @@ inline void atomicStoreRelaxed(QAtomicPointer& atomicPtr, T* newValue) { atomicPtr.store(newValue); #endif } - -#undef DEPRECATED_QATOMIC_OPS From 77798f102ed94e6a423580e9fcde4d3393d608fa Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Wed, 9 Oct 2024 11:57:19 +0200 Subject: [PATCH 18/20] fixup! chore: mark `DISALLOW_COPY_AND_ASSIGN` macro as deprecated --- src/util/class.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/util/class.h b/src/util/class.h index 415a0edd8a2..7fbc82a1573 100644 --- a/src/util/class.h +++ b/src/util/class.h @@ -1,9 +1,11 @@ #pragma once -// DEPRECATED: Instead rely on "the rule of zero". See -// https://en.cppreference.com/w/cpp/language/rule_of_three#Rule_of_zero -// See also: Cpp Core Guidelines C.20, C.21 & C.22 as well as the clang-tidy rule -// `modernize-use-equals-delete` +// DEPRECATED: Adhere to the rule "the rule of zero" or "the rule of five". +// See https://en.cppreference.com/w/cpp/language/rule_of_three +// Rationale: If a class deals with ownership, it should do nothing more and explicitly +// define the behavior of all special member functions. +// This macro is sprinkled into lots of big classes and ignores the move-related SMF's. +// So its common use violates both principles and thus it should not be used anymore! #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName&) = delete; \ void operator=(const TypeName&) = delete; From 0f69157931f2ba23caf85bf5463029e3a7295d45 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Wed, 9 Oct 2024 12:11:44 +0200 Subject: [PATCH 19/20] fixup! refactor: cleanup SemanticVersion --- src/util/semanticversion.h | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/util/semanticversion.h b/src/util/semanticversion.h index b7eb1ae3a2e..c8a9a9f276e 100644 --- a/src/util/semanticversion.h +++ b/src/util/semanticversion.h @@ -1,6 +1,7 @@ #pragma once #include +#include class QString; @@ -26,6 +27,9 @@ class SemanticVersion { friend constexpr std::strong_ordering operator<=>( const SemanticVersion&, const SemanticVersion&) noexcept; + friend constexpr bool operator==( + const SemanticVersion&, const SemanticVersion&) noexcept; + // Do not change the order because the synthesized comparison operators // depend on it! unsigned int majorVersion; @@ -36,9 +40,21 @@ class SemanticVersion { // you should not be able to create an invalid version easily from the outside constexpr SemanticVersion() : SemanticVersion(0, 0, 0){}; + // make tuple, which is used for the implementation of the comparison operators + constexpr std::tuple makeTuple() const { + return std::tie(majorVersion, minorVersion, patchVersion); + } }; +// TODO: replace with = default (synthesized) implementations once widely +// supported on target compilers. constexpr std::strong_ordering operator<=>( - const SemanticVersion&, const SemanticVersion&) noexcept = default; - + const SemanticVersion& lhs, const SemanticVersion& rhs) noexcept { + return lhs.makeTuple() <=> rhs.makeTuple(); +} + +constexpr bool operator==( + const SemanticVersion& lhs, const SemanticVersion& rhs) noexcept { + return lhs.makeTuple() == rhs.makeTuple(); +} } // namespace mixxx From c03c588afe471a73f1681119bdf066a33dbe63bc Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Wed, 9 Oct 2024 12:22:58 +0200 Subject: [PATCH 20/20] fixup! refactor: remove unused and unmaintained ThreadCpuTimer --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 66721940f74..c408073eeb1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1470,7 +1470,6 @@ set(MIXXX_LIB_PRECOMPILED_HEADER src/util/taskmonitor.h src/util/thread_affinity.h src/util/thread_annotations.h - src/util/threadcputimer.h src/util/time.h src/util/timer.h src/util/trace.h