The batch deletion did not take into account the possibility that
some or all of the playlist may still need to be loaded afterwards
(this happens when there are tracks at the end of the target playlist
which are not in the current play queue).
This resulted in erroneous operation. Fix that up.
And separate the batch loading into a separate routine to hopefully
clarify what the various track indices are so future me understands.
-# Copyright © 2019-2020 Nick Bowler
+# Copyright © 2019-2021 Nick Bowler
#
# Replace the current MPD play queue with a saved playlist, by rearranging
# existing queue entries when possible. This avoids losing the current
#
# Replace the current MPD play queue with a saved playlist, by rearranging
# existing queue entries when possible. This avoids losing the current
my $num_added = 0;
my $add_start;
my $num_added = 0;
my $add_start;
+sub load_tracks($) {
+ my ($seq) = @_;
+
+ my $start = $add_start // $seq;
+ my $end = $seq+1;
+
+ my $add_position = $end_position;
+ MPD::exec("load", $ARGV[0], "$start:$end");
+ $end_position += $end - $start;
+ MPD::exec("move", "$add_position:$end_position", "$start")
+ if ($add_position != $start);
+
+ undef $add_start;
+}
+
MPD::exec("command_list_begin");
for (my $i = 0; $i < @$target; $i++) {
my $f = $target->[$i];
my $id = shift @{ $current->{$f} };
MPD::exec("command_list_begin");
for (my $i = 0; $i < @$target; $i++) {
my $f = $target->[$i];
my $id = shift @{ $current->{$f} };
- if (defined $id and defined $add_start) {
- my $add_position = $end_position;
-
- MPD::exec("load", $ARGV[0], "$add_start:$i");
- $end_position += $i - $add_start;
- MPD::exec("move", "$add_position:$end_position", "$add_start");
-
- undef $add_start;
- }
+ load_tracks($i - 1) if (defined $id and defined $add_start);
if (defined $id) {
# Try not to move tracks already in the right place.
if (defined $id) {
# Try not to move tracks already in the right place.
# Now all unwanted tracks from the original playqueue have been moved to the
# end and can be deleted all at once.
# Now all unwanted tracks from the original playqueue have been moved to the
# end and can be deleted all at once.
-my $rem = ($add_start // @$target) - @$target;
-MPD::exec("delete", @$target - $rem . ":") if map { @$_ } values %$current;
+
+my $pos = $add_start // @$target;
+MPD::exec("delete", $pos . ":") if map { @$_ } values %$current;
MPD::exec("load", $ARGV[0], "$add_start:") if defined $add_start;
MPD::run("command_list_end");
MPD::exec("load", $ARGV[0], "$add_start:") if defined $add_start;
MPD::run("command_list_end");