MacOSX/Framework/VLCEventManager: Code clean up/documentation. Standardized the...
authorFaustino Osuna <riquedafreak@videolan.org>
Sat, 5 Jan 2008 01:11:47 +0000 (01:11 +0000)
committerFaustino Osuna <riquedafreak@videolan.org>
Sat, 5 Jan 2008 01:11:47 +0000 (01:11 +0000)
extras/MacOSX/Framework/Sources/VLCEventManager.m

index 0c2f6ce..1526c49 100644 (file)
 #import "VLCEventManager.h"
 #import <pthread.h>
 
-static VLCEventManager * defaultManager = NULL;
-
-enum message_type_t
+/**
+ * Defines the type of interthread message on the queue.
+ */
+typedef enum
 {
-    VLCNotification,
-    VLCObjectMethodWithObjectArg,
-    VLCObjectMethodWithArrayArg
-};
-
-struct message {
-    id target;
-    SEL sel;
-    union u
+    VLCNotification,                //< Standard NSNotification.
+    VLCObjectMethodWithObjectArg,   //< Method with an object argument.
+    VLCObjectMethodWithArrayArg     //< Method with an array argument.
+} message_type_t;
+
+/**
+ * Data structured used to enqueue messages onto the queue.
+ */
+typedef struct {
+    id target;                      //< Target object that should receive the message (retained until method is called).
+    SEL sel;                        //< A selector that identifies the message to be sent to the target.
+    union u                         //< Object could either be a VLCNotification or other.
     {
-        NSString * name;
-        id object;
+        NSString * name;            //< Name to be used for NSNotification
+        id object;                  //< Object argument to pass to the target via the selector.
     } u;
-    enum message_type_t type;
-};
+    message_type_t type;            //< Type of queued message.
+} message_t;
 
 @interface VLCEventManager (Private)
 - (void)callDelegateOfObjectAndSendNotificationWithArgs:(NSData*)data;
 - (void)callObjectMethodWithArgs:(NSData*)data;
-- (void)callDelegateOfObject:(id) aTarget withDelegateMethod:(SEL)aSelector withNotificationName: (NSString *)aNotificationName;
+- (void)callDelegateOfObject:(id) aTarget withDelegateMethod:(SEL)aSelector withNotificationName:(NSString *)aNotificationName;
 - (pthread_cond_t *)signalData;
 - (pthread_mutex_t *)queueLock;
 - (NSMutableArray *)messageQueue;
 @end
 
+/**
+ * Provides a function for the main entry point for the dispatch thread.  It dispatches any messages that is queued.
+ * \param user_data Pointer to the VLCEventManager instance that instiated this thread.
+ */
 static void * EventDispatcherMainLoop(void * user_data)
 {
     VLCEventManager * self = user_data;
@@ -62,7 +70,7 @@ static void * EventDispatcherMainLoop(void * user_data)
     for(;;)
     {
         NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-        struct message * message, * message_newer = NULL;
+        message_t * message, * message_newer = NULL;
         NSData * dataMessage;
         int i;
 
@@ -81,14 +89,17 @@ static void * EventDispatcherMainLoop(void * user_data)
         //if( [[self messageQueue] count] % 100 == 0 || [[self messageQueue] count] < 100 )
           //  NSLog(@"[EVENT_MANAGER] On the stack we have %d elements", [[self messageQueue] count]);
 
-        message = (struct message *)[(NSData *)[[self messageQueue] lastObject] bytes];
+        /* Get the first object off the queue. */
+        dataMessage = [[[self messageQueue] lastObject] retain];    // Released in 'call'
+        [[self messageQueue] removeLastObject];
+        message = (message_t *)[dataMessage bytes];
         
-        /* Don't send the same notification twice */
+        /* Remove duplicate notifications. */
         if( message->type == VLCNotification )
         {
-            for( i = 0; i < [[self messageQueue] count]-1; i++ )
+            for( i = [[self messageQueue] count]-1; i >= 0; i-- )
             {
-                message_newer = (struct message *)[(NSData *)[[self messageQueue] objectAtIndex:i] bytes];
+                message_newer = (message_t *)[(NSData *)[[self messageQueue] objectAtIndex:i] bytes];
                 if( message_newer->type == VLCNotification &&
                     message_newer->target == message->target &&
                    [message_newer->u.name isEqualToString:message->u.name] )
@@ -96,56 +107,53 @@ static void * EventDispatcherMainLoop(void * user_data)
                     [message_newer->target release];
                     [message_newer->u.name release];
                     [[self messageQueue] removeObjectAtIndex:i];
-                    i--;
-                    continue;
                 }
             }
         }
         else if( message->type == VLCObjectMethodWithArrayArg )
         {
             NSMutableArray * newArg = nil;
+
             /* Collapse messages that takes array arg by sending one bigger array */
-            for( i = [[self messageQueue] count]-2; i >= 0; i-- )
+            for( i = [[self messageQueue] count]-1; i >= 0; i-- )
             {
-                message_newer = (struct message *)[(NSData *)[[self messageQueue] objectAtIndex: i] bytes];
+                message_newer = (message_t *)[(NSData *)[[self messageQueue] objectAtIndex: i] bytes];
                 if( message_newer->type == VLCObjectMethodWithArrayArg &&
                     message_newer->target == message->target && 
                     message_newer->sel == message->sel )
                 {
                     if(!newArg)
+                    {
                         newArg = [NSMutableArray arrayWithArray:message->u.object];
+                        [message->u.object release];
+                    }
+                    
                     [newArg addObjectsFromArray:message_newer->u.object];
                     [message_newer->target release];
                     [message_newer->u.object release];
-                    [[self messageQueue] removeObjectAtIndex: i];
-                    continue;
+                    [[self messageQueue] removeObjectAtIndex:i];
                 }
                 /* It should be a good idea not to collapse event, with other kind of event in-between
                  * Ignore for now only if target is the same */
-                else if( message_newer->target == message->target )
+                else if( message_newer->target != message->target )
                     break;
             }
+            
             if( newArg )
-            {
-                [message->u.object release];
                 message->u.object = [newArg retain];
-                [newArg retain];
-            }
         }
-
-        dataMessage = [[self messageQueue] lastObject];
         
         pthread_mutex_unlock( [self queueLock] );
 
         if( message->type == VLCNotification )
-            [self performSelectorOnMainThread:@selector(callDelegateOfObjectAndSendNotificationWithArgs:) withObject:[dataMessage retain]  /* released in the call */ waitUntilDone: NO];
+            [self performSelectorOnMainThread:@selector(callDelegateOfObjectAndSendNotificationWithArgs:) 
+                                   withObject:dataMessage
+                                waitUntilDone: NO];
         else
-            [self performSelectorOnMainThread:@selector(callObjectMethodWithArgs:) withObject:[dataMessage retain]  /* released in the call */ waitUntilDone: YES];
+            [self performSelectorOnMainThread:@selector(callObjectMethodWithArgs:) 
+                                   withObject:dataMessage
+                                waitUntilDone: YES];
 
-        pthread_mutex_lock( [self queueLock] );
-        [[self messageQueue] removeLastObject];
-        pthread_mutex_unlock( [self queueLock] );
-    
         [pool release];
     }
     return nil;
@@ -154,6 +162,8 @@ static void * EventDispatcherMainLoop(void * user_data)
 @implementation VLCEventManager
 + (id)sharedManager
 {
+    static VLCEventManager * defaultManager = NULL;
+    
     /* We do want a lock here to avoid leaks */
     if ( !defaultManager )
     {
@@ -197,9 +207,9 @@ static void * EventDispatcherMainLoop(void * user_data)
 
 - (void)callOnMainThreadDelegateOfObject:(id)aTarget withDelegateMethod:(SEL)aSelector withNotificationName: (NSString *)aNotificationName
 {
-    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+//    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
     
-    struct message message = 
+    message_t message = 
     { 
         [aTarget retain], 
         aSelector, 
@@ -207,16 +217,17 @@ static void * EventDispatcherMainLoop(void * user_data)
         VLCNotification 
     };
 
-    if([NSThread isMainThread])
-    {
-        [self callDelegateOfObjectAndSendNotificationWithArgs:[[NSData dataWithBytes:&message length:sizeof(struct message)] retain] /* released in the call */];
-        return;
-    }
-
-   // pthread_mutex_lock( [self queueLock] );
-   // [[self messageQueue] insertObject:[NSData dataWithBytes:&message length:sizeof(struct message)] atIndex:0];
-   // pthread_cond_signal( [self signalData] );
-   // pthread_mutex_unlock( [self queueLock] );
+//    if( [NSThread isMainThread] )
+//    {
+        [self callDelegateOfObjectAndSendNotificationWithArgs:[[NSData dataWithBytes:&message length:sizeof(message_t)] retain] /* released in the call */];
+//    } 
+//    else 
+//    {
+//        pthread_mutex_lock( [self queueLock] );
+//        [[self messageQueue] insertObject:[NSData dataWithBytes:&message length:sizeof(message_t)] atIndex:0];
+//        pthread_cond_signal( [self signalData] );
+//        pthread_mutex_unlock( [self queueLock] );
+//    }
     
     [pool release];
 }
@@ -224,7 +235,7 @@ static void * EventDispatcherMainLoop(void * user_data)
 - (void)callOnMainThreadObject:(id)aTarget withMethod:(SEL)aSelector withArgumentAsObject: (id)arg
 {
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-    struct message message = 
+    message_t message = 
     { 
         [aTarget retain], 
         aSelector, 
@@ -233,7 +244,7 @@ static void * EventDispatcherMainLoop(void * user_data)
     };
 
     pthread_mutex_lock( [self queueLock] );
-    [[self messageQueue] insertObject:[NSData dataWithBytes:&message length:sizeof(struct message)] atIndex:0];
+    [[self messageQueue] insertObject:[NSData dataWithBytes:&message length:sizeof(message_t)] atIndex:0];
     pthread_cond_signal( [self signalData] );
     pthread_mutex_unlock( [self queueLock] );
     
@@ -244,7 +255,7 @@ static void * EventDispatcherMainLoop(void * user_data)
 @implementation VLCEventManager (Private)
 - (void)callDelegateOfObjectAndSendNotificationWithArgs:(NSData*)data
 {
-    struct message * message = (struct message *)[data bytes];
+    message_t * message = (message_t *)[data bytes];
 
     [self callDelegateOfObject:message->target withDelegateMethod:message->sel withNotificationName:message->u.name];
     [message->u.name release];
@@ -254,7 +265,7 @@ static void * EventDispatcherMainLoop(void * user_data)
 
 - (void)callObjectMethodWithArgs:(NSData*)data
 {
-    struct message * message = (struct message *)[data bytes];
+    message_t * message = (message_t *)[data bytes];
     void (*method)(id, SEL, id) = (void (*)(id, SEL, id))[message->target methodForSelector: message->sel];
 
     method( message->target, message->sel, message->u.object);
@@ -263,6 +274,17 @@ static void * EventDispatcherMainLoop(void * user_data)
     [data release];
 }
 
+- (void)callDelegateOfObject:(id) aTarget withDelegateMethod:(SEL)aSelector withNotificationName: (NSString *)aNotificationName
+{
+    //    [[NSNotificationCenter defaultCenter] postNotification: [NSNotification notificationWithName:aNotificationName object:aTarget]];
+    
+    if (![aTarget delegate] || ![[aTarget delegate] respondsToSelector:aSelector])
+        return;
+    
+    void (*method)(id, SEL, id) = (void (*)(id, SEL, id))[[aTarget delegate] methodForSelector: aSelector];
+    method( [aTarget delegate], aSelector, [NSNotification notificationWithName:aNotificationName object:aTarget]);
+}
+
 - (NSMutableArray *)messageQueue
 {
     return messageQueue;
@@ -277,15 +299,4 @@ static void * EventDispatcherMainLoop(void * user_data)
 {
     return &queueLock;
 }
-
-- (void)callDelegateOfObject:(id) aTarget withDelegateMethod:(SEL)aSelector withNotificationName: (NSString *)aNotificationName
-{
-//    [[NSNotificationCenter defaultCenter] postNotification: [NSNotification notificationWithName:aNotificationName object:aTarget]];
-
-    if (![aTarget delegate] || ![[aTarget delegate] respondsToSelector: aSelector])
-        return;
-
-    void (*method)(id, SEL, id) = (void (*)(id, SEL, id))[[aTarget delegate] methodForSelector: aSelector];
-    method( [aTarget delegate], aSelector, [NSNotification notificationWithName:aNotificationName object:aTarget]);
-}
 @end