Commit 592c1efc authored by Pierre's avatar Pierre

macosx/framework: Get rid of VLCMediaListAspect, and remove a bunch of exception.

parent cb9e605b
......@@ -23,14 +23,13 @@
*****************************************************************************/
#import "VLCLibrary.h"
#import "VLCMediaListAspect.h"
#import "VLCStreamOutput.h"
#import "VLCMediaPlayer.h"
/* Utility functions */
/**
* \function catch_execption( ex )
* Utility function that catches a LibVLC generated exception by throwing a Cocoa based NSException.
* Utility function that catches a LibVLC generated exception by throwing a Cocoa based NSException.
* \param ex LibVLC exception returned by LibVLC internal functions.
*/
#define catch_exception( ex ) __catch_exception( (void *)(ex), __FUNCTION__, __FILE__, __LINE__ )
......@@ -44,7 +43,7 @@ extern void __catch_exception( void * e, const char * function, const char * fil
/**
* Manufactures new object wrapped around specified media list.
* \param p_new_mlist LibVLC media list pointer.
* \return Newly create media list instance using specified media list
* \return Newly create media list instance using specified media list
* pointer.
*/
+ (id)mediaListWithLibVLCMediaList:(void *)p_new_mlist;
......@@ -129,41 +128,13 @@ extern void __catch_exception( void * e, const char * function, const char * fil
@property (readonly) void * instance;
@end
/**
* Bridges functionality between VLCMediaListAspect and libvlc.
*/
@interface VLCMediaListAspect (VLCLibVLCBridging)
/* Factories */
/**
* Manufactures a new media list aspect object with libvlc media list view instance.
* \return Newly created media list aspect using specified libvlc media list view.
*/
+ (id)mediaListAspectWithLibVLCMediaListView:(libvlc_media_list_view_t *)p_new_mlv;
/**
* Manufactures a new media list aspect object with libvlc media list view instance.
* \return Newly created media list aspect using specified libvlc media list view.
*/
+ (id)mediaListAspectWithLibVLCMediaListView:(libvlc_media_list_view_t *)p_new_mlv andMediaList:(VLCMediaList*)mediaList;
/* Initializers */
/**
* Initializes a new media list aspect object with libvlc media list view instance.
* \return Newly created media list aspect using specified libvlc media list view.
*/
- (id)initWithLibVLCMediaListView:(libvlc_media_list_view_t *)p_new_mlv andMediaList:(VLCMediaList*)mediaList;
/* Properties */
@property (readonly) libvlc_media_list_view_t * libVLCMediaListView; //< Libvlc pointer to media list view instance.
@end
/**
* Bridges functionality between VLCLibrary and VLCAudio.
*/
@interface VLCLibrary (VLCAudioBridging)
/**
* Called by VLCAudio, each library has a singleton VLCaudio instance. VLCAudio
* calls this function to let the VLCLibrary instance know how to get in touch
* calls this function to let the VLCLibrary instance know how to get in touch
* with the VLCAudio instance. TODO: Each media player instance should have it's
* own audio instance...not each library instance.
*/
......
......@@ -31,7 +31,6 @@
#import <VLCKit/VLCMediaLibrary.h>
#import <VLCKit/VLCMediaList.h>
#import <VLCKit/VLCMediaListPlayer.h>
#import <VLCKit/VLCMediaListAspect.h>
#import <VLCKit/VLCMediaDiscoverer.h>
#import <VLCKit/VLCMediaPlayer.h>
#import <VLCKit/VLCTime.h>
......
......@@ -30,7 +30,6 @@ extern NSString * VLCMediaListItemDeleted;
@class VLCMedia;
@class VLCMediaList;
@class VLCMediaListAspect;
/**
* TODO: Documentation VLCMediaListDelegate
......@@ -56,9 +55,6 @@ extern NSString * VLCMediaListItemDeleted;
id <VLCMediaListDelegate,NSObject> delegate; //< Delegate object
/* We need that private copy because of Cocoa Bindings, that need to be working on first thread */
NSMutableArray * cachedMedia; //< Private copy of media objects.
VLCMediaListAspect * flatAspect; //< TODO: Documentation VLCMediaList.flatAspect
VLCMediaListAspect * hierarchicalAspect; //< TODO: Documentation VLCMediaList.hierarchicalAspect
VLCMediaListAspect * hierarchicalNodeAspect; //< TODO: Documentation VLCMediaList.hierarchicalNodeAspect
}
/* Operations */
......@@ -113,19 +109,4 @@ extern NSString * VLCMediaListItemDeleted;
*/
@property (readonly) BOOL isReadOnly;
/* Media list aspect */
/**
* TODO: Documentation VLCMediaList.hierarchicalAspect
*/
@property (readonly) VLCMediaListAspect * hierarchicalAspect;
/**
* TODO: Documentation VLCMediaList.hierarchicalNodeAspect
*/
@property (readonly) VLCMediaListAspect * hierarchicalNodeAspect;
/**
* TODO: Documentation VLCMediaList.flatAspect
*/
@property (readonly) VLCMediaListAspect * flatAspect;
@end
/*****************************************************************************
* VLCMediaLisAspect.h: VLCKit.framework VLCMediaLisAspect header
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "VLCMediaList.h"
@class VLCMedia;
@class VLCMediaList;
@interface VLCMediaListAspectNode : NSObject
{
VLCMedia * media;
VLCMediaListAspect * children;
}
@property (retain) VLCMedia * media;
@property (retain) VLCMediaListAspect * children;
- (BOOL)isLeaf;
@end
@interface VLCMediaListAspect : NSObject
{
void * p_mlv; //< Internal instance of media list view
NSMutableArray * cachedNode;
VLCMediaList * parentMediaList;
BOOL ownHisMediaList;
}
- (VLCMedia *)mediaAtIndex:(NSInteger)index;
- (VLCMediaListAspectNode *)nodeAtIndex:(NSInteger)index;
- (NSInteger)count;
- (VLCMediaList *)parentMediaList;
@end
......@@ -68,7 +68,7 @@ NSString * VLCMediaPlayerVolumeChanged = @"VLCMediaPlayerVolumeChanged";
value = VOLUME_MIN;
else if (value > VOLUME_MAX)
value = VOLUME_MAX;
libvlc_audio_set_volume([library instance], value, NULL);
libvlc_audio_set_volume([library instance], value);
}
- (void)volumeUp
......
......@@ -41,7 +41,7 @@ void __catch_exception( void * e, const char * function, const char * file, int
{
NSException* libvlcException = [NSException
exceptionWithName:@"LibVLCException"
reason:[NSString stringWithFormat:@"libvlc has thrown us an error: %s (%s:%d %s)",
reason:[NSString stringWithFormat:@"libvlc has thrown us an error: %s (%s:%d %s)",
libvlc_errmsg(), file, line_number, function]
userInfo:nil];
libvlc_exception_clear( ex );
......@@ -52,7 +52,7 @@ void __catch_exception( void * e, const char * function, const char * file, int
@implementation VLCLibrary
+ (VLCLibrary *)sharedLibrary
{
if (!sharedLibrary)
if (!sharedLibrary)
{
/* Initialize a shared instance */
sharedLibrary = [[self alloc] init];
......@@ -60,13 +60,13 @@ void __catch_exception( void * e, const char * function, const char * file, int
return sharedLibrary;
}
- (id)init
- (id)init
{
if (self = [super init])
if (self = [super init])
{
libvlc_exception_t ex;
libvlc_exception_init( &ex );
NSArray *vlcParams = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"VLCParams"];
if (!vlcParams) {
NSMutableArray *defaultParams = [NSMutableArray array];
......@@ -93,8 +93,7 @@ void __catch_exception( void * e, const char * function, const char * file, int
lib_vlc_params[paramNum] = [vlcParam cStringUsingEncoding:NSASCIIStringEncoding];
paramNum++;
}
instance = (void *)libvlc_new( sizeof(lib_vlc_params)/sizeof(lib_vlc_params[0]), lib_vlc_params, &ex );
catch_exception( &ex );
instance = (void *)libvlc_new( sizeof(lib_vlc_params)/sizeof(lib_vlc_params[0]), lib_vlc_params);
NSAssert(instance, @"libvlc failed to initialize");
// Assignment unneeded, as the audio unit will do it for us
......@@ -103,24 +102,24 @@ void __catch_exception( void * e, const char * function, const char * file, int
return self;
}
- (NSString *)version
- (NSString *)version
{
return [NSString stringWithUTF8String:libvlc_get_version()];
}
- (NSString *)changeset
- (NSString *)changeset
{
return [NSString stringWithUTF8String:libvlc_get_changeset()];
}
- (void)dealloc
- (void)dealloc
{
if( instance )
if( instance )
libvlc_release( instance );
if( self == sharedLibrary )
if( self == sharedLibrary )
sharedLibrary = nil;
instance = nil;
[audio release];
[super dealloc];
......
......@@ -81,7 +81,6 @@ static void HandleMediaListItemDeleted( const libvlc_event_t * event, void * use
// Initialize internals to defaults
cachedMedia = [[NSMutableArray alloc] init];
delegate = flatAspect = hierarchicalAspect = hierarchicalNodeAspect = nil;
[self initInternalMediaList];
}
return self;
......@@ -111,9 +110,6 @@ static void HandleMediaListItemDeleted( const libvlc_event_t * event, void * use
libvlc_media_list_release( p_mlist );
[cachedMedia release];
[flatAspect release];
[hierarchicalAspect release];
[hierarchicalNodeAspect release];
[super dealloc];
}
......@@ -211,40 +207,6 @@ static void HandleMediaListItemDeleted( const libvlc_event_t * event, void * use
return libvlc_media_list_is_readonly( p_mlist );
}
/* Media list aspect */
- (VLCMediaListAspect *)hierarchicalAspect
{
if( hierarchicalAspect )
return hierarchicalAspect;
libvlc_media_list_view_t * p_mlv = libvlc_media_list_hierarchical_view(p_mlist);
hierarchicalAspect = [[VLCMediaListAspect mediaListAspectWithLibVLCMediaListView:p_mlv andMediaList:self] retain];
libvlc_media_list_view_release( p_mlv );
return hierarchicalAspect;
}
- (VLCMediaListAspect *)hierarchicalNodeAspect
{
if( hierarchicalNodeAspect )
return hierarchicalNodeAspect;
libvlc_media_list_view_t * p_mlv = libvlc_media_list_hierarchical_node_view(p_mlist);
hierarchicalNodeAspect = [[VLCMediaListAspect mediaListAspectWithLibVLCMediaListView:p_mlv andMediaList:self] retain];
libvlc_media_list_view_release( p_mlv );
return hierarchicalNodeAspect;
}
- (VLCMediaListAspect *)flatAspect
{
if( flatAspect )
return flatAspect;
libvlc_media_list_view_t * p_mlv = libvlc_media_list_flat_view(p_mlist, NULL);
flatAspect = [[VLCMediaListAspect mediaListAspectWithLibVLCMediaListView:p_mlv andMediaList:self] retain];
libvlc_media_list_view_release( p_mlv );
return flatAspect;
}
@end
@implementation VLCMediaList (LibVLCBridging)
......
/*****************************************************************************
* VLCMediaListAspect.m: VLCKit.framework VLCMediaListAspect implementation
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "VLCMediaListAspect.h"
#import "VLCLibrary.h"
#import "VLCEventManager.h"
#import "VLCLibVLCBridging.h"
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc/vlc.h>
#include <vlc/libvlc.h>
// TODO: Documentation
@interface VLCMediaListAspect (Private)
/* Initializers */
- (void)initInternalMediaListView;
- (void)mediaListViewItemAdded:(NSArray *)args;
- (void)mediaListViewItemRemoved:(NSNumber *)index;
@end
@implementation VLCMediaListAspectNode
- (id)init
{
if(self = [super init])
{
media = nil;
children = nil;
}
return self;
}
- (void)dealloc
{
[media release];
[children release];
[super dealloc];
}
@synthesize media;
@synthesize children;
- (BOOL)isLeaf
{
return self.children == nil;
}
@end
@implementation VLCMediaListAspect (KeyValueCodingCompliance)
/* For the @"media" key */
- (NSInteger) countOfMedia
{
return [cachedNode count];
}
- (id) objectInMediaAtIndex:(NSInteger)i
{
return [[cachedNode objectAtIndex:i] media];
}
/* For the @"node" key */
- (NSInteger) countOfNode
{
return [cachedNode count];
}
- (id) objectInNodeAtIndex:(NSInteger)i
{
return [cachedNode objectAtIndex:i];
}
@end
/* libvlc event callback */
static void HandleMediaListViewItemAdded(const libvlc_event_t * event, void * user_data)
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
id self = user_data;
[[VLCEventManager sharedManager] callOnMainThreadObject:self
withMethod:@selector(mediaListViewItemAdded:)
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]]];
[pool release];
}
static void HandleMediaListViewItemDeleted( const libvlc_event_t * event, void * user_data)
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
id self = user_data;
[[VLCEventManager sharedManager] callOnMainThreadObject:self
withMethod:@selector(mediaListViewItemRemoved:)
withArgumentAsObject:[NSNumber numberWithInt:event->u.media_list_item_deleted.index]];
[pool release];
}
@implementation VLCMediaListAspect
- (void)dealloc
{
// Release allocated memory
libvlc_media_list_view_release(p_mlv);
[cachedNode release];
if( ownHisMediaList )
[parentMediaList release];
[super dealloc];
}
- (void)release
{
@synchronized(self)
{
if([self retainCount] <= 1)
{
/* We must make sure we won't receive new event after an upcoming dealloc
* We also may receive a -retain in some event callback that may occcur
* Before libvlc_event_detach. So this can't happen in dealloc */
libvlc_event_manager_t * p_em = libvlc_media_list_view_event_manager(p_mlv);
libvlc_event_detach(p_em, libvlc_MediaListViewItemDeleted, HandleMediaListViewItemDeleted, self);
libvlc_event_detach(p_em, libvlc_MediaListViewItemAdded, HandleMediaListViewItemAdded, self);
}
[super release];
}
}
- (NSString *)description
{
NSMutableString * content = [NSMutableString string];
NSUInteger 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:(NSInteger)index
{
libvlc_exception_t p_e;
libvlc_exception_init( &p_e );
libvlc_media_t * p_md = libvlc_media_list_view_item_at_index( p_mlv, index, &p_e );
catch_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];
}
- (VLCMediaListAspect *)childrenAtIndex:(NSInteger)index
{
libvlc_exception_t p_e;
libvlc_exception_init( &p_e );
libvlc_media_list_view_t * p_sub_mlv = libvlc_media_list_view_children_at_index( p_mlv, index, &p_e );
catch_exception( &p_e );
if( !p_sub_mlv )
return nil;
// 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 [VLCMediaListAspect mediaListAspectWithLibVLCMediaListView:p_sub_mlv];
}
- (VLCMediaListAspectNode *)nodeAtIndex:(NSInteger)index
{
VLCMediaListAspectNode * node = [[[VLCMediaListAspectNode alloc] init] autorelease];
[node setMedia:[self mediaAtIndex: index]];
libvlc_media_list_view_t * p_sub_mlv = libvlc_media_list_view_children_for_item([self libVLCMediaListView], [node.media libVLCMediaDescriptor], NULL);
if( p_sub_mlv )
{
[node setChildren:[VLCMediaListAspect mediaListAspectWithLibVLCMediaListView: p_sub_mlv]];
libvlc_media_list_view_release(p_sub_mlv);
}
return node;
}
- (NSInteger)count
{
libvlc_exception_t p_e;
libvlc_exception_init( &p_e );
NSInteger result = libvlc_media_list_view_count( p_mlv, &p_e );
catch_exception( &p_e );
return result;
}
- (VLCMediaList *)parentMediaList
{
return parentMediaList;
}
@end
@implementation VLCMediaListAspect (LibVLCBridging)
+ (id)mediaListAspectWithLibVLCMediaListView:(libvlc_media_list_view_t *)p_new_mlv
{
return [[[VLCMediaListAspect alloc] initWithLibVLCMediaListView:p_new_mlv andMediaList:nil] autorelease];
}
+ (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);
/* 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;
}
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 );
NSUInteger i, count = libvlc_media_list_view_count(p_mlv, NULL);
for( i = 0; i < count; i++ )
{
libvlc_media_t * p_md = libvlc_media_list_view_item_at_index(p_mlv, i, NULL);
libvlc_media_list_view_t * p_sub_mlv = libvlc_media_list_view_children_at_index(p_mlv, i, NULL);
VLCMediaListAspectNode * node = [[[VLCMediaListAspectNode alloc] init] autorelease];
[node setMedia:[VLCMedia mediaWithLibVLCMediaDescriptor: p_md]];
[node setChildren: p_sub_mlv ? [VLCMediaListAspect mediaListAspectWithLibVLCMediaListView: p_sub_mlv] : nil];
if( p_sub_mlv ) NSAssert(![node isLeaf], @"Not leaf");
[cachedNode addObject:node];
libvlc_media_release(p_md);
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 );
}
return self;
}
- (libvlc_media_list_view_t *)libVLCMediaListView
{
return (libvlc_media_list_view_t *)p_mlv;
}
@end
@implementation VLCMediaListAspect (Private)
- (void)initInternalMediaListView
{
libvlc_event_manager_t * p_em = libvlc_media_list_event_manager(p_mlv);
/* Add internal callback */
libvlc_event_attach(p_em, libvlc_MediaListViewItemAdded, HandleMediaListViewItemAdded, self);
libvlc_event_attach(p_em, libvlc_MediaListViewItemDeleted, HandleMediaListViewItemDeleted, self);
}
- (void)mediaListViewItemAdded:(NSArray *)arrayOfArgs
{
NSAssert([NSThread isMainThread], @"We are not on main thread");