From 532a761def76ca5507916dd112bf49b510df6c15 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Cl=C3=A9ment=20Stenac?= Date: Sat, 2 Sep 2006 16:59:50 +0000 Subject: [PATCH] Re-enable random. 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 | 9 ++++- src/playlist/control.c | 78 +++++++++++++++++++++++++++--------------- src/playlist/engine.c | 5 +++ src/playlist/item.c | 3 ++ src/playlist/tree.c | 18 ++++++++++ 5 files changed, 84 insertions(+), 29 deletions(-) diff --git a/include/vlc_playlist.h b/include/vlc_playlist.h index 778a025c47..cd326927ad 100644 --- a/include/vlc_playlist.h +++ b/include/vlc_playlist.h @@ -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 ); diff --git a/src/playlist/control.c b/src/playlist/control.c index 718b49d115..7cc468d9f5 100644 --- a/src/playlist/control.c +++ b/src/playlist/control.c @@ -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 */ diff --git a/src/playlist/engine.c b/src/playlist/engine.c index 55fb0888b3..dae3f17025 100644 --- a/src/playlist/engine.c +++ b/src/playlist/engine.c @@ -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); diff --git a/src/playlist/item.c b/src/playlist/item.c index fedd4cc41b..f6dbdaa8d6 100644 --- a/src/playlist/item.c +++ b/src/playlist/item.c @@ -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 */ diff --git a/src/playlist/tree.c b/src/playlist/tree.c index 3eea5e3ab3..cb18d9a192 100644 --- a/src/playlist/tree.c +++ b/src/playlist/tree.c @@ -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 * -- 2.39.2