diff --git a/core/playlists/generic.c b/core/playlists/generic.c index 2cae0cf9..f24f4156 100644 --- a/core/playlists/generic.c +++ b/core/playlists/generic.c @@ -21,6 +21,14 @@ void playlist_noop_sort(struct playlist *playlist, /* * Generic playlist operations. */ +bool playlist_generic_add_track(struct playlist *playlist, struct track *track) +{ + if (queue_has(&playlist->pl_queue, track)) + return false; + queue_add(&playlist->pl_queue, track); + return true; +} + void playlist_generic_set_flag(struct playlist *playlist, enum queue_flags flag, bool enabled) { diff --git a/core/playlists/system.c b/core/playlists/system.c index bc8efd84..47ded1ba 100644 --- a/core/playlists/system.c +++ b/core/playlists/system.c @@ -5,16 +5,63 @@ #include #include +static bool pl_system_add_track(const gchar *, struct track *); +static inline struct queue *__sys_pl_queue(enum sys_playlist_t); static bool __sys_pl_remove(enum sys_playlist_t, struct track *); static void __sys_pl_save_collection(); +static void __sys_pl_save(); static struct file sys_file = FILE_INIT("playlist.db", 0, 0); static struct file sys_collection = FILE_INIT("library.q", 0, 0); +/* + * Generic system playlist operations. + */ +static bool sys_pl_generic_add(struct playlist *playlist, struct track *track) +{ + if (queue_has(__sys_pl_queue(SYS_PL_HIDDEN), track)) + return false; + return playlist_generic_add_track(playlist, track); +} + + +/* + * Favorite tracks playlist operations. + */ +static bool sys_pl_favorites_add(struct playlist *playlist, struct track *track) +{ + bool ret = playlist_generic_add_track(playlist, track); + __sys_pl_save(); + return ret; +} + + +/* + * Hidden tracks playlist operations. + */ +static bool sys_pl_hidden_add(struct playlist *playlist, struct track *track) +{ + bool ret = playlist_generic_add_track(playlist, track); + __sys_pl_remove(SYS_PL_COLLECTION, track); + __sys_pl_remove(SYS_PL_UNPLAYED, track); + __sys_pl_remove(SYS_PL_MOST_PLAYED, track); + __sys_pl_remove(SYS_PL_LEAST_PLAYED, track); + __sys_pl_save(); + return ret; +} + + /* * Collection playlist operations. */ +static bool sys_pl_collection_add(struct playlist *playlist, struct track *track) +{ + if (track->tr_library->li_enabled != true) + return false; + return sys_pl_generic_add(playlist, track); +} + static void sys_pl_collection_set_flag(struct playlist *playlist, enum queue_flags flag, bool enabled) { @@ -30,39 +77,92 @@ static void sys_pl_collection_sort(struct playlist *playlist, } +/* + * History playlist operations. + */ +static bool sys_pl_history_add(struct playlist *playlist, struct track *track) +{ + queue_add(&playlist->pl_queue, track); + queue_iter_set(&playlist->pl_queue, &playlist->pl_queue.q_cur, 0); + return true; +} + + +/* + * Unplayed tracks playlist operations. + */ +static bool sys_pl_unplayed_add(struct playlist *playlist, struct track *track) +{ + if (track->tr_count > 0) + return false; + return sys_pl_generic_add(playlist, track); +} + + +/* + * Most played tracks playlist operations. + */ +static bool sys_pl_most_played_add(struct playlist *playlist, struct track *track) +{ + unsigned int average = track_db_average_plays(); + if (track->tr_count <= average) + return false; + return sys_pl_generic_add(playlist, track); +} + + +/* + * Least played tracks playlist operations. + */ +static bool sys_pl_least_played_add(struct playlist *playlist, struct track *track) +{ + unsigned int average = track_db_average_plays(); + if (!track->tr_count || track->tr_count > average) + return false; + return sys_pl_generic_add(playlist, track); +} + + static struct sys_playlist sys_playlists[SYS_PL_NUM_PLAYLISTS] = { [SYS_PL_FAVORITES] = { .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Favorites"), + .spl_add = sys_pl_favorites_add, .spl_set_flag = playlist_generic_set_flag, .spl_sort = playlist_generic_sort, }, [SYS_PL_HIDDEN] = { .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Hidden"), + .spl_add = sys_pl_hidden_add, .spl_set_flag = playlist_generic_set_flag, .spl_sort = playlist_generic_sort, }, [SYS_PL_COLLECTION] = { .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Collection"), + .spl_add = sys_pl_collection_add, .spl_set_flag = sys_pl_collection_set_flag, .spl_sort = sys_pl_collection_sort, }, [SYS_PL_HISTORY] = { .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "History"), + .spl_add = sys_pl_history_add, .spl_set_flag = playlist_noop_set_flag, .spl_sort = playlist_noop_sort, }, [SYS_PL_UNPLAYED] = { .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Unplayed"), + .spl_add = sys_pl_unplayed_add, .spl_set_flag = playlist_generic_set_flag, .spl_sort = playlist_generic_sort, }, [SYS_PL_MOST_PLAYED] = { .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Most Played"), + .spl_add = sys_pl_most_played_add, .spl_set_flag = playlist_generic_set_flag, .spl_sort = playlist_generic_sort, }, [SYS_PL_LEAST_PLAYED] = { .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Least Played"), + .spl_add = sys_pl_least_played_add, .spl_set_flag = playlist_generic_set_flag, .spl_sort = playlist_generic_sort, }, @@ -176,47 +276,6 @@ static bool __sys_pl_can_add(enum sys_playlist_t plist, struct track *track, return plist == SYS_PL_MOST_PLAYED; } -static bool __sys_pl_add(enum sys_playlist_t plist, struct track *track, - unsigned int average) -{ - if (plist != SYS_PL_FAVORITES && plist != SYS_PL_HIDDEN && - plist != SYS_PL_HISTORY) { - if (!__sys_pl_can_add(plist, track, average)) - return false; - if (queue_has(__sys_pl_queue(SYS_PL_HIDDEN), track)) - return false; - } - - if (plist != SYS_PL_HISTORY && queue_has(__sys_pl_queue(plist), track)) - return false; - queue_add(__sys_pl_queue(plist), track); - - switch (plist) { - case SYS_PL_HIDDEN: - __sys_pl_remove(SYS_PL_COLLECTION, track); - __sys_pl_remove(SYS_PL_UNPLAYED, track); - __sys_pl_remove(SYS_PL_MOST_PLAYED, track); - __sys_pl_remove(SYS_PL_LEAST_PLAYED, track); - case SYS_PL_FAVORITES: - __sys_pl_save(); - break; - case SYS_PL_MOST_PLAYED: - __sys_pl_remove(SYS_PL_UNPLAYED, track); - __sys_pl_remove(SYS_PL_LEAST_PLAYED, track); - break; - case SYS_PL_LEAST_PLAYED: - __sys_pl_remove(SYS_PL_UNPLAYED, track); - __sys_pl_remove(SYS_PL_MOST_PLAYED, track); - break; - case SYS_PL_HISTORY: - queue_iter_set(__sys_pl_queue(plist), - &__sys_pl_queue(plist)->q_cur, 0); - default: - break; - } - return true; -} - static bool __sys_pl_remove(enum sys_playlist_t plist, struct track *track) { if (!queue_remove_all(__sys_pl_queue(plist), track)) @@ -224,10 +283,10 @@ static bool __sys_pl_remove(enum sys_playlist_t plist, struct track *track) switch (plist) { case SYS_PL_HIDDEN: - __sys_pl_add(SYS_PL_COLLECTION, track, track_db_average_plays()); - __sys_pl_add(SYS_PL_UNPLAYED, track, track_db_average_plays()); - __sys_pl_add(SYS_PL_MOST_PLAYED, track, track_db_average_plays()); - __sys_pl_add(SYS_PL_LEAST_PLAYED, track, track_db_average_plays()); + pl_system_add_track("Collection", track); + pl_system_add_track("Unplayed", track); + pl_system_add_track("Most Played", track); + pl_system_add_track("Least Played", track); case SYS_PL_FAVORITES: __sys_pl_save(); default: @@ -238,12 +297,13 @@ static bool __sys_pl_remove(enum sys_playlist_t plist, struct track *track) static bool __sys_pl_update(enum sys_playlist_t plist) { + struct sys_playlist *sys_pl = &sys_playlists[plist]; unsigned int average = track_db_average_plays(); struct db_entry *dbe, *next; db_for_each(dbe, next, track_db_get()) { if (__sys_pl_can_add(plist, TRACK(dbe), average)) - __sys_pl_add(plist, TRACK(dbe), average); + sys_pl->spl_add(&sys_pl->spl_playlist, TRACK(dbe)); else __sys_pl_remove(plist, TRACK(dbe)); } @@ -266,10 +326,8 @@ static bool pl_system_new_delete(const gchar *name) static bool pl_system_add_track(const gchar *name, struct track *track) { - enum sys_playlist_t plist = __sys_pl_convert(name); - if (plist == SYS_PL_NUM_PLAYLISTS) - return false; - return __sys_pl_add(plist, track, track_db_average_plays()); + struct sys_playlist *sys_pl = __sys_pl_lookup(name); + return sys_pl ? sys_pl->spl_add(&sys_pl->spl_playlist, track) : false; } static bool pl_system_remove_track(const gchar *name, struct track *track) @@ -350,8 +408,8 @@ void pl_system_deinit() void pl_system_new_track(struct track *track) { - __sys_pl_add(SYS_PL_COLLECTION, track, 0); - __sys_pl_add(SYS_PL_UNPLAYED, track, 0); + pl_system_add_track("Collection", track); + pl_system_add_track("Unplayed", track); } void pl_system_delete_track(struct track *track) diff --git a/include/core/playlists/system.h b/include/core/playlists/system.h index e37efdaa..3d263576 100644 --- a/include/core/playlists/system.h +++ b/include/core/playlists/system.h @@ -20,6 +20,7 @@ enum sys_playlist_t { struct sys_playlist { struct playlist spl_playlist; + bool (*spl_add)(struct playlist *, struct track *); void (*spl_set_flag)(struct playlist *, enum queue_flags, bool); void (*spl_sort)(struct playlist *, enum compare_t, bool); }; diff --git a/include/core/playlists/type.h b/include/core/playlists/type.h index 9935e313..5624f6b2 100644 --- a/include/core/playlists/type.h +++ b/include/core/playlists/type.h @@ -61,6 +61,9 @@ void playlist_noop_set_flag(struct playlist *, enum queue_flags, bool); void playlist_noop_sort(struct playlist *, enum compare_t, bool); +/* Generic playlist add track operation. */ +bool playlist_generic_add_track(struct playlist *, struct track *); + /* Generic playlist set_flag operation. */ void playlist_generic_set_flag(struct playlist *, enum queue_flags, bool);