summaryrefslogtreecommitdiffstats
path: root/player/loadfile.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-12-28 21:12:02 +0100
committerwm4 <wm4@nowhere>2019-12-28 21:32:15 +0100
commit582f3f7cc01f81345df5c20a012b1f47587e6a97 (patch)
tree03ddce6c9cc0e5aa48135b5af45a57ec37150355 /player/loadfile.c
parent4564a22d13b693efed847ba77361ea4e2448a7bf (diff)
downloadmpv-582f3f7cc01f81345df5c20a012b1f47587e6a97.tar.bz2
mpv-582f3f7cc01f81345df5c20a012b1f47587e6a97.tar.xz
playlist: change from linked list to an array
Although a linked list was ideal at first, there are cases where it sucks, and became increasingly awkward (with the mpv command API preferring integer indexes to access the list). In future, we probably want to add more playlist-related functionality, so better change it to an array now. An array isn't always ideal either. Since playlist entries are still separate objects (because in some cases you need a stable "iterator" to it), but you still need to efficiently get the next/previous playlist entry, there's a pl_index field, that needs to be maintained. E.g. adding an entry at the start of the playlist => update the pl_index field for all other entries. Well, it's not really worth to do something more complicated to avoid these things. This commit is probably buggy as shit. It's not like I bothered to test everything. That's _your_ role.
Diffstat (limited to 'player/loadfile.c')
-rw-r--r--player/loadfile.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/player/loadfile.c b/player/loadfile.c
index 462355f60e..f9dac4684d 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -905,14 +905,14 @@ void prepare_playlist(struct MPContext *mpctx, struct playlist *pl)
pl->current = mp_check_playlist_resume(mpctx, pl);
if (!pl->current)
- pl->current = pl->first;
+ pl->current = playlist_get_first(pl);
}
// Replace the current playlist entry with playlist contents. Moves the entries
// from the given playlist pl, so the entries don't actually need to be copied.
static void transfer_playlist(struct MPContext *mpctx, struct playlist *pl)
{
- if (pl->first) {
+ if (pl->num_entries) {
prepare_playlist(mpctx, pl);
struct playlist_entry *new = pl->current;
if (mpctx->playlist->current)
@@ -1441,8 +1441,7 @@ static void play_current_file(struct MPContext *mpctx)
handle_force_window(mpctx, false);
- if (mpctx->playlist->first != mpctx->playing ||
- mpctx->playlist->last != mpctx->playing ||
+ if (mpctx->playlist->num_entries > 1 ||
mpctx->playing->num_redirects)
MP_INFO(mpctx, "Playing: %s\n", mpctx->filename);
@@ -1720,34 +1719,33 @@ struct playlist_entry *mp_next_file(struct MPContext *mpctx, int direction,
if (next && direction < 0 && !force) {
// Don't jump to files that would immediately go to next file anyway
while (next && next->playback_short)
- next = next->prev;
+ next = playlist_entry_get_rel(next, -1);
// Always allow jumping to first file
if (!next && mpctx->opts->loop_times == 1)
- next = mpctx->playlist->first;
+ next = playlist_get_first(mpctx->playlist);
}
if (!next && mpctx->opts->loop_times != 1) {
if (direction > 0) {
if (mpctx->opts->shuffle)
playlist_shuffle(mpctx->playlist);
- next = mpctx->playlist->first;
+ next = playlist_get_first(mpctx->playlist);
if (next && mpctx->opts->loop_times > 1) {
mpctx->opts->loop_times--;
m_config_notify_change_opt_ptr(mpctx->mconfig,
&mpctx->opts->loop_times);
}
} else {
- next = mpctx->playlist->last;
+ next = playlist_get_last(mpctx->playlist);
// Don't jump to files that would immediately go to next file anyway
while (next && next->playback_short)
- next = next->prev;
+ next = playlist_entry_get_rel(next, -1);
}
bool ignore_failures = mpctx->opts->loop_times == -2;
if (!force && next && next->init_failed && !ignore_failures) {
// Don't endless loop if no file in playlist is playable
bool all_failed = true;
- struct playlist_entry *cur;
- for (cur = mpctx->playlist->first; cur; cur = cur->next) {
- all_failed &= cur->init_failed;
+ for (int n = 0; n < mpctx->playlist->num_entries; n++) {
+ all_failed &= mpctx->playlist->entries[n]->init_failed;
if (!all_failed)
break;
}