MacOSX/Framework: Support event collapsing, and save the media list thats own the...
authorPierre d'Herbemont <pdherbemont@videolan.org>
Tue, 1 Jan 2008 15:29:05 +0000 (15:29 +0000)
committerPierre d'Herbemont <pdherbemont@videolan.org>
Tue, 1 Jan 2008 15:29:05 +0000 (15:29 +0000)
extras/MacOSX/Framework/Headers/Internal/VLCLibVLCBridging.h
extras/MacOSX/Framework/Headers/Public/VLCMediaListAspect.h
extras/MacOSX/Framework/Sources/VLCMediaList.m
extras/MacOSX/Framework/Sources/VLCMediaListAspect.m

index 4200986..58dbea1 100644 (file)
@@ -71,7 +71,8 @@
 
 @interface VLCMediaListAspect (VLCLibVLCBridging)
 + (id)mediaListAspectWithLibVLCMediaListView:(libvlc_media_list_view_t *)p_new_mlv;
-- (id)initWithLibVLCMediaListView:(libvlc_media_list_view_t *)p_new_mlv;
++ (id)mediaListAspectWithLibVLCMediaListView:(libvlc_media_list_view_t *)p_new_mlv andMediaList:(VLCMediaList*)mediaList;
+- (id)initWithLibVLCMediaListView:(libvlc_media_list_view_t *)p_new_mlv andMediaList:(VLCMediaList*)mediaList;
 - (libvlc_media_list_view_t *)libVLCMediaListView;
 @end
 
index 35e8450..94243e0 100644 (file)
@@ -42,6 +42,7 @@
     void * p_mlv;                //< Internal instance of media list view
     NSMutableArray * cachedNode;
     VLCMediaList *parentMediaList;
+    BOOL ownHisMediaList;
 }
 - (VLCMedia *)mediaAtIndex:(int)index;
 - (VLCMediaListAspectNode *)nodeAtIndex:(int)index;
index 4e15e06..82e7b4a 100644 (file)
@@ -31,7 +31,7 @@
 
 /* Notification Messages */
 NSString *VLCMediaListItemAdded        = @"VLCMediaListItemAdded";
-NSString *VLCMediaListItemDeleted    = @"VLCMediaListItemDeleted";
+NSString *VLCMediaListItemDeleted      = @"VLCMediaListItemDeleted";
 
 // TODO: Documentation
 @interface VLCMediaList (Private)
@@ -39,7 +39,7 @@ NSString *VLCMediaListItemDeleted    = @"VLCMediaListItemDeleted";
 - (void)initInternalMediaList;
 
 /* Libvlc event bridges */
-- (void)mediaListItemAdded:(NSDictionary *)args;
+- (void)mediaListItemAdded:(NSArray *)args;
 - (void)mediaListItemRemoved:(NSNumber *)index;
 @end
 
@@ -50,10 +50,10 @@ static void HandleMediaListItemAdded(const libvlc_event_t *event, void *user_dat
     id self = user_data;
     [[VLCEventManager sharedManager] callOnMainThreadObject:self 
                                                  withMethod:@selector(mediaListItemAdded:) 
-                                       withArgumentAsObject:[NSDictionary dictionaryWithObjectsAndKeys:
+                                       withArgumentAsObject:[NSArray arrayWithObject:[NSDictionary dictionaryWithObjectsAndKeys:
                                                           [VLCMedia mediaWithLibVLCMediaDescriptor:event->u.media_list_item_added.item], @"media",
                                                           [NSNumber numberWithInt:event->u.media_list_item_added.index], @"index",
-                                                          nil]];
+                                                          nil]]];
     [pool release];
 }
 
@@ -130,12 +130,10 @@ static void HandleMediaListItemDeleted( const libvlc_event_t * event, void * use
 {
     NSMutableString *content = [NSMutableString string];
     int i;
-    [self lock];
     for( i = 0; i < [self count]; i++)
     {
         [content appendFormat:@"%@\n", [self mediaAtIndex: i]];
     }
-    [self unlock];
     return [NSString stringWithFormat:@"<%@ %p> {\n%@}", [self className], self, content];
 }
 
@@ -224,7 +222,7 @@ static void HandleMediaListItemDeleted( const libvlc_event_t * event, void * use
     if( hierarchicalAspect )
         return hierarchicalAspect;
     libvlc_media_list_view_t * p_mlv = libvlc_media_list_hierarchical_view( p_mlist, NULL );
-    hierarchicalAspect = [[VLCMediaListAspect mediaListAspectWithLibVLCMediaListView: p_mlv] retain];
+    hierarchicalAspect = [[VLCMediaListAspect mediaListAspectWithLibVLCMediaListView: p_mlv andMediaList:self] retain];
     libvlc_media_list_view_release( p_mlv );
     return hierarchicalAspect;
 }
@@ -234,7 +232,7 @@ static void HandleMediaListItemDeleted( const libvlc_event_t * event, void * use
     if( hierarchicalAspect )
         return hierarchicalAspect;
     libvlc_media_list_view_t * p_mlv = libvlc_media_list_hierarchical_node_view( p_mlist, NULL );
-    hierarchicalAspect = [[VLCMediaListAspect mediaListAspectWithLibVLCMediaListView: p_mlv] retain];
+    hierarchicalAspect = [[VLCMediaListAspect mediaListAspectWithLibVLCMediaListView: p_mlv andMediaList:self] retain];
     libvlc_media_list_view_release( p_mlv );
     return hierarchicalAspect;
 }
@@ -244,7 +242,7 @@ static void HandleMediaListItemDeleted( const libvlc_event_t * event, void * use
     if( flatAspect )
         return flatAspect;
     libvlc_media_list_view_t * p_mlv = libvlc_media_list_flat_view( p_mlist, NULL );
-    flatAspect = [[VLCMediaListAspect mediaListAspectWithLibVLCMediaListView: p_mlv] retain];
+    flatAspect = [[VLCMediaListAspect mediaListAspectWithLibVLCMediaListView: p_mlv andMediaList:self] retain];
     libvlc_media_list_view_release( p_mlv );
     return flatAspect;
 }
@@ -298,23 +296,35 @@ static void HandleMediaListItemDeleted( const libvlc_event_t * event, void * use
     quit_on_exception( &p_e );
 }
 
-- (void)mediaListItemAdded:(NSDictionary *)args
+- (void)mediaListItemAdded:(NSArray *)arrayOfArgs
 {
-    int index = [[args objectForKey:@"index"] intValue];
-    VLCMedia * media = [args objectForKey:@"media"];
-
-    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:index] forKey:@"media"];
-    [cachedMedia insertObject:media atIndex:index];
-    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:index] forKey:@"media"];
+    /* We hope to receive index in a nide range, that could change one day */
+    int start = [[[arrayOfArgs objectAtIndex: 0] objectForKey:@"index"] intValue];
+    int end = [[[arrayOfArgs objectAtIndex: [arrayOfArgs count]-1] objectForKey:@"index"] intValue];
+    NSRange range = NSMakeRange(start, end-start);
+    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndexesInRange:range] forKey:@"media"];
+    int i = [[[arrayOfArgs objectAtIndex: 0] objectForKey:@"index"] intValue];
+    [arrayOfArgs retain];
+    for( NSDictionary * args in arrayOfArgs )
+    {
+        int index = [[args objectForKey:@"index"] intValue];
+        VLCMedia * media = [args objectForKey:@"media"];
+        /* Sanity check */
+        NSAssert( i == index, @"Expects some troubles, inserted items are not in a range" ); i++;
+        if( index && index >= [cachedMedia count] )
+            index = [cachedMedia count] - 1;
+        [cachedMedia insertObject:media atIndex:index];
+    }
+    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndexesInRange:range] forKey:@"media"];
 
     // Post the notification
-    [[NSNotificationCenter defaultCenter] postNotificationName:VLCMediaListItemAdded
-                                                        object:self
-                                                      userInfo:args];
+//    [[NSNotificationCenter defaultCenter] postNotificationName:VLCMediaListItemAdded
+//                                                        object:self
+//                                                      userInfo:args];
 
     // Let the delegate know that the item was added
-    if (delegate && [delegate respondsToSelector:@selector(mediaList:mediaAdded:atIndex:)])
-        [delegate mediaList:self mediaAdded:media atIndex:index];
+  //  if (delegate && [delegate respondsToSelector:@selector(mediaList:mediaAdded:atIndex:)])
+    //    [delegate mediaList:self mediaAdded:media atIndex:index];
 }
 
 - (void)mediaListItemRemoved:(NSNumber *)index
index abc5441..73bc402 100644 (file)
@@ -34,7 +34,7 @@
 /* Initializers */
 - (void)initInternalMediaListView;
 
-- (void)mediaListViewItemAdded:(NSDictionary *)args;
+- (void)mediaListViewItemAdded:(NSArray *)args;
 - (void)mediaListViewItemRemoved:(NSNumber *)index;
 @end
 
@@ -82,10 +82,10 @@ static void HandleMediaListViewItemAdded(const libvlc_event_t *event, void *user
     id self = user_data;
     [[VLCEventManager sharedManager] callOnMainThreadObject:self 
                                                  withMethod:@selector(mediaListViewItemAdded:) 
-                                       withArgumentAsObject:[NSDictionary dictionaryWithObjectsAndKeys:
+                                       withArgumentAsObject:[NSArray arrayWithObject:[NSDictionary dictionaryWithObjectsAndKeys:
                                                           [VLCMedia mediaWithLibVLCMediaDescriptor:event->u.media_list_item_added.item], @"media",
                                                           [NSNumber numberWithInt:event->u.media_list_item_added.index], @"index",
-                                                          nil]];
+                                                          nil]]];
     [pool release];
 }
 
@@ -105,9 +105,21 @@ static void HandleMediaListViewItemDeleted( const libvlc_event_t * event, void *
     // Release allocated memory
     libvlc_media_list_view_release(p_mlv);
     [cachedNode release];
-    [parentMediaList release];
+    if( ownHisMediaList )
+        [parentMediaList release];
     [super dealloc];
 }
+- (NSString *)description
+{
+    NSMutableString *content = [NSMutableString string];
+    int i;
+    for( i = 0; i < [self count]; i++)
+    {
+        [content appendFormat:@"%@\n", [self mediaAtIndex: i]];
+    }
+    return [NSString stringWithFormat:@"<%@ %p> {\n%@}", [self className], self, content];
+}
+
 - (VLCMedia *)mediaAtIndex:(int)index
 {
     libvlc_exception_t p_e;
@@ -154,28 +166,47 @@ static void HandleMediaListViewItemDeleted( const libvlc_event_t * event, void *
 
 - (VLCMediaList *)parentMediaList
 {
-    return [[parentMediaList retain] autorelease];
+    return parentMediaList;
 }
 @end
 
 @implementation VLCMediaListAspect (LibVLCBridging)
-+ (id)mediaListAspectWithLibVLCMediaListView:(libvlc_media_list_view_t *)p_new_mlv;
++ (id)mediaListAspectWithLibVLCMediaListView:(libvlc_media_list_view_t *)p_new_mlv
 {
-    return [[[VLCMediaListAspect alloc] initWithLibVLCMediaListView:p_new_mlv] autorelease];
+    return [[[VLCMediaListAspect alloc] initWithLibVLCMediaListView:p_new_mlv andMediaList:nil] autorelease];
 }
 
-- (id)initWithLibVLCMediaListView:(libvlc_media_list_view_t *)p_new_mlv;
++ (id)mediaListAspectWithLibVLCMediaListView:(libvlc_media_list_view_t *)p_new_mlv andMediaList:(VLCMediaList *)mediaList;
+{
+    return [[[VLCMediaListAspect alloc] initWithLibVLCMediaListView:p_new_mlv andMediaList:mediaList] autorelease];
+}
+
+- (id)initWithLibVLCMediaListView:(libvlc_media_list_view_t *)p_new_mlv andMediaList:(VLCMediaList *)mediaList;
 {
     if( self = [super init] )
     {
         p_mlv = p_new_mlv;
         libvlc_media_list_view_retain(p_mlv);
-        libvlc_media_list_t * p_mlist = libvlc_media_list_view_parent_media_list(p_mlv, NULL);
-        parentMediaList = [[VLCMediaList mediaListWithLibVLCMediaList: p_mlist] retain];
-        libvlc_media_list_release( p_mlist );
+
+        /* parentMediaList isn't retained, because we need a mediaList to exists, and not the contrary */
+        parentMediaList = mediaList;
+        ownHisMediaList = NO;
+        if( !parentMediaList )
+        {
+            /* We have to create it then */
+            libvlc_media_list_view_retain(p_mlv);
+            libvlc_media_list_t * p_mlist = libvlc_media_list_view_parent_media_list(p_mlv, NULL);
+            parentMediaList = [[VLCMediaList mediaListWithLibVLCMediaList: p_mlist] retain];
+            libvlc_media_list_release( p_mlist );
+            /* This is an exception, and we owns it here */
+            ownHisMediaList = YES;
+        }
 
         //libvlc_media_list_lock(p_mlv->p_mlist);
         cachedNode = [[NSMutableArray alloc] initWithCapacity:libvlc_media_list_view_count(p_mlv, NULL)];
+        libvlc_media_list_t * p_mlist;
+        p_mlist = libvlc_media_list_view_parent_media_list( p_mlv, NULL );
+        libvlc_media_list_lock( p_mlist );
         int i, count = libvlc_media_list_view_count(p_mlv, NULL);
         for( i = 0; i < count; i++ )
         {
@@ -189,6 +220,8 @@ static void HandleMediaListViewItemDeleted( const libvlc_event_t * event, void *
             if( p_sub_mlv ) libvlc_media_list_view_release(p_sub_mlv);
         }
         [self initInternalMediaListView];
+        libvlc_media_list_unlock( p_mlist );
+        libvlc_media_list_release( p_mlist );
         //libvlc_media_list_unlock(p_mlv->p_mlist);
     }
     return self;
@@ -214,20 +247,33 @@ static void HandleMediaListViewItemDeleted( const libvlc_event_t * event, void *
     quit_on_exception( &e );
 }
 
-- (void)mediaListViewItemAdded:(NSDictionary *)args
+- (void)mediaListViewItemAdded:(NSArray *)arrayOfArgs
 {
-    int index = [[args objectForKey:@"index"] intValue];
-    VLCMedia * media = [args objectForKey:@"media"];
+    NSAssert([NSThread isMainThread], @"We are not on main thread");
 
-    VLCMediaListAspectNode * node = [[[VLCMediaListAspectNode alloc] init] autorelease];
-    [node setMedia:media];
-    [node setChildren:[self childrenAtIndex:index]];
-
-    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:index] forKey:@"media"];
-    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:index] forKey:@"node"];
-    [cachedNode insertObject:node atIndex:index];
-    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:index] forKey:@"node"];
-    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:index] forKey:@"media"];
+    /* We hope to receive index in a nide range, that could change one day */
+    int start = [[[arrayOfArgs objectAtIndex: 0] objectForKey:@"index"] intValue];
+    int end = [[[arrayOfArgs objectAtIndex: [arrayOfArgs count]-1] objectForKey:@"index"] intValue];
+    NSRange range = NSMakeRange(start, end-start);
+
+    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndexesInRange:range] forKey:@"media"];
+    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndexesInRange:range] forKey:@"node"];
+    int i = [[[arrayOfArgs objectAtIndex: 0] objectForKey:@"index"] intValue];
+    for( NSDictionary * args in arrayOfArgs )
+    {
+        int index = [[args objectForKey:@"index"] intValue];
+        VLCMedia * media = [args objectForKey:@"media"];
+        VLCMediaListAspectNode * node = [[[VLCMediaListAspectNode alloc] init] autorelease];
+        [node setMedia:media];
+        [node setChildren:[self childrenAtIndex:index]];
+        /* Sanity check */
+        NSAssert( i == index, @"Expects some troubles, inserted items are not in a range" ); i++;
+        if( index && index >= [cachedNode count] )
+            index = [cachedNode count] - 1;
+        [cachedNode insertObject:node atIndex:index];
+    }
+    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndexesInRange:range] forKey:@"node"];
+    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndexesInRange:range] forKey:@"media"];
 }
 
 - (void)mediaListViewItemRemoved:(NSNumber *)index