[vlc-commits] input: add input_item_node_Sort

Thomas Guillem git at videolan.org
Wed May 20 16:10:25 CEST 2015


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | 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



More information about the vlc-commits mailing list