core/playlist: playlist_delete() uses a playlist-level function pointer

Rather than going through the playlist-type operations.  Additionally, I
take this opportunity to change playlist_delete() to take a playlist
struct directly.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2016-09-09 10:17:37 -04:00
parent ca5f0701e9
commit 066027ecb6
16 changed files with 188 additions and 114 deletions

View File

@ -70,9 +70,19 @@ struct playlist *playlist_new(enum playlist_type_t type, const gchar *name)
return NULL; return NULL;
} }
bool playlist_delete(enum playlist_type_t type, const gchar *name) bool playlist_delete(struct playlist *playlist)
{ {
return playlist_types[type]->pl_delete(name); enum playlist_type_t type;
bool ret;
if (!playlist || !playlist->pl_ops->pl_delete)
return false;
type = playlist->pl_type;
ret = playlist->pl_ops->pl_delete(playlist);
if (ret)
playlist_types[type]->pl_save();
return ret;
} }
bool playlist_add(enum playlist_type_t type, const gchar *name, bool playlist_add(enum playlist_type_t type, const gchar *name,

View File

@ -8,6 +8,8 @@
static struct queue_ops *artist_ops = NULL; static struct queue_ops *artist_ops = NULL;
static struct file artist_file = FILE_INIT("playlist.artist", 0); static struct file artist_file = FILE_INIT("playlist.artist", 0);
static struct playlist_ops pl_artist_ops;
static struct playlist *__artist_pl_alloc(gchar *name) static struct playlist *__artist_pl_alloc(gchar *name)
{ {
@ -15,6 +17,7 @@ static struct playlist *__artist_pl_alloc(gchar *name)
playlist->pl_name = name; playlist->pl_name = name;
playlist->pl_type = PL_ARTIST; playlist->pl_type = PL_ARTIST;
playlist->pl_ops = &pl_artist_ops;
playlist_generic_init(playlist, Q_REPEAT, artist_ops); playlist_generic_init(playlist, Q_REPEAT, artist_ops);
return playlist; return playlist;
@ -117,11 +120,6 @@ static gchar *pl_artist_get_name(unsigned int id)
return artist ? g_strdup(artist->ar_name) : NULL; return artist ? g_strdup(artist->ar_name) : NULL;
} }
static bool pl_artist_delete(const gchar *name)
{
return false;
}
static bool pl_artist_add_rm(const gchar *name, struct track *track) static bool pl_artist_add_rm(const gchar *name, struct track *track)
{ {
return false; return false;
@ -161,7 +159,6 @@ struct playlist_type pl_artist = {
.pl_get_id = pl_artist_get_id, .pl_get_id = pl_artist_get_id,
.pl_get_name = pl_artist_get_name, .pl_get_name = pl_artist_get_name,
.pl_can_select = pl_artist_can_select, .pl_can_select = pl_artist_can_select,
.pl_delete = pl_artist_delete,
.pl_add_track = pl_artist_add_rm, .pl_add_track = pl_artist_add_rm,
.pl_remove_track = pl_artist_add_rm, .pl_remove_track = pl_artist_add_rm,
.pl_update = pl_artist_update, .pl_update = pl_artist_update,

View File

@ -13,10 +13,6 @@ bool playlist_noop_can_select(struct playlist *playlist)
return false; return false;
} }
void playlist_noop_clear(struct playlist *playlist)
{
}
void playlist_noop_set_flag(struct playlist *playlist, void playlist_noop_set_flag(struct playlist *playlist,
enum queue_flags flag, bool enabled) enum queue_flags flag, bool enabled)
{ {

View File

@ -5,6 +5,7 @@
#include <core/playlists/artist.h> #include <core/playlists/artist.h>
#include <core/playlists/library.h> #include <core/playlists/library.h>
#include <core/playlists/system.h> #include <core/playlists/system.h>
#include <core/playlists/user.h>
#include <unistd.h> #include <unistd.h>
struct scan_data { struct scan_data {
@ -16,6 +17,8 @@ static bool __lib_pl_scan_dir(void *);
static struct queue_ops *lib_ops = NULL; static struct queue_ops *lib_ops = NULL;
static struct file lib_file = FILE_INIT("playlist.library", 0); static struct file lib_file = FILE_INIT("playlist.library", 0);
static struct playlist_ops pl_library_ops;
static struct playlist *__lib_pl_alloc(struct library *library) static struct playlist *__lib_pl_alloc(struct library *library)
{ {
@ -23,6 +26,7 @@ static struct playlist *__lib_pl_alloc(struct library *library)
playlist->pl_name = library->li_path; playlist->pl_name = library->li_path;
playlist->pl_type = PL_LIBRARY; playlist->pl_type = PL_LIBRARY;
playlist->pl_ops = &pl_library_ops;
playlist_generic_init(playlist, Q_REPEAT, lib_ops); playlist_generic_init(playlist, Q_REPEAT, lib_ops);
return playlist; return playlist;
@ -167,6 +171,32 @@ static bool __lib_pl_update(void *data)
} }
static bool pl_library_delete(struct playlist *playlist)
{
struct library *library = library_lookup(playlist->pl_name);
struct queue_iter it;
if (!library)
return false;
queue_for_each(&playlist->pl_queue, &it) {
pl_system_delete_track(queue_iter_val(&it));
pl_artist_delete_track(queue_iter_val(&it));
pl_user_delete_track(queue_iter_val(&it));
}
__lib_pl_free(playlist);
track_remove_all(library);
library_remove(library);
return true;
}
static struct playlist_ops pl_library_ops = {
.pl_delete = pl_library_delete,
};
static void pl_library_save(void) static void pl_library_save(void)
{ {
struct db_entry *dbe, *next; struct db_entry *dbe, *next;
@ -222,27 +252,6 @@ static struct playlist *pl_library_new(const gchar *name)
return library->li_playlist; return library->li_playlist;
} }
static bool pl_library_delete(const gchar *name)
{
struct playlist *playlist = __lib_pl_lookup(name);
struct library *library = library_lookup(name);
struct queue_iter it;
if (!library)
return false;
queue_for_each(&playlist->pl_queue, &it) {
pl_system_delete_track(queue_iter_val(&it));
pl_artist_delete_track(queue_iter_val(&it));
}
__lib_pl_free(playlist);
track_remove_all(library);
library_remove(library);
pl_library_save();
return true;
}
static bool pl_library_add_rm(const gchar *name, struct track *track) static bool pl_library_add_rm(const gchar *name, struct track *track)
{ {
return false; return false;
@ -286,7 +295,6 @@ struct playlist_type pl_library = {
.pl_get_name = pl_library_get_name, .pl_get_name = pl_library_get_name,
.pl_can_select = pl_library_can_select, .pl_can_select = pl_library_can_select,
.pl_new = pl_library_new, .pl_new = pl_library_new,
.pl_delete = pl_library_delete,
.pl_add_track = pl_library_add_rm, .pl_add_track = pl_library_add_rm,
.pl_remove_track = pl_library_add_rm, .pl_remove_track = pl_library_add_rm,
.pl_update = pl_library_update, .pl_update = pl_library_update,

View File

@ -22,6 +22,13 @@ static struct sys_playlist *sys_playlists[SYS_PL_NUM_PLAYLISTS];
/* /*
* Generic system playlist operations. * Generic system playlist operations.
*/ */
static bool sys_pl_delete_clear(struct playlist *playlist)
{
playlist_generic_clear(playlist);
__sys_pl_save();
return false;
}
static void sys_pl_generic_init(struct playlist *playlist, unsigned int flags, static void sys_pl_generic_init(struct playlist *playlist, unsigned int flags,
struct queue_ops *ops) struct queue_ops *ops)
{ {
@ -78,15 +85,18 @@ static bool sys_pl_generic_add_front(struct playlist *playlist,
/* /*
* Favorite tracks playlist operations. * Favorite tracks playlist operations.
*/ */
static struct playlist_ops favorites_ops = {
.pl_delete = sys_pl_delete_clear,
};
static struct sys_playlist sys_favorites = { static struct sys_playlist sys_favorites = {
.spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Favorites"), .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Favorites", &favorites_ops),
.spl_init = playlist_generic_init, .spl_init = playlist_generic_init,
.spl_save = sys_pl_save_full, .spl_save = sys_pl_save_full,
.spl_load = sys_pl_load_full, .spl_load = sys_pl_load_full,
.spl_can_select = playlist_generic_can_select, .spl_can_select = playlist_generic_can_select,
.spl_add = playlist_generic_add_track, .spl_add = playlist_generic_add_track,
.spl_remove = playlist_generic_remove_track, .spl_remove = playlist_generic_remove_track,
.spl_clear = playlist_generic_clear,
.spl_set_flag = playlist_generic_set_flag, .spl_set_flag = playlist_generic_set_flag,
.spl_sort = playlist_generic_sort, .spl_sort = playlist_generic_sort,
.spl_next = playlist_generic_next, .spl_next = playlist_generic_next,
@ -116,7 +126,7 @@ static bool sys_pl_hidden_remove(struct playlist *playlist, struct track *track)
return ret; return ret;
} }
static void sys_pl_hidden_clear(struct playlist *playlist) static bool sys_pl_hidden_clear(struct playlist *playlist)
{ {
struct track *track; struct track *track;
@ -124,17 +134,23 @@ static void sys_pl_hidden_clear(struct playlist *playlist)
track = queue_at(&playlist->pl_queue, 0); track = queue_at(&playlist->pl_queue, 0);
sys_pl_hidden_remove(playlist, track); sys_pl_hidden_remove(playlist, track);
} }
__sys_pl_save();
return false;
} }
static struct playlist_ops hidden_ops = {
.pl_delete = sys_pl_hidden_clear,
};
static struct sys_playlist sys_hidden = { static struct sys_playlist sys_hidden = {
.spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Hidden"), .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Hidden", &hidden_ops),
.spl_init = playlist_generic_init, .spl_init = playlist_generic_init,
.spl_save = sys_pl_save_full, .spl_save = sys_pl_save_full,
.spl_load = sys_pl_load_full, .spl_load = sys_pl_load_full,
.spl_can_select = playlist_generic_can_select, .spl_can_select = playlist_generic_can_select,
.spl_add = sys_pl_hidden_add, .spl_add = sys_pl_hidden_add,
.spl_remove = sys_pl_hidden_remove, .spl_remove = sys_pl_hidden_remove,
.spl_clear = sys_pl_hidden_clear,
.spl_set_flag = playlist_generic_set_flag, .spl_set_flag = playlist_generic_set_flag,
.spl_sort = playlist_generic_sort, .spl_sort = playlist_generic_sort,
.spl_next = playlist_generic_next, .spl_next = playlist_generic_next,
@ -173,15 +189,18 @@ static void sys_pl_queued_init(struct playlist *playlist,
queue_init(&playlist->pl_queue, 0, ops, playlist); queue_init(&playlist->pl_queue, 0, ops, playlist);
} }
static struct playlist_ops queued_ops = {
.pl_delete = sys_pl_delete_clear,
};
static struct sys_playlist sys_queued = { static struct sys_playlist sys_queued = {
.spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Queued Tracks"), .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Queued Tracks", &queued_ops),
.spl_init = sys_pl_queued_init, .spl_init = sys_pl_queued_init,
.spl_save = sys_pl_save_full, .spl_save = sys_pl_save_full,
.spl_load = sys_pl_load_full, .spl_load = sys_pl_load_full,
.spl_can_select = playlist_generic_can_select, .spl_can_select = playlist_generic_can_select,
.spl_add = playlist_generic_add_track, .spl_add = playlist_generic_add_track,
.spl_remove = playlist_generic_remove_track, .spl_remove = playlist_generic_remove_track,
.spl_clear = playlist_generic_clear,
.spl_set_flag = playlist_generic_set_flag, .spl_set_flag = playlist_generic_set_flag,
.spl_sort = playlist_generic_sort, .spl_sort = playlist_generic_sort,
.spl_next = playlist_generic_next, .spl_next = playlist_generic_next,
@ -215,15 +234,17 @@ static bool sys_pl_collection_update(struct playlist *playlist,
return sys_pl_generic_add(playlist, track) || true; return sys_pl_generic_add(playlist, track) || true;
} }
static struct playlist_ops collection_ops;
static struct sys_playlist sys_collection = { static struct sys_playlist sys_collection = {
.spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Collection"), .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Collection",
&collection_ops),
.spl_init = sys_pl_update_init, .spl_init = sys_pl_update_init,
.spl_save = sys_pl_save_partial, .spl_save = sys_pl_save_partial,
.spl_load = sys_pl_load_partial, .spl_load = sys_pl_load_partial,
.spl_can_select = sys_pl_collection_can_select, .spl_can_select = sys_pl_collection_can_select,
.spl_add = sys_pl_generic_add, .spl_add = sys_pl_generic_add,
.spl_remove = playlist_generic_remove_track, .spl_remove = playlist_generic_remove_track,
.spl_clear = playlist_noop_clear,
.spl_update = sys_pl_collection_update, .spl_update = sys_pl_collection_update,
.spl_set_flag = playlist_generic_set_flag, .spl_set_flag = playlist_generic_set_flag,
.spl_sort = playlist_generic_sort, .spl_sort = playlist_generic_sort,
@ -247,15 +268,16 @@ static bool sys_pl_history_add(struct playlist *playlist, struct track *track)
return true; return true;
} }
static struct playlist_ops history_ops;
static struct sys_playlist sys_history = { static struct sys_playlist sys_history = {
.spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "History"), .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "History", &history_ops),
.spl_init = sys_pl_history_init, .spl_init = sys_pl_history_init,
.spl_save = sys_pl_save_partial, .spl_save = sys_pl_save_partial,
.spl_load = sys_pl_load_partial, .spl_load = sys_pl_load_partial,
.spl_can_select = playlist_noop_can_select, .spl_can_select = playlist_noop_can_select,
.spl_add = sys_pl_history_add, .spl_add = sys_pl_history_add,
.spl_remove = playlist_generic_remove_track, .spl_remove = playlist_generic_remove_track,
.spl_clear = playlist_noop_clear,
.spl_set_flag = playlist_noop_set_flag, .spl_set_flag = playlist_noop_set_flag,
.spl_sort = playlist_noop_sort, .spl_sort = playlist_noop_sort,
.spl_next = playlist_generic_next, .spl_next = playlist_generic_next,
@ -280,15 +302,16 @@ static bool sys_pl_unplayed_update(struct playlist *playlist,
return sys_pl_generic_add_front(playlist, track) || true; return sys_pl_generic_add_front(playlist, track) || true;
} }
static struct playlist_ops unplayed_ops;
static struct sys_playlist sys_unplayed = { static struct sys_playlist sys_unplayed = {
.spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Unplayed"), .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Unplayed", &unplayed_ops),
.spl_init = sys_pl_update_init, .spl_init = sys_pl_update_init,
.spl_save = sys_pl_save_partial, .spl_save = sys_pl_save_partial,
.spl_load = sys_pl_load_partial, .spl_load = sys_pl_load_partial,
.spl_can_select = playlist_generic_can_select, .spl_can_select = playlist_generic_can_select,
.spl_add = sys_pl_unplayed_add, .spl_add = sys_pl_unplayed_add,
.spl_remove = playlist_generic_remove_track, .spl_remove = playlist_generic_remove_track,
.spl_clear = playlist_noop_clear,
.spl_update = sys_pl_unplayed_update, .spl_update = sys_pl_unplayed_update,
.spl_set_flag = playlist_generic_set_flag, .spl_set_flag = playlist_generic_set_flag,
.spl_sort = playlist_generic_sort, .spl_sort = playlist_generic_sort,
@ -316,8 +339,11 @@ static bool sys_pl_most_played_update(struct playlist *playlist,
return sys_pl_generic_add_front(playlist, track) || true; return sys_pl_generic_add_front(playlist, track) || true;
} }
static struct playlist_ops most_played_ops;
static struct sys_playlist sys_most_played = { static struct sys_playlist sys_most_played = {
.spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Most Played"), .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Most Played",
&most_played_ops),
.spl_init = sys_pl_update_init, .spl_init = sys_pl_update_init,
.spl_save = sys_pl_save_partial, .spl_save = sys_pl_save_partial,
.spl_load = sys_pl_load_partial, .spl_load = sys_pl_load_partial,
@ -325,7 +351,6 @@ static struct sys_playlist sys_most_played = {
.spl_add = sys_pl_most_played_add, .spl_add = sys_pl_most_played_add,
.spl_remove = playlist_generic_remove_track, .spl_remove = playlist_generic_remove_track,
.spl_update = sys_pl_most_played_update, .spl_update = sys_pl_most_played_update,
.spl_clear = playlist_noop_clear,
.spl_set_flag = playlist_generic_set_flag, .spl_set_flag = playlist_generic_set_flag,
.spl_sort = playlist_generic_sort, .spl_sort = playlist_generic_sort,
.spl_next = playlist_generic_next, .spl_next = playlist_generic_next,
@ -352,13 +377,15 @@ static bool sys_pl_least_played_update(struct playlist *playlist,
return sys_pl_generic_add_front(playlist, track) || true; return sys_pl_generic_add_front(playlist, track) || true;
} }
static struct playlist_ops least_played_ops;
static struct sys_playlist sys_least_played = { static struct sys_playlist sys_least_played = {
.spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Least Played"), .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Least Played",
&least_played_ops),
.spl_init = sys_pl_update_init, .spl_init = sys_pl_update_init,
.spl_save = sys_pl_save_partial, .spl_save = sys_pl_save_partial,
.spl_load = sys_pl_load_partial, .spl_load = sys_pl_load_partial,
.spl_can_select = playlist_generic_can_select, .spl_can_select = playlist_generic_can_select,
.spl_clear = playlist_noop_clear,
.spl_add = sys_pl_least_played_add, .spl_add = sys_pl_least_played_add,
.spl_remove = playlist_generic_remove_track, .spl_remove = playlist_generic_remove_track,
.spl_update = sys_pl_least_played_update, .spl_update = sys_pl_least_played_update,
@ -510,16 +537,6 @@ static bool pl_system_can_select(const gchar *name)
return sys_pl ? sys_pl->spl_can_select(&sys_pl->spl_playlist) : false; return sys_pl ? sys_pl->spl_can_select(&sys_pl->spl_playlist) : false;
} }
static bool pl_system_delete(const gchar *name)
{
struct sys_playlist *sys_pl = __sys_pl_lookup(name);
if (sys_pl) {
sys_pl->spl_clear(&sys_pl->spl_playlist);
__sys_pl_save();
}
return false; /* Don't remove the playlist from the sidebar. */
}
static bool pl_system_add_track(const gchar *name, struct track *track) static bool pl_system_add_track(const gchar *name, struct track *track)
{ {
struct sys_playlist *sys_pl = __sys_pl_lookup(name); struct sys_playlist *sys_pl = __sys_pl_lookup(name);
@ -590,7 +607,6 @@ struct playlist_type pl_system = {
.pl_get_id = pl_system_get_id, .pl_get_id = pl_system_get_id,
.pl_get_name = pl_system_get_name, .pl_get_name = pl_system_get_name,
.pl_can_select = pl_system_can_select, .pl_can_select = pl_system_can_select,
.pl_delete = pl_system_delete,
.pl_add_track = pl_system_add_track, .pl_add_track = pl_system_add_track,
.pl_remove_track = pl_system_remove_track, .pl_remove_track = pl_system_remove_track,
.pl_update = pl_system_update, .pl_update = pl_system_update,
@ -634,6 +650,6 @@ void pl_system_delete_track(struct track *track)
for (i = 0; i < SYS_PL_NUM_PLAYLISTS; i++) { for (i = 0; i < SYS_PL_NUM_PLAYLISTS; i++) {
sys_pl = sys_playlists[i]; sys_pl = sys_playlists[i];
sys_pl->spl_remove(&sys_pl->spl_playlist, track); playlist_generic_remove_track(&sys_pl->spl_playlist, track);
} }
} }

View File

@ -3,8 +3,9 @@
*/ */
#include <core/playlists/user.h> #include <core/playlists/user.h>
static struct queue_ops *user_pl_ops = NULL; static struct queue_ops *user_pl_ops = NULL;
static struct database user_db; static struct database user_db;
static struct playlist_ops user_ops;
static struct user_playlist *__user_db_alloc(gchar *name) static struct user_playlist *__user_db_alloc(gchar *name)
{ {
@ -13,6 +14,7 @@ static struct user_playlist *__user_db_alloc(gchar *name)
dbe_init(&playlist->pl_dbe, playlist); dbe_init(&playlist->pl_dbe, playlist);
playlist->pl_playlist.pl_name = name; playlist->pl_playlist.pl_name = name;
playlist->pl_playlist.pl_type = PL_USER; playlist->pl_playlist.pl_type = PL_USER;
playlist->pl_playlist.pl_ops = &user_ops;
playlist_generic_init(&playlist->pl_playlist, Q_REPEAT, user_pl_ops); playlist_generic_init(&playlist->pl_playlist, Q_REPEAT, user_pl_ops);
return playlist; return playlist;
@ -68,6 +70,22 @@ static const struct db_ops user_db_ops = {
}; };
static bool pl_user_delete(struct playlist *playlist)
{
struct db_entry *dbe = db_get(&user_db, playlist->pl_name);
if (dbe) {
db_remove(&user_db, dbe);
db_defrag(&user_db);
}
return dbe != NULL;
}
static struct playlist_ops user_ops = {
.pl_delete = pl_user_delete,
};
static struct playlist *__user_pl_lookup(const gchar *name) static struct playlist *__user_pl_lookup(const gchar *name)
{ {
struct db_entry *dbe = db_get(&user_db, name); struct db_entry *dbe = db_get(&user_db, name);
@ -111,16 +129,6 @@ static struct playlist *pl_user_new(const gchar *name)
return dbe ? &USER_PLAYLIST(dbe)->pl_playlist : NULL; return dbe ? &USER_PLAYLIST(dbe)->pl_playlist : NULL;
} }
static bool pl_user_delete(const gchar *name)
{
struct db_entry *dbe = db_get(&user_db, name);
if (dbe) {
db_remove(&user_db, dbe);
db_defrag(&user_db);
}
return dbe != NULL;
}
static bool pl_user_add(const gchar *name, struct track *track) static bool pl_user_add(const gchar *name, struct track *track)
{ {
struct playlist *playlist = __user_pl_lookup(name); struct playlist *playlist = __user_pl_lookup(name);
@ -184,7 +192,6 @@ struct playlist_type pl_user = {
.pl_get_name = pl_user_get_name, .pl_get_name = pl_user_get_name,
.pl_can_select = pl_user_can_select, .pl_can_select = pl_user_can_select,
.pl_new = pl_user_new, .pl_new = pl_user_new,
.pl_delete = pl_user_delete,
.pl_add_track = pl_user_add, .pl_add_track = pl_user_add,
.pl_remove_track = pl_user_remove, .pl_remove_track = pl_user_remove,
.pl_update = pl_user_update, .pl_update = pl_user_update,
@ -210,3 +217,14 @@ struct database *pl_user_db_get()
{ {
return &user_db; return &user_db;
} }
void pl_user_delete_track(struct track *track)
{
struct db_entry *dbe, *next;
struct playlist *playlist;
db_for_each(dbe, next, &user_db) {
playlist = &USER_PLAYLIST(dbe)->pl_playlist;
playlist_generic_remove_track(playlist, track);
}
}

View File

@ -156,7 +156,7 @@ bool __gui_sidebar_keypress(GtkTreeView *treeview, GdkEventKey *event,
return false; return false;
__gui_sidebar_filter_iter_convert(&iter, &child); __gui_sidebar_filter_iter_convert(&iter, &child);
if (playlist_delete(playlist->pl_type, playlist->pl_name)) if (playlist_delete(playlist))
gtk_tree_store_remove(gui_sidebar_store(), &child); gtk_tree_store_remove(gui_sidebar_store(), &child);
return true; return true;
} }

View File

@ -32,7 +32,7 @@ bool playlist_select(enum playlist_type_t, const gchar *);
struct playlist *playlist_new(enum playlist_type_t, const gchar *); struct playlist *playlist_new(enum playlist_type_t, const gchar *);
/* Called to delete a playlist. */ /* Called to delete a playlist. */
bool playlist_delete(enum playlist_type_t, const gchar *); bool playlist_delete(struct playlist *);
/* Called to add a track to a playlist. */ /* Called to add a track to a playlist. */

View File

@ -27,7 +27,6 @@ struct sys_playlist {
bool (*spl_can_select)(struct playlist *); bool (*spl_can_select)(struct playlist *);
bool (*spl_add)(struct playlist *, struct track *); bool (*spl_add)(struct playlist *, struct track *);
bool (*spl_remove)(struct playlist *, struct track *); bool (*spl_remove)(struct playlist *, struct track *);
void (*spl_clear)(struct playlist *);
bool (*spl_update)(struct playlist *, struct track *); bool (*spl_update)(struct playlist *, struct track *);
void (*spl_set_flag)(struct playlist *, enum queue_flags, bool); void (*spl_set_flag)(struct playlist *, enum queue_flags, bool);
void (*spl_sort)(struct playlist *, enum compare_t, bool); void (*spl_sort)(struct playlist *, enum compare_t, bool);

View File

@ -8,6 +8,8 @@
#include <glib.h> #include <glib.h>
#include <stdbool.h> #include <stdbool.h>
struct playlist;
enum playlist_type_t { enum playlist_type_t {
PL_SYSTEM, PL_SYSTEM,
@ -18,15 +20,27 @@ enum playlist_type_t {
}; };
struct playlist_ops {
/* Called to delete a playlist. */
bool (*pl_delete)(struct playlist *);
};
struct playlist { struct playlist {
enum playlist_type_t pl_type; /* This playlist's type. */ enum playlist_type_t pl_type; /* This playlist's type. */
gchar *pl_name; /* This playlist's name. */ gchar *pl_name; /* This playlist's name. */
void *pl_private; /* This playlist's private data. */ void *pl_private; /* This playlist's private data. */
struct queue pl_queue; /* This playlist's queue of tracks. */ struct queue pl_queue; /* This playlist's queue of tracks. */
const struct playlist_ops *pl_ops; /* This playlist's supported operations. */
}; };
#define DEFINE_PLAYLIST(type, name) { .pl_type = type, .pl_name = name } #define DEFINE_PLAYLIST(type, name, ops) { \
.pl_type = type, \
.pl_name = name, \
.pl_ops = ops, \
}
struct playlist_type { struct playlist_type {
@ -48,9 +62,6 @@ struct playlist_type {
/* Called to create a new playlist. */ /* Called to create a new playlist. */
struct playlist *(*pl_new)(const gchar *); struct playlist *(*pl_new)(const gchar *);
/* Called to delete a playlist. */
bool (*pl_delete)(const gchar *);
/* Called to add a track to the playlist. */ /* Called to add a track to the playlist. */
bool (*pl_add_track)(const gchar *, struct track *); bool (*pl_add_track)(const gchar *, struct track *);
@ -74,9 +85,6 @@ struct playlist_type {
/* Noop playlist can-select operation. */ /* Noop playlist can-select operation. */
bool playlist_noop_can_select(struct playlist *); bool playlist_noop_can_select(struct playlist *);
/* Noop playlist clear operation. */
void playlist_noop_clear(struct playlist *);
/* Noop playlist set_flag operation. */ /* Noop playlist set_flag operation. */
void playlist_noop_set_flag(struct playlist *, enum queue_flags, bool); void playlist_noop_set_flag(struct playlist *, enum queue_flags, bool);

View File

@ -24,5 +24,8 @@ void pl_user_init(struct queue_ops *ops);
/* Called to deinitialize user playlists. */ /* Called to deinitialize user playlists. */
void pl_user_deinit(); void pl_user_deinit();
/* Called to tell user playlists that a track is getting deleted. */
void pl_user_delete_track(struct track *);
struct database *pl_user_db_get(); struct database *pl_user_db_get();
#endif /* OCARINA_CORE_PLAYLISTS_USER_H */ #endif /* OCARINA_CORE_PLAYLISTS_USER_H */

View File

@ -10,6 +10,7 @@ static void test_null()
{ {
g_assert_null(playlist_new(PL_MAX_TYPE, "NULL")); g_assert_null(playlist_new(PL_MAX_TYPE, "NULL"));
g_assert_null(playlist_new(PL_MAX_TYPE, NULL)); g_assert_null(playlist_new(PL_MAX_TYPE, NULL));
g_assert_false(playlist_delete(NULL));
} }
int main(int argc, char **argv) int main(int argc, char **argv)

View File

@ -12,7 +12,8 @@
void test_artist() void test_artist()
{ {
struct artist *artist; struct playlist *playlist;
struct artist *artist;
g_assert_null(playlist_new(PL_ARTIST, "Koji Kondo")); g_assert_null(playlist_new(PL_ARTIST, "Koji Kondo"));
g_assert_null(playlist_get_queue(PL_ARTIST, "Koji Kondo")); g_assert_null(playlist_get_queue(PL_ARTIST, "Koji Kondo"));
@ -30,6 +31,9 @@ void test_artist()
g_assert_cmpstr_free(playlist_get_name(PL_ARTIST, 0), ==, "Koji Kondo"); g_assert_cmpstr_free(playlist_get_name(PL_ARTIST, 0), ==, "Koji Kondo");
while (idle_run_task()) {}; while (idle_run_task()) {};
playlist = playlist_get(PL_ARTIST, "Koji Kondo");
g_assert_nonnull(playlist);
g_assert_cmpuint(playlist_size(PL_ARTIST, "Koji Kondo"), ==, 2); g_assert_cmpuint(playlist_size(PL_ARTIST, "Koji Kondo"), ==, 2);
g_assert_nonnull(artist->ar_playlist); g_assert_nonnull(artist->ar_playlist);
g_assert_false(playlist_remove(PL_ARTIST, "Koji Kondo", track_get(0))); g_assert_false(playlist_remove(PL_ARTIST, "Koji Kondo", track_get(0)));
@ -41,7 +45,7 @@ void test_artist()
g_assert_cmpuint(settings_get("core.playlist.cur.id"), ==, 0); g_assert_cmpuint(settings_get("core.playlist.cur.id"), ==, 0);
g_assert(playlist_cur() == playlist_get(PL_ARTIST, "Koji Kondo")); g_assert(playlist_cur() == playlist_get(PL_ARTIST, "Koji Kondo"));
g_assert_false(playlist_delete(PL_ARTIST, "Koji Kondo")); g_assert_false(playlist_delete(playlist));
pl_artist_deinit(); pl_artist_deinit();
g_assert_null(artist->ar_playlist); g_assert_null(artist->ar_playlist);
} }

View File

@ -94,8 +94,7 @@ void test_library()
g_assert_cmpuint(track_db_get()->db_size, ==, 48); g_assert_cmpuint(track_db_get()->db_size, ==, 48);
g_assert_cmpuint(playlist_size(PL_LIBRARY, "tests/Music"), ==, 48); g_assert_cmpuint(playlist_size(PL_LIBRARY, "tests/Music"), ==, 48);
g_assert_true( playlist_delete(PL_LIBRARY, "tests/Music")); g_assert_true(playlist_delete(playlist));
g_assert_false(playlist_delete(PL_LIBRARY, "tests/Music"));
g_assert_null(library_get(0)); g_assert_null(library_get(0));
g_assert_cmpuint(playlist_size(PL_SYSTEM, "Unplayed"), ==, 0); g_assert_cmpuint(playlist_size(PL_SYSTEM, "Unplayed"), ==, 0);
g_assert_cmpuint(playlist_size(PL_SYSTEM, "Collection"), ==, 0); g_assert_cmpuint(playlist_size(PL_SYSTEM, "Collection"), ==, 0);

View File

@ -45,10 +45,6 @@
g_assert_false(playlist_remove(PL_SYSTEM, name, track_get(1))); \ g_assert_false(playlist_remove(PL_SYSTEM, name, track_get(1))); \
__test_playlist_state(name, 0, false, false) __test_playlist_state(name, 0, false, false)
#define __test_playlist_clear(name, ex_size, ex_track0, ex_track1) \
g_assert_false(playlist_delete(PL_SYSTEM, name)); \
__test_playlist_state(name, ex_size, ex_track0, ex_track1)
#define __test_playlist_update(name, ex_size, ex_track0, ex_track1) \ #define __test_playlist_update(name, ex_size, ex_track0, ex_track1) \
playlist_update(PL_SYSTEM, name); \ playlist_update(PL_SYSTEM, name); \
while (idle_run_task()) {}; \ while (idle_run_task()) {}; \
@ -64,7 +60,8 @@
__test_playlist_state(name, ex_size, ex_track0, ex_track1) __test_playlist_state(name, ex_size, ex_track0, ex_track1)
#define __test_playlist_clear_hidden(name, ex_size, ex_track0, ex_track1) \ #define __test_playlist_clear_hidden(name, ex_size, ex_track0, ex_track1) \
__test_playlist_clear("Hidden", 0, false, false); \ g_assert_false(playlist_delete(playlist_get(PL_SYSTEM, "Hidden"))); \
__test_playlist_state("Hidden", 0, false, false); \
__test_playlist_state(name, ex_size, ex_track0, ex_track1); __test_playlist_state(name, ex_size, ex_track0, ex_track1);
#define __test_playlist_select(name, id) \ #define __test_playlist_select(name, id) \
@ -126,15 +123,12 @@ static void test_invalid()
SYS_PL_NUM_PLAYLISTS); SYS_PL_NUM_PLAYLISTS);
g_assert_null(playlist_get_name(PL_SYSTEM, SYS_PL_NUM_PLAYLISTS)); g_assert_null(playlist_get_name(PL_SYSTEM, SYS_PL_NUM_PLAYLISTS));
g_assert_false(playlist_delete(PL_SYSTEM, "Favorites"));
__test_playlist_noselect(NULL); __test_playlist_noselect(NULL);
__test_playlist_noselect("Invalid"); __test_playlist_noselect("Invalid");
playlist_update(PL_SYSTEM, NULL); playlist_update(PL_SYSTEM, NULL);
g_assert_false(playlist_add(PL_SYSTEM, NULL, track_get(0))); g_assert_false(playlist_add(PL_SYSTEM, NULL, track_get(0)));
g_assert_false(playlist_remove(PL_SYSTEM, NULL, track_get(0))); g_assert_false(playlist_remove(PL_SYSTEM, NULL, track_get(0)));
g_assert_false(playlist_delete(PL_SYSTEM, NULL));
g_assert_false(playlist_has(PL_SYSTEM, NULL, track_get(0))); g_assert_false(playlist_has(PL_SYSTEM, NULL, track_get(0)));
g_assert_cmpuint(playlist_size(PL_SYSTEM, NULL), ==, 0); g_assert_cmpuint(playlist_size(PL_SYSTEM, NULL), ==, 0);
@ -157,9 +151,6 @@ static void test_favorites()
__test_playlist_select("Favorites", SYS_PL_FAVORITES); __test_playlist_select("Favorites", SYS_PL_FAVORITES);
__test_playlist_reinit("Favorites", 2, true, true); __test_playlist_reinit("Favorites", 2, true, true);
__test_playlist_update("Favorites", 2, true, true); __test_playlist_update("Favorites", 2, true, true);
__test_playlist_clear("Favorites", 0, false, false);
__test_playlist_reinit("Favorites", 0, false, false);
__test_playlist_add("Favorites");
__test_playlist_remove("Favorites"); __test_playlist_remove("Favorites");
} }
@ -178,9 +169,6 @@ static void test_hidden()
__test_playlist_select("Hidden", SYS_PL_HIDDEN); __test_playlist_select("Hidden", SYS_PL_HIDDEN);
__test_playlist_reinit("Hidden", 2, true, true); __test_playlist_reinit("Hidden", 2, true, true);
__test_playlist_update("Hidden", 2, true, true); __test_playlist_update("Hidden", 2, true, true);
__test_playlist_clear("Hidden", 0, false, false);
__test_playlist_reinit("Hidden", 0, false, false);
__test_playlist_add("Hidden");
__test_playlist_remove("Hidden"); __test_playlist_remove("Hidden");
} }
@ -212,9 +200,6 @@ static void test_queued()
__test_playlist_add("Queued Tracks"); __test_playlist_add("Queued Tracks");
__test_playlist_remove("Queued Tracks"); __test_playlist_remove("Queued Tracks");
__test_playlist_update("Queued Tracks", 0, false, false); __test_playlist_update("Queued Tracks", 0, false, false);
__test_playlist_add("Queued Tracks");
__test_playlist_clear("Queued Tracks", 0, false, false);
__test_playlist_reinit("Queued Tracks", 0, false, false);
} }
static void test_collection() static void test_collection()
@ -237,7 +222,6 @@ static void test_collection()
__test_playlist_unhide_track("Collection", 2, true, true); __test_playlist_unhide_track("Collection", 2, true, true);
__test_playlist_hide_track("Collection", 1, false, true); __test_playlist_hide_track("Collection", 1, false, true);
__test_playlist_clear_hidden("Collection", 2, true, true); __test_playlist_clear_hidden("Collection", 2, true, true);
__test_playlist_clear("Collection", 2, true, true);
} }
static void test_history() static void test_history()
@ -272,7 +256,6 @@ static void test_history()
g_assert_cmpuint(playlist_size(PL_SYSTEM, "History"), ==, 5); g_assert_cmpuint(playlist_size(PL_SYSTEM, "History"), ==, 5);
g_assert(playlist_prev() == track_get(1)); g_assert(playlist_prev() == track_get(1));
__test_playlist_clear("History", 5, true, true);
__test_playlist_remove("History"); __test_playlist_remove("History");
__test_playlist_update("History", 0, false, false); __test_playlist_update("History", 0, false, false);
} }
@ -312,7 +295,6 @@ static void test_unplayed()
__test_playlist_unhide_track("Unplayed", 2, true, true); __test_playlist_unhide_track("Unplayed", 2, true, true);
__test_playlist_hide_track("Unplayed", 1, false, true); __test_playlist_hide_track("Unplayed", 1, false, true);
__test_playlist_clear_hidden("Unplayed", 2, true, true); __test_playlist_clear_hidden("Unplayed", 2, true, true);
__test_playlist_clear("Unplayed", 2, true, true);
} }
static void test_most_played() static void test_most_played()
@ -357,7 +339,6 @@ static void test_most_played()
__test_playlist_unhide_track("Most Played", 1, true, false); __test_playlist_unhide_track("Most Played", 1, true, false);
__test_playlist_hide_track("Most Played", 0, false, false); __test_playlist_hide_track("Most Played", 0, false, false);
__test_playlist_clear_hidden("Most Played", 1, true, false); __test_playlist_clear_hidden("Most Played", 1, true, false);
__test_playlist_clear("Most Played", 1, true, false);
} }
static void test_least_played() static void test_least_played()
@ -400,7 +381,37 @@ static void test_least_played()
__test_playlist_unhide_track("Least Played", 1, true, false); __test_playlist_unhide_track("Least Played", 1, true, false);
__test_playlist_hide_track("Least Played", 0, false, false); __test_playlist_hide_track("Least Played", 0, false, false);
__test_playlist_clear_hidden("Least Played", 1, true, false); __test_playlist_clear_hidden("Least Played", 1, true, false);
__test_playlist_clear("Least Played", 1, true, false); }
static void test_delete()
{
struct library *library = library_find("tests/Music");
track_add(library, "tests/Music/Hyrule Symphony/03 - Hyrule Field.ogg");
pl_system_new_track(track_get(2));
playlist_add(PL_SYSTEM, "Favorites", track_get(0));
playlist_add(PL_SYSTEM, "Hidden ", track_get(1));
playlist_add(PL_SYSTEM, "Hidden ", track_get(2));
playlist_add(PL_SYSTEM, "Queued Tracks", track_get(0));
playlist_add(PL_SYSTEM, "History", track_get(0));
g_assert_false(playlist_delete(playlist_get(PL_SYSTEM, "Favorites")));
g_assert_false(playlist_delete(playlist_get(PL_SYSTEM, "Hidden")));
g_assert_false(playlist_delete(playlist_get(PL_SYSTEM, "Queued Tracks")));
g_assert_false(playlist_delete(playlist_get(PL_SYSTEM, "Collection")));
g_assert_false(playlist_delete(playlist_get(PL_SYSTEM, "History")));
g_assert_false(playlist_delete(playlist_get(PL_SYSTEM, "Unplayed")));
g_assert_false(playlist_delete(playlist_get(PL_SYSTEM, "Most Played")));
g_assert_false(playlist_delete(playlist_get(PL_SYSTEM, "Least Played")));
g_assert_cmpuint(playlist_size(PL_SYSTEM, "Favorites"), ==, 0);
g_assert_cmpuint(playlist_size(PL_SYSTEM, "Hidden"), ==, 0);
g_assert_cmpuint(playlist_size(PL_SYSTEM, "Queued Tracks"), ==, 0);
g_assert_cmpuint(playlist_size(PL_SYSTEM, "Collection"), ==, 3);
g_assert_cmpuint(playlist_size(PL_SYSTEM, "History"), ==, 1);
g_assert_cmpuint(playlist_size(PL_SYSTEM, "Unplayed"), ==, 1);
g_assert_cmpuint(playlist_size(PL_SYSTEM, "Most Played"), ==, 1);
g_assert_cmpuint(playlist_size(PL_SYSTEM, "Least Played"), ==, 1);
} }
static void test_delete_tracks() static void test_delete_tracks()
@ -411,6 +422,7 @@ static void test_delete_tracks()
pl_system_delete_track(track_get(0)); pl_system_delete_track(track_get(0));
pl_system_delete_track(track_get(1)); pl_system_delete_track(track_get(1));
pl_system_delete_track(track_get(2));
g_assert_cmpuint(playlist_size(PL_SYSTEM, "Favorites"), ==, 0); g_assert_cmpuint(playlist_size(PL_SYSTEM, "Favorites"), ==, 0);
g_assert_cmpuint(playlist_size(PL_SYSTEM, "Hidden"), ==, 0); g_assert_cmpuint(playlist_size(PL_SYSTEM, "Hidden"), ==, 0);
@ -444,6 +456,7 @@ int main(int argc, char **argv)
g_test_add_func("/Core/Playlists/System/Unplayed Tracks", test_unplayed); g_test_add_func("/Core/Playlists/System/Unplayed Tracks", test_unplayed);
g_test_add_func("/Core/Playlists/System/Most Played Tracks", test_most_played); g_test_add_func("/Core/Playlists/System/Most Played Tracks", test_most_played);
g_test_add_func("/Core/Playlists/System/Least Played Tracks", test_least_played); g_test_add_func("/Core/Playlists/System/Least Played Tracks", test_least_played);
g_test_add_func("/Core/Playlists/System/Delete", test_delete);
g_test_add_func("/Core/PLaylists/System/Delete Tracks", test_delete_tracks); g_test_add_func("/Core/PLaylists/System/Delete Tracks", test_delete_tracks);
ret = g_test_run(); ret = g_test_run();

View File

@ -52,6 +52,9 @@ void test_user()
while (idle_run_task()) {}; while (idle_run_task()) {};
g_assert_cmpuint(db->db_size, ==, 1); g_assert_cmpuint(db->db_size, ==, 1);
playlist = playlist_get(PL_USER, "Test Playlist");
g_assert_nonnull(playlist);
g_assert_cmpuint(playlist_size(PL_USER, "Test Playlist"), ==, 1); g_assert_cmpuint(playlist_size(PL_USER, "Test Playlist"), ==, 1);
g_assert_true( playlist_has( PL_USER, "Test Playlist", track_get(0))); g_assert_true( playlist_has( PL_USER, "Test Playlist", track_get(0)));
g_assert_true( playlist_remove(PL_USER, "Test Playlist", track_get(0))); g_assert_true( playlist_remove(PL_USER, "Test Playlist", track_get(0)));
@ -59,8 +62,7 @@ void test_user()
g_assert_false(playlist_has( PL_USER, "Test Playlist", track_get(0))); g_assert_false(playlist_has( PL_USER, "Test Playlist", track_get(0)));
g_assert_cmpuint(playlist_size(PL_USER, "Test Playlist"), ==, 0); g_assert_cmpuint(playlist_size(PL_USER, "Test Playlist"), ==, 0);
g_assert_true( playlist_delete(PL_USER, "Test Playlist")); g_assert_true(playlist_delete(playlist));
g_assert_false(playlist_delete(PL_USER, "Test Playlist"));
g_assert_cmpuint(db->db_size, ==, 0); g_assert_cmpuint(db->db_size, ==, 0);
g_assert_cmpuint(db_actual_size(db), ==, 0); g_assert_cmpuint(db_actual_size(db), ==, 0);
} }