control/media_list_view.c: Rework the media_list_view. Make it unmutable.
authorPierre d'Herbemont <pdherbemont@videolan.org>
Sat, 13 Oct 2007 13:53:45 +0000 (13:53 +0000)
committerPierre d'Herbemont <pdherbemont@videolan.org>
Sat, 13 Oct 2007 13:53:45 +0000 (13:53 +0000)
include/vlc/libvlc.h
src/control/libvlc_internal.h
src/control/media_list_view.c

index df8e5a0..64f9f8d 100644 (file)
@@ -509,6 +509,9 @@ VLC_PUBLIC_API libvlc_event_manager_t *
  * LibVLC Media List View
  * @{ */
 
+VLC_PUBLIC_API void
+    libvlc_media_list_view_retain( libvlc_media_list_view_t * p_mlv );
+
 VLC_PUBLIC_API int
     libvlc_media_list_view_count(  libvlc_media_list_view_t * p_mlv,
                                    libvlc_exception_t * p_e );
index 5e50ff3..0ad0b52 100644 (file)
@@ -106,13 +106,24 @@ struct libvlc_media_list_t
     vlc_mutex_t                 object_lock;
     libvlc_media_descriptor_t * p_md; /* The media_descriptor from which the
                                        * mlist comes, if any. */
-    DECL_ARRAY(void *)          items;
+    vlc_array_t                items;
  
     /* Other way to see that media list */
     /* Used in flat_media_list.c */
     libvlc_media_list_t *       p_flat_mlist;
 };
 
+typedef int (*libvlc_media_list_view_release_func_t)( libvlc_media_list_view_t * p_mlv ) ;
+
+typedef int (*libvlc_media_list_view_count_func_t)( struct libvlc_media_list_view_t * p_mlv,
+        libvlc_exception_t * ) ;
+
+typedef libvlc_media_descriptor_t *
+        (*libvlc_media_list_view_item_at_index_func_t)(
+                struct libvlc_media_list_view_t * p_mlv,
+                int index,
+                libvlc_exception_t * ) ;
+
 /* A way to see a media list */
 struct libvlc_media_list_view_t
 {
@@ -126,28 +137,14 @@ struct libvlc_media_list_view_t
     void *                      this_view_data;
 
     /* Accessors */
-    int (*pf_count)( struct libvlc_media_list_view_t * p_mlv,
-                      libvlc_exception_t * );
-    libvlc_media_descriptor_t *
-        (*pf_item_at_index)( struct libvlc_media_list_view_t * p_mlv,
-                              int index,
-                              libvlc_exception_t * );
-    int  (*pf_index_of_item)( struct libvlc_media_list_view_t * p_mlv,
-                              libvlc_media_descriptor_t * p_md,
-                              libvlc_exception_t * );
-
-    /* Setters */
-    void (*pf_insert_at_index)( struct libvlc_media_list_view_t * p_mlv,
-                                     libvlc_media_descriptor_t * p_md,
-                                     int index,
-                                     libvlc_exception_t * );
-    void (*pf_remove_at_index)( struct libvlc_media_list_view_t * p_mlv,
-                                     int index,
-                                     libvlc_exception_t * );
-    void (*pf_add_item)( struct libvlc_media_list_view_t * p_mlv,
-                         libvlc_media_descriptor_t * p_md,
-                         libvlc_exception_t * );
-        
+    libvlc_media_list_view_count_func_t         pf_count;
+    libvlc_media_list_view_item_at_index_func_t pf_item_at_index;
+
+    libvlc_media_list_view_release_func_t       pf_release;
+
+    /* Notification callback */
+    void (*pf_ml_item_added)(const libvlc_event_t *, void *);
+    void (*pf_ml_item_removed)(const libvlc_event_t *, void *);
 };
 
 struct libvlc_dynamic_media_list_t
@@ -289,6 +286,20 @@ VLC_EXPORT (libvlc_media_descriptor_t *, libvlc_media_descriptor_duplicate,
 /* Media List */
 VLC_EXPORT ( void, libvlc_media_list_flat_media_list_release, ( libvlc_media_list_t * ) );
 
+/* Media List View */
+VLC_EXPORT ( libvlc_media_list_view_t *, libvlc_media_list_view_new,
+                          ( libvlc_media_list_t * p_mlist,
+                            libvlc_media_list_view_count_func_t pf_count,
+                            libvlc_media_list_view_item_at_index_func_t pf_item_at_index,
+                            libvlc_media_list_view_release_func_t pf_release,
+                            void * this_view_data,
+                            libvlc_exception_t * p_e ) );
+
+VLC_EXPORT ( void, libvlc_media_list_view_set_ml_notification_callback, (
+                libvlc_media_list_view_t * p_mlv,
+                void (*item_added)(const libvlc_event_t *, void *),
+                void (*item_removed)(const libvlc_event_t *, void *) ));
+
 /* Events */
 VLC_EXPORT (void, libvlc_event_init, ( libvlc_instance_t *p_instance, libvlc_exception_t *p_e ) );
 
index e75d786..b80ce0c 100644 (file)
 /*
  * Private functions
  */
+static void
+media_list_item_removed( const libvlc_event_t * p_event, void * p_user_data );
+
+static void
+media_list_item_added( const libvlc_event_t * p_event, void * p_user_data )
+{
+    libvlc_media_list_view_t * p_mlv = p_user_data;
+    libvlc_media_descriptor_t * p_md = p_event->u.media_list_item_added.item;
+    libvlc_media_list_t * p_mlist;
+    if((p_mlist = libvlc_media_descriptor_subitems( p_md, NULL )))
+    {
+        libvlc_event_attach( p_mlist->p_event_manager,
+                             libvlc_MediaListItemAdded,
+                             media_list_item_added, p_mlv, NULL );
+        libvlc_event_attach( p_mlist->p_event_manager,
+                             libvlc_MediaListItemDeleted,
+                             media_list_item_removed, p_mlv, NULL );
+    }
+    if( p_mlv->pf_ml_item_added ) p_mlv->pf_ml_item_added( p_event, p_user_data );
+}
+
+static void
+media_list_item_removed( const libvlc_event_t * p_event, void * p_user_data )
+{
+    libvlc_media_list_view_t * p_mlv = p_user_data;
+    libvlc_media_descriptor_t * p_md = p_event->u.media_list_item_added.item;
+    libvlc_media_list_t * p_mlist;
+    if((p_mlist = libvlc_media_descriptor_subitems( p_md, NULL )))
+    {
+        libvlc_event_attach( p_mlist->p_event_manager,
+                             libvlc_MediaListItemAdded,
+                             media_list_item_added, p_mlv, NULL );
+        libvlc_event_attach( p_mlist->p_event_manager,
+                             libvlc_MediaListItemDeleted,
+                             media_list_item_removed, p_mlv, NULL );
+    }
+    if( p_mlv->pf_ml_item_removed ) p_mlv->pf_ml_item_removed( p_event, p_user_data );
+}
+
+
+/*
+ * LibVLC Internal functions
+ */
+void
+libvlc_media_list_view_set_ml_notification_callback(
+                libvlc_media_list_view_t * p_mlv,
+                void (*item_added)(const libvlc_event_t *, void *),
+                void (*item_removed)(const libvlc_event_t *, void *) )
+{
+    p_mlv->pf_ml_item_added = item_added;
+    p_mlv->pf_ml_item_removed = item_removed;
+    libvlc_event_attach( p_mlv->p_mlist->p_event_manager,
+                         libvlc_MediaListItemAdded,
+                         media_list_item_added, p_mlv, NULL );
+    libvlc_event_attach( p_mlv->p_mlist->p_event_manager,
+                         libvlc_MediaListItemDeleted,
+                         media_list_item_removed, p_mlv, NULL );
+}
+
+/**************************************************************************
+ *       libvlc_media_list_view_new (Internal)
+ **************************************************************************/
+libvlc_media_list_view_t *
+libvlc_media_list_view_new( libvlc_media_list_t * p_mlist,
+                            libvlc_media_list_view_count_func_t pf_count,
+                            libvlc_media_list_view_item_at_index_func_t pf_item_at_index,
+                            libvlc_media_list_view_release_func_t pf_release,
+                            void * this_view_data,
+                            libvlc_exception_t * p_e )
+{
+    libvlc_media_list_view_t * p_mlv;
+    p_mlv = calloc( 1, sizeof(libvlc_media_list_view_t) );
+    if( !p_mlv )
+        return NULL;
+
+    p_mlv->p_libvlc_instance = p_mlist->p_libvlc_instance;
+    p_mlv->p_event_manager = libvlc_event_manager_new( p_mlist,
+                                    p_mlv->p_libvlc_instance, p_e );
+
+    libvlc_media_list_retain( p_mlist );
+    p_mlv->p_mlist = p_mlist;
+
+    p_mlv->pf_count         = pf_count;
+    p_mlv->pf_item_at_index = pf_item_at_index;
+    p_mlv->pf_release       = pf_release;
+
+    p_mlv->this_view_data = this_view_data;
+
+    vlc_mutex_init( p_mlv->p_libvlc_instance->p_libvlc_int, &p_mlv->object_lock );
+    p_mlv->i_refcount = 1;
+
+    return p_mlv;
+}
+
 
 /*
  * Public libvlc functions
  */
 
+/**************************************************************************
+ *       libvlc_media_list_view_release (Public)
+ **************************************************************************/
+void
+libvlc_media_list_view_release( libvlc_media_list_view_t * p_mlv )
+{
+    vlc_mutex_lock( &p_mlv->object_lock );
+    p_mlv->i_refcount--;
+    if( p_mlv->i_refcount > 0 )
+    {
+        vlc_mutex_unlock( &p_mlv->object_lock );
+        return;
+    }
+    vlc_mutex_unlock( &p_mlv->object_lock );
+
+    /* Refcount null, time to free */
+
+    if( p_mlv->pf_ml_item_added )
+    {
+        libvlc_event_detach( p_mlv->p_mlist->p_event_manager,
+                            libvlc_MediaListItemAdded,
+                            p_mlv->pf_ml_item_added, p_mlv, NULL );
+        /* XXX: descend the whole tree and remove observer */
+    }
+    if( p_mlv->pf_ml_item_removed )
+    {
+        libvlc_event_detach( p_mlv->p_mlist->p_event_manager,
+                            libvlc_MediaListItemDeleted,
+                            p_mlv->pf_ml_item_removed, p_mlv, NULL );
+        /* XXX: descend the whole tree and remove observer */
+    }
+
+    libvlc_event_manager_release( p_mlv->p_event_manager );
+
+    if( p_mlv->pf_release ) p_mlv->pf_release( p_mlv );
+    libvlc_media_list_release( p_mlv->p_mlist );
+    vlc_mutex_destroy( &p_mlv->object_lock );
+}
+
 /* Limited to four args, because it should be enough */
 
 #define AN_SELECT( collapser, dec1, dec2, dec3, dec4, p, ...) p
 
 MEDIA_LIST_VIEW_FUNCTION( count, int, 0 )
 MEDIA_LIST_VIEW_FUNCTION( item_at_index, libvlc_media_descriptor_t *, NULL, int arg1 )
-MEDIA_LIST_VIEW_FUNCTION( index_of_item, int, -1, libvlc_media_descriptor_t * arg1 )
-
-MEDIA_LIST_VIEW_FUNCTION_VOID_RET( insert_at_index, libvlc_media_descriptor_t * arg1, int arg2 )
-MEDIA_LIST_VIEW_FUNCTION_VOID_RET( remove_at_index, int arg1 )
-MEDIA_LIST_VIEW_FUNCTION_VOID_RET( add_item, libvlc_media_descriptor_t * arg1 )