Changeset 799b2826ee321796c8c4695c5a7b7489ed5da851

Show
Ignore:
Timestamp:
10/21/06 13:09:51 (2 years ago)
Author:
Clément Stenac <zorglub@videolan.org>
git-committer:
Clément Stenac <zorglub@videolan.org> 1161428991 +0000
git-parent:

[c925ed563df12610851862d43f0cd6b30c37dec8]

git-author:
Clément Stenac <zorglub@videolan.org> 1161428991 +0000
Message:

Playlist

  • Remove the random special case
  • Use the array of currently playing items for all cases
  • Convert array items to array API
  • Replace standard searches in sorted arrays by bsearches
  • Size is not yet fixed (next round).

Array

  • Add reset/value and bsearch functions
  • Add foreach helper
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • include/vlc_arrays.h

    r266fb28 r799b282  
    119119 
    120120/** 
    121  * Binary search in an array 
     121 * Binary search in a sorted array. The key must be comparable by < and > 
    122122 * \param entries array of entries 
    123123 * \param count number of entries 
     
    219219    array.p_elems = NULL; 
    220220 
     221#define ARRAY_RESET(array)                                                  \ 
     222    array.i_alloc = 0;                                                      \ 
     223    array.i_size = 0;                                                       \ 
     224    free( array.p_elems ); array.p_elems = NULL; 
     225 
    221226#define ARRAY_APPEND(array, elem) {                                         \ 
    222227    _ARRAY_GROW1(array);                                                    \ 
     
    245250} 
    246251 
     252#define ARRAY_VAL(array, pos) array.p_elems[pos] 
     253 
     254#define ARRAY_BSEARCH(array, elem, zetype, key, answer) \ 
     255    BSEARCH( array.p_elems, array.i_size, elem, zetype, key, answer) 
     256 
     257#define FOREACH_ARRAY( item, array ) { \ 
     258    int fe_idx; \ 
     259    for( fe_idx = 0 ; fe_idx < array.i_size ; fe_idx++ ) \ 
     260    { \ 
     261        item = array.p_elems[fe_idx]; 
     262 
     263#define FOREACH_END() } } 
     264 
    247265#endif 
  • include/vlc_playlist.h

    r9cd8ee7 r799b282  
    2727#include <assert.h> 
    2828 
    29 /** 
    30  *  \file 
    31  *  This file contain structures and function prototypes related 
    32  * to the playlist in vlc 
    33  */ 
    34  
    35 /*
     29TYPEDEF_ARRAY(playlist_item_t*, playlist_item_array_t); 
     30TYPEDEF_ARRAY(input_item_t*, input_item_array_t); 
     31/** 
     32 * \file 
     33 * This file contain structures and function prototypes related 
     34 * to the playlist in vlc 
     35
    3636 * \defgroup vlc_playlist Playlist 
    3737 * @{ 
     
    103103    int                   i_enabled; /**< How many items are enabled ? */ 
    104104 
    105     /* Arrays of items */ 
    106     int                   i_size;   /**< total size of the list */ 
    107     playlist_item_t **    pp_items; /**< array of pointers to the 
    108                                      * playlist items */ 
    109     int                   i_all_size; /**< size of list of items and nodes */ 
    110     playlist_item_t **    pp_all_items; /**< array of pointers to the 
    111                                          * playlist items and nodes */ 
    112     int                   i_input_items; 
    113     input_item_t **       pp_input_items; 
    114  
    115     int                   i_random;     /**< Number of candidates for random */ 
    116     playlist_item_t **    pp_random;    /**< Random candidate items */ 
    117     int                   i_random_index; /**< Current random item */ 
    118     vlc_bool_t            b_reset_random; /**< Recreate random array ?*/ 
     105    playlist_item_array_t items; /**< Arrays of items */ 
     106    playlist_item_array_t all_items; /**< Array of items and nodes */ 
     107 
     108    input_item_array_t    input_items; /**< Array of input items */ 
     109 
     110    playlist_item_array_t current; /**< Items currently being played */ 
     111    int                   i_current_index; /**< Index in current array */ 
     112    /** Reset current item ? */ 
     113    vlc_bool_t            b_reset_currently_playing; 
    119114 
    120115    int                   i_last_playlist_id; /**< Last id to an item */ 
     
    346341} 
    347342 
    348 /** Add an input item to the playlist node  
     343/** Add an input item to the playlist node 
    349344 * \see playlist_AddInput 
    350345 */ 
     
    434429    vlc_bool_t b_empty; 
    435430    vlc_mutex_lock( &p_playlist->object_lock ); 
    436     b_empty = p_playlist->i_size == 0; 
     431    b_empty = p_playlist->items.i_size == 0; 
    437432    vlc_mutex_unlock( &p_playlist->object_lock ); 
    438433    return( b_empty ); 
  • modules/control/hotkeys.c

    r353ece4 r799b282  
    797797 
    798798    char *psz_bookmark = strdup( val.psz_string ); 
    799     for( i = 0; i < p_playlist->i_size; i++) 
     799    for( i = 0; i < p_playlist->items.i_size; i++) 
    800800    { 
    801801        if( !strcmp( psz_bookmark, 
    802                      p_playlist->pp_items[i]->p_input->psz_uri ) ) 
     802                     ARRAY_VAL( p_playlist->items,i )->p_input->psz_uri ) ) 
    803803        { 
    804804            playlist_LockControl( p_playlist, PLAYLIST_VIEWPLAY, NULL, 
    805                                   p_playlist->pp_items[i] ); 
     805                                  ARRAY_VAL( p_playlist->items, i ) ); 
    806806            break; 
    807807        } 
  • modules/control/http/macro.c

    r4963328 r799b282  
    399399                    } 
    400400 
    401                     for( i = p_sys->p_playlist->i_size - 1 ; i >= 0; i-- ) 
     401                    for( i = p_sys->p_playlist->items.i_size - 1 ; i >= 0; i-- ) 
    402402                    { 
    403403                        /* Check if the item is in the keep list */ 
     
    405405                        { 
    406406                            if( p_items[j] == 
    407                                 p_sys->p_playlist->pp_items[i]->p_input->i_id ) 
     407                                 ARRAY_VAL(p_sys->p_playlist->items,i) 
     408                                                ->p_input->i_id) 
    408409                                break; 
    409410                        } 
     
    411412                        { 
    412413                            playlist_LockDeleteAllFromInput( p_sys->p_playlist, 
    413                             p_sys->p_playlist->pp_items[i]->p_input->i_id ); 
     414                           p_sys->p_playlist->items.p_elems[i]->p_input->i_id ); 
    414415                            msg_Dbg( p_intf, "requested playlist delete: %d", 
    415416                                     i ); 
  • modules/gui/macosx/controls.m

    rd016a42 r799b282  
    6969 
    7070    vlc_mutex_lock( &p_playlist->object_lock ); 
    71     if( p_playlist->i_size <= 0
     71    if( playlist_IsEmpty( p_playlist )
    7272    { 
    7373        vlc_mutex_unlock( &p_playlist->object_lock ); 
     
    813813             [[o_mi title] isEqualToString: _NS("Next")] ) 
    814814    { 
    815             bEnabled = p_playlist->i_size > 1; 
     815        /** \todo fix i_size use */ 
     816            bEnabled = p_playlist->items.i_size > 1; 
    816817    } 
    817818    else if( [[o_mi title] isEqualToString: _NS("Random")] ) 
  • modules/gui/macosx/intf.m

    r9d7bec3 r799b282  
    10681068 
    10691069        playlist_t * p_playlist = pl_Yield( p_intf ); 
    1070         b_plmul = p_playlist->i_size > 1; 
     1070    /** \todo fix i_size use */ 
     1071        b_plmul = p_playlist->items.i_size > 1; 
    10711072 
    10721073        vlc_object_release( p_playlist ); 
  • modules/gui/macosx/playlist.m

    r1194766 r799b282  
    465465    playlist_t *p_playlist = pl_Yield( VLCIntf ); 
    466466 
    467     if( p_playlist->i_size >= 2 ) 
     467    /** \todo fix i_size use */ 
     468    if( p_playlist->items.i_size >= 2 ) 
    468469    { 
    469470        [o_status_field setStringValue: [NSString stringWithFormat: 
    470                     _NS("%i items in the playlist"), p_playlist->i_size]]; 
     471                    _NS("%i items in the playlist"), p_playlist->items.i_size]]; 
    471472    } 
    472473    else 
    473474    { 
    474         if( p_playlist->i_size == 0
     475        if( playlist_IsEmpty( p_playlist )
    475476        { 
    476477            [o_status_field setStringValue: _NS("No items in the playlist")]; 
     
    13671368    /* FIXME: playlist->i_size doesn't provide the correct number of items anymore 
    13681369     * check the playlist API for the fixed function, once zorglub implemented it -- fpk, 9/17/06 */ 
    1369  
    1370     if( p_playlist->i_size >= 2 ) 
     1370    /** \todo fix i_size use */ 
     1371    if( p_playlist->items.i_size >= 2 ) 
    13711372    { 
    13721373        [o_status_field setStringValue: [NSString stringWithFormat: 
    1373                     _NS("%i items in the playlist"), p_playlist->i_size]]; 
     1374                    _NS("%i items in the playlist"), p_playlist->items.i_size]]; 
    13741375    } 
    13751376    else 
    13761377    { 
    1377         if( p_playlist->i_size == 0
     1378        if( playlist_IsEmpty( p_playlist )
    13781379        { 
    13791380            [o_status_field setStringValue: _NS("No items in the playlist")]; 
  • modules/gui/qt4/main_interface.cpp

    rac471f2 r799b282  
    557557void MainInterface::play() 
    558558{ 
    559     if( !THEPL->i_size || !THEPL->i_enabled ) 
     559    if( !playlist_IsEmpty(THEPL) || !THEPL->i_enabled ) 
    560560    { 
    561561        /* The playlist is empty, open a file requester */ 
  • modules/gui/qt4/menus.cpp

    r141dd1d r799b282  
    355355            MIM_SADD( qtr("Pause"), "", "", togglePlayPause() ) \ 
    356356    } \ 
    357     else if( THEPL->i_size && THEPL->i_enabled ) \ 
     357    else if( THEPL->items.i_size && THEPL->i_enabled ) \ 
    358358        MIM_SADD( qtr("Play"), "", "", togglePlayPause() ) \ 
    359359    \ 
  • modules/gui/skins2/commands/cmd_input.cpp

    radc858d r799b282  
    3636    } 
    3737 
    38     if( pPlaylist->i_size ) 
    39     { 
     38    if( !playlist_IsEmpty( pPlaylist ) ) 
    4039        playlist_Play( pPlaylist ); 
    41     } 
    4240    else 
    4341    { 
  • src/control/mediacontrol_core.c

    r90d2639 r799b282  
    221221 
    222222    vlc_mutex_lock( &p_playlist->object_lock ); 
    223     if( p_playlist->i_size ) 
     223    if( p_playlist->items.i_size ) 
    224224    { 
    225225        int i_from; 
     
    361361 
    362362    vlc_mutex_lock( &p_playlist->object_lock ); 
    363     i_playlist_size = p_playlist->i_size; 
     363    i_playlist_size = p_playlist->items.i_size; 
    364364 
    365365    retval = mediacontrol_PlaylistSeq__alloc( i_playlist_size ); 
     
    367367    for( i_index = 0 ; i_index < i_playlist_size ; i_index++ ) 
    368368    { 
    369         retval->data[i_index] = strdup( p_playlist->pp_items[i_index]->p_input->psz_uri ); 
     369        retval->data[i_index] = strdup( ARRAY_VAL(p_playlist->items, i_index)->p_input->psz_uri ); 
    370370    } 
    371371    vlc_mutex_unlock( &p_playlist->object_lock ); 
  • src/control/playlist.c

    r822485d r799b282  
    4545    ///\todo Handle additionnal options 
    4646 
    47     if( PL->i_size == 0 ) RAISEVOID( "Empty playlist" ); 
     47    if( PL->items.i_size == 0 ) RAISEVOID( "Empty playlist" ); 
    4848    if( i_id > 0 ) 
    4949    { 
     
    137137{ 
    138138    assert( PL ); 
    139     return PL->i_size; 
     139    return PL->items.i_size; 
    140140} 
    141141 
  • src/input/item.c

    r2ffa2bd r799b282  
    7777    input_ItemClean( p_input ); 
    7878 
    79     for( i = 0 ; i< p_playlist->i_input_items ; i++ ) 
    80     { 
    81         if( p_playlist->pp_input_items[i]->i_id == p_input->i_id ) 
    82         { 
    83             REMOVE_ELEM( p_playlist->pp_input_items, 
    84                          p_playlist->i_input_items, i ); 
    85             break; 
    86         } 
    87     } 
     79    ARRAY_BSEARCH( p_playlist->input_items,->i_id, int, p_input->i_id, i); 
     80    if( i != -1 ) 
     81        ARRAY_REMOVE( p_playlist->input_items, i); 
     82 
    8883    pl_Release( p_obj ); 
    8984    free( p_input ); 
     
    187182input_item_t *input_ItemGetById( playlist_t *p_playlist, int i_id ) 
    188183{ 
    189     int i, i_top, i_bottom; 
    190     i_bottom = 0; i_top = p_playlist->i_input_items -1; 
    191     i = i_top  /2 ; 
    192     while( p_playlist->pp_input_items[i]->i_id != i_id && 
    193            i_top > i_bottom ) 
    194     { 
    195         if( p_playlist->pp_input_items[i]->i_id < i_id ) 
    196             i_bottom = i + 1; 
    197         else 
    198             i_top = i - 1; 
    199         i = i_bottom + ( i_top - i_bottom ) / 2; 
    200     } 
    201     if( p_playlist->pp_input_items[i]->i_id == i_id ) 
    202     { 
    203         return p_playlist->pp_input_items[i]; 
    204     } 
     184    int i; 
     185    ARRAY_BSEARCH( p_playlist->input_items, ->i_id, int, i_id, i); 
     186    if( i != -1 ) 
     187        return ARRAY_VAL( p_playlist->input_items, i); 
    205188    return NULL; 
    206189} 
     
    229212    PL_LOCK; 
    230213    p_input->i_id = ++p_playlist->i_last_input_id; 
    231     TAB_APPEND( p_playlist->i_input_items, 
    232                 p_playlist->pp_input_items, 
    233                 p_input ); 
     214    ARRAY_APPEND( p_playlist->input_items, p_input ); 
    234215    PL_UNLOCK; 
    235216    pl_Release( p_obj ); 
  • src/libvlc.c

    r2ffa2bd r799b282  
    671671    int i_size; 
    672672    LIBVLC_PLAYLIST_FUNC; 
    673     i_size = p_libvlc->p_playlist->i_size; 
     673    i_size = p_libvlc->p_playlist->items.i_size; 
    674674    LIBVLC_PLAYLIST_FUNC_END; 
    675675    return i_size; 
  • src/playlist/control.c

    reb463ca r799b282  
    8585    vlc_value_t val; 
    8686 
    87     if( p_playlist->i_size <= 0 ) 
    88     { 
     87    if( p_playlist->items.i_size <= 0 ) 
    8988        return VLC_EGENERIC; 
    90     } 
    9189 
    9290    switch( i_query ) 
     
    10199    // Item null = take the first child of node 
    102100    case PLAYLIST_VIEWPLAY: 
    103         p_playlist->b_reset_random = VLC_TRUE; 
    104101        p_node = (playlist_item_t *)va_arg( args, playlist_item_t * ); 
    105102        p_item = (playlist_item_t *)va_arg( args, playlist_item_t * ); 
     
    114111        p_playlist->request.p_node = p_node; 
    115112        p_playlist->request.p_item = p_item; 
     113        if( p_item && var_GetBool( p_playlist, "random" ) ) 
     114            p_playlist->b_reset_currently_playing = VLC_TRUE; 
    116115        break; 
    117116 
     
    262261 *****************************************************************************/ 
    263262 
     263static void ResyncCurrentIndex(playlist_t *p_playlist, playlist_item_t *p_cur ) 
     264{ 
     265     PL_DEBUG("resyncing on %s", PLI_NAME(p_cur) ); 
     266     /* Simply resync index */ 
     267     int i; 
     268     p_playlist->i_current_index = -1; 
     269     for( i = 0 ; i< p_playlist->current.i_size; i++ ) 
     270     { 
     271          if( ARRAY_VAL(p_playlist->current, i) == p_cur ) 
     272          { 
     273              p_playlist->i_current_index = i; 
     274              break; 
     275          } 
     276     } 
     277     PL_DEBUG("%s is at %i", PLI_NAME(p_cur), p_playlist->i_current_index ); 
     278} 
     279 
     280static void ResetCurrentlyPlaying( playlist_t *p_playlist, vlc_bool_t b_random, 
     281                                   playlist_item_t *p_cur ) 
     282{ 
     283    playlist_item_t *p_next = NULL; 
     284    PL_DEBUG("rebuilding array of current - root %s", 
     285              PLI_NAME(p_playlist->status.p_node) ); 
     286    ARRAY_RESET(p_playlist->current); 
     287    p_playlist->i_current_index = -1; 
     288    while( 1 ) 
     289    { 
     290        /** FIXME: this is *slow* */ 
     291        p_next = playlist_GetNextLeaf( p_playlist, 
     292                                       p_playlist->status.p_node, 
     293                                       p_next, VLC_TRUE, VLC_FALSE ); 
     294        if( p_next ) 
     295        { 
     296            if( p_next == p_cur ) 
     297                p_playlist->i_current_index = p_playlist->current.i_size; 
     298            ARRAY_APPEND( p_playlist->current, p_next); 
     299        } 
     300        else break; 
     301    } 
     302    PL_DEBUG("rebuild done - %i items, index %i", p_playlist->current.i_size, 
     303                                                  p_playlist->i_current_index); 
     304    if( b_random ) 
     305    { 
     306        /* Shuffle the array */ 
     307        srand( (unsigned int)mdate() ); 
     308        int swap = 0; 
     309        int j; 
     310        for( j = p_playlist->current.i_size - 1; j > 0; j-- ) 
     311        { 
     312            swap++; 
     313            int i = rand() % (j+1); /* between 0 and j */ 
     314            playlist_item_t *p_tmp; 
     315            p_tmp = ARRAY_VAL(p_playlist->current, i); 
     316            ARRAY_VAL(p_playlist->current,i) = ARRAY_VAL(p_playlist->current,j); 
     317            ARRAY_VAL(p_playlist->current,j) = p_tmp; 
     318        } 
     319    } 
     320    p_playlist->b_reset_currently_playing = VLC_FALSE; 
     321} 
     322 
    264323/** This function calculates the next playlist item, depending 
    265324 *  on the playlist course mode (forward, backward, random, view,...). */ 
     
    276335    /* Handle quickly a few special cases */ 
    277336    /* No items to play */ 
    278     if( p_playlist->i_size == 0 ) 
     337    if( p_playlist->items.i_size == 0 ) 
    279338    { 
    280339        msg_Info( p_playlist, "playlist is empty" ); 
     
    309368    } 
    310369 
    311     /* Random case. This is an exception: if request, but request is skip +- 1 
    312      * we don't go to next item but select a new random one. */ 
    313     if( b_random && 
    314         ( !p_playlist->request.b_request || 
    315         ( p_playlist->request.b_request && 
    316             ( p_playlist->request.p_item == NULL || 
    317               p_playlist->request.i_skip == 1    || 
    318               p_playlist->request.i_skip == -1 ) ) ) ) 
    319     { 
    320        PL_DEBUG( "doing random, have %i items, currently at %i, reset %i\n", 
    321                         p_playlist->i_random, p_playlist->i_random_index, 
    322                         p_playlist->b_reset_random ); 
    323        if( p_playlist->b_reset_random ) 
    324         { 
    325             int j; 
    326             FREE( p_playlist->pp_random ); 
    327             if( !p_playlist->b_reset_random &&  !b_loop ) goto end; 
    328             p_playlist->i_random = 0; 
    329             p_playlist->i_random_index = 0; 
    330             p_playlist->i_random = playlist_GetAllEnabledChildren( 
    331                                                 p_playlist, 
    332                                                 p_playlist->status.p_node, 
    333                                                 &p_playlist->pp_random ); 
    334             /* Shuffle the array */ 
    335             srand( (unsigned int)mdate() ); 
    336             int swap = 0; 
    337             for( j = p_playlist->i_random -1; j > 0; j-- ) 
    338             { 
    339                 swap++; 
    340                 int i = rand() % (j+1); /* between 0 and j */ 
    341                 playlist_item_t *p_tmp; 
    342                 p_tmp = p_playlist->pp_random[i]; 
    343                 p_playlist->pp_random[i] = p_playlist->pp_random[j]; 
    344                 p_playlist->pp_random[j] = p_tmp; 
    345             } 
    346             p_playlist->b_reset_random = VLC_FALSE; 
    347             PL_DEBUG( "random rebuilt, have %i items", p_playlist->i_random ); 
    348         } 
    349         else 
    350         { 
    351             /* Go backward or forward */ 
    352             if( !p_playlist->request.b_request || !p_playlist->request.p_item || 
    353                                                p_playlist->request.i_skip == 1 ) 
    354                 p_playlist->i_random_index++; 
    355             else 
    356                 p_playlist->i_random_index--; 
    357             /* Handle bounds situations */ 
    358             if( p_playlist->i_random_index == -1 ) 
    359             { 
    360                 if( !b_loop || p_playlist->i_random == 0 ) goto end; 
    361                 p_playlist->i_random_index = p_playlist->i_random - 1; 
    362             } 
    363             else if( p_playlist->i_random_index == p_playlist->i_random ) 
    364             { 
    365                 if( !b_loop || p_playlist->i_random == 0 ) goto end; 
    366                 p_playlist->i_random_index = 0; 
    367             } 
    368         } 
    369         PL_DEBUG( "using random item %i", p_playlist->i_random_index ); 
    370         if ( p_playlist->i_random == 0 ) goto end; /* Can this happen ?? */ 
    371         p_new = p_playlist->pp_random[p_playlist->i_random_index]; 
    372 end: 
    373         if( !p_new ) p_playlist->b_reset_random = VLC_TRUE; 
    374         p_playlist->request.i_skip = 0; 
    375         p_playlist->request.b_request = VLC_FALSE; 
    376         return p_new; 
    377     } 
    378  
    379370    /* Start the real work */ 
    380371    if( p_playlist->request.b_request ) 
     
    386377                        PLI_NAME( p_playlist->request.p_node ), i_skip ); 
    387378 
    388         if( p_playlist->request.p_node ) 
     379        if( p_playlist->request.p_node && 
     380            p_playlist->request.p_node != p_playlist->status.p_node ) 
     381        { 
    389382            p_playlist->status.p_node = p_playlist->request.p_node; 
     383            p_playlist->b_reset_currently_playing = VLC_TRUE; 
     384        } 
    390385 
    391386        /* If we are asked for a node, dont take it */ 
     
    393388            i_skip++; 
    394389 
    395         if( i_skip > 0 ) 
     390        if( p_playlist->b_reset_currently_playing ) 
     391            ResetCurrentlyPlaying( p_playlist, b_random, p_new ); 
     392        else if( p_new ) 
     393            ResyncCurrentIndex( p_playlist, p_new ); 
     394        else 
     395            p_playlist->i_current_index = -1; 
     396 
     397        if( p_playlist->current.i_size && i_skip > 0 ) 
    396398        { 
    397399            for( i = i_skip; i > 0 ; i-- ) 
    398400            { 
    399                 p_new = playlist_GetNextLeaf( p_playlist, 
    400                                               p_playlist->request.p_node, 
    401                                               p_new, VLC_TRUE, VLC_FALSE ); 
    402                 if( p_new == NULL ) 
     401                p_playlist->i_current_index++; 
     402                if( p_playlist->i_current_index == p_playlist->current.i_size ) 
    403403                { 
    404404                    PL_DEBUG( "looping - restarting at beginning of node" ); 
    405                     p_new = playlist_GetNextLeaf( p_playlist, 
    406                                                   p_playlist->request.p_node, 
    407                                                   NULL, VLC_TRUE, VLC_FALSE); 
    408                     if( p_new == NULL ) break; 
     405                    p_playlist->i_current_index = 0; 
    409406                } 
    410407            } 
    411         } 
    412         else if( i_skip < 0 ) 
     408            p_new = ARRAY_VAL( p_playlist->current, 
     409                               p_playlist->i_current_index ); 
     410        } 
     411        else if( p_playlist->current.i_size && i_skip < 0 ) 
    413412        { 
    414413            for( i = i_skip; i < 0 ; i++ ) 
    415414            { 
    416                 p_new = playlist_GetPrevLeaf( p_playlist, 
    417                                               p_playlist->request.p_node, 
    418                                               p_new, VLC_FALSE, VLC_FALSE ); 
    419                 if( p_new == NULL ) 
     415                p_playlist->i_current_index--; 
     416                if( p_playlist->i_current_index == -1 ) 
    420417                { 
    421418                    PL_DEBUG( "looping - restarting at end of node" ); 
    422                     /** \bug This is needed because GetPrevLeaf does not loop 
    423                       * by itself */ 
    424                     p_new = playlist_GetLastLeaf( p_playlist, 
    425                                                  p_playlist->request.p_node ); 
     419                    p_playlist->i_current_index = p_playlist->current.i_size-1; 
    426420                } 
    427                 if( p_new == NULL ) break; 
    428421            } 
     422            p_new = ARRAY_VAL( p_playlist->current, 
     423                               p_playlist->i_current_index ); 
    429424        } 
    430425        /* Clear the request */ 
     
    434429    else 
    435430    { 
    436         PL_DEBUG( "changing item without a request" ); 
     431        PL_DEBUG( "changing item without a request (current %i/%i)", 
     432                  p_playlist->i_current_index, p_playlist->current.i_size ); 
    437433        /* Cant go to next from current item */ 
    438434        if( p_playlist->status.p_item && 
     
    440436            return NULL; 
    441437 
    442         p_new = playlist_GetNextLeaf( p_playlist, 
    443                                       p_playlist->status.p_node, 
    444                                       p_playlist->status.p_item, 
    445                                       VLC_TRUE, VLC_FALSE ); 
    446         if( p_new == NULL && b_loop ) 
    447         { 
    448             PL_DEBUG( "looping" ); 
    449             p_new = playlist_GetNextLeaf( p_playlist, 
    450                                           p_playlist->status.p_node, 
    451                                           NULL, VLC_TRUE, VLC_FALSE ); 
    452         } 
     438        if( p_playlist->b_reset_currently_playing ) 
     439            ResetCurrentlyPlaying( p_playlist, b_random, 
     440                                   p_playlist->status.p_item ); 
     441 
     442        p_playlist->i_current_index++; 
     443        if( p_playlist->i_current_index == p_playlist->current.i_size ) 
     444        { 
     445            if( !b_loop || p_playlist->current.i_size == 0 ) return NULL; 
     446            p_playlist->i_current_index = 0; 
     447        } 
     448        PL_DEBUG( "using item %i", p_playlist->i_current_index ); 
     449        if ( p_playlist->current.i_size == 0 ) return NULL; 
     450 
     451        p_new = ARRAY_VAL( p_playlist->current, p_playlist->i_current_index ); 
    453452        /* The new item can't be autoselected  */ 
    454453        if( p_new != NULL && p_new->i_flags & PLAYLIST_SKIP_FLAG ) 
    455454            return NULL; 
    456     } 
    457     if( p_new == NULL ) 
    458     { 
    459         msg_Dbg( p_playlist, "did not find something to play" ); 
    460455    } 
    461456    return p_new; 
  • src/playlist/engine.c

    r4e03ca0 r799b282  
    3535static void VariablesInit( playlist_t *p_playlist ); 
    3636 
     37static int RandomCallback( vlc_object_t *p_this, char const *psz_cmd, 
     38                           vlc_value_t oldval, vlc_value_t newval, void *a ) 
     39{ 
     40    ((playlist_t*)p_this)->b_reset_currently_playing = VLC_TRUE; 
     41    return VLC_SUCCESS; 
     42} 
     43 
    3744/** 
    3845 * Create playlist 
     
    6774    p_playlist->i_sout_destroyed_date = 0; 
    6875 
    69     p_playlist->i_size = 0; 
    70     p_playlist->pp_items = NULL; 
    71     p_playlist->i_all_size = 0; 
    72     p_playlist->pp_all_items = NULL; 
    73  
    74     p_playlist->i_input_items = 0; 
    75     p_playlist->pp_input_items = NULL; 
    76  
    77     p_playlist->i_random = 0; 
    78     p_playlist->pp_random = NULL; 
    79     p_playlist->i_random_index = 0; 
    80     p_playlist->b_reset_random = VLC_TRUE; 
     76    ARRAY_INIT( p_playlist->items ); 
     77    ARRAY_INIT( p_playlist->all_items ); 
     78    ARRAY_INIT( p_playlist->input_items ); 
     79    ARRAY_INIT( p_playlist->current ); 
     80 
     81    p_playlist->i_current_index = 0; 
     82    p_playlist->b_reset_currently_playing = VLC_TRUE; 
    8183 
    8284    i_tree = var_CreateGetBool( p_playlist, "playlist-tree" ); 
     
    163165 
    164166    PL_LOCK; 
    165     playlist_NodeDelete( p_playlist, p_playlist->p_root_category, VLC_TRUE, 
    166                          VLC_TRUE ); 
    167     playlist_NodeDelete( p_playlist, p_playlist->p_root_onelevel, VLC_TRUE, 
    168                          VLC_TRUE ); 
     167    /* Go through all items, and simply free everything without caring 
     168     * about the tree structure. Do not decref, it will be done by doing 
     169     * the same thing on the input items array */ 
     170    FOREACH_ARRAY( playlist_item_t *p_del, p_playlist->all_items ) 
     171        free( p_del->pp_children ); 
     172        free( p_del ); 
     173    FOREACH_END(); 
     174    ARRAY_RESET( p_playlist->all_items ); 
     175 
     176    FOREACH_ARRAY( input_item_t *p_del, p_playlist->input_items ) 
     177        input_ItemClean( p_del ); 
     178        free( p_del ); 
     179    FOREACH_END(); 
     180    ARRAY_RESET( p_playlist->input_items ); 
     181 
     182    ARRAY_RESET( p_playlist->items ); 
     183    ARRAY_RESET( p_playlist->current ); 
     184 
    169185    PL_UNLOCK; 
    170186 
     
    636652    var_CreateGetBool( p_playlist, "repeat" ); 
    637653    var_CreateGetBool( p_playlist, "loop" ); 
    638 
     654 
     655    var_AddCallback( p_playlist, "random", RandomCallback, NULL ); 
     656
  • src/playlist/item.c

    rdfd24ab r799b282  
    404404                                      p_playlist->p_root_onelevel, VLC_FALSE ); 
    405405        } 
    406         p_playlist->b_reset_random = VLC_TRUE; 
     406        p_playlist->b_reset_currently_playing = VLC_TRUE; 
    407407        var_SetInteger( p_playlist, "item-change", p_item_in_category-> 
    408408                                                        p_input->i_id ); 
     
    545545    p_add->i_node = i_node_id; 
    546546    val.p_address = p_add; 
    547     p_playlist->b_reset_random = VLC_TRUE; 
     547    p_playlist->b_reset_currently_playing = VLC_TRUE; 
    548548    var_Set( p_playlist, "item-append", val ); 
    549549    free( p_add ); 
     
    611611              playlist_item_t *p_node, int i_pos ) 
    612612{ 
    613     INSERT_ELEM( p_playlist->pp_items, p_playlist->i_size, 
    614                  p_playlist->i_size, p_item ); 
    615     INSERT_ELEM( p_playlist->pp_all_items, p_playlist->i_all_size, 
    616                  p_playlist->i_all_size, p_item ); 
     613    ARRAY_APPEND(p_playlist->items, p_item); 
     614    ARRAY_APPEND(p_playlist->all_items, p_item); 
    617615    p_playlist->i_enabled ++; 
    618616 
    619617    if( i_pos == PLAYLIST_END ) 
    620     { 
    621618        playlist_NodeAppend( p_playlist, p_item, p_node ); 
    622     } 
    623619    else 
    624     { 
    625620        playlist_NodeInsert( p_playlist, p_item, p_node, i_pos ); 
    626     } 
     621 
    627622    if( !p_playlist->b_doing_ml ) 
    628623        playlist_SendAddNotify( p_playlist, p_item->i_id, p_node->i_id ); 
     
    637632 
    638633    /* Remove it from the array of available items */ 
    639     for( i = 0 ; i < p_playlist->i_size ; i++ ) 
    640     { 
    641         if( p_item == p_playlist->pp_items[i] ) 
    642         { 
    643             REMOVE_ELEM( p_playlist->pp_items, p_playlist->i_size, i ); 
    644         } 
    645     } 
     634    ARRAY_BSEARCH( p_playlist->items,->i_id, int, p_item->i_id, i ); 
     635    if( i != -1 ) 
     636        ARRAY_REMOVE( p_playlist->items, i ); 
    646637} 
    647638 
     
    650641                vlc_bool_t b_stop ) 
    651642{ 
    652     int i, i_top, i_bottom
     643    int i
    653644    int i_id = p_item->i_id; 
    654645    vlc_bool_t b_flag = VLC_FALSE; 
     
    658649        return playlist_NodeDelete( p_playlist, p_item, VLC_TRUE, VLC_FALSE ); 
    659650    } 
    660     p_playlist->b_reset_random = VLC_TRUE; 
     651    p_playlist->b_reset_currently_playing = VLC_TRUE; 
    661652    var_SetInteger( p_playlist, "item-deleted", i_id ); 
    662653 
    663654    /* Remove the item from the bank */ 
    664     i_bottom = 0; i_top = p_playlist->i_all_size - 1; 
    665     i = i_top / 2; 
    666     while( p_playlist->pp_all_items[i]->i_id != i_id && 
    667            i_top > i_bottom ) 
    668     { 
    669         if( p_playlist->pp_all_items[i]->i_id < i_id ) 
    670         { 
    671             i_bottom = i + 1; 
    672         } 
    673         else 
    674         { 
    675             i_top = i - 1; 
    676         } 
    677         i = i_bottom + ( i_top - i_bottom ) / 2; 
    678     } 
    679     if( p_playlist->pp_all_items[i]->i_id == i_id ) 
    680     { 
    681         REMOVE_ELEM( p_playlist->pp_all_items, p_playlist->i_all_size, i ); 
    682     } 
     655    ARRAY_BSEARCH( p_playlist->all_items,->i_id, int, i_id, i ); 
     656    if( i != -1 ) 
     657        ARRAY_REMOVE( p_playlist->all_items, i ); 
    683658 
    684659    /* Check if it is the current item */ 
  • src/playlist/search.c

    r315069b r799b282