diff --git a/libtransmission/torrent-queue.cc b/libtransmission/torrent-queue.cc index a3d7c28e1..3acce27c7 100644 --- a/libtransmission/torrent-queue.cc +++ b/libtransmission/torrent-queue.cc @@ -63,35 +63,42 @@ size_t tr_torrent_queue::get_pos(tr_torrent_id_t const id) return pos_cache_[uid]; } -bool tr_torrent_queue::set_pos(tr_torrent_id_t const id, size_t new_pos) +// returns the list of torrent IDs whose queue position changed +std::vector tr_torrent_queue::set_pos(tr_torrent_id_t const id, size_t new_pos) { auto const old_pos = get_pos(id); auto const n_queue = std::size(queue_); if (old_pos >= n_queue || queue_[old_pos] != id) { - return false; + return {}; } new_pos = std::min(new_pos, n_queue - 1U); if (old_pos == new_pos) { - return false; + return {}; } + auto ret = std::vector{}; + auto const begin = std::begin(queue_); auto const old_it = std::next(begin, old_pos); - auto const next_it = std::next(old_it); + auto const old_next_it = std::next(old_it); auto const new_it = std::next(begin, new_pos); if (old_pos > new_pos) { - std::rotate(new_it, old_it, next_it); + ret.assign(new_it, old_next_it); + std::rotate(new_it, old_it, old_next_it); } else { - std::rotate(old_it, next_it, std::next(new_it)); + auto const new_next_it = std::next(new_it); + ret.assign(old_it, new_next_it); + std::rotate(old_it, old_next_it, new_next_it); } - return true; + + return ret; } bool tr_torrent_queue::to_file() const diff --git a/libtransmission/torrent-queue.h b/libtransmission/torrent-queue.h index e622395ce..3086c7eb5 100644 --- a/libtransmission/torrent-queue.h +++ b/libtransmission/torrent-queue.h @@ -41,7 +41,7 @@ public: void remove(tr_torrent_id_t id); [[nodiscard]] size_t get_pos(tr_torrent_id_t id); - bool set_pos(tr_torrent_id_t id, size_t new_pos); + [[nodiscard]] std::vector set_pos(tr_torrent_id_t id, size_t new_pos); bool to_file() const; // NOLINT(modernize-use-nodiscard) [[nodiscard]] std::vector from_file(); diff --git a/libtransmission/torrent.h b/libtransmission/torrent.h index f5f72a4c7..fc63ff91d 100644 --- a/libtransmission/torrent.h +++ b/libtransmission/torrent.h @@ -991,14 +991,15 @@ struct tr_torrent return session->torrent_queue().get_pos(id()); } - bool set_queue_position(size_t new_pos) // NOLINT(readability-make-member-function-const) + void set_queue_position(size_t const new_pos) // NOLINT(readability-make-member-function-const) { - if (!session->torrent_queue().set_pos(id(), new_pos)) + for (auto const& changed_id : session->torrent_queue().set_pos(id(), new_pos)) { - return false; + if (auto* const tor = session->torrents().get(changed_id)) + { + tor->mark_changed(); + } } - mark_changed(); - return true; } static constexpr struct diff --git a/tests/libtransmission/torrent-queue-test.cc b/tests/libtransmission/torrent-queue-test.cc index ffb00edb2..0d84816e4 100644 --- a/tests/libtransmission/torrent-queue-test.cc +++ b/tests/libtransmission/torrent-queue-test.cc @@ -92,6 +92,17 @@ TEST_F(TorrentQueueTest, addRemoveToFromQueue) TEST_F(TorrentQueueTest, setQueuePos) { static auto constexpr QueuePos = std::array{ 1U, 3U, 0U, 2U }; + static auto const ExpectedChangedIds = std::array, std::size(QueuePos)>{ { + // Queue order: 1, 2, 3, 4 + { 1, 2 }, + // Queue order: 2, 1, 3, 4 + { 1, 2, 3, 4 }, + // Queue order: 1, 3, 4, 2 + { 1, 3 }, + // Queue order: 3, 1, 4, 2 + {}, + // Queue order: 3, 1, 4, 2 + } }; auto queue = tr_torrent_queue{ mediator_ }; @@ -117,8 +128,11 @@ TEST_F(TorrentQueueTest, setQueuePos) { auto const id = owned[i]->id(); auto const pos = QueuePos[i]; - queue.set_pos(id, pos); + auto changed_ids = queue.set_pos(id, pos); + std::ranges::sort(changed_ids); EXPECT_EQ(queue.get_pos(id), pos); + EXPECT_EQ(changed_ids, ExpectedChangedIds[i]); + EXPECT_EQ(std::ranges::adjacent_find(changed_ids), std::ranges::end(changed_ids)); // check if unique } for (size_t i = 0; i < std::size(owned); ++i)