[vlc-commits] core: playlist: notify on AddListener()

Romain Vimont git at videolan.org
Thu Nov 15 17:29:14 CET 2018


vlc | branch: master | Romain Vimont <rom1v at videolabs.io> | 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 <thomas at gllm.fr>

> 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();



More information about the vlc-commits mailing list