control/flat_media_list.c: Fix a bunch of bug, plus add a tracing capability.
authorPierre d'Herbemont <pdherbemont@videolan.org>
Tue, 28 Aug 2007 01:46:56 +0000 (01:46 +0000)
committerPierre d'Herbemont <pdherbemont@videolan.org>
Tue, 28 Aug 2007 01:46:56 +0000 (01:46 +0000)
src/control/flat_media_list.c

index 372f5fd..fe2d047 100644 (file)
 #include <assert.h>
 #include "vlc_arrays.h"
 
+//#define DEBUG_FLAT_LIST
+
+#ifdef DEBUG_FLAT_LIST
+# define trace( fmt, ... ) printf( "%s(): " fmt, __FUNCTION__, ##__VA_ARGS__ )
+#else
+# define trace( ... )
+#endif
+
 /*
  * Private functions
  */
@@ -47,13 +55,13 @@ static void
 uninstall_media_list_observer( libvlc_media_list_t * p_mlist,
                              libvlc_media_list_t * p_submlist )
 {
+    trace("\n");
     libvlc_event_detach( p_submlist->p_event_manager,
                          libvlc_MediaListItemAdded,
                          sublist_item_added, p_mlist, NULL );
     libvlc_event_detach( p_submlist->p_event_manager,
                          libvlc_MediaListItemDeleted,
                          sublist_item_removed, p_mlist, NULL );
-
 }
 
 /**************************************************************************
@@ -63,6 +71,7 @@ static void
 install_media_list_observer( libvlc_media_list_t * p_mlist,
                              libvlc_media_list_t * p_submlist )
 {
+    trace("\n");
     libvlc_event_attach( p_submlist->p_event_manager,
                          libvlc_MediaListItemAdded,
                          sublist_item_added, p_mlist, NULL );
@@ -80,6 +89,7 @@ add_media_list( libvlc_media_list_t * p_mlist,
 {
     int count = libvlc_media_list_count( p_submlist, NULL );
     int i;
+    trace("\n");
 
     for( i = 0; i < count; i++ )
     {
@@ -97,6 +107,7 @@ static void
 remove_media_list( libvlc_media_list_t * p_mlist,
                    libvlc_media_list_t * p_submlist )
 {
+    trace("\n");
     int count = libvlc_media_list_count( p_submlist, NULL );    
     int i;
     uninstall_media_list_observer( p_mlist, p_submlist );
@@ -116,22 +127,27 @@ remove_media_list( libvlc_media_list_t * p_mlist,
 static void
 add_item( libvlc_media_list_t * p_mlist, libvlc_media_descriptor_t * p_md )
 {
+    trace( "p_md '%s'\n", p_md->p_input_item->psz_name );
+
     /* Only add the media descriptor once to our flat list */
     if( libvlc_media_list_index_of_item( p_mlist->p_flat_mlist, p_md, NULL ) < 0 )
     {
         if( p_md->p_subitems )
         {
-            add_media_list( p_mlist->p_flat_mlist, p_md->p_subitems );
+            add_media_list( p_mlist, p_md->p_subitems );
         }
         else
         {
+            libvlc_media_list_lock( p_mlist->p_flat_mlist );
             libvlc_event_attach( p_md->p_event_manager,
                                  libvlc_MediaDescriptorSubItemAdded,
                                  subitems_created, p_mlist, NULL );
             uninstall_flat_mlist_observer( p_mlist );
             libvlc_media_list_add_media_descriptor( p_mlist->p_flat_mlist,
                                                     p_md, NULL );
-            install_flat_mlist_observer( p_mlist );           
+            install_flat_mlist_observer( p_mlist );
+            libvlc_media_list_unlock( p_mlist->p_flat_mlist );
+       
         }
     }
 }
@@ -142,15 +158,23 @@ add_item( libvlc_media_list_t * p_mlist, libvlc_media_descriptor_t * p_md )
 static void
 remove_item( libvlc_media_list_t * p_mlist, libvlc_media_descriptor_t * p_md )
 {
+    trace( "p_md '%s'\n", p_md->p_input_item->psz_name );
+
     if( p_md->p_subitems ) /* XXX: Don't access that directly */
         remove_media_list( p_mlist, p_md->p_subitems );
     libvlc_event_detach( p_md->p_event_manager,
                          libvlc_MediaDescriptorSubItemAdded,
                          subitems_created, p_mlist, NULL );
+
+    libvlc_media_list_lock( p_mlist->p_flat_mlist );
     int i = libvlc_media_list_index_of_item( p_mlist->p_flat_mlist, p_md, NULL );
-    uninstall_flat_mlist_observer( p_mlist );
-    libvlc_media_list_remove_index( p_mlist->p_flat_mlist, i, NULL );
-    install_flat_mlist_observer( p_mlist );
+    if( i >= 0 )
+    {
+        uninstall_flat_mlist_observer( p_mlist );
+        libvlc_media_list_remove_index( p_mlist->p_flat_mlist, i, NULL );
+        install_flat_mlist_observer( p_mlist );
+    }
+    libvlc_media_list_unlock( p_mlist->p_flat_mlist );
 }
 
 /**************************************************************************
@@ -160,12 +184,30 @@ static void
 subitems_created( const libvlc_event_t * p_event , void * p_user_data)
 {
     libvlc_media_list_t * p_mlist = p_user_data;
-    libvlc_media_descriptor_t * p_md = p_event->u.media_list_item_deleted.item;
+    libvlc_media_descriptor_t * p_md = p_event->p_obj;
+
+    trace( "parent p_md '%s'\n", p_md->p_input_item->psz_name );
 
     /* Remove the item and add the playlist */
-    remove_item( p_mlist->p_flat_mlist, p_md );
+    libvlc_media_list_lock( p_mlist->p_flat_mlist );
+    int i = libvlc_media_list_index_of_item( p_mlist->p_flat_mlist, p_md, NULL );
+    if( i >=  0 )
+    {
+        libvlc_event_detach_lock_state( p_md->p_event_manager,
+                         libvlc_MediaDescriptorSubItemAdded,
+                         subitems_created, p_mlist, libvlc_Locked, NULL );
+        uninstall_flat_mlist_observer( p_mlist );
+        libvlc_media_list_remove_index( p_mlist->p_flat_mlist, i, NULL );
+        install_flat_mlist_observer( p_mlist );
+    }
+    libvlc_media_list_unlock( p_mlist->p_flat_mlist );
+
+    trace( "Adding p_md '%s''s media list\n", p_md->p_input_item->psz_name );
+
+    add_media_list( p_mlist, p_md->p_subitems );
+
+    trace( "done\n" );
 
-    add_media_list( p_mlist->p_flat_mlist, p_md->p_subitems );
 }
 
 /**************************************************************************
@@ -178,6 +220,8 @@ sublist_item_added( const libvlc_event_t * p_event, void * p_user_data )
 {
     libvlc_media_list_t * p_mlist = p_user_data;
     libvlc_media_descriptor_t * p_md = p_event->u.media_list_item_added.item;
+    trace( "p_md '%s'\n", p_md->p_input_item->psz_name );
+
     add_item( p_mlist, p_md );
 }
 
@@ -189,6 +233,8 @@ sublist_item_removed( const libvlc_event_t * p_event, void * p_user_data )
 {
     libvlc_media_list_t * p_mlist = p_user_data;
     libvlc_media_descriptor_t * p_md = p_event->u.media_list_item_deleted.item;
+    trace( "p_md '%s'\n", p_md->p_input_item->psz_name );
+
     remove_item( p_mlist, p_md );
 }
 
@@ -203,18 +249,21 @@ remove_item_in_submlist_rec( libvlc_media_list_t * p_mlist,
     libvlc_media_descriptor_t * p_md_insub;    
     int count = libvlc_media_list_count( p_submlist, NULL );    
     int i;
+    trace("p_md '%s'\n", p_md->p_input_item->psz_name);
+
     for( i = 0; i < count; i++ )
     {
         p_md_insub = libvlc_media_list_item_at_index( p_submlist,
                                                       i, NULL );
-        if( p_md_insub->p_subitems )
-            remove_item_in_submlist_rec( p_mlist, p_submlist, p_md );
         if( p_md == p_md_insub )
         {
+            libvlc_media_list_lock( p_submlist );
             uninstall_media_list_observer( p_mlist, p_submlist );
             libvlc_media_list_remove_index( p_submlist, i, NULL );
             install_media_list_observer( p_mlist, p_submlist );
-        }
+            libvlc_media_list_unlock( p_submlist );
+        } else if( p_md_insub->p_subitems )
+            remove_item_in_submlist_rec( p_mlist, p_md_insub->p_subitems, p_md );
     }
 }
 
@@ -224,6 +273,7 @@ remove_item_in_submlist_rec( libvlc_media_list_t * p_mlist,
 static void
 flat_mlist_item_removed( const libvlc_event_t * p_event, void * p_user_data )
 {
+    trace("\n");
     /* Remove all occurences of that one in sublist */
     libvlc_media_list_t * p_mlist = p_user_data;
     libvlc_media_descriptor_t * p_md = p_event->u.media_list_item_deleted.item;
@@ -237,9 +287,14 @@ flat_mlist_item_removed( const libvlc_event_t * p_event, void * p_user_data )
 static void
 flat_mlist_item_added( const libvlc_event_t * p_event, void * p_user_data )
 {
+    trace("\n");
     libvlc_media_list_t * p_mlist = p_user_data;
     libvlc_media_descriptor_t * p_md = p_event->u.media_list_item_added.item;
 
+    libvlc_event_attach( p_md->p_event_manager,
+                        libvlc_MediaDescriptorSubItemAdded,
+                        subitems_created, p_mlist, NULL );
+
     /* Add in our root */
     uninstall_media_list_observer( p_mlist, p_mlist );    
     libvlc_media_list_add_media_descriptor( p_mlist, p_md, NULL );
@@ -252,6 +307,7 @@ flat_mlist_item_added( const libvlc_event_t * p_event, void * p_user_data )
 static void
 install_flat_mlist_observer( libvlc_media_list_t * p_mlist )
 {
+    trace("\n");
     libvlc_event_attach( p_mlist->p_flat_mlist->p_event_manager,
                          libvlc_MediaListItemAdded,
                          flat_mlist_item_added, p_mlist, NULL );
@@ -267,10 +323,11 @@ install_flat_mlist_observer( libvlc_media_list_t * p_mlist )
 static void
 uninstall_flat_mlist_observer( libvlc_media_list_t * p_mlist )
 {
+    trace("\n");
     libvlc_event_detach( p_mlist->p_flat_mlist->p_event_manager,
                          libvlc_MediaListItemAdded,
                          flat_mlist_item_added, p_mlist, NULL );
-    libvlc_event_attach( p_mlist->p_flat_mlist->p_event_manager,
+    libvlc_event_detach( p_mlist->p_flat_mlist->p_event_manager,
                          libvlc_MediaListItemDeleted,
                          flat_mlist_item_removed, p_mlist, NULL );
 
@@ -302,14 +359,16 @@ libvlc_media_list_t *
 libvlc_media_list_flat_media_list( libvlc_media_list_t * p_mlist,
                                    libvlc_exception_t * p_e )
 {
+    trace("\n");
+    libvlc_media_list_lock( p_mlist );
     if( !p_mlist->p_flat_mlist )
     {
         p_mlist->p_flat_mlist = libvlc_media_list_new(
                                             p_mlist->p_libvlc_instance,
                                             p_e );
         add_media_list( p_mlist, p_mlist );
-        install_flat_mlist_observer( p_mlist );
     }
+    libvlc_media_list_unlock( p_mlist );
     libvlc_media_list_retain( p_mlist->p_flat_mlist );
     return p_mlist->p_flat_mlist;
 }