media_list.c: Handle item addition and removal in the flat list. Also Get the media_l...
authorPierre d'Herbemont <pdherbemont@videolan.org>
Fri, 24 Aug 2007 14:02:11 +0000 (14:02 +0000)
committerPierre d'Herbemont <pdherbemont@videolan.org>
Fri, 24 Aug 2007 14:02:11 +0000 (14:02 +0000)
src/control/flat_media_list.c
src/control/libvlc_internal.h
src/control/media_list.c

index ca1f20e..628df34 100644 (file)
 /*
  * Private functions
  */
+static void add_media_list( libvlc_media_list_t * p_mlist, libvlc_media_list_t * p_submlist );
+static void remove_media_list( libvlc_media_list_t * p_fmlist, libvlc_media_list_t * p_mlist );
 static void 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 );
 static void subitems_created( const libvlc_event_t * p_event , void * p_user_data);
 static void sublist_item_added( const libvlc_event_t * p_event, void * p_user_data );
 static void sublist_item_removed( const libvlc_event_t * p_event, void * p_user_data );
-static void add_media_list( libvlc_media_list_t * p_mlist, libvlc_media_list_t * p_submlist );
-static void remove_media_list( libvlc_media_list_t * p_fmlist, libvlc_media_list_t * p_mlist );
+static void install_flat_mlist_observer( libvlc_media_list_t * p_mlist );
+static void uninstall_flat_mlist_observer( libvlc_media_list_t * p_mlist );
+
+/**************************************************************************
+ *       uninstall_media_list_observer (Private)
+ **************************************************************************/
+static void
+uninstall_media_list_observer( libvlc_media_list_t * p_mlist,
+                             libvlc_media_list_t * p_submlist )
+{
+    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 );
+
+}
+
+/**************************************************************************
+ *       install_media_list_observer (Private)
+ **************************************************************************/
+static void
+install_media_list_observer( libvlc_media_list_t * p_mlist,
+                             libvlc_media_list_t * p_submlist )
+{
+    libvlc_event_attach( p_submlist->p_event_manager,
+                         libvlc_MediaListItemAdded,
+                         sublist_item_added, p_mlist, NULL );
+    libvlc_event_attach( p_submlist->p_event_manager,
+                         libvlc_MediaListItemDeleted,
+                         sublist_item_removed, p_mlist, NULL );
+}
+
+/**************************************************************************
+ *       add_media_list (Private)
+ **************************************************************************/
+static void
+add_media_list( libvlc_media_list_t * p_mlist,
+                libvlc_media_list_t * p_submlist )
+{
+    int count = libvlc_media_list_count( p_submlist, NULL );
+    int i;
+
+    for( i = 0; i < count; i++ )
+    {
+        libvlc_media_descriptor_t * p_md;
+        p_md = libvlc_media_list_item_at_index( p_submlist, i, NULL );
+        add_item( p_mlist->p_flat_mlist, p_md );
+    }
+    install_media_list_observer( p_mlist, p_submlist );
+}
+
+/**************************************************************************
+ *       remove_media_list (Private)
+ **************************************************************************/
+static void
+remove_media_list( libvlc_media_list_t * p_mlist,
+                   libvlc_media_list_t * p_submlist )
+{
+    int count = libvlc_media_list_count( p_submlist, NULL );    
+    int i;
+    uninstall_media_list_observer( p_mlist, p_submlist );
+
+    for( i = 0; i < count; i++ )
+    {
+        libvlc_media_descriptor_t * p_md;
+        p_md = libvlc_media_list_item_at_index( p_submlist, i, NULL );
+        remove_item( p_mlist, p_md );
+    }
+}
+
 
 /**************************************************************************
  *       add_item (private) 
@@ -56,8 +128,10 @@ add_item( libvlc_media_list_t * p_mlist, libvlc_media_descriptor_t * p_md )
             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 );           
         }
     }
 }
@@ -74,7 +148,9 @@ remove_item( libvlc_media_list_t * p_mlist, libvlc_media_descriptor_t * p_md )
                          libvlc_MediaDescriptorSubItemAdded,
                          subitems_created, p_mlist, NULL );
     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 );
 }
 
 /**************************************************************************
@@ -117,53 +193,103 @@ sublist_item_removed( const libvlc_event_t * p_event, void * p_user_data )
 }
 
 /**************************************************************************
- *       add_media_list (Private)
+ *       remove_item_in_submlist_rec (private)
  **************************************************************************/
-void
-add_media_list( libvlc_media_list_t * p_mlist,
-                libvlc_media_list_t * p_submlist )
+static void
+remove_item_in_submlist_rec( libvlc_media_list_t * p_mlist,
+                             libvlc_media_list_t * p_submlist,
+                             libvlc_media_descriptor_t * p_md )
 {
-    int count = libvlc_media_list_count( p_submlist, NULL );
+    libvlc_media_descriptor_t * p_md_insub;    
+    int count = libvlc_media_list_count( p_submlist, NULL );    
     int i;
-
-    libvlc_event_attach( p_submlist->p_event_manager,
-                         libvlc_MediaListItemAdded,
-                         sublist_item_added, p_mlist, NULL );
-    libvlc_event_attach( p_submlist->p_event_manager,
-                         libvlc_MediaListItemDeleted,
-                         sublist_item_removed, p_mlist, NULL );
     for( i = 0; i < count; i++ )
     {
-        libvlc_media_descriptor_t * p_md;
-        p_md = libvlc_media_list_item_at_index( p_submlist, i, NULL );
-        add_item( p_mlist->p_flat_mlist, p_md );    
+        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 )
+        {
+            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 );
+        }
     }
 }
 
 /**************************************************************************
- *       remove_media_list (Private)
+ *       flat_mlist_item_removed (private) (Event Callback)
  **************************************************************************/
-void
-remove_media_list( libvlc_media_list_t * p_mlist,
-                   libvlc_media_list_t * p_submlist )
+static void
+flat_mlist_item_removed( const libvlc_event_t * p_event, void * p_user_data )
 {
-    int count = libvlc_media_list_count( p_submlist, NULL );    
-    int i;
-    for( i = 0; i < count; i++ )
-    {
-        libvlc_media_descriptor_t * p_md;
-        p_md = libvlc_media_list_item_at_index( p_submlist, i, NULL );
-        remove_item( p_mlist, p_md );
-    }
-    
-    libvlc_event_detach( p_mlist->p_event_manager,
+    /* 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;
+    remove_item( p_mlist, p_md ); /* Just to detach the event */
+    remove_item_in_submlist_rec( p_mlist, p_mlist, p_md );
+}
+
+/**************************************************************************
+ *       flat_mlist_item_added (private) (Event Callback)
+ **************************************************************************/
+static void
+flat_mlist_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;
+
+    /* Add in our root */
+    uninstall_media_list_observer( p_mlist, p_mlist );    
+    libvlc_media_list_add_media_descriptor( p_mlist, p_md, NULL );
+    install_media_list_observer( p_mlist, p_mlist );
+}
+
+/**************************************************************************
+ *       install_flat_mlist_observer (Private)
+ **************************************************************************/
+static void
+install_flat_mlist_observer( libvlc_media_list_t * p_mlist )
+{
+    libvlc_event_attach( p_mlist->p_flat_mlist->p_event_manager,
                          libvlc_MediaListItemAdded,
-                         sublist_item_added, p_mlist, NULL );
-    libvlc_event_detach( p_mlist->p_event_manager,
+                         flat_mlist_item_added, p_mlist, NULL );
+    libvlc_event_attach( p_mlist->p_flat_mlist->p_event_manager,
                          libvlc_MediaListItemDeleted,
-                         sublist_item_removed, p_mlist, NULL );
+                         flat_mlist_item_removed, p_mlist, NULL );
+
+}
+
+/**************************************************************************
+ *       uninstall_flat_mlist_observer (Private)
+ **************************************************************************/
+static void
+uninstall_flat_mlist_observer( libvlc_media_list_t * p_mlist )
+{
+    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_MediaListItemDeleted,
+                         flat_mlist_item_removed, p_mlist, NULL );
+
 }
 
+/*
+ * libvlc Internal functions
+ */
+/**************************************************************************
+ *       flat_media_list_release (Internal)
+ **************************************************************************/
+void
+libvlc_media_list_flat_media_list_release( libvlc_media_list_t * p_mlist )
+{
+    if( !p_mlist->p_flat_mlist )
+        return;
+    uninstall_flat_mlist_observer( p_mlist );
+    libvlc_media_list_release( p_mlist->p_flat_mlist );
+}
 
 /*
  * Public libvlc functions
@@ -182,6 +308,7 @@ libvlc_media_list_flat_media_list( libvlc_media_list_t * p_mlist,
                                             p_mlist->p_libvlc_instance,
                                             p_e );
         add_media_list( p_mlist->p_flat_mlist, p_mlist );
+        install_flat_mlist_observer( p_mlist );
     }
     libvlc_media_list_retain( p_mlist->p_flat_mlist );
     return p_mlist->p_flat_mlist;
index b5fe9ee..d5f1d51 100644 (file)
@@ -246,6 +246,10 @@ VLC_EXPORT (libvlc_media_descriptor_t *, libvlc_media_descriptor_new_from_input_
 VLC_EXPORT (libvlc_media_descriptor_t *, libvlc_media_descriptor_duplicate,
                         ( libvlc_media_descriptor_t * ) );
 
+/* Media List */
+VLC_EXPORT ( void, libvlc_media_list_flat_media_list_release,
+                        ( libvlc_media_list_t * ) );
+
 /* Events */
 VLC_EXPORT (void, libvlc_event_init, ( libvlc_instance_t *p_instance, libvlc_exception_t *p_e ) );
 
index 461ffd5..136d152 100644 (file)
@@ -217,8 +217,7 @@ void libvlc_media_list_release( libvlc_media_list_t * p_mlist )
     /* Refcount null, time to free */
 
     /* Handled in flat_media_list.c */
-    if( p_mlist->p_flat_mlist )
-        libvlc_media_list_release( p_mlist->p_flat_mlist );
+    libvlc_media_list_flat_media_list_release( p_mlist );
 
     libvlc_event_manager_release( p_mlist->p_event_manager );