vlc | branch: master | Thomas Guillem <[email protected]> | Wed May 20 15:14:02 2015 +0200| [0b79f865b6e49194f156e693135aaf561cb4ba22] | committer: Thomas Guillem
input: add input_item_node_Sort Sort all p_item children of the node recursively. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=0b79f865b6e49194f156e693135aaf561cb4ba22 --- include/vlc_input_item.h | 9 +++++++++ src/input/item.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/libvlccore.sym | 1 + 3 files changed, 56 insertions(+) diff --git a/include/vlc_input_item.h b/include/vlc_input_item.h index 48dcd32..60dce6e 100644 --- a/include/vlc_input_item.h +++ b/include/vlc_input_item.h @@ -113,12 +113,15 @@ enum input_item_type_e ITEM_TYPE_NUMBER }; +typedef int (*input_item_compar_cb)( input_item_t *, input_item_t * ); + struct input_item_node_t { input_item_t * p_item; int i_children; input_item_node_t **pp_children; input_item_node_t *p_parent; + input_item_compar_cb compar_cb; }; VLC_API void input_item_CopyOptions( input_item_t *p_parent, input_item_t *p_child ); @@ -154,6 +157,12 @@ VLC_API input_item_node_t * input_item_node_AppendItem( input_item_node_t *p_nod VLC_API void input_item_node_AppendNode( input_item_node_t *p_parent, input_item_node_t *p_child ); /** + * Sort all p_item children of the node recursively. + */ +VLC_API void input_item_node_Sort( input_item_node_t *p_node, + input_item_compar_cb compar_cb ); + +/** * Delete a node created with input_item_node_Create() and all its children. */ VLC_API void input_item_node_Delete( input_item_node_t *p_node ); diff --git a/src/input/item.c b/src/input/item.c index d357c25..10e7216 100644 --- a/src/input/item.c +++ b/src/input/item.c @@ -1160,6 +1160,52 @@ void input_item_node_AppendNode( input_item_node_t *p_parent, input_item_node_t p_child->p_parent = p_parent; } +static int compar_node( const void *p1, const void *p2 ) +{ + input_item_node_t *p_node1 = *((input_item_node_t **) p1); + input_item_node_t *p_node2 = *((input_item_node_t **) p2); + + assert( p_node1->p_parent && p_node1->p_parent == p_node2->p_parent && + p_node1->p_parent->compar_cb ); + + input_item_compar_cb compar_cb = p_node1->p_parent->compar_cb; + return compar_cb( p_node1->p_item, p_node2->p_item ); +} + +static void sort_subitems( input_item_node_t *p_node, + input_item_compar_cb compar_cb ) +{ + if( p_node->i_children < 0 || !compar_cb ) + return; + + p_node->compar_cb = compar_cb; + + /* Lock first all children. This avoids to lock/unlock them from each + * compar callback call */ + for( int i = 0; i < p_node->i_children; i++ ) + vlc_mutex_lock( &p_node->pp_children[i]->p_item->lock ); + + /* Sort current node */ + qsort( p_node->pp_children, p_node->i_children, + sizeof(input_item_node_t *), compar_node ); + + /* Unlock all children */ + for( int i = 0; i < p_node->i_children; i++ ) + vlc_mutex_unlock( &p_node->pp_children[i]->p_item->lock ); + + p_node->compar_cb = NULL; + + /* Sort all children */ + for( int i = 0; i < p_node->i_children; i++ ) + sort_subitems( p_node->pp_children[i], compar_cb ); +} + +void input_item_node_Sort( input_item_node_t *p_node, + input_item_compar_cb compar_cb ) +{ + sort_subitems( p_node, compar_cb ); +} + void input_item_node_PostAndDelete( input_item_node_t *p_root ) { post_subitems( p_root ); diff --git a/src/libvlccore.sym b/src/libvlccore.sym index 5350f96..86a3a82 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -208,6 +208,7 @@ input_item_node_AppendNode input_item_node_Create input_item_node_Delete input_item_node_PostAndDelete +input_item_node_Sort input_item_PostSubItem input_item_ReplaceInfos input_item_SetDuration _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
