core/playlists/system: Move the unplayed tracks playlist into system.c

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2016-04-26 08:20:27 -04:00 committed by Anna Schumaker
parent 1527ee0e6d
commit 5ab2e63734
6 changed files with 152 additions and 29 deletions

View File

@ -5,6 +5,7 @@
#include <core/collection.h>
#include <core/history.h>
#include <core/idle.h>
#include <core/playlist.h>
#include <core/tempq.h>
static struct file audio_file = FILE_INIT("cur_track", 0, 0);
@ -214,8 +215,10 @@ struct track *audio_prev()
struct track *audio_eos()
{
/* Mark current track as played */
if (audio_track)
if (audio_track) {
track_played(audio_track);
playlist_update(PL_UNPLAYED);
}
/* Check pause count and pick the next track */
if (audio_pause_count >= 0) {

View File

@ -54,8 +54,10 @@ static void __scan_path(struct scan_data *scan, const gchar *name)
__scan_dir_later(scan->sd_lib, path);
else {
track = track_add(scan->sd_lib, path);
if (track)
if (track) {
queue_add(&c_queue, track);
playlist_add(PL_UNPLAYED, track);
}
}
g_free(path);
@ -108,6 +110,7 @@ static bool __validate_library(void *data)
if (collection_check_library(library) < 0)
return true;
queue_remove_all(&c_queue, track);
playlist_remove(PL_UNPLAYED, track);
track_remove(track);
}
}

View File

@ -7,8 +7,18 @@
static struct file sys_file = FILE_INIT("playlist.db", 0, 0);
static struct queue sys_playlists[SYS_PL_NUM_PLAYLISTS];
static struct queue *pl_system_get_queue(const gchar *);
static bool __sys_pl_remove(enum sys_playlist_t, struct track *);
static enum sys_playlist_t __sys_pl_convert(const gchar *name)
{
if (string_match(name, "Favorites"))
return SYS_PL_FAVORITES;
else if (string_match(name, "Hidden") || string_match(name, "Banned"))
return SYS_PL_HIDDEN;
else if (string_match(name, "Unplayed"))
return SYS_PL_UNPLAYED;
return SYS_PL_NUM_PLAYLISTS;
}
static void __sys_pl_save()
{
@ -26,7 +36,7 @@ static void __sys_pl_save()
static bool __sys_pl_load()
{
struct queue *queue;
enum sys_playlist_t plist;
unsigned int i, n;
gchar *name;
@ -37,8 +47,8 @@ static bool __sys_pl_load()
for (i = 0; i < n; i++) {
file_readf(&sys_file, "%*u %m[^\n]\n", &name);
queue = pl_system_get_queue(name);
queue_load_tracks(queue, &sys_file);
plist = __sys_pl_convert(name);
queue_load_tracks(&sys_playlists[plist], &sys_file);
g_free(name);
}
@ -46,42 +56,99 @@ static bool __sys_pl_load()
return true;
}
static bool __sys_pl_can_add(enum sys_playlist_t plist, struct track *track)
{
if (track->tr_count == 0)
return plist == SYS_PL_UNPLAYED;
return false;
}
static bool __sys_pl_add(enum sys_playlist_t plist, struct track *track)
{
if (plist != SYS_PL_FAVORITES && plist != SYS_PL_HIDDEN) {
if (!__sys_pl_can_add(plist, track))
return false;
if (queue_has(&sys_playlists[SYS_PL_HIDDEN], track))
return false;
}
if (queue_has(&sys_playlists[plist], track))
return false;
queue_add(&sys_playlists[plist], track);
switch (plist) {
case SYS_PL_HIDDEN:
__sys_pl_remove(SYS_PL_UNPLAYED, track);
case SYS_PL_FAVORITES:
__sys_pl_save();
default:
break;
}
return true;
}
static bool __sys_pl_remove(enum sys_playlist_t plist, struct track *track)
{
if (!queue_remove_all(&sys_playlists[plist], track))
return false;
switch (plist) {
case SYS_PL_HIDDEN:
__sys_pl_add(SYS_PL_UNPLAYED, track);
case SYS_PL_FAVORITES:
__sys_pl_save();
default:
break;
}
return true;
}
static bool __sys_pl_update(enum sys_playlist_t plist)
{
struct db_entry *dbe, *next;
db_for_each(dbe, next, track_db_get()) {
if (TRACK(dbe)->tr_count == 0)
__sys_pl_add(SYS_PL_UNPLAYED, TRACK(dbe));
else
__sys_pl_remove(SYS_PL_UNPLAYED, TRACK(dbe));
}
queue_unset_flag(&sys_playlists[plist], Q_ADD_FRONT);
return true;
}
static struct queue *pl_system_get_queue(const gchar *name)
{
if (string_match(name, "Favorites"))
return &sys_playlists[SYS_PL_FAVORITES];
else if (string_match(name, "Hidden") || string_match(name, "Banned"))
return &sys_playlists[SYS_PL_HIDDEN];
return NULL;
enum sys_playlist_t plist = __sys_pl_convert(name);
if (plist == SYS_PL_NUM_PLAYLISTS)
return NULL;
return &sys_playlists[plist];
}
static bool pl_system_add_track(const gchar *name, struct track *track)
{
struct queue *queue = pl_system_get_queue(name);
if (!queue)
enum sys_playlist_t plist = __sys_pl_convert(name);
if (plist == SYS_PL_NUM_PLAYLISTS)
return false;
if (queue_has(queue, track))
return false;
queue_add(queue, track);
__sys_pl_save();
return true;
return __sys_pl_add(plist, track);
}
static bool pl_system_remove_track(const gchar *name, struct track *track)
{
struct queue *queue = pl_system_get_queue(name);
if (!queue)
enum sys_playlist_t plist = __sys_pl_convert(name);
if (plist == SYS_PL_NUM_PLAYLISTS)
return false;
if (!queue_remove_all(queue, track))
return false;
__sys_pl_save();
return true;
return __sys_pl_remove(plist, track);
}
static void pl_system_update(const gchar *name)
{
return;
enum sys_playlist_t plist = __sys_pl_convert(name);
if (plist != SYS_PL_FAVORITES && plist != SYS_PL_HIDDEN)
idle_schedule(IDLE_SYNC, IDLE_FUNC(__sys_pl_update),
GUINT_TO_POINTER(plist));
}
@ -102,9 +169,12 @@ void pl_system_init(struct queue_ops *ops)
queue_sort(&sys_playlists[i], COMPARE_ARTIST, true);
queue_sort(&sys_playlists[i], COMPARE_YEAR, false);
queue_sort(&sys_playlists[i], COMPARE_TRACK, false);
if (i >= SYS_PL_UNPLAYED)
queue_set_flag(&sys_playlists[i], Q_ADD_FRONT);
}
idle_schedule(IDLE_SYNC, __sys_pl_load, NULL);
idle_schedule(IDLE_SYNC, __sys_pl_load, NULL);
pl_system_update("Unplayed");
}
void pl_system_deinit()

View File

@ -9,6 +9,7 @@
enum sys_playlist_t {
SYS_PL_FAVORITES, /* Songs that the user likes. */
SYS_PL_HIDDEN, /* Songs that the user has hidden. */
SYS_PL_UNPLAYED, /* Songs that have not been played yet. */
SYS_PL_NUM_PLAYLISTS, /* Number of system playlists. */
};

View File

@ -115,10 +115,10 @@ static void test_remove()
static void test_dynamic()
{
struct queue *q = playlist_get_queue(PL_UNPLAYED);
struct db_entry *dbe, *next;
unsigned int i, average = 0;
struct track *track;
struct queue *q;
/* Set play count to (track_number - 1) (average = 6) */
db_for_each(dbe, next, track_db_get()) {
@ -127,16 +127,19 @@ static void test_dynamic()
average += TRACK(dbe)->tr_count;
}
average /= track_db_get()->db_size;
playlist_update(PL_UNPLAYED);
/* Only one unplayed track (tr_track == 1) */
playlist_select(PL_UNPLAYED);
q = playlist_get_queue(PL_UNPLAYED);
test_equal(playlist_add(PL_UNPLAYED, track_get(1)), (bool)false);
test_equal(playlist_remove(PL_UNPLAYED, queue_at(q, 0)), (bool)false);
test_equal(playlist_remove(PL_UNPLAYED, queue_at(q, 0)), (bool)true);
test_equal(playlist_add(PL_UNPLAYED, track_get(0)), (bool)true);
test_equal(queue_size(q), 1);
test_equal(queue_at(q, 0)->tr_track, 1);
test_equal(queue_at(q, 0)->tr_count, 0);
/* Six tracks have tr_count <= average && tr_count > 0 */
q = playlist_get_queue(PL_LEAST_PLAYED);
playlist_select(PL_LEAST_PLAYED);
test_equal(playlist_add(PL_LEAST_PLAYED, track_get(0)), (bool)false);
test_equal(queue_size(q), 6);
@ -149,6 +152,7 @@ static void test_dynamic()
} test_loop_passed();
/* Six tracks have tr_count > average */
q = playlist_get_queue(PL_MOST_PLAYED);
playlist_select(PL_MOST_PLAYED);
test_equal(playlist_add(PL_MOST_PLAYED, track_get(0)), (bool)false);
test_equal(queue_size(q), 6);

View File

@ -32,6 +32,14 @@
while (idle_run_task()) {}; \
__test_playlist_state(queue, ex_size, ex_track0, ex_track1)
#define __test_playlist_hide_track(name, queue, ex_size, ex_track0, ex_track1) \
test_equal(pl_system.pl_add_track("Hidden", track_get(0)), (bool)true); \
__test_playlist_state(queue, ex_size, ex_track0, ex_track1); \
test_equal(pl_system.pl_add_track(name, track_get(0)), (bool)false)
#define __test_playlist_unhide_track(name, queue, ex_size, ex_track0, ex_track1) \
test_equal(pl_system.pl_remove_track("Hidden", track_get(0)), (bool)true); \
__test_playlist_state(queue, ex_size, ex_track0, ex_track1)
#define __test_playlist_reinit(queue, ex_size, ex_track0, ex_track1) \
pl_system_deinit(); \
@ -73,6 +81,7 @@ static void test_favorites()
struct queue *queue = pl_system.pl_get_queue("Favorites");
test_not_equal((void *)queue, NULL);
test_equal(queue_has_flag(queue, Q_ADD_FRONT), (bool)false);
__test_playlist_add("Favorites", queue);
__test_playlist_reinit(queue, 2, true, true);
@ -86,11 +95,43 @@ static void test_hidden()
test_not_equal((void *)queue, NULL);
test_equal((void *)pl_system.pl_get_queue("Banned"), (void *)queue);
test_equal(queue_has_flag(queue, Q_ADD_FRONT), (bool)false);
__test_playlist_add("Hidden", queue);
__test_playlist_reinit(queue, 2, true, true);
__test_playlist_update("Hidden", queue, 2, true, true);
__test_playlist_remove("Hidden", queue);
}
static void test_unplayed()
{
struct queue *queue = pl_system.pl_get_queue("Unplayed");
pl_system_deinit();
pl_system_init(NULL);
test_not_equal((void *)queue, NULL);
test_equal(queue_has_flag(queue, Q_ADD_FRONT), (bool)true);
__test_playlist_reinit(queue, 2, true, true);
__test_playlist_remove("Unplayed", queue);
track_get(1)->tr_count = 1;
test_equal(pl_system.pl_add_track("Unplayed", track_get(0)), (bool)true);
test_equal(pl_system.pl_add_track("Unplayed", track_get(0)), (bool)false);
test_equal(queue_size(queue), 1);
track_get(0)->tr_count = 1;
track_get(1)->tr_count = 0;
__test_playlist_update("Unplayed", queue, 1, false, true);
track_get(0)->tr_count = 0;
__test_playlist_update("Unplayed", queue, 2, true, true);
__test_playlist_hide_track("Unplayed", queue, 1, false, true);
__test_playlist_reinit(queue, 1, false, true);
__test_playlist_update("Unplayed", queue, 1, false, true);
__test_playlist_unhide_track("Unplayed", queue, 2, true, true);
pl_system_deinit();
}
@ -99,4 +140,5 @@ DECLARE_UNIT_TESTS(
UNIT_TEST("Invalid Playlist", test_invalid),
UNIT_TEST("Favorites Playlist", test_favorites),
UNIT_TEST("Hidden Playlist", test_hidden),
UNIT_TEST("Unplayed Tracks Playlist", test_unplayed),
);