Commit 532a761d authored by Clément Stenac's avatar Clément Stenac

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
parent d2b97910
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
/** /**
* \defgroup vlc_playlist Playlist * \defgroup vlc_playlist Playlist
* Brief description. Longer description
* @{ * @{
*/ */
...@@ -121,6 +120,11 @@ struct playlist_t ...@@ -121,6 +120,11 @@ struct playlist_t
int i_input_items; int i_input_items;
input_item_t ** pp_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_playlist_id; /**< Last id to an item */
int i_last_input_id ; /**< Last id on an input */ int i_last_input_id ; /**< Last id on an input */
...@@ -416,6 +420,9 @@ VLC_EXPORT( void, playlist_NodesCreateForSD, (playlist_t *, char *, playlist_ite ...@@ -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 ) ); 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 */ /* 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 *playlist_GetNextLeaf( playlist_t *p_playlist,
playlist_item_t *p_root, playlist_item_t *p_root,
playlist_item_t *, vlc_bool_t, vlc_bool_t ); playlist_item_t *, vlc_bool_t, vlc_bool_t );
......
/***************************************************************************** /*****************************************************************************
* 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 * 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 $ * $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 ) ...@@ -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 ... // Node can be null, it will keep the same. Use with care ...
// Item null = take the first child of node // Item null = take the first child of node
case PLAYLIST_VIEWPLAY: case PLAYLIST_VIEWPLAY:
p_playlist->b_reset_random = VLC_TRUE;
p_node = (playlist_item_t *)va_arg( args, playlist_item_t * ); p_node = (playlist_item_t *)va_arg( args, playlist_item_t * );
p_item = (playlist_item_t *)va_arg( args, playlist_item_t * ); p_item = (playlist_item_t *)va_arg( args, playlist_item_t * );
if ( p_node == NULL ) if ( p_node == NULL )
...@@ -287,41 +288,62 @@ playlist_item_t * playlist_NextItem( playlist_t *p_playlist ) ...@@ -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 ||
p_playlist->request.i_skip == -1 ) ) ) ) p_playlist->request.i_skip == -1 ) ) ) )
{ {
#if 0 PL_DEBUG( "doing random, have %i items, currently at %i, reset %i\n",
/* how many items to choose from ? */ p_playlist->i_random, p_playlist->i_random_index,
int i_count = 0, i_new; p_playlist->b_reset_random );
for ( i = 0; i < p_playlist->i_size; i++ ) if( p_playlist->b_reset_random )
{ {
if ( p_playlist->pp_items[i]->p_input->i_nb_played == 0 ) int j;
i_count++; FREE( p_playlist->pp_random );
} if( !p_playlist->b_reset_random && !b_loop ) goto end;
/* Nothing left? */ p_playlist->i_random = 0;
if ( i_count == 0 ) p_playlist->i_random_index = 0;
{ p_playlist->i_random = playlist_GetAllEnabledChildren(
/* Don't loop? Exit! */ p_playlist,
if( !b_loop ) p_playlist->status.p_node,
return NULL; &p_playlist->pp_random );
/* Otherwise reset the counter */ /* Shuffle the array */
for ( i = 0; i < p_playlist->i_size; i++ ) 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() ); else
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++ )
{ {
if ( p_playlist->pp_items[i_new]->p_input->i_nb_played == 0 ) /* Go backward or forward */
i--; 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.i_skip = 0;
p_playlist->request.b_request = VLC_FALSE; p_playlist->request.b_request = VLC_FALSE;
return p_playlist->pp_items[i_new]; return p_new;
#endif
} }
/* Start the real work */ /* Start the real work */
......
...@@ -72,6 +72,11 @@ playlist_t * playlist_Create( vlc_object_t *p_parent ) ...@@ -72,6 +72,11 @@ playlist_t * playlist_Create( vlc_object_t *p_parent )
p_playlist->i_input_items = 0; p_playlist->i_input_items = 0;
p_playlist->pp_input_items = NULL; 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" ); i_tree = var_CreateGetBool( p_playlist, "playlist-tree" );
p_playlist->b_always_tree = (i_tree == 1); p_playlist->b_always_tree = (i_tree == 1);
p_playlist->b_never_tree = (i_tree == 2); p_playlist->b_never_tree = (i_tree == 2);
......
...@@ -400,6 +400,7 @@ playlist_item_t *playlist_ItemToNode( playlist_t *p_playlist, ...@@ -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, playlist_DeleteFromInput( p_playlist, p_item_in_one->p_input->i_id,
p_playlist->p_root_onelevel, VLC_FALSE ); 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 ); var_SetInteger( p_playlist, "item-change", p_item->p_input->i_id );
return p_item_in_category; return p_item_in_category;
} }
...@@ -492,6 +493,7 @@ void playlist_SendAddNotify( playlist_t *p_playlist, int i_item_id, ...@@ -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_item = i_item_id;
p_add->i_node = i_node_id; p_add->i_node = i_node_id;
val.p_address = p_add; val.p_address = p_add;
p_playlist->b_reset_random = VLC_TRUE;
var_Set( p_playlist, "item-append", val ); var_Set( p_playlist, "item-append", val );
free( p_add ); free( p_add );
} }
...@@ -603,6 +605,7 @@ int DeleteInner( playlist_t * p_playlist, playlist_item_t *p_item, ...@@ -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 ); 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 ); var_SetInteger( p_playlist, "item-deleted", i_id );
/* Remove the item from the bank */ /* Remove the item from the bank */
......
...@@ -359,6 +359,24 @@ playlist_item_t *playlist_GetLastLeaf(playlist_t *p_playlist, ...@@ -359,6 +359,24 @@ playlist_item_t *playlist_GetLastLeaf(playlist_t *p_playlist,
return NULL; 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 * Finds the next item to play
* *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment