Commit 40e325ad authored by Pierre d'Herbemont's avatar Pierre d'Herbemont

MacOSX/Framework/VLCMediaList.m: Cache the media list objects in a...

MacOSX/Framework/VLCMediaList.m: Cache the media list objects in a NSMutableArray. We do this because we want to use bindings. Cocoa bindings requires us to send willChangeValueForKey/didChangeValueForKey on the main thread. And that's one of the simpler way to do that without having locking problems.
parent 17d26df4
...@@ -43,6 +43,7 @@ extern NSString * VLCMediaListItemDeleted; ...@@ -43,6 +43,7 @@ extern NSString * VLCMediaListItemDeleted;
{ {
void * p_mlist; //< Internal instance of media list void * p_mlist; //< Internal instance of media list
id <VLCMediaListDelegate,NSObject> delegate; //< Delegate object id <VLCMediaListDelegate,NSObject> delegate; //< Delegate object
NSMutableArray *cachedMedia; /* We need that private copy because of Cocoa Bindings, that need to be working on first thread */
} }
/* Properties */ /* Properties */
......
...@@ -48,8 +48,6 @@ static void HandleMediaListItemAdded(const libvlc_event_t *event, void *user_dat ...@@ -48,8 +48,6 @@ static void HandleMediaListItemAdded(const libvlc_event_t *event, void *user_dat
{ {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
id self = user_data; id self = user_data;
int index = event->u.media_list_item_added.index;
[self didChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:index] forKey:@"Media"];
[[VLCEventManager sharedManager] callOnMainThreadObject:self [[VLCEventManager sharedManager] callOnMainThreadObject:self
withMethod:@selector(mediaListItemAdded:) withMethod:@selector(mediaListItemAdded:)
withArgumentAsObject:[NSDictionary dictionaryWithObjectsAndKeys: withArgumentAsObject:[NSDictionary dictionaryWithObjectsAndKeys:
...@@ -58,40 +56,17 @@ static void HandleMediaListItemAdded(const libvlc_event_t *event, void *user_dat ...@@ -58,40 +56,17 @@ static void HandleMediaListItemAdded(const libvlc_event_t *event, void *user_dat
nil]]; nil]];
[pool release]; [pool release];
} }
static void HandleMediaListWillAddItem(const libvlc_event_t *event, void *user_data)
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
id self = user_data;
int index = event->u.media_list_will_add_item.index;
[self willChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:index] forKey:@"Media"];
[pool release];
}
static void HandleMediaListItemDeleted( const libvlc_event_t * event, void * user_data) static void HandleMediaListItemDeleted( const libvlc_event_t * event, void * user_data)
{ {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
id self = user_data; id self = user_data;
int index = event->u.media_list_will_add_item.index;
[self didChange:NSKeyValueChangeRemoval valuesAtIndexes:[NSIndexSet indexSetWithIndex:index] forKey:@"Media"];
// Check to see if the last item deleted is this item we're trying delete now.
// If no, then delete the item from the local list, otherwise, the item has already
// been deleted
[[VLCEventManager sharedManager] callOnMainThreadObject:self [[VLCEventManager sharedManager] callOnMainThreadObject:self
withMethod:@selector(mediaListItemRemoved:) withMethod:@selector(mediaListItemRemoved:)
withArgumentAsObject:[NSNumber numberWithInt:event->u.media_list_item_deleted.index]]; withArgumentAsObject:[NSNumber numberWithInt:event->u.media_list_item_deleted.index]];
[pool release]; [pool release];
} }
static void HandleMediaListWillDeleteItem(const libvlc_event_t *event, void *user_data)
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
id self = user_data;
int index = event->u.media_list_will_add_item.index;
[self willChange:NSKeyValueChangeRemoval valuesAtIndexes:[NSIndexSet indexSetWithIndex:index] forKey:@"Media"];
[pool release];
}
@implementation VLCMediaList (KeyValueCodingCompliance) @implementation VLCMediaList (KeyValueCodingCompliance)
/* For the @"Media" key */ /* For the @"Media" key */
- (int) countOfMedia - (int) countOfMedia
...@@ -117,6 +92,7 @@ static void HandleMediaListWillDeleteItem(const libvlc_event_t *event, void *use ...@@ -117,6 +92,7 @@ static void HandleMediaListWillDeleteItem(const libvlc_event_t *event, void *use
quit_on_exception(&p_e); quit_on_exception(&p_e);
// Initialize internals to defaults // Initialize internals to defaults
cachedMedia = [[NSMutableArray alloc] init];
delegate = nil; delegate = nil;
[self initInternalMediaList]; [self initInternalMediaList];
} }
...@@ -134,9 +110,7 @@ static void HandleMediaListWillDeleteItem(const libvlc_event_t *event, void *use ...@@ -134,9 +110,7 @@ static void HandleMediaListWillDeleteItem(const libvlc_event_t *event, void *use
* Before libvlc_event_detach. So this can't happen in dealloc */ * Before libvlc_event_detach. So this can't happen in dealloc */
libvlc_event_manager_t * p_em = libvlc_media_list_event_manager(p_mlist, NULL); libvlc_event_manager_t * p_em = libvlc_media_list_event_manager(p_mlist, NULL);
libvlc_event_detach(p_em, libvlc_MediaListItemDeleted, HandleMediaListItemDeleted, self, NULL); libvlc_event_detach(p_em, libvlc_MediaListItemDeleted, HandleMediaListItemDeleted, self, NULL);
libvlc_event_detach(p_em, libvlc_MediaListWillDeleteItem, HandleMediaListWillDeleteItem, self, NULL);
libvlc_event_detach(p_em, libvlc_MediaListItemAdded, HandleMediaListItemAdded, self, NULL); libvlc_event_detach(p_em, libvlc_MediaListItemAdded, HandleMediaListItemAdded, self, NULL);
libvlc_event_detach(p_em, libvlc_MediaListWillAddItem, HandleMediaListWillAddItem, self, NULL);
} }
[super release]; [super release];
} }
...@@ -146,7 +120,7 @@ static void HandleMediaListWillDeleteItem(const libvlc_event_t *event, void *use ...@@ -146,7 +120,7 @@ static void HandleMediaListWillDeleteItem(const libvlc_event_t *event, void *use
{ {
// Release allocated memory // Release allocated memory
libvlc_media_list_release(p_mlist); libvlc_media_list_release(p_mlist);
[cachedMedia release];
[super dealloc]; [super dealloc];
} }
...@@ -201,24 +175,12 @@ static void HandleMediaListWillDeleteItem(const libvlc_event_t *event, void *use ...@@ -201,24 +175,12 @@ static void HandleMediaListWillDeleteItem(const libvlc_event_t *event, void *use
- (VLCMedia *)mediaAtIndex:(int)index - (VLCMedia *)mediaAtIndex:(int)index
{ {
libvlc_exception_t p_e; return [cachedMedia objectAtIndex:index];
libvlc_exception_init( &p_e );
libvlc_media_descriptor_t *p_md = libvlc_media_list_item_at_index( p_mlist, index, &p_e );
quit_on_exception( &p_e );
// Returns local object for media descriptor, searchs for user data first. If not found it creates a
// new cocoa object representation of the media descriptor.
return [VLCMedia mediaWithLibVLCMediaDescriptor:p_md];
} }
- (int)count - (int)count
{ {
libvlc_exception_t p_e; return [cachedMedia count];
libvlc_exception_init( &p_e );
int result = libvlc_media_list_count( p_mlist, &p_e );
quit_on_exception( &p_e );
return result;
} }
- (int)indexOfMedia:(VLCMedia *)media - (int)indexOfMedia:(VLCMedia *)media
...@@ -264,7 +226,17 @@ static void HandleMediaListWillDeleteItem(const libvlc_event_t *event, void *use ...@@ -264,7 +226,17 @@ static void HandleMediaListWillDeleteItem(const libvlc_event_t *event, void *use
{ {
p_mlist = p_new_mlist; p_mlist = p_new_mlist;
libvlc_media_list_retain(p_mlist); libvlc_media_list_retain(p_mlist);
libvlc_media_list_lock(p_mlist);
cachedMedia = [[NSMutableArray alloc] initWithCapacity:libvlc_media_list_count(p_mlist, NULL)];
int i, count = libvlc_media_list_count(p_mlist, NULL);
for( i = 0; i < count; i++ )
{
libvlc_media_descriptor_t * p_md = libvlc_media_list_item_at_index(p_mlist, i, NULL);
[cachedMedia addObject:[VLCMedia mediaWithLibVLCMediaDescriptor: p_md]];
libvlc_media_descriptor_release(p_md);
}
[self initInternalMediaList]; [self initInternalMediaList];
libvlc_media_list_unlock(p_mlist);
} }
return self; return self;
} }
...@@ -285,9 +257,7 @@ static void HandleMediaListWillDeleteItem(const libvlc_event_t *event, void *use ...@@ -285,9 +257,7 @@ static void HandleMediaListWillDeleteItem(const libvlc_event_t *event, void *use
libvlc_event_manager_t *p_em = libvlc_media_list_event_manager( p_mlist, &p_e ); libvlc_event_manager_t *p_em = libvlc_media_list_event_manager( p_mlist, &p_e );
libvlc_event_attach( p_em, libvlc_MediaListItemAdded, HandleMediaListItemAdded, self, &p_e ); libvlc_event_attach( p_em, libvlc_MediaListItemAdded, HandleMediaListItemAdded, self, &p_e );
libvlc_event_attach( p_em, libvlc_MediaListWillAddItem, HandleMediaListWillAddItem, self, &p_e );
libvlc_event_attach( p_em, libvlc_MediaListItemDeleted, HandleMediaListItemDeleted, self, &p_e ); libvlc_event_attach( p_em, libvlc_MediaListItemDeleted, HandleMediaListItemDeleted, self, &p_e );
libvlc_event_attach( p_em, libvlc_MediaListWillDeleteItem, HandleMediaListWillDeleteItem, self, &p_e );
[self unlock]; [self unlock];
quit_on_exception( &p_e ); quit_on_exception( &p_e );
...@@ -295,6 +265,13 @@ static void HandleMediaListWillDeleteItem(const libvlc_event_t *event, void *use ...@@ -295,6 +265,13 @@ static void HandleMediaListWillDeleteItem(const libvlc_event_t *event, void *use
- (void)mediaListItemAdded:(NSDictionary *)args - (void)mediaListItemAdded:(NSDictionary *)args
{ {
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"];
// Post the notification // Post the notification
[[NSNotificationCenter defaultCenter] postNotificationName:VLCMediaListItemAdded [[NSNotificationCenter defaultCenter] postNotificationName:VLCMediaListItemAdded
object:self object:self
...@@ -302,11 +279,15 @@ static void HandleMediaListWillDeleteItem(const libvlc_event_t *event, void *use ...@@ -302,11 +279,15 @@ static void HandleMediaListWillDeleteItem(const libvlc_event_t *event, void *use
// Let the delegate know that the item was added // Let the delegate know that the item was added
if (delegate && [delegate respondsToSelector:@selector(mediaList:mediaAdded:atIndex:)]) if (delegate && [delegate respondsToSelector:@selector(mediaList:mediaAdded:atIndex:)])
[delegate mediaList:self mediaAdded:[args objectForKey:@"media"] atIndex:[[args objectForKey:@"index"] intValue]]; [delegate mediaList:self mediaAdded:media atIndex:index];
} }
- (void)mediaListItemRemoved:(NSNumber *)index - (void)mediaListItemRemoved:(NSNumber *)index
{ {
[self willChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:[index intValue]] forKey:@"Media"];
[cachedMedia removeObjectAtIndex:[index intValue]];
[self didChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:[index intValue]] forKey:@"Media"];
// Post the notification // Post the notification
[[NSNotificationCenter defaultCenter] postNotificationName:VLCMediaListItemDeleted [[NSNotificationCenter defaultCenter] postNotificationName:VLCMediaListItemDeleted
object:self object:self
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment