diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 759d7c7..40d296d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,6 +37,11 @@ jobs: - name: Build run: cmake --build build --config Release --parallel + - name: Test + run: ctest --test-dir build --output-on-failure + env: + QT_QPA_PLATFORM: offscreen + - name: Upload artifact uses: actions/upload-artifact@v4 with: @@ -82,6 +87,13 @@ jobs: - name: Build run: cmake --build build --parallel + - name: Test + run: | + $env:PATH = "C:\Qt\6.11.0\msvc2022_64\bin;$env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\bin;$env:PATH" + ctest --test-dir build --output-on-failure + env: + QT_QPA_PLATFORM: offscreen + - name: Deploy Qt run: | mkdir build\deploy @@ -117,6 +129,11 @@ jobs: - name: Build run: cmake --build build --config Release --parallel + - name: Test + run: ctest --test-dir build --output-on-failure + env: + QT_QPA_PLATFORM: offscreen + - name: Deploy, sign, & package run: | /opt/homebrew/opt/qt@6/bin/macdeployqt build/OpenMix.app diff --git a/CMakeLists.txt b/CMakeLists.txt index e65c85d..e278832 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,7 +38,7 @@ include(FetchContent) FetchContent_Declare( qlementine-icons GIT_REPOSITORY "https://github.com/oclero/qlementine-icons.git" - GIT_TAG "master" + GIT_TAG "e2ad8c109d245f11b3fcb2c39f8b26aeee87ff50" ) FetchContent_MakeAvailable(qlementine-icons) diff --git a/src/core/PlaybackEngine.cpp b/src/core/PlaybackEngine.cpp index da66f80..4091090 100644 --- a/src/core/PlaybackEngine.cpp +++ b/src/core/PlaybackEngine.cpp @@ -425,47 +425,31 @@ void PlaybackEngine::executeMacroCue(const Cue& cue) { } void PlaybackEngine::executeNextMacroChild() { - if (m_currentMacroId.isEmpty() || m_macroPendingChildren.isEmpty() || !m_cueList) { - if (!m_currentMacroId.isEmpty()) { - const Cue* macroCue = m_cueList->findById(m_currentMacroId); - - m_currentMacroId.clear(); - m_macroPendingChildren.clear(); - m_macroChildIndex = 0; - - emit cueCompleted(m_currentIndex); - - if (macroCue) { - handleAutoFollow(*macroCue); - } - } + if (m_currentMacroId.isEmpty() || !m_cueList) { + m_currentMacroId.clear(); + m_macroPendingChildren.clear(); + m_macroChildIndex = 0; return; } - QString childId = m_macroPendingChildren.takeFirst(); - const Cue* childCue = m_cueList->findById(childId); - if (childCue) { + while (!m_macroPendingChildren.isEmpty()) { + QString childId = m_macroPendingChildren.takeFirst(); + const Cue* childCue = m_cueList->findById(childId); + if (!childCue) + continue; executeCueInternal(*childCue); emit macroChildExecuted(m_currentMacroId, childId); m_macroChildIndex++; + } - if (!m_macroPendingChildren.isEmpty()) { - executeNextMacroChild(); - } else { - const Cue* macroCue = m_cueList->findById(m_currentMacroId); - - m_currentMacroId.clear(); - m_macroPendingChildren.clear(); - m_macroChildIndex = 0; + const Cue* macroCue = m_cueList->findById(m_currentMacroId); + m_currentMacroId.clear(); + m_macroPendingChildren.clear(); + m_macroChildIndex = 0; - emit cueCompleted(m_currentIndex); - if (macroCue) { - handleAutoFollow(*macroCue); - } - } - } else { - executeNextMacroChild(); - } + emit cueCompleted(m_currentIndex); + if (macroCue) + handleAutoFollow(*macroCue); } void PlaybackEngine::executeGoToCue(const Cue& cue) { diff --git a/src/core/UndoCommands.cpp b/src/core/UndoCommands.cpp index 0411d8a..2d35bce 100644 --- a/src/core/UndoCommands.cpp +++ b/src/core/UndoCommands.cpp @@ -82,7 +82,7 @@ RemoveCueCommand::RemoveCueCommand(CueList* cueList, int index, QUndoCommand* pa } void RemoveCueCommand::undo() { - if (m_cueList) { + if (m_cueList && m_index >= 0 && m_index <= m_cueList->count()) { m_cueList->insertCue(m_index, m_cue); } } diff --git a/src/protocol/allenheath/AllenHeathTcpProtocol.cpp b/src/protocol/allenheath/AllenHeathTcpProtocol.cpp index e96bb38..8e8c875 100644 --- a/src/protocol/allenheath/AllenHeathTcpProtocol.cpp +++ b/src/protocol/allenheath/AllenHeathTcpProtocol.cpp @@ -72,7 +72,10 @@ void AllenHeathTcpProtocol::sendParameter(const QString& path, const QVariant& v if (path.startsWith("/dca/")) { QStringList parts = path.split('/'); if (parts.size() >= 4) { - int dca = parts[2].toInt(); + bool ok; + int dca = parts[2].toInt(&ok); + if (!ok || dca < 1) + return; QString param = parts[3]; if (param == "fader") { @@ -132,6 +135,9 @@ void AllenHeathTcpProtocol::refresh() { } QByteArray AllenHeathTcpProtocol::buildDCAFaderMessage(int dca, float level) { + if (dca < 1) + return {}; + QByteArray msg; // ACE Protocol frame: [Length(2)] [Type(1)] [Payload...] @@ -155,6 +161,9 @@ QByteArray AllenHeathTcpProtocol::buildDCAFaderMessage(int dca, float level) { // buildDCAMuteMessage QByteArray AllenHeathTcpProtocol::buildDCAMuteMessage(int dca, bool muted) { + if (dca < 1) + return {}; + QByteArray msg; // DCA mute: Type 0x10, Payload: [DCA index(1)] [0x80 flag for mute] [Mute state(1)]