vlc | branch: master | Romain Vimont <[email protected]> | Tue Oct 16 15:57:55 2018 +0200| [1bfc79ccd638b825ccc6dc196849d1c48707bd8a] | committer: Thomas Guillem
core: playlist: notify on AddListener() When a client registers a listener, it may optionally receive the current state of the playlist via callbacks. This provides a convenient way to initialize clients automatically. Signed-off-by: Thomas Guillem <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=1bfc79ccd638b825ccc6dc196849d1c48707bd8a --- include/vlc_playlist.h | 16 +++++-- src/playlist/notify.c | 23 ++++++++++- src/playlist/test.c | 110 ++++++++++++++++++++++++++++++++++++------------- 3 files changed, 116 insertions(+), 33 deletions(-) diff --git a/include/vlc_playlist.h b/include/vlc_playlist.h index 9253bbb90d..e0e56c4bb0 100644 --- a/include/vlc_playlist.h +++ b/include/vlc_playlist.h @@ -366,15 +366,23 @@ vlc_playlist_Unlock(vlc_playlist_t *); * Return an opaque listener identifier, to be passed to * vlc_player_RemoveListener(). * - * \param playlist the playlist, locked - * \param cbs the callbacks (must be valid until the listener is removed) - * \param userdata userdata provided as a parameter in callbacks + * If notify_current_state is true, the callbacks are called once with the + * current state of the playlist. This is useful because when a client + * registers to the playlist, it may already contain items. Calling callbacks + * is a convenient way to initialize the client automatically. + * + * \param playlist the playlist, locked + * \param cbs the callbacks (must be valid until the listener + * is removed) + * \param userdata userdata provided as a parameter in callbacks + * \param notify_current_state true to notify the current state immediately via + * callbacks * \return a listener identifier, or NULL if an error occurred */ VLC_API VLC_USED vlc_playlist_listener_id * vlc_playlist_AddListener(vlc_playlist_t *playlist, const struct vlc_playlist_callbacks *cbs, - void *userdata); + void *userdata, bool notify_current_state); /** * Remove a player listener. diff --git a/src/playlist/notify.c b/src/playlist/notify.c index 3ac68b12ed..b3133d6a8d 100644 --- a/src/playlist/notify.c +++ b/src/playlist/notify.c @@ -27,10 +27,28 @@ #include "item.h" #include "playlist.h" +static void +vlc_playlist_NotifyCurrentState(vlc_playlist_t *playlist, + vlc_playlist_listener_id *listener) +{ + vlc_playlist_NotifyListener(playlist, listener, on_items_reset, + playlist->items.data, playlist->items.size); + vlc_playlist_NotifyListener(playlist, listener, on_playback_repeat_changed, + playlist->repeat); + vlc_playlist_NotifyListener(playlist, listener, on_playback_order_changed, + playlist->order); + vlc_playlist_NotifyListener(playlist, listener, on_current_index_changed, + playlist->current); + vlc_playlist_NotifyListener(playlist, listener, on_has_prev_changed, + playlist->has_prev); + vlc_playlist_NotifyListener(playlist, listener, on_has_next_changed, + playlist->has_next); +} + vlc_playlist_listener_id * vlc_playlist_AddListener(vlc_playlist_t *playlist, const struct vlc_playlist_callbacks *cbs, - void *userdata) + void *userdata, bool notify_current_state) { vlc_playlist_AssertLocked(playlist); @@ -42,6 +60,9 @@ vlc_playlist_AddListener(vlc_playlist_t *playlist, listener->userdata = userdata; vlc_list_append(&listener->node, &playlist->listeners); + if (notify_current_state) + vlc_playlist_NotifyCurrentState(playlist, listener); + return listener; } diff --git a/src/playlist/test.c b/src/playlist/test.c index 5c3b75f3be..c42254ec22 100644 --- a/src/playlist/test.c +++ b/src/playlist/test.c @@ -569,7 +569,7 @@ test_items_added_callbacks(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); int ret = vlc_playlist_AppendOne(playlist, media[0]); @@ -667,7 +667,7 @@ test_items_moved_callbacks(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); vlc_playlist_Move(playlist, 2, 3, 5); @@ -783,7 +783,7 @@ test_items_removed_callbacks(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); vlc_playlist_RemoveOne(playlist, 4); @@ -874,7 +874,7 @@ test_items_reset_callbacks(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); callback_ctx_reset(&ctx); @@ -920,7 +920,7 @@ test_playback_repeat_changed_callbacks(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); vlc_playlist_SetPlaybackRepeat(playlist, VLC_PLAYLIST_PLAYBACK_REPEAT_ALL); @@ -951,7 +951,7 @@ test_playback_order_changed_callbacks(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); vlc_playlist_SetPlaybackOrder(playlist, VLC_PLAYLIST_PLAYBACK_ORDER_RANDOM); @@ -969,6 +969,65 @@ test_playback_order_changed_callbacks(void) } static void +test_callbacks_on_add_listener(void) +{ + vlc_playlist_t *playlist = vlc_playlist_New(NULL); + assert(playlist); + + input_item_t *media[10]; + CreateDummyMediaArray(media, 10); + + /* initial playlist with 10 items */ + int ret = vlc_playlist_Append(playlist, media, 10); + assert(ret == VLC_SUCCESS); + + vlc_playlist_SetPlaybackRepeat(playlist, VLC_PLAYLIST_PLAYBACK_REPEAT_ALL); + vlc_playlist_SetPlaybackOrder(playlist, VLC_PLAYLIST_PLAYBACK_ORDER_NORMAL); + + ret = vlc_playlist_GoTo(playlist, 5); + assert(ret == VLC_SUCCESS); + + struct vlc_playlist_callbacks cbs = { + .on_items_reset = callback_on_items_reset, + .on_playback_repeat_changed = callback_on_playback_repeat_changed, + .on_playback_order_changed = callback_on_playback_order_changed, + .on_current_index_changed = callback_on_current_index_changed, + .on_has_prev_changed = callback_on_has_prev_changed, + .on_has_next_changed = callback_on_has_next_changed, + }; + + struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; + vlc_playlist_listener_id *listener = + vlc_playlist_AddListener(playlist, &cbs, &ctx, true); + assert(listener); + + assert(ctx.vec_items_reset.size == 1); + assert(ctx.vec_items_reset.data[0].count == 10); + + assert(ctx.vec_playback_repeat_changed.size == 1); + assert(ctx.vec_playback_repeat_changed.data[0].repeat == + VLC_PLAYLIST_PLAYBACK_REPEAT_ALL); + + assert(ctx.vec_playback_order_changed.size == 1); + assert(ctx.vec_playback_order_changed.data[0].order == + VLC_PLAYLIST_PLAYBACK_ORDER_NORMAL); + + assert(ctx.vec_current_index_changed.size == 1); + assert(ctx.vec_current_index_changed.data[0].current == 5); + + assert(ctx.vec_has_prev_changed.size == 1); + assert(ctx.vec_has_prev_changed.data[0].has_prev); + + assert(ctx.vec_has_next_changed.size == 1); + assert(ctx.vec_has_next_changed.data[0].has_next); + + callback_ctx_destroy(&ctx); + vlc_playlist_RemoveListener(playlist, listener); + DestroyMediaArray(media, 10); + vlc_playlist_Delete(playlist); +} + +static void test_index_of(void) { vlc_playlist_t *playlist = vlc_playlist_New(NULL); @@ -1018,7 +1077,7 @@ test_prev(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); playlist->current = 2; /* last item */ @@ -1094,7 +1153,7 @@ test_next(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); playlist->current = 0; /* first item */ @@ -1170,7 +1229,7 @@ test_goto(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); /* go to an item in the middle */ @@ -1284,7 +1343,7 @@ test_request_insert(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); /* insert 5 items at index 10 (out-of-bounds) */ @@ -1329,7 +1388,7 @@ test_request_remove_with_matching_hint(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); vlc_playlist_item_t *items_to_remove[] = { @@ -1381,7 +1440,7 @@ test_request_remove_without_hint(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); vlc_playlist_item_t *items_to_remove[] = { @@ -1433,7 +1492,7 @@ test_request_remove_adapt(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); vlc_playlist_item_t *dummy = vlc_playlist_item_New(media[10]); @@ -1505,7 +1564,7 @@ test_request_move_with_matching_hint(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); vlc_playlist_item_t *items_to_move[] = { @@ -1561,7 +1620,7 @@ test_request_move_without_hint(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); vlc_playlist_item_t *items_to_move[] = { @@ -1631,7 +1690,7 @@ test_request_move_adapt(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); vlc_playlist_item_t *dummy = vlc_playlist_item_New(media[15]); @@ -1734,7 +1793,7 @@ test_request_goto_with_matching_hint(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); /* go to an item in the middle, with incorrect index_hint */ @@ -1781,7 +1840,7 @@ test_request_goto_without_hint(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); /* go to an item in the middle, with incorrect index_hint */ @@ -1827,7 +1886,7 @@ test_request_goto_adapt(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); /* go to an item in the middle, with incorrect index_hint */ @@ -1876,7 +1935,7 @@ test_random(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); assert(!vlc_playlist_HasPrev(playlist)); @@ -2016,12 +2075,9 @@ test_shuffle(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); - /* on_items_reset is called once during AddListener() */ - callback_ctx_reset(&ctx); - playlist->current = 4; playlist->has_prev = true; playlist->has_next = true; @@ -2108,12 +2164,9 @@ test_sort(void) struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; vlc_playlist_listener_id *listener = - vlc_playlist_AddListener(playlist, &cbs, &ctx); + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); - /* on_items_reset is called once during AddListener() */ - callback_ctx_reset(&ctx); - playlist->current = 0; playlist->has_prev = false; playlist->has_next = true; @@ -2200,6 +2253,7 @@ int main(void) test_items_reset_callbacks(); test_playback_repeat_changed_callbacks(); test_playback_order_changed_callbacks(); + test_callbacks_on_add_listener(); test_index_of(); test_prev(); test_next(); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
