]> git.sesse.net Git - vlc/commitdiff
Re-enable random.
authorClément Stenac <zorglub@videolan.org>
Sat, 2 Sep 2006 16:59:50 +0000 (16:59 +0000)
committerClément Stenac <zorglub@videolan.org>
Sat, 2 Sep 2006 16:59:50 +0000 (16:59 +0000)
It is now based on a shuffled array of items, so that next + prev takes you back to what you were playing

include/vlc_playlist.h
src/playlist/control.c
src/playlist/engine.c
src/playlist/item.c
src/playlist/tree.c

index 778a025c47651619989797c64696edb44bae7479..cd326927adb4ec1161c7bebee25c657c4a57cb2f 100644 (file)
@@ -32,7 +32,6 @@
 
 /**
  * \defgroup vlc_playlist Playlist
- * Brief description. Longer description
  * @{
  */
 
@@ -121,6 +120,11 @@ struct playlist_t
     int                   i_input_items;
     input_item_t **       pp_input_items;
 
+    int                   i_random;     /**< Number of candidates for random */
+    playlist_item_t **    pp_random;    /**< Random candidate items */
+    int                   i_random_index; /**< Current random item */
+    vlc_bool_t            b_reset_random; /**< Recreate random array ?*/
+
     int                   i_last_playlist_id; /**< Last id to an item */
     int                   i_last_input_id ; /**< Last id on an input */
 
@@ -416,6 +420,9 @@ VLC_EXPORT( void, playlist_NodesCreateForSD, (playlist_t *, char *, playlist_ite
 VLC_EXPORT( playlist_item_t *, playlist_GetPreferredNode, ( playlist_t *p_playlist, playlist_item_t *p_node ) );
 
 /* Tree walking - These functions are only for playlist, not plugins */
+int playlist_GetAllEnabledChildren( playlist_t *p_playlist,
+                                    playlist_item_t *p_node,
+                                    playlist_item_t ***ppp_items );
 playlist_item_t *playlist_GetNextLeaf( playlist_t *p_playlist,
                                     playlist_item_t *p_root,
                                     playlist_item_t *, vlc_bool_t, vlc_bool_t );
index 718b49d1157c06509e34d15f3c176e7c6776dfc3..7cc468d9f508af962450d62f6721b804186e5dac 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * control.c : Hanle control of the playlist & running through it
+ * control.c : Handle control of the playlist & running through it
  *****************************************************************************
  * Copyright (C) 1999-2004 the VideoLAN team
  * $Id: /local/vlc/0.8.6-playlist-vlm/src/playlist/playlist.c 13741 2006-03-21T19:29:39.792444Z zorglub  $
@@ -99,6 +99,7 @@ int PlaylistVAControl( playlist_t * p_playlist, int i_query, va_list args )
     // Node can be null, it will keep the same. Use with care ...
     // Item null = take the first child of node
     case PLAYLIST_VIEWPLAY:
+        p_playlist->b_reset_random = VLC_TRUE;
         p_node = (playlist_item_t *)va_arg( args, playlist_item_t * );
         p_item = (playlist_item_t *)va_arg( args, playlist_item_t * );
         if ( p_node == NULL )
@@ -287,41 +288,62 @@ playlist_item_t * playlist_NextItem( playlist_t *p_playlist )
               p_playlist->request.i_skip == 1    ||
               p_playlist->request.i_skip == -1 ) ) ) )
     {
-#if 0
-        /* how many items to choose from ? */
-        int i_count = 0, i_new;
-        for ( i = 0; i < p_playlist->i_size; i++ )
+       PL_DEBUG( "doing random, have %i items, currently at %i, reset %i\n",
+                        p_playlist->i_random, p_playlist->i_random_index,
+                        p_playlist->b_reset_random );
+       if( p_playlist->b_reset_random )
         {
-            if ( p_playlist->pp_items[i]->p_input->i_nb_played == 0 )
-                i_count++;
-        }
-        /* Nothing left? */
-        if ( i_count == 0 )
-        {
-            /* Don't loop? Exit! */
-            if( !b_loop )
-                return NULL;
-            /* Otherwise reset the counter */
-            for ( i = 0; i < p_playlist->i_size; i++ )
+            int j;
+            FREE( p_playlist->pp_random );
+            if( !p_playlist->b_reset_random &&  !b_loop ) goto end;
+            p_playlist->i_random = 0;
+            p_playlist->i_random_index = 0;
+            p_playlist->i_random = playlist_GetAllEnabledChildren(
+                                                p_playlist,
+                                                p_playlist->status.p_node,
+                                                &p_playlist->pp_random );
+            /* Shuffle the array */
+            srand( (unsigned int)mdate() );
+            int swap = 0;
+            for( j = p_playlist->i_random -1; j > 0; j-- )
             {
-                p_playlist->pp_items[i]->p_input->i_nb_played = 0;
+                swap++;
+                int i = rand() % (j+1); /* between 0 and j */
+                playlist_item_t *p_tmp;
+                p_tmp = p_playlist->pp_random[i];
+                p_playlist->pp_random[i] = p_playlist->pp_random[j];
+                p_playlist->pp_random[j] = p_tmp;
             }
-            i_count = p_playlist->i_size;
+            p_playlist->b_reset_random = VLC_FALSE;
         }
-        srand( (unsigned int)mdate() );
-        i = rand() % i_count + 1 ;
-        /* loop thru the list and count down the unplayed items to the selected one */
-        for ( i_new = 0; i_new < p_playlist->i_size && i > 0; i_new++ )
+        else
         {
-            if ( p_playlist->pp_items[i_new]->p_input->i_nb_played == 0 )
-                i--;
+            /* Go backward or forward */
+            if( !p_playlist->request.b_request || !p_playlist->request.p_item ||
+                                               p_playlist->request.i_skip == 1 )
+                p_playlist->i_random_index++;
+            else
+                p_playlist->i_random_index--;
+            /* Handle bounds situations */
+            if( p_playlist->i_random_index == -1 )
+            {
+                if( !b_loop || p_playlist->i_random == 0 ) goto end;
+                p_playlist->i_random_index = p_playlist->i_random - 1;
+            }
+            else if( p_playlist->i_random_index == p_playlist->i_random )
+            {
+                if( !b_loop || p_playlist->i_random == 0 ) goto end;
+                p_playlist->i_random_index = 0;
+            }
         }
-        i_new--;
-
+        PL_DEBUG( "using random item %i", p_playlist->i_random_index );
+        if ( p_playlist->i_random == 0 ) goto end; /* Can this happen ?? */
+        p_new = p_playlist->pp_random[p_playlist->i_random_index];
+end:
+        if( !p_new ) p_playlist->b_reset_random = VLC_TRUE;
         p_playlist->request.i_skip = 0;
         p_playlist->request.b_request = VLC_FALSE;
-        return p_playlist->pp_items[i_new];
-#endif
+        return p_new;
     }
 
     /* Start the real work */
index 55fb0888b30383cbffa69bd1decbe9c2fbd34fa9..dae3f170259cd876029d409fc63e6a4a853e445c 100644 (file)
@@ -72,6 +72,11 @@ playlist_t * playlist_Create( vlc_object_t *p_parent )
     p_playlist->i_input_items = 0;
     p_playlist->pp_input_items = NULL;
 
+    p_playlist->i_random = 0;
+    p_playlist->pp_random = NULL;
+    p_playlist->i_random_index = 0;
+    p_playlist->b_reset_random = VLC_TRUE;
+
     i_tree = var_CreateGetBool( p_playlist, "playlist-tree" );
     p_playlist->b_always_tree = (i_tree == 1);
     p_playlist->b_never_tree = (i_tree == 2);
index fedd4cc41b51ecbc9b2cdff9ea2111f770e6e01c..f6dbdaa8d66904b46e06a4baf2f480a1fbc96492 100644 (file)
@@ -400,6 +400,7 @@ playlist_item_t *playlist_ItemToNode( playlist_t *p_playlist,
             playlist_DeleteFromInput( p_playlist, p_item_in_one->p_input->i_id,
                                       p_playlist->p_root_onelevel, VLC_FALSE );
         }
+        p_playlist->b_reset_random = VLC_TRUE;
         var_SetInteger( p_playlist, "item-change", p_item->p_input->i_id );
         return p_item_in_category;
     }
@@ -492,6 +493,7 @@ void playlist_SendAddNotify( playlist_t *p_playlist, int i_item_id,
     p_add->i_item = i_item_id;
     p_add->i_node = i_node_id;
     val.p_address = p_add;
+    p_playlist->b_reset_random = VLC_TRUE;
     var_Set( p_playlist, "item-append", val );
     free( p_add );
 }
@@ -603,6 +605,7 @@ int DeleteInner( playlist_t * p_playlist, playlist_item_t *p_item,
     {
         return playlist_NodeDelete( p_playlist, p_item, VLC_TRUE, VLC_FALSE );
     }
+    p_playlist->b_reset_random = VLC_TRUE;
     var_SetInteger( p_playlist, "item-deleted", i_id );
 
     /* Remove the item from the bank */
index 3eea5e3ab3fb1a952160a8f31d1d2757d14dd45d..cb18d9a192b820bc120cc29a015a546264e71af7 100644 (file)
@@ -359,6 +359,24 @@ playlist_item_t *playlist_GetLastLeaf(playlist_t *p_playlist,
     return NULL;
 }
 
+int playlist_GetAllEnabledChildren( playlist_t *p_playlist,
+                                    playlist_item_t *p_node,
+                                    playlist_item_t ***ppp_items )
+{
+    int i_count = 0;
+    playlist_item_t *p_next = NULL;
+    while( 1 )
+    {
+        p_next = playlist_GetNextLeaf( p_playlist, p_node,
+                                       p_next, VLC_TRUE, VLC_TRUE );
+        if( p_next )
+            INSERT_ELEM( *ppp_items, i_count, i_count, p_next );
+        else
+            break;
+    }
+    return i_count;
+}
+
 /**
  * Finds the next item to play
  *