core/playlist: Add playlist_generic_load() function

This function uses the playlist save flags enum to determine what
exactly to load, including support for backwards compatibility with
6.4.x playlists.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2016-09-16 11:12:41 -04:00
parent a87373f335
commit 37d95656e9
10 changed files with 138 additions and 85 deletions

View File

@ -71,13 +71,10 @@ static bool __artist_pl_load(void *data)
for (i = 0; i < n; i++) {
name = file_readl(&artist_file);
playlist = __artist_pl_lookup(name);
if (playlist)
playlist_generic_load(playlist, &artist_file,
PL_SAVE_METADATA);
g_free(name);
if (!playlist)
continue;
queue_load_flags(&playlist->pl_queue, &artist_file, true);
queue_iter_set(&playlist->pl_queue, &playlist->pl_queue.q_cur,
playlist->pl_queue.q_cur.it_pos);
}
file_close(&artist_file);

View File

@ -22,6 +22,50 @@ void playlist_generic_init(struct playlist *playlist, unsigned int flags,
playlist->pl_private = NULL;
}
void playlist_generic_load(struct playlist *playlist, struct file *file,
unsigned int flags)
{
unsigned int f, n, i, t, it = 0;
int field, ascending;
GSList *sort = NULL;
gchar *line;
if (!playlist)
return;
if (flags & PL_SAVE_ITER)
file_readf(file, "%u", &it);
if (flags & PL_SAVE_FLAGS) {
file_readf(file, "%u %u", &f, &n);
for (i = 0; i < n; i++) {
file_readf(file, "%u %d", &field, &ascending);
field += 1;
if (!ascending)
field = -field;
sort = g_slist_append(sort, GINT_TO_POINTER(field));
}
playlist->pl_queue.q_sort = sort;
queue_resort(&playlist->pl_queue);
if (file_readf(file, "%m\n", &line))
g_free(line);
}
if (flags & PL_SAVE_TRACKS) {
file_readf(file, "%u ", &n);
for (i = 0; i < n; i++) {
file_readf(file, "%u", &t);
queue_add(&playlist->pl_queue, track_get(t));
}
if (file_readf(file, "%m\n", &line))
g_free(line);
}
playlist->pl_queue.q_flags |= (f & Q_VALID_FLAGS);
queue_iter_set(&playlist->pl_queue, &playlist->pl_queue.q_cur, it);
}
bool playlist_generic_can_select(struct playlist *playlist)
{
return queue_size(&playlist->pl_queue) > 0;

View File

@ -75,13 +75,10 @@ static bool __lib_pl_load(void *data)
for (i = 0; i < n; i++) {
name = file_readl(&lib_file);
playlist = __lib_pl_lookup(name);
if (playlist)
playlist_generic_load(playlist, &lib_file,
PL_SAVE_METADATA);
g_free(name);
if (!playlist)
continue;
queue_load_flags(&playlist->pl_queue, &lib_file, true);
queue_iter_set(&playlist->pl_queue, &playlist->pl_queue.q_cur,
playlist->pl_queue.q_cur.it_pos);
}
file_close(&lib_file);

View File

@ -154,7 +154,8 @@ static bool sys_pl_queued_load()
flags &= Q_VALID_FLAGS;
if (i == 0)
queue->q_flags |= flags;
queue_load_tracks(queue, &sys_deck_f);
playlist_generic_load(pl_system_get(SYS_PL_QUEUED),
&sys_deck_f, PL_SAVE_TRACKS);
}
file_close(&sys_deck_f);
@ -191,7 +192,7 @@ static bool sys_pl_collection_load()
struct playlist *playlist = pl_system_get(SYS_PL_COLLECTION);
if (file_open(&sys_collection_f, OPEN_READ)) {
queue_load_flags(&playlist->pl_queue, &sys_collection_f, false);
playlist_generic_load(playlist, &sys_collection_f, PL_SAVE_FLAGS);
file_close(&sys_collection_f);
file_remove(&sys_collection_f);
}
@ -275,7 +276,7 @@ static bool __sys_pl_load()
g_free(name);
if (playlist)
queue_load_tracks(&playlist->pl_queue, &sys_file);
playlist_generic_load(playlist, &sys_file, PL_SAVE_TRACKS);
}
file_close(&sys_file);
@ -286,7 +287,7 @@ static bool __sys_pl_load()
static bool __sys_pl_load_new()
{
struct playlist *playlist;
unsigned int i, n;
unsigned int i, n, load;
gchar *name;
if (!file_open(&sys_pl_file, OPEN_READ)) {
@ -299,19 +300,25 @@ static bool __sys_pl_load_new()
file_readf(&sys_pl_file, "%u\n", &n);
for (i = 0; i < n; i++) {
name = file_readl(&sys_pl_file);
load = PL_SAVE_METADATA;
name = file_readl(&sys_pl_file);
if (string_match(name, "Banned")) {
g_free(name);
name = g_strdup("Hidden");
}
playlist = pl_system_lookup(name);
g_free(name);
queue_load_flags(&playlist->pl_queue, &sys_pl_file, true);
switch (i) {
case SYS_PL_FAVORITES:
case SYS_PL_HIDDEN:
case SYS_PL_QUEUED:
queue_load_tracks(&playlist->pl_queue, &sys_pl_file);
default:
break;
load = PL_SAVE_ALL;
}
playlist_generic_load(playlist, &sys_pl_file, load);
}
file_close(&sys_pl_file);

View File

@ -43,12 +43,7 @@ static struct db_entry *user_db_read(struct file *file, unsigned int index)
gchar *name = file_readl(file);
struct user_playlist *playlist = __user_db_alloc(name, index);
queue_load_flags(&playlist->pl_playlist.pl_queue, file, true);
queue_load_tracks(&playlist->pl_playlist.pl_queue, file);
queue_iter_set(&playlist->pl_playlist.pl_queue,
&playlist->pl_playlist.pl_queue.q_cur,
playlist->pl_playlist.pl_queue.q_cur.it_pos);
playlist_generic_load(&playlist->pl_playlist, file, PL_SAVE_ALL);
return &playlist->pl_dbe;
}

View File

@ -163,47 +163,6 @@ void queue_save_tracks(struct queue *queue, struct file *file)
file_writef(file, "\n");
}
void queue_load_flags(struct queue *queue, struct file *file, bool iter)
{
unsigned int flags, n, i;
int field, ascending;
unsigned int it = 0;
gchar *line;
if (iter)
file_readf(file, "%u", &it);
file_readf(file, "%u %u", &flags, &n);
for (i = 0; i < n; i++) {
file_readf(file, "%u %d", &field, &ascending);
queue_sort(queue, field + 1, (i == 0) ? true : false);
if (ascending == false)
queue_sort(queue, field + 1, false);
}
flags &= Q_VALID_FLAGS;
queue->q_flags |= flags;
queue->q_cur.it_pos = it;
if (file_readf(file, "%m\n", &line))
g_free(line);
}
void queue_load_tracks(struct queue *queue, struct file *file)
{
unsigned int i, n, t;
gchar *line;
file_readf(file, "%u ", &n);
for (i = 0; i < n; i++) {
file_readf(file, "%u", &t);
queue_add(queue, track_get(t));
}
if (file_readf(file, "%m\n", &line))
g_free(line);
}
void queue_set_flag(struct queue *queue, enum queue_flags flag)
{
queue->q_flags |= flag;

View File

@ -5,6 +5,14 @@
#define OCARINA_CORE_PLAYLISTS_GENERIC_H
#include <core/playlists/playlist.h>
enum playlist_save_flags {
PL_SAVE_FLAGS = (1 << 0), /* Save playlist random and sort data. */
PL_SAVE_ITER = (1 << 1), /* Save playlist iterator position. */
PL_SAVE_TRACKS = (1 << 2), /* Save playlist tracks. */
};
#define PL_SAVE_METADATA (PL_SAVE_FLAGS | PL_SAVE_ITER)
#define PL_SAVE_ALL (PL_SAVE_TRACKS | PL_SAVE_METADATA)
struct playlist_callbacks {
};
@ -15,6 +23,9 @@ void playlist_generic_set_callbacks(struct playlist_callbacks *);
/* Generic playlist init function. */
void playlist_generic_init(struct playlist *, unsigned int, struct queue_ops *);
/* Generic playlist load function. */
void playlist_generic_load(struct playlist *, struct file *, unsigned int);
/* Generic playlist can-select function. */
bool playlist_generic_can_select(struct playlist *);

View File

@ -120,12 +120,6 @@ void queue_save_flags(struct queue *, struct file *, bool);
/* Called to save the list of queued tracks. */
void queue_save_tracks(struct queue *, struct file *);
/* Called to load flags, sort order, and (optionally) iterator pos from file. */
void queue_load_flags(struct queue *, struct file *, bool);
/* Called to load queued tracks from file. */
void queue_load_tracks(struct queue *, struct file *);
/* Called to set a queue flag. */
void queue_set_flag(struct queue *, enum queue_flags);

View File

@ -34,6 +34,52 @@ static void test_null()
g_assert_false(playlist_sort(NULL, COMPARE_TRACK, true));
g_assert_false(playlist_sort(NULL, COMPARE_TRACK, false));
playlist_generic_load(NULL, NULL, PL_SAVE_ALL);
}
static void test_save_load()
{
struct playlist p = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test", 0, NULL);
struct playlist q = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test 2", 0, NULL);
struct playlist r = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test", 0, NULL);
struct playlist s = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test 2", 0, NULL);
struct file f = FILE_INIT("test.playlist", 0);
unsigned int i;
for (i = 0; i < 13; i++) {
queue_add(&p.pl_queue, track_get(i));
queue_add(&q.pl_queue, track_get(i));
}
queue_set_flag(&p.pl_queue, Q_RANDOM);
queue_sort(&p.pl_queue, COMPARE_TRACK, true);
p.pl_queue.q_cur.it_pos = 3;
q.pl_queue.q_cur.it_pos = 4;
g_assert_false(file_exists(&f));
g_assert_true( file_open(&f, OPEN_WRITE));
queue_save_flags(&p.pl_queue, &f, true);
queue_save_flags(&q.pl_queue, &f, true);
queue_save_tracks(&q.pl_queue, &f);
file_close(&f);
g_assert_true(file_open(&f, OPEN_READ));
playlist_generic_load(&r, &f, PL_SAVE_METADATA);
playlist_generic_load(&s, &f, PL_SAVE_ALL);
file_close(&f);
g_assert_true(queue_has_flag(&r.pl_queue, Q_RANDOM));
g_assert_cmpuint(r.pl_queue.q_cur.it_pos, ==, 3);
g_assert_cmpuint(g_slist_length(r.pl_queue.q_sort), ==, 1);
g_assert_cmpuint(GPOINTER_TO_UINT(r.pl_queue.q_sort->data),
==, COMPARE_TRACK);
g_assert_cmpuint(g_queue_get_length(&r.pl_queue.q_tracks), ==, 0);
g_assert_false(queue_has_flag(&s.pl_queue, Q_RANDOM));
g_assert_cmpuint(s.pl_queue.q_cur.it_pos, ==, 4);
g_assert(queue_iter_val(&s.pl_queue.q_cur) == queue_at(&q.pl_queue, 4));
g_assert_cmpuint(g_slist_length(s.pl_queue.q_sort), ==, 0);
g_assert_cmpuint(g_queue_get_length(&s.pl_queue.q_tracks), ==, 13);
}
int main(int argc, char **argv)
@ -49,9 +95,23 @@ int main(int argc, char **argv)
library = library_find("tests/Music");
track_add(library, "tests/Music/Hyrule Symphony/01 - Title Theme.ogg");
track_add(library, "tests/Music/Hyrule Symphony/02 - Kokiri Forest.ogg");
track_add(library, "tests/Music/Hyrule Symphony/03 - Hyrule Field.ogg");
track_add(library, "tests/Music/Hyrule Symphony/04 - Hyrule Castle.ogg");
track_add(library, "tests/Music/Hyrule Symphony/05 - Lon Lon Ranch.ogg");
track_add(library, "tests/Music/Hyrule Symphony/06 - Kakariko Village.ogg");
track_add(library, "tests/Music/Hyrule Symphony/07 - Death Mountain.ogg");
track_add(library, "tests/Music/Hyrule Symphony/08 - Zora's Domain.ogg");
track_add(library, "tests/Music/Hyrule Symphony/09 - Gerudo Valley.ogg");
track_add(library, "tests/Music/Hyrule Symphony/10 - Ganondorf.ogg");
track_add(library, "tests/Music/Hyrule Symphony/11 - Princess Zelda.ogg");
track_add(library, "tests/Music/Hyrule Symphony/12 - Ocarina Medley.ogg");
track_add(library,
"tests/Music/Hyrule Symphony/13 - The Legend of Zelda Medley.ogg");
g_test_init(&argc, &argv, NULL);
g_test_add_func("/Core/Playlist/NULL", test_null);
g_test_add_func("/Core/Playlist/Save and Load", test_save_load);
ret = g_test_run();
playlist_deinit();

View File

@ -340,17 +340,6 @@ static void test_save_load()
queue_save_tracks(&q, &f);
file_close(&f);
g_assert_true(file_exists(&f));
g_assert_true(file_open(&f, OPEN_READ));
queue_load_tracks(&r, &f);
file_close(&f);
g_assert_cmpuint(queue_size(&r), ==, 13);
for (i = 0; i < 13; i++)
g_assert_true(queue_has(&r, track_get(i)));
queue_deinit(&q);
queue_deinit(&r);
}
int main(int argc, char **argv)