core/playlist: Use playlist_t enum to access playlists

Using strings is pretty tedious, so let's restrict restrict playlist
access to known values.

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2015-12-10 13:26:22 -05:00
parent 88f6fc526c
commit b7a4bb3872
7 changed files with 112 additions and 124 deletions

View File

@ -9,27 +9,23 @@ extern "C" {
static struct database playlist_db;
static struct queue playlist_q;
static std::string cur_plist;
static enum playlist_t playlist_cur;
static const gchar *playlist_names[2] = { "Favorites", "Banned" };
static inline bool __playlist_is_static(const gchar *name)
static inline index_entry *__playlist_lookup(enum playlist_t plist)
{
if (!name)
return false;
if (string_compare(name, "Favorites") == 0)
return true;
return string_compare(name, "Banned") == 0;
return INDEX_ENTRY(db_get(&playlist_db, playlist_names[plist]));
}
static inline bool __playlist_is_dynamic(const gchar *name)
static inline bool __playlist_is_static(enum playlist_t plist)
{
if (!name)
return false;
if (string_compare(name, "Most Played") == 0)
return true;
if (string_compare(name, "Least Played") == 0)
return true;
return string_compare(name, "Unplayed") == 0;
return (plist == PL_FAVORITED) || (plist == PL_BANNED);
}
static inline bool __playlist_is_dynamic(enum playlist_t plist)
{
return !__playlist_is_static(plist);
}
static unsigned int __playlist_find_average()
@ -45,12 +41,12 @@ static unsigned int __playlist_find_average()
return total / track_db_get()->db_size;
}
static void __playlist_fill(const gchar *name, struct set *set)
static void __playlist_fill(enum playlist_t plist, struct set *set)
{
struct set_iter it;
queue_clear(&playlist_q);
cur_plist = name;
playlist_cur = plist;
if (!set)
return;
@ -63,37 +59,34 @@ static void __playlist_fill(const gchar *name, struct set *set)
queue_resort(&playlist_q);
}
static void __playlist_fill_static(const gchar *name)
static void __playlist_fill_static(enum playlist_t plist)
{
struct index_entry *ent = INDEX_ENTRY(db_get(&playlist_db, name));
__playlist_fill(name, ent ? &ent->ie_set : NULL);
struct index_entry *ent = __playlist_lookup(plist);
__playlist_fill(plist, ent ? &ent->ie_set : NULL);
}
static void __playlist_fill_dynamic(const gchar *name)
static void __playlist_fill_dynamic(enum playlist_t plist)
{
struct db_entry *track, *next;
unsigned int count = 0, average = 0;
struct db_entry *track, *next;
struct set set;
if (string_compare(name, "Most Played") == 0 ||
string_compare(name, "Least Played") == 0)
if (plist == PL_MOST_PLAYED || plist == PL_LEAST_PLAYED)
average = __playlist_find_average();
set_init(&set);
db_for_each(track, next, track_db_get()) {
count = TRACK(track)->tr_count;
if (string_compare(name, "Unplayed") == 0 && count == 0)
if (plist == PL_UNPLAYED && count == 0)
set_insert(&set, track->dbe_index);
else if (string_compare(name, "Most Played") == 0 &&
count > average)
else if (plist == PL_MOST_PLAYED && count > average)
set_insert(&set, track->dbe_index);
else if (string_compare(name, "Least Played") == 0 &&
count < average && count > 0)
else if (plist == PL_LEAST_PLAYED && count < average && count > 0)
set_insert(&set, track->dbe_index);
}
__playlist_fill(name, &set);
__playlist_fill(plist, &set);
set_deinit(&set);
}
@ -119,7 +112,7 @@ void playlist_deinit()
void playlist_fixup_collection()
{
struct index_entry *ent = INDEX_ENTRY(db_get(&playlist_db, "Banned"));
struct index_entry *ent = __playlist_lookup(PL_BANNED);
struct set_iter it;
if (!ent)
@ -129,47 +122,47 @@ void playlist_fixup_collection()
queue_remove_all(collection_get_queue(), track_get(it.it_val));
}
void playlist_add(const gchar *name, struct track *track)
void playlist_add(enum playlist_t plist, struct track *track)
{
if (!track || !__playlist_is_static(name))
if (!track || !__playlist_is_static(plist))
return;
if (!playlist_has(name, track)) {
index_insert(&playlist_db, name, track->tr_dbe.dbe_index);
if (cur_plist == name)
if (!playlist_has(plist, track)) {
index_insert(&playlist_db, playlist_names[plist],
track->tr_dbe.dbe_index);
if (playlist_cur == plist)
queue_add(&playlist_q, track);
if (string_compare(name, "Banned") == 0)
if (plist == PL_BANNED)
queue_remove_all(collection_get_queue(), track);
}
}
void playlist_remove(const gchar *name, struct track *track)
void playlist_remove(enum playlist_t plist, struct track *track)
{
if (!track || !name)
if (!track)
return;
if (playlist_has(name, track)) {
index_remove(&playlist_db, name, track->tr_dbe.dbe_index);
if (cur_plist == name)
queue_remove_all(&playlist_q, track);
if (string_compare(name, "Banned") == 0)
queue_add(collection_get_queue(), track);
}
index_remove(&playlist_db, playlist_names[plist],
track->tr_dbe.dbe_index);
if (playlist_cur == plist)
queue_remove_all(&playlist_q, track);
if (plist == PL_BANNED)
queue_add(collection_get_queue(), track);
}
bool playlist_has(const gchar *name, struct track *track)
bool playlist_has(enum playlist_t plist, struct track *track)
{
if (!track || !name)
if (!track)
return false;
return index_has(&playlist_db, name, track->tr_dbe.dbe_index);
return index_has(&playlist_db, playlist_names[plist], track->tr_dbe.dbe_index);
}
void playlist_select(const gchar *name)
void playlist_select(enum playlist_t plist)
{
if (__playlist_is_static(name))
__playlist_fill_static(name);
else if (__playlist_is_dynamic(name))
__playlist_fill_dynamic(name);
if (__playlist_is_static(plist))
__playlist_fill_static(plist);
else if (__playlist_is_dynamic(plist))
__playlist_fill_dynamic(plist);
}
struct queue *playlist_get_queue()

View File

@ -41,7 +41,7 @@ public:
tab_selected_ids(ids);
for (unsigned int i = 0; i < ids.size(); i++)
playlist_add("Banned", track_get(ids[i]));
playlist_add(PL_BANNED, track_get(ids[i]));
return true;
}

View File

@ -43,7 +43,7 @@ public:
~PlaylistWindow() {}
Glib::ustring current_playlist()
enum playlist_t current_playlist()
{
Gtk::TreePath path;
Gtk::TreeModel::Row row;
@ -51,12 +51,21 @@ public:
p_treeview->get_cursor(path, col);
row = *(p_list->get_iter(path));
return row[p_cols.p_name];
if (row[p_cols.p_name] == "Favorites")
return PL_FAVORITED;
else if (row[p_cols.p_name] == "Banned")
return PL_BANNED;
else if (row[p_cols.p_name] == "Most Played")
return PL_MOST_PLAYED;
else if (row[p_cols.p_name] == "Least Played")
return PL_LEAST_PLAYED;
return PL_UNPLAYED;
}
void on_cursor_changed()
{
playlist_select(current_playlist().c_str());
playlist_select(current_playlist());
}
bool on_clicked(GdkEventButton *button)
@ -103,19 +112,17 @@ public:
bool on_key_press_event(const std::string &key)
{
std::string cur;
enum playlist_t cur;
std::vector<unsigned int> ids;
if (key != "Delete")
return Tab :: on_key_press_event(key);
cur = playlist_window->current_playlist();
if (cur == "")
return true;
tab_selected_ids(ids);
for (unsigned int i = 0; i < ids.size(); i++)
playlist_remove(cur.c_str(), track_get(ids[i]));
playlist_remove(cur, track_get(ids[i]));
return true;
}
} *p_tab;
@ -126,21 +133,21 @@ static void on_ban()
{
struct track *track = audio :: current_track();
if (o_ban->get_active()) {
if (!playlist_has("Banned", track)) {
playlist_add("Banned", track);
if (!playlist_has(PL_BANNED, track)) {
playlist_add(PL_BANNED, track);
audio :: next();
}
} else
playlist_remove("Banned", track);
playlist_remove(PL_BANNED, track);
}
static void on_favorite()
{
struct track *track = audio :: current_track();
if (o_fav->get_active())
playlist_add("Favorites", track);
playlist_add(PL_FAVORITED, track);
else
playlist_remove("Favorites", track);
playlist_remove(PL_FAVORITED, track);
}
static void playlist_added(struct queue *queue, unsigned int pos)
@ -175,8 +182,8 @@ struct queue_ops playlist_ops = {
void plist :: track_loaded(struct track *track)
{
if (p_tab) {
o_ban->set_active(playlist_has("Banned", track));
o_fav->set_active(playlist_has("Favorites", track));
o_ban->set_active(playlist_has(PL_BANNED, track));
o_fav->set_active(playlist_has(PL_FAVORITED, track));
}
}

View File

@ -220,25 +220,25 @@ bool Tab :: tab_add_to_queue(unsigned int n)
return true;
}
bool Tab :: tab_add_to_playlist(const std::string &playlist)
bool Tab :: tab_add_to_playlist(enum playlist_t plist)
{
std::vector<unsigned int> ids;
tab_selected_ids(ids);
for (unsigned int i = 0; i < ids.size(); i++)
playlist_add(playlist.c_str(), track_get(ids[i]));
playlist_add(plist, track_get(ids[i]));
return true;
}
bool Tab :: tab_favorite_selected()
{
return tab_add_to_playlist("Favorites");
return tab_add_to_playlist(PL_FAVORITED);
}
void Tab :: tab_ban_selected()
{
tab_add_to_playlist("Banned");
tab_add_to_playlist(PL_BANNED);
}

View File

@ -4,16 +4,6 @@
* The playlist manager is in charge of the various playlists Ocarina
* knows about. This code also manages a special queue used by the GUI
* to display the tracks in each playlist.
*
* Currently supported playlists are:
*
* Name | Description
* -------------|------------
* Banned | Songs that the user doesn't like.
* Favorites | Songs that the user likes.
* Unplayed | Songs that have not been played yet.
* Most Played | Songs with an above average play count.
* Least Played | Songs with a below average play count.
*/
#ifndef OCARINA_CORE_PLAYLIST_H
#define OCARINA_CORE_PLAYLIST_H
@ -25,6 +15,14 @@ extern "C" {
#include <string>
enum playlist_t {
PL_FAVORITED, /* Songs that the user likes. */
PL_BANNED, /* Songs that the user doesn't like. */
PL_UNPLAYED, /* Songs that have not been played yet. */
PL_MOST_PLAYED, /* Songs with an above average play count. */
PL_LEAST_PLAYED, /* Songs with a below average play count. */
};
/* Called to initialize the playlist manager. */
void playlist_init(struct queue_ops *);
@ -36,17 +34,17 @@ void playlist_fixup_collection();
/* Called to add a track to a playlist. */
void playlist_add(const gchar *, struct track *);
void playlist_add(enum playlist_t, struct track *);
/* Called to remove a track from a playlist. */
void playlist_remove(const gchar *, struct track *);
void playlist_remove(enum playlist_t, struct track *);
/* Called to check if a specific track is in the playlist. */
bool playlist_has(const gchar *, struct track *);
bool playlist_has(enum playlist_t, struct track *);
/* Called to fill the queue with a specific playlist. */
void playlist_select(const gchar *);
void playlist_select(enum playlist_t);
/* Called to access the playlist queue. */

View File

@ -8,6 +8,7 @@
#include <gui/queue/model.h>
#include <gui/queue/toolbar.h>
#include <gui/queue/window.h>
#include <core/playlist.h>
#include <core/queue.h>
class Tab {
@ -54,7 +55,7 @@ public:
void tab_queue_add(queue *);
bool tab_queue_selected(bool);
bool tab_add_to_queue(unsigned int);
bool tab_add_to_playlist(const std::string &);
bool tab_add_to_playlist(enum playlist_t);
bool tab_favorite_selected();
void tab_ban_selected();

View File

@ -45,34 +45,25 @@ static void test_add()
struct queue *q = playlist_get_queue();
struct track *track = track_get(0);
playlist_add(NULL, track);
test_equal(playlist_has(NULL, track), false);
playlist_add(PL_FAVORITED, NULL);
test_equal(playlist_has(PL_FAVORITED, NULL), false);
playlist_add("Favorites", NULL);
test_equal(playlist_has("Favorites", NULL), false);
playlist_add("No Playlist", track);
test_equal(playlist_has("No Playlist", track), false);
test_equal(playlist_has("Favorites", track), false);
playlist_add("Favorites", track);
test_equal(playlist_has("Favorites", track), true);
test_equal(queue_size(q), 0);
playlist_select("Favorites");
test_equal(playlist_has(PL_FAVORITED, track), false);
playlist_add(PL_FAVORITED, track);
test_equal(playlist_has(PL_FAVORITED, track), true);
test_equal(queue_size(q), 1);
playlist_add("Favorites", track);
playlist_add(PL_FAVORITED, track);
test_equal(queue_size(q), 1);
playlist_add("Favorites", track_get(1));
playlist_add(PL_FAVORITED, track_get(1));
test_equal(queue_size(q), 2);
track = track_get(2);
playlist_select("Banned");
playlist_select(PL_BANNED);
test_equal(queue_size(q), 0);
test_equal(queue_size(c), 13);
test_equal(playlist_has("Banned", track), false);
playlist_add("Banned", track);
test_equal(playlist_has("Banned", track), true);
test_equal(playlist_has(PL_BANNED, track), false);
playlist_add(PL_BANNED, track);
test_equal(playlist_has(PL_BANNED, track), true);
test_equal(queue_size(q), 1);
test_equal(queue_size(c), 12);
@ -90,29 +81,27 @@ static void test_remove()
struct track *track = track_get(0);
/* The important thing here is that we don't crash */
playlist_remove(NULL, track);
playlist_remove("Favorites", NULL);
playlist_remove("No Playlist", track);
playlist_remove(PL_FAVORITED, NULL);
playlist_select("Favorites");
playlist_select(PL_FAVORITED);
test_equal(queue_size(q), 2);
test_equal(playlist_has("Favorites", track), true);
playlist_remove("Favorites", track);
test_equal(playlist_has("Favorites", track), false);
test_equal(playlist_has(PL_FAVORITED, track), true);
playlist_remove(PL_FAVORITED, track);
test_equal(playlist_has(PL_FAVORITED, track), false);
test_equal(queue_size(q), 1);
playlist_remove("Favorites", track);
playlist_remove(PL_FAVORITED, track);
test_equal(queue_size(q), 1);
playlist_remove("Favorites", track_get(1));
playlist_remove(PL_FAVORITED, track_get(1));
test_equal(queue_size(q), 0);
track = track_get(2);
playlist_select("Banned");
playlist_select(PL_BANNED);
test_equal(queue_size(q), 1);
test_equal(queue_size(c), 12);
test_equal(playlist_has("Banned", track), true);
playlist_remove("Banned", track);
test_equal(playlist_has("Banned", track), false);
test_equal(playlist_has(PL_BANNED, track), true);
playlist_remove(PL_BANNED, track);
test_equal(playlist_has(PL_BANNED, track), false);
test_equal(queue_size(q), 0);
test_equal(queue_size(c), 13);
}
@ -131,13 +120,13 @@ static void test_dynamic()
average /= track_db_get()->db_size;
/* Only one unplayed track (tr_track == 1) */
playlist_select("Unplayed");
playlist_select(PL_UNPLAYED);
test_equal(queue_size(q), 1);
test_equal(queue_at(q, 0)->tr_track, 1);
test_equal(queue_at(q, 0)->tr_count, 0);
/* Five tracks have tr_count < average && tr_count > 0 */
playlist_select("Least Played");
playlist_select(PL_LEAST_PLAYED);
test_equal(queue_size(q), 5);
for (i = 0; i < queue_size(q); i++) {
test_loop_equal(queue_at(q, i)->tr_track, i + 2, i);
@ -145,7 +134,7 @@ static void test_dynamic()
} test_loop_passed();
/* Six tracks have tr_count > average */
playlist_select("Most Played");
playlist_select(PL_MOST_PLAYED);
test_equal(queue_size(q), 6);
for (i = 0; i < queue_size(q); i++) {
test_loop_equal(queue_at(q, i)->tr_track, i + 8, i);