core/playlist: Implement playlist_generic_add_front() directly
This function adds a track directly to the front of the playlist, without any existence checks. This lets us use it for the History playlist, which allows multiple tracks. Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
6dbc574954
commit
92bb742f8f
|
@ -44,7 +44,7 @@ static bool __artist_pl_add(void *data)
|
||||||
|
|
||||||
db_for_each(dbe, next, track_db_get()) {
|
db_for_each(dbe, next, track_db_get()) {
|
||||||
if (TRACK(dbe)->tr_album->al_artist == artist)
|
if (TRACK(dbe)->tr_album->al_artist == artist)
|
||||||
queue_add_front(&playlist->pl_queue, TRACK(dbe));
|
playlist_generic_add_front(playlist, TRACK(dbe));
|
||||||
}
|
}
|
||||||
|
|
||||||
playlist_generic_resort(playlist);
|
playlist_generic_resort(playlist);
|
||||||
|
|
|
@ -154,12 +154,15 @@ bool playlist_generic_add_track(struct playlist *playlist, struct track *track)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool playlist_generic_add_track_front(struct playlist *playlist,
|
bool playlist_generic_add_front(struct playlist *playlist, struct track *track)
|
||||||
struct track *track)
|
|
||||||
{
|
{
|
||||||
if (playlist_has(playlist, track))
|
if (!playlist || !track)
|
||||||
return false;
|
return false;
|
||||||
queue_add_front(&playlist->pl_queue, track);
|
|
||||||
|
playlist->pl_queue.q_length += track->tr_length;
|
||||||
|
g_queue_push_head(&playlist->pl_queue.q_tracks, track);
|
||||||
|
if (callbacks)
|
||||||
|
callbacks->pl_cb_added(playlist, track);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ static bool __lib_pl_add(void *data)
|
||||||
|
|
||||||
db_for_each(dbe, next, track_db_get()) {
|
db_for_each(dbe, next, track_db_get()) {
|
||||||
if (TRACK(dbe)->tr_library == library)
|
if (TRACK(dbe)->tr_library == library)
|
||||||
queue_add_front(&playlist->pl_queue, TRACK(dbe));
|
playlist_generic_add_front(playlist, TRACK(dbe));
|
||||||
}
|
}
|
||||||
|
|
||||||
playlist_generic_resort(playlist);
|
playlist_generic_resort(playlist);
|
||||||
|
|
|
@ -47,11 +47,11 @@ static bool sys_pl_update_func(void *data)
|
||||||
db_for_each(dbe, next, track_db_get()) {
|
db_for_each(dbe, next, track_db_get()) {
|
||||||
struct track *track = TRACK(dbe);
|
struct track *track = TRACK(dbe);
|
||||||
|
|
||||||
if (sys_pl_update_check(playlist, track) &&
|
if (!sys_pl_update_check(playlist, track))
|
||||||
!playlist_has(pl_system_get(SYS_PL_HIDDEN), track))
|
|
||||||
playlist_generic_add_track_front(playlist, track);
|
|
||||||
else
|
|
||||||
playlist_generic_remove(playlist, track);
|
playlist_generic_remove(playlist, track);
|
||||||
|
else if (!playlist_has(pl_system_get(SYS_PL_HIDDEN), track) &&
|
||||||
|
!playlist_has(playlist, track))
|
||||||
|
playlist_generic_add_front(playlist, track);
|
||||||
}
|
}
|
||||||
|
|
||||||
playlist_generic_resort(playlist);
|
playlist_generic_resort(playlist);
|
||||||
|
@ -200,7 +200,7 @@ static struct playlist_ops collection_ops = {
|
||||||
*/
|
*/
|
||||||
static bool sys_pl_history_add(struct playlist *playlist, struct track *track)
|
static bool sys_pl_history_add(struct playlist *playlist, struct track *track)
|
||||||
{
|
{
|
||||||
queue_add_front(&playlist->pl_queue, track);
|
playlist_generic_add_front(playlist, track);
|
||||||
queue_iter_set(&playlist->pl_queue, &playlist->pl_queue.q_cur, 0);
|
queue_iter_set(&playlist->pl_queue, &playlist->pl_queue.q_cur, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
12
core/queue.c
12
core/queue.c
|
@ -51,13 +51,6 @@ static inline unsigned int __queue_added(struct queue *queue,
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int __queue_add_head(struct queue *queue,
|
|
||||||
struct track *track)
|
|
||||||
{
|
|
||||||
g_queue_push_head(&queue->q_tracks, track);
|
|
||||||
return __queue_added(queue, track, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned int __queue_add_tail(struct queue *queue,
|
static inline unsigned int __queue_add_tail(struct queue *queue,
|
||||||
struct track *track)
|
struct track *track)
|
||||||
{
|
{
|
||||||
|
@ -105,8 +98,3 @@ unsigned int queue_add(struct queue *queue, struct track *track)
|
||||||
return __queue_add_sorted(queue, track);
|
return __queue_add_sorted(queue, track);
|
||||||
return __queue_add_tail(queue, track);
|
return __queue_add_tail(queue, track);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int queue_add_front(struct queue *queue, struct track *track)
|
|
||||||
{
|
|
||||||
return __queue_add_head(queue, track);
|
|
||||||
}
|
|
||||||
|
|
|
@ -275,7 +275,7 @@ GType gui_model_get_type()
|
||||||
return gui_model_type;
|
return gui_model_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gui_model_add(struct playlist *playlist, unsigned int row)
|
void gui_model_add(struct playlist *playlist, struct track *track)
|
||||||
{
|
{
|
||||||
GtkTreePath *path;
|
GtkTreePath *path;
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
|
@ -283,11 +283,12 @@ void gui_model_add(struct playlist *playlist, unsigned int row)
|
||||||
if (cur_playlist != playlist)
|
if (cur_playlist != playlist)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
path = gtk_tree_path_new_from_indices(row, -1);
|
path = gtk_tree_path_new_from_indices(0, -1);
|
||||||
__gui_model_get_iter(GTK_TREE_MODEL(gui_model), &iter, path);
|
__gui_model_get_iter(GTK_TREE_MODEL(gui_model), &iter, path);
|
||||||
gtk_tree_model_row_inserted(GTK_TREE_MODEL(gui_model), path, &iter);
|
gtk_tree_model_row_inserted(GTK_TREE_MODEL(gui_model), path, &iter);
|
||||||
__gui_model_set_runtime();
|
|
||||||
gtk_tree_path_free(path);
|
gtk_tree_path_free(path);
|
||||||
|
|
||||||
|
__gui_model_set_runtime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void gui_model_remove(struct playlist *playlist, struct track *track,
|
void gui_model_remove(struct playlist *playlist, struct track *track,
|
||||||
|
|
|
@ -42,10 +42,15 @@ static void __gui_playlist_deinit(struct queue *queue)
|
||||||
gui_filter_clear_search(queue->q_private);
|
gui_filter_clear_search(queue->q_private);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __gui_playlist_added(struct queue *queue, unsigned int row)
|
static void __gui_playlist_added(struct playlist *playlist, struct track *track)
|
||||||
{
|
{
|
||||||
gui_model_add(queue->q_private, row);
|
gui_model_add(playlist, track);
|
||||||
__gui_playlist_update_size(queue->q_private);
|
__gui_playlist_update_size(playlist);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __gui_playlist_track_added(struct queue *queue, unsigned int row)
|
||||||
|
{
|
||||||
|
__gui_playlist_added(queue->q_private, queue_at(queue, row));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __gui_playlist_removed(struct playlist *playlist, struct track *track,
|
static void __gui_playlist_removed(struct playlist *playlist, struct track *track,
|
||||||
|
@ -59,10 +64,11 @@ static void __gui_playlist_removed(struct playlist *playlist, struct track *trac
|
||||||
struct queue_ops playlist_ops = {
|
struct queue_ops playlist_ops = {
|
||||||
.qop_init = __gui_playlist_init,
|
.qop_init = __gui_playlist_init,
|
||||||
.qop_deinit = __gui_playlist_deinit,
|
.qop_deinit = __gui_playlist_deinit,
|
||||||
.qop_added = __gui_playlist_added,
|
.qop_added = __gui_playlist_track_added,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct playlist_callbacks playlist_cb = {
|
struct playlist_callbacks playlist_cb = {
|
||||||
|
.pl_cb_added = __gui_playlist_added,
|
||||||
.pl_cb_removed = __gui_playlist_removed,
|
.pl_cb_removed = __gui_playlist_removed,
|
||||||
.pl_cb_updated = gui_model_update,
|
.pl_cb_updated = gui_model_update,
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,6 +14,9 @@ enum playlist_save_flags {
|
||||||
#define PL_SAVE_ALL (PL_SAVE_TRACKS | PL_SAVE_METADATA)
|
#define PL_SAVE_ALL (PL_SAVE_TRACKS | PL_SAVE_METADATA)
|
||||||
|
|
||||||
struct playlist_callbacks {
|
struct playlist_callbacks {
|
||||||
|
/* Called to notify that a track has been added. */
|
||||||
|
void (*pl_cb_added)(struct playlist *, struct track *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called to notify that N instances of a track have been removed.
|
* Called to notify that N instances of a track have been removed.
|
||||||
* Track may be NULL to indicate that several different tracks were
|
* Track may be NULL to indicate that several different tracks were
|
||||||
|
@ -49,7 +52,7 @@ void playlist_generic_clear(struct playlist *);
|
||||||
|
|
||||||
/* Generic playlist add track operations. */
|
/* Generic playlist add track operations. */
|
||||||
bool playlist_generic_add_track(struct playlist *, struct track *);
|
bool playlist_generic_add_track(struct playlist *, struct track *);
|
||||||
bool playlist_generic_add_track_front(struct playlist *, struct track *);
|
bool playlist_generic_add_front(struct playlist *, struct track *);
|
||||||
|
|
||||||
/* Generic playlist remove track operation. */
|
/* Generic playlist remove track operation. */
|
||||||
bool playlist_generic_remove(struct playlist *, struct track *);
|
bool playlist_generic_remove(struct playlist *, struct track *);
|
||||||
|
|
|
@ -107,7 +107,4 @@ static inline struct track *queue_at(struct queue *queue, unsigned int index)
|
||||||
/* Called to add a track to the queue. */
|
/* Called to add a track to the queue. */
|
||||||
unsigned int queue_add(struct queue *, struct track *);
|
unsigned int queue_add(struct queue *, struct track *);
|
||||||
|
|
||||||
/* Called to add a track to the front of the queue. */
|
|
||||||
unsigned int queue_add_front(struct queue *, struct track *);
|
|
||||||
|
|
||||||
#endif /* OCARINA_CORE_QUEUE_H */
|
#endif /* OCARINA_CORE_QUEUE_H */
|
||||||
|
|
|
@ -52,7 +52,7 @@ GuiModel *gui_model_get(void);
|
||||||
GType gui_model_get_type();
|
GType gui_model_get_type();
|
||||||
|
|
||||||
/* Called to add a row to the model */
|
/* Called to add a row to the model */
|
||||||
void gui_model_add(struct playlist *, unsigned int);
|
void gui_model_add(struct playlist *, struct track *);
|
||||||
|
|
||||||
/* Called to remove a row from the model */
|
/* Called to remove a row from the model */
|
||||||
void gui_model_remove(struct playlist *, struct track *, unsigned int);
|
void gui_model_remove(struct playlist *, struct track *, unsigned int);
|
||||||
|
|
|
@ -30,6 +30,7 @@ static struct playlist_ops test_ops = {
|
||||||
.pl_sort = playlist_generic_sort,
|
.pl_sort = playlist_generic_sort,
|
||||||
};
|
};
|
||||||
static struct playlist_callbacks test_cb = {
|
static struct playlist_callbacks test_cb = {
|
||||||
|
.pl_cb_added = test_pl_callback,
|
||||||
.pl_cb_removed = test_pl_removed,
|
.pl_cb_removed = test_pl_removed,
|
||||||
.pl_cb_updated = test_pl_callback,
|
.pl_cb_updated = test_pl_callback,
|
||||||
};
|
};
|
||||||
|
@ -65,6 +66,7 @@ static void test_null()
|
||||||
playlist_generic_resort(NULL);
|
playlist_generic_resort(NULL);
|
||||||
playlist_clear_sort(NULL);
|
playlist_clear_sort(NULL);
|
||||||
|
|
||||||
|
g_assert_false(playlist_generic_add_front(NULL, NULL));
|
||||||
g_assert_false(playlist_generic_remove(NULL, NULL));
|
g_assert_false(playlist_generic_remove(NULL, NULL));
|
||||||
playlist_generic_update(NULL, NULL);
|
playlist_generic_update(NULL, NULL);
|
||||||
playlist_generic_clear(NULL);
|
playlist_generic_clear(NULL);
|
||||||
|
@ -82,10 +84,14 @@ static void test_playlist()
|
||||||
playlist_generic_init(&p, NULL);
|
playlist_generic_init(&p, NULL);
|
||||||
|
|
||||||
for (i = 0; i < 13; i++) {
|
for (i = 0; i < 13; i++) {
|
||||||
playlist_generic_add_track_front(&p, track_get(i));
|
|
||||||
g_assert_true(playlist_has(&p, track_get(i)));
|
|
||||||
ex_length += track_get(i)->tr_length;
|
ex_length += track_get(i)->tr_length;
|
||||||
|
playlist_generic_add_front(&p, track_get(i));
|
||||||
|
g_assert_true(playlist_has(&p, track_get(i)));
|
||||||
|
g_assert_cmpuint(p.pl_queue.q_length, ==, ex_length);
|
||||||
|
g_assert(cb_playlist == &p);
|
||||||
|
g_assert(cb_track == track_get(i));
|
||||||
}
|
}
|
||||||
|
g_assert_false(playlist_generic_add_front(&p, NULL));
|
||||||
|
|
||||||
/* Trigger an update for each track. */
|
/* Trigger an update for each track. */
|
||||||
for (i = 0; i < 13; i++) {
|
for (i = 0; i < 13; i++) {
|
||||||
|
@ -120,7 +126,7 @@ static void test_playlist()
|
||||||
|
|
||||||
/* Re-add the tracks! */
|
/* Re-add the tracks! */
|
||||||
for (i = 0; i < 13; i++) {
|
for (i = 0; i < 13; i++) {
|
||||||
playlist_generic_add_track_front(&p, track_get(i));
|
playlist_generic_add_front(&p, track_get(i));
|
||||||
g_assert_true(playlist_has(&p, track_get(i)));
|
g_assert_true(playlist_has(&p, track_get(i)));
|
||||||
ex_length += track_get(i)->tr_length;
|
ex_length += track_get(i)->tr_length;
|
||||||
}
|
}
|
||||||
|
@ -144,15 +150,16 @@ static void test_sorting()
|
||||||
g_assert_cmpuint(g_slist_length(p.pl_queue.q_sort), ==, 3);
|
g_assert_cmpuint(g_slist_length(p.pl_queue.q_sort), ==, 3);
|
||||||
playlist_clear_sort(&p);
|
playlist_clear_sort(&p);
|
||||||
g_assert_cmpuint(g_slist_length(p.pl_queue.q_sort), ==, 0);
|
g_assert_cmpuint(g_slist_length(p.pl_queue.q_sort), ==, 0);
|
||||||
cb_playlist = NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < 13; i++) {
|
for (i = 0; i < 13; i++) {
|
||||||
track = track_get(i);
|
track = track_get(i);
|
||||||
track->tr_count = (track->tr_track % 2) ? 4 : 2;
|
track->tr_count = (track->tr_track % 2) ? 4 : 2;
|
||||||
playlist_generic_add_track_front(&p, track);
|
playlist_generic_add_front(&p, track);
|
||||||
}
|
}
|
||||||
|
|
||||||
p.pl_ops = &test_noop;
|
cb_playlist = NULL;
|
||||||
|
cb_track = NULL;
|
||||||
|
p.pl_ops = &test_noop;
|
||||||
g_assert_false(playlist_sort(&p, COMPARE_TRACK));
|
g_assert_false(playlist_sort(&p, COMPARE_TRACK));
|
||||||
g_assert_null(cb_playlist);
|
g_assert_null(cb_playlist);
|
||||||
g_assert_null(cb_track);
|
g_assert_null(cb_track);
|
||||||
|
|
|
@ -13,7 +13,7 @@ void *test_queue_init(struct queue *queue, void *data)
|
||||||
void test_queue_deinit(struct queue *queue)
|
void test_queue_deinit(struct queue *queue)
|
||||||
{ gui_filter_clear_search(queue->q_private); }
|
{ gui_filter_clear_search(queue->q_private); }
|
||||||
void test_queue_add(struct queue *queue, unsigned int n)
|
void test_queue_add(struct queue *queue, unsigned int n)
|
||||||
{ gui_model_add(queue->q_private, n); }
|
{ gui_model_add(queue->q_private, queue_at(queue, n)); }
|
||||||
|
|
||||||
struct queue_ops test_ops = {
|
struct queue_ops test_ops = {
|
||||||
.qop_init = test_queue_init,
|
.qop_init = test_queue_init,
|
||||||
|
|
|
@ -28,7 +28,7 @@ void *test_queue_init(struct queue *queue, void *data)
|
||||||
void test_queue_deinit(struct queue *queue)
|
void test_queue_deinit(struct queue *queue)
|
||||||
{ }
|
{ }
|
||||||
void test_queue_add(struct queue *queue, unsigned int n)
|
void test_queue_add(struct queue *queue, unsigned int n)
|
||||||
{ gui_model_add(queue->q_private, n); }
|
{ gui_model_add(queue->q_private, queue_at(queue, n)); }
|
||||||
void test_on_load(struct track *track) {}
|
void test_on_load(struct track *track) {}
|
||||||
void test_on_state_change(GstState state) {}
|
void test_on_state_change(GstState state) {}
|
||||||
void test_on_config_pause(int count) {}
|
void test_on_config_pause(int count) {}
|
||||||
|
@ -40,6 +40,7 @@ struct queue_ops test_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct playlist_callbacks test_cb = {
|
struct playlist_callbacks test_cb = {
|
||||||
|
.pl_cb_added = gui_model_add,
|
||||||
.pl_cb_removed = gui_model_remove,
|
.pl_cb_removed = gui_model_remove,
|
||||||
.pl_cb_updated = gui_model_update,
|
.pl_cb_updated = gui_model_update,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue