]> granicus.if.org Git - handbrake/commitdiff
MacGui: clean up HBCore, add a way to register a block as error handler.
authorritsuka <damiog@gmail.com>
Fri, 23 Jan 2015 10:17:36 +0000 (10:17 +0000)
committerritsuka <damiog@gmail.com>
Fri, 23 Jan 2015 10:17:36 +0000 (10:17 +0000)
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@6799 b64f7644-9d1e-0410-96f1-a4d463321fa5

macosx/HBAppDelegate.m
macosx/HBController.m
macosx/HBCore.h
macosx/HBCore.m
macosx/HBPreviewGenerator.m
macosx/HBQueueController.m

index 77adfd8579c17b1bd6eb0e1ad397ba9ae8a89767..b87a77b0705437943c6d9b586ec8a1b46edb3b5a 100644 (file)
 #import "HBCore.h"
 #import "HBController.h"
 
-static void hb_error_handler(const char *errmsg)
-{
-    NSString *error = @(errmsg);
-
-    if (error && [[NSUserDefaults standardUserDefaults] boolForKey:@"HBDebugAlert"])
-    {
-        dispatch_async(dispatch_get_main_queue(), ^{
-            NSAlert *alert = [[NSAlert alloc] init];
-            [alert setMessageText:NSLocalizedString(@"Internal Error.", @"")];
-            [alert runModal];
-            [alert release];
-        });
-    }
-
-    fprintf(stderr, "error: %s\n", errmsg);
-}
-
 @interface HBAppDelegate ()
 
 @property (nonatomic, retain) HBPresetsManager *presetsManager;
@@ -54,15 +37,15 @@ static void hb_error_handler(const char *errmsg)
     self = [super init];
     if (self)
     {
-        hb_global_init();
-        hb_register_error_handler(&hb_error_handler);
+        // Register the default preferences
+        [HBPreferencesController registerUserDefaults];
 
-        // Optionally use dvd nav
+        [HBCore initGlobal];
+        [HBCore registerErrorHandler:^(NSString *error) {
+            fprintf(stderr, "error: %s\n", error.UTF8String);
+        }];
         [HBCore setDVDNav:[[[NSUserDefaults standardUserDefaults] objectForKey:@"UseDvdNav"] boolValue]];
 
-        // Register the defaults preferences
-        [HBPreferencesController registerUserDefaults];
-
         _outputPanel = [[HBOutputPanelController alloc] init];
 
         // Lets report the HandBrake version number here to the activity log and text log file
index f083b2d6a6b834fa4b1761e2365b1631a79c50fd..68620c4dc950cdca2fa8842cd4cc6e40b392d065 100644 (file)
             fScanIndicator.doubleValue = 100.0 * p.progress;
         #undef p
         }
-    completationHandler:^(BOOL success)
+    completionHandler:^(BOOL success)
         {
             fScanHorizontalLine.hidden = NO;
             fScanIndicator.hidden = YES;
index 8a417af9a9d494a366d270cd3bf379cb985b80a2..6eee94065788680347104f4227edea8f8c693ca3 100644 (file)
@@ -4,8 +4,7 @@
  Homepage: <http://handbrake.fr/>.
  It may be used under the terms of the GNU General Public License. */
 
-#import <Cocoa/Cocoa.h>
-
+#import <Foundation/Foundation.h>
 #include "hb.h"
 
 @class HBJob;
@@ -23,7 +22,7 @@ typedef NS_ENUM(NSUInteger, HBState) {
 };
 
 typedef void (^HBCoreProgressHandler)(HBState state, hb_state_t hb_state);
-typedef void (^HBCoreCompletationHandler)(BOOL success);
+typedef void (^HBCoreCompletionHandler)(BOOL success);
 
 /**
  * HBCore is an Objective-C interface to the low-level HandBrake library.
@@ -40,18 +39,28 @@ typedef void (^HBCoreCompletationHandler)(BOOL success);
  */
 + (void)setDVDNav:(BOOL)enabled;
 
+/**
+ *  Inits libhb globals.
+ */
++ (void)initGlobal;
+
 /**
  *  Performs the final cleanup for the process.
  */
 + (void)closeGlobal;
 
+/**
+ *  Registers a global error handler block.
+ *
+ *  @param handler a block called with the error message.
+ */
++ (void)registerErrorHandler:(void (^)(NSString *error))handler;
+
 /**
  * Opens low level HandBrake library. This should be called once before other
  * functions HBCore are used.
  *
  * @param loggingLevel         the desired libhb logging level.
- *
- * @return YES if libhb was opened, NO if there was an error.
  */
 - (instancetype)initWithLoggingLevel:(int)loggingLevel;
 
@@ -83,17 +92,14 @@ typedef void (^HBCoreCompletationHandler)(BOOL success);
 /**
  *  Starts the asynchronous execution of a scan.
  *
- *  @param url              the URL of the input file.
- *  @param titleNum         the number of the desired title. Use 0 to scan every title.
- *  @param previewsNum      the number of previews image to generate.
- *  @param minTitleDuration the minimum duration of the wanted titles in seconds.
+ *  @param url                 the URL of the input file.
+ *  @param index            the index of the desired title. Use 0 to scan every title.
+ *  @param previewsNum         the number of previews image to generate.
+ *  @param seconds             the minimum duration of the wanted titles in seconds.
+ *  @param progressHandler     a block called periodically with the progress information.
+ *  @param completionHandler   a block called with the scan result.
  */
-- (void)scanURL:(NSURL *)url
-     titleIndex:(NSUInteger)titleNum
-       previews:(NSUInteger)previewsNum
-    minDuration:(NSUInteger)minTitleDuration
-progressHandler:(HBCoreProgressHandler)progressHandler
-completationHandler:(HBCoreCompletationHandler)completationHandler;
+- (void)scanURL:(NSURL *)url titleIndex:(NSUInteger)index previews:(NSUInteger)previewsNum minDuration:(NSUInteger)seconds progressHandler:(HBCoreProgressHandler)progressHandler completionHandler:(HBCoreCompletionHandler)completionHandler;
 
 /**
  *  Cancels the scan execution.
@@ -108,9 +114,11 @@ completationHandler:(HBCoreCompletationHandler)completationHandler;
 /**
  *  Starts an asynchronous encoding session with the passed job.
  *
- *  @param job the job to encode.
+ *  @param job                 the job to encode
+ *  @param progressHandler     a block called periodically with the progress information.
+ *  @param completionHandler   a block called with the scan result
  */
-- (void)encodeJob:(HBJob *)job progressHandler:(HBCoreProgressHandler)progressHandler completationHandler:(HBCoreCompletationHandler)completationHandler;
+- (void)encodeJob:(HBJob *)job progressHandler:(HBCoreProgressHandler)progressHandler completionHandler:(HBCoreCompletionHandler)completionHandler;
 
 /**
  * Stops encoding session and releases resources.
index 4b0f0f3c30ed0e5688f58d825040c4b315b35cb0..61afbcdc433a0384c1c7940f59c976b42e48beb0 100644 (file)
 
 #include <dlfcn.h>
 
+static BOOL globalInitialized = NO;
+
+static void (^errorHandler)(NSString *error) = NULL;
+static void hb_error_handler(const char *errmsg)
+{
+    NSString *error = @(errmsg);
+    if (error)
+    {
+        errorHandler(error);
+    }
+}
+
 /**
  * Private methods of HBCore.
  */
 /// Progress handler.
 @property (nonatomic, readwrite, copy) HBCoreProgressHandler progressHandler;
 
-/// Completation handler.
-@property (nonatomic, readwrite, copy) HBCoreCompletationHandler completationHandler;
+/// Completion handler.
+@property (nonatomic, readwrite, copy) HBCoreCompletionHandler completionHandler;
 
 /// User cancelled.
 @property (nonatomic, readwrite, getter=isCancelled) BOOL cancelled;
 
-- (void)stateUpdateTimer:(NSTimer *)timer;
-
 @end
 
 @implementation HBCore
     hb_dvd_set_dvdnav(enabled);
 }
 
++ (void)initGlobal
+{
+    hb_global_init();
+    globalInitialized = YES;
+}
+
 + (void)closeGlobal
 {
+    NSAssert(globalInitialized, @"[HBCore closeGlobal] global closed but not initialized");
+    [errorHandler release];
     hb_global_close();
 }
 
++ (void)registerErrorHandler:(void (^)(NSString *error))handler
+{
+    errorHandler = [handler copy];
+    hb_register_error_handler(&hb_error_handler);
+}
+
 /**
  * Initializes HBCore.
  */
     return YES;
 }
 
-- (void)scanURL:(NSURL *)url titleIndex:(NSUInteger)titleNum previews:(NSUInteger)previewsNum minDuration:(NSUInteger)minTitleDuration progressHandler:(HBCoreProgressHandler)progressHandler completationHandler:(HBCoreCompletationHandler)completationHandler
+- (void)scanURL:(NSURL *)url titleIndex:(NSUInteger)index previews:(NSUInteger)previewsNum minDuration:(NSUInteger)seconds progressHandler:(HBCoreProgressHandler)progressHandler completionHandler:(HBCoreCompletionHandler)completionHandler
 {
+    NSAssert(self.state == HBStateIdle, @"[HBCore scanURL:] called while another scan or encode already in progress");
+
+    // Reset the titles array
+    self.titles = nil;
+
     // Copy the progress/completation blocks
     self.progressHandler = progressHandler;
-    self.completationHandler = completationHandler;
+    self.completionHandler = completionHandler;
 
     // Start the timer to handle libhb state changes
     [self startUpdateTimerWithInterval:0.2];
     }
 
     // convert minTitleDuration from seconds to the internal HB time
-    uint64_t min_title_duration_ticks = 90000LL * minTitleDuration;
+    uint64_t min_title_duration_ticks = 90000LL * seconds;
 
     // If there is no title number passed to scan, we use 0
     // which causes the default behavior of a full source scan
-    if (titleNum > 0)
+    if (index > 0)
     {
-        [HBUtilities writeToActivityLog:"%s scanning specifically for title: %d", self.name.UTF8String, titleNum];
+        [HBUtilities writeToActivityLog:"%s scanning specifically for title: %d", self.name.UTF8String, index];
     }
     else
     {
         // minimum title duration doesn't apply to title-specific scan
         // it doesn't apply to batch scan either, but we can't tell it apart from DVD & BD folders here
-        [HBUtilities writeToActivityLog:"%s scanning titles with a duration of %d seconds or more", self.name.UTF8String, minTitleDuration];
+        [HBUtilities writeToActivityLog:"%s scanning titles with a duration of %d seconds or more", self.name.UTF8String, seconds];
     }
 
     hb_system_sleep_prevent(_hb_handle);
 
     hb_scan(_hb_handle, path.fileSystemRepresentation,
-            (int)titleNum, (int)previewsNum,
+            (int)index, (int)previewsNum,
             1, min_title_duration_ticks);
 
     // Set the state, so the UI can be update
  */
 - (BOOL)scanDone
 {
+    if (self.isCancelled)
+    {
+        self.cancelled = NO;
+        return NO;
+    }
+
     hb_title_set_t *title_set = hb_get_title_set(_hb_handle);
     NSMutableArray *titles = [NSMutableArray array];
 
 
 - (void)cancelScan
 {
+    self.cancelled = YES;
     hb_scan_stop(_hb_handle);
-
     [HBUtilities writeToActivityLog:"%s scan cancelled", self.name.UTF8String];
 }
 
 #pragma mark - Encodes
 
-- (void)encodeJob:(HBJob *)job progressHandler:(HBCoreProgressHandler)progressHandler completationHandler:(HBCoreCompletationHandler)completationHandler;
+- (void)encodeJob:(HBJob *)job progressHandler:(HBCoreProgressHandler)progressHandler completionHandler:(HBCoreCompletionHandler)completionHandler;
 {
+    NSAssert(self.state == HBStateIdle, @"[HBCore encodeJob:] called while another scan or encode already in progress");
+
     // Copy the progress/completation blocks
     self.progressHandler = progressHandler;
-    self.completationHandler = completationHandler;
+    self.completionHandler = completionHandler;
 
     // Start the timer to handle libhb state changes
     [self startUpdateTimerWithInterval:0.5];
     // Add the job to libhb
     hb_job_t *hb_job = job.hb_job;
     hb_job_set_file(hb_job, job.destURL.path.fileSystemRepresentation);
-    hb_add(self.hb_handle, hb_job);
+    hb_add(_hb_handle, hb_job);
 
     // Free the job
     hb_job_close(&hb_job);
 - (void)cancelEncode
 {
     self.cancelled = YES;
-
     hb_stop(_hb_handle);
-    hb_system_sleep_allow(_hb_handle);
-
-    [HBUtilities writeToActivityLog:"%s stop", self.name.UTF8String];
+    [HBUtilities writeToActivityLog:"%s encode cancelled", self.name.UTF8String];
 }
 
 
         case HB_STATE_SEARCHING:
             return @selector(handleProgress);
         case HB_STATE_SCANDONE:
-            return @selector(handleScanCompletation);
+            return @selector(handleScanCompletion);
         case HB_STATE_WORKDONE:
-            return @selector(handleWorkCompletation);
+            return @selector(handleWorkCompletion);
         default:
             NSAssert1(NO, @"[HBCore selectorForState:] unknown state %lu", stateValue);
             return NULL;
 /**
  * This method polls libhb continuously for state changes and processes them.
  * Additional processing for each state is performed in methods that start
- * with 'handle' (e.g. handleHBStateScanning).
+ * with 'handle'.
  */
 - (void)stateUpdateTimer:(NSTimer *)timer
 {
-    if (!_hb_handle)
-    {
-        // Libhb is not open so we cannot do anything.
-        return;
-    }
     hb_get_state(_hb_handle, _hb_state);
 
     if (_hb_state->state == HB_STATE_IDLE)
 #pragma mark - Notifications
 
 /**
- * Processes HBStateSearching state information. Current implementation just
- * sends HBCoreSearchingNotification.
+ * Processes progress state information.
  */
 - (void)handleProgress
 {
 }
 
 /**
- * Processes HBStateScanDone state information. Current implementation just
- * sends HBCoreScanDoneNotification.
+ *  Runs the completion block and clean ups the internal blocks.
+ *
+ *  @param result the result to pass to the completion block.
  */
-- (void)handleScanCompletation
+- (void)runCompletionBlockAndCleanUpWithResult:(BOOL)result
 {
-    BOOL success = [self scanDone];
-
-    if (self.completationHandler)
+    if (self.completionHandler)
     {
-        HBCoreCompletationHandler completationHandler = [self.completationHandler retain];
+        HBCoreCompletionHandler completionHandler = [self.completionHandler retain];
         self.progressHandler = nil;
-        self.completationHandler = nil;
-        completationHandler(success);
-        [completationHandler release];
+        self.completionHandler = nil;
+        completionHandler(result);
+        [completionHandler release];
     }
 }
 
 /**
- * Processes HBStateWorkDone state information. Current implementation just
- * sends HBCoreWorkDoneNotification.
+ * Processes scan completion.
  */
-- (void)handleWorkCompletation
+- (void)handleScanCompletion
 {
-    BOOL success = [self workDone];
+    BOOL result = [self scanDone];
+    [self runCompletionBlockAndCleanUpWithResult:result];
+}
 
-    if (self.completationHandler)
-    {
-        HBCoreCompletationHandler completationHandler = [self.completationHandler retain];
-        self.progressHandler = nil;
-        self.completationHandler = nil;
-        completationHandler(success);
-        [completationHandler release];
-    }
+/**
+ * Processes work completion.
+ */
+- (void)handleWorkCompletion
+{
+    BOOL result = [self workDone];
+    [self runCompletionBlockAndCleanUpWithResult:result];
 }
 
 @end
index f58e157cbb274be3d57587f99f15f0396a72af09..c4a0d2aa738abdb2480ed42bcd3fc2667cb89449 100644 (file)
                 break;
         }
     }
-    completationHandler:^(BOOL success) {
+    completionHandler:^(BOOL success) {
         // Encode done, call the delegate and close libhb handle
         if (success)
         {
index 130c03ac05bda73bed1c6c88008d7a2524f16673..2e4249fb8d40c2cdb5805fd6248187aa35bc74f7 100644 (file)
            self.progressTextField.stringValue = status;
            [self.controller setQueueInfo:status progress:0 hidden:NO];
        }
-   completationHandler:^(BOOL success) {
+   completionHandler:^(BOOL success) {
        if (success)
        {
            [self doEncodeQueueItem];
              self.progressTextField.stringValue = string;
              [self.controller setQueueInfo:string progress:progress * 100.0 hidden:NO];
          }
-     completationHandler:^(BOOL success) {
+     completionHandler:^(BOOL success) {
          NSString *info = NSLocalizedString(@"Encode Finished.", @"");
 
          self.progressTextField.stringValue = info;