From 4b87fa68c3a252cf82267eaeb09520ce8b803e52 Mon Sep 17 00:00:00 2001 From: Akop Karapetyan Date: Fri, 6 Dec 2019 23:17:35 -0800 Subject: [PATCH] Completed Import Completed list state saving --- .../xcode/Emulator.xcodeproj/project.pbxproj | 14 ++- .../Controllers/FBLauncherController.h | 3 +- .../Controllers/FBLauncherController.m | 109 ++++++++++++++---- src/burner/macos/FBImporter.h | 28 +++++ src/burner/macos/FBImporter.m | 74 ++++++++++++ src/burner/macos/FBScanner.h | 2 +- src/burner/macos/FBScanner.mm | 4 +- 7 files changed, 205 insertions(+), 29 deletions(-) create mode 100644 src/burner/macos/FBImporter.h create mode 100644 src/burner/macos/FBImporter.m diff --git a/projectfiles/xcode/Emulator.xcodeproj/project.pbxproj b/projectfiles/xcode/Emulator.xcodeproj/project.pbxproj index dd1d0fe8c..5888a867f 100644 --- a/projectfiles/xcode/Emulator.xcodeproj/project.pbxproj +++ b/projectfiles/xcode/Emulator.xcodeproj/project.pbxproj @@ -12,6 +12,7 @@ FE0A7E9D2393A1FF001E6997 /* FBScanner.mm in Sources */ = {isa = PBXBuildFile; fileRef = FE0A7E9C2393A1FE001E6997 /* FBScanner.mm */; }; FE0A7EA12394B87B001E6997 /* FBRomSetStatusAsNSImage.m in Sources */ = {isa = PBXBuildFile; fileRef = FE0A7E9F2394B87B001E6997 /* FBRomSetStatusAsNSImage.m */; }; FE0A7EA42394ED91001E6997 /* FBDropFileScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = FE0A7EA32394ED91001E6997 /* FBDropFileScrollView.m */; }; + FE0A7EA7239501FF001E6997 /* FBImporter.m in Sources */ = {isa = PBXBuildFile; fileRef = FE0A7EA5239501FF001E6997 /* FBImporter.m */; }; FE1B1092235615940065200C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1B1091235615940065200C /* AppDelegate.m */; }; FE1B1094235615950065200C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FE1B1093235615950065200C /* Assets.xcassets */; }; FE1B1097235615950065200C /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = FE1B1095235615950065200C /* MainMenu.xib */; }; @@ -1050,6 +1051,8 @@ FE0A7EA02394B87B001E6997 /* FBRomSetStatusAsNSImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBRomSetStatusAsNSImage.h; sourceTree = ""; }; FE0A7EA22394ED90001E6997 /* FBDropFileScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBDropFileScrollView.h; sourceTree = ""; }; FE0A7EA32394ED91001E6997 /* FBDropFileScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBDropFileScrollView.m; sourceTree = ""; }; + FE0A7EA5239501FF001E6997 /* FBImporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBImporter.m; sourceTree = ""; }; + FE0A7EA6239501FF001E6997 /* FBImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBImporter.h; sourceTree = ""; }; FE1B108D235615940065200C /* FinalBurn Neo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "FinalBurn Neo.app"; sourceTree = BUILT_PRODUCTS_DIR; }; FE1B1090235615940065200C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; FE1B1091235615940065200C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -4645,6 +4648,8 @@ isa = PBXGroup; children = ( FE1B287F235626280065200C /* burner_macos.h */, + FE0A7EA6239501FF001E6997 /* FBImporter.h */, + FE0A7EA5239501FF001E6997 /* FBImporter.m */, FEED9E1A235845EE00B7AF83 /* FBMainThread.h */, FEED9E1B235845EE00B7AF83 /* FBMainThread.mm */, FE2BC6CF2362D5BD00B9D150 /* FBMainThread+Etc.mm */, @@ -5626,6 +5631,7 @@ FE1B25C923561A760065200C /* k051316.cpp in Sources */, FE1B25AC23561A760065200C /* k056832.cpp in Sources */, FE1B26B623561A770065200C /* d_mrdo.cpp in Sources */, + FE0A7EA7239501FF001E6997 /* FBImporter.m in Sources */, FE1B27DD23561A790065200C /* mathbox.cpp in Sources */, FE1B268E23561A770065200C /* d_bionicc.cpp in Sources */, FE1B24BF23561A750065200C /* smssystem.cpp in Sources */, @@ -6129,7 +6135,7 @@ CODE_SIGN_ENTITLEMENTS = Emulator/FinalBurnNeo.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(LOCAL_LIBRARY_DIR)/Frameworks", @@ -6142,7 +6148,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.13; - MARKETING_VERSION = 1.01; + MARKETING_VERSION = 1.02; OTHER_CFLAGS = ( "-DINLINE=\"static inline\"", "-DUSE_SPEEDHACKS", @@ -6189,7 +6195,7 @@ CODE_SIGN_ENTITLEMENTS = Emulator/FinalBurnNeo.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(LOCAL_LIBRARY_DIR)/Frameworks", @@ -6202,7 +6208,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.13; - MARKETING_VERSION = 1.01; + MARKETING_VERSION = 1.02; OTHER_CFLAGS = ( "-DINLINE=\"static inline\"", "-DUSE_SPEEDHACKS", diff --git a/projectfiles/xcode/Emulator/Controllers/FBLauncherController.h b/projectfiles/xcode/Emulator/Controllers/FBLauncherController.h index 288d17eb4..b7e007141 100644 --- a/projectfiles/xcode/Emulator/Controllers/FBLauncherController.h +++ b/projectfiles/xcode/Emulator/Controllers/FBLauncherController.h @@ -9,6 +9,7 @@ #import #import "FBScanner.h" +#import "FBImporter.h" #import "FBDropFileScrollView.h" @interface FBLauncherItem: NSObject @@ -20,7 +21,7 @@ @end -@interface FBLauncherController : NSWindowController +@interface FBLauncherController : NSWindowController { IBOutlet NSPanel *progressPanel; IBOutlet NSProgressIndicator *progressPanelBar; diff --git a/projectfiles/xcode/Emulator/Controllers/FBLauncherController.m b/projectfiles/xcode/Emulator/Controllers/FBLauncherController.m index 63c86c1a3..af15f49e5 100644 --- a/projectfiles/xcode/Emulator/Controllers/FBLauncherController.m +++ b/projectfiles/xcode/Emulator/Controllers/FBLauncherController.m @@ -33,11 +33,15 @@ - (NSString *) setCachePath; - (NSSet *) supportedRomSets; +- (void) importFiles:(NSArray *) files; +- (void) initiateScan; + @end @implementation FBLauncherController { FBScanner *scanner; + FBImporter *importer; } - (id) init @@ -54,8 +58,14 @@ if ([NSFileManager.defaultManager fileExistsAtPath:self.setCachePath]) { // Restore from cache NSArray *cached = [NSKeyedUnarchiver unarchiveObjectWithFile:self.setCachePath]; - if (cached) + if (cached) { [self reloadSets:cached]; + + // Restore previous selection + NSData *data = [NSUserDefaults.standardUserDefaults objectForKey:@"selectedGame"]; + romSetTreeController.selectionIndexPaths = [NSKeyedUnarchiver unarchiveTopLevelObjectWithData:data + error:nil]; + } } if (_romSets.count == 0) @@ -70,9 +80,10 @@ - (void) windowWillClose:(NSNotification *) notification { - @synchronized (self) { - [scanner cancel]; - } + [NSUserDefaults.standardUserDefaults setObject:[NSKeyedArchiver archivedDataWithRootObject:romSetTreeController.selectionIndexPaths] + forKey:@"selectedGame"]; + [importer cancel]; + [scanner cancel]; } #pragma mark - FBScannerDelegate @@ -87,16 +98,14 @@ completionHandler:^(NSModalResponse returnCode) { }]; } -- (void) progressDidUpdate:(float) progress +- (void) scanDidProgress:(float) progress { progressPanelBar.doubleValue = progress; } - (void) scanDidEnd:(NSArray *) romSets { - @synchronized (self) { - scanner = nil; - } + scanner = nil; [self.window endSheet:progressPanel]; @@ -110,6 +119,37 @@ [self reloadSets:romSets]; } +#pragma mark - FBImporterDelegate + +- (void) importDidStart +{ + progressPanelBar.doubleValue = 0; + progressPanelLabel.stringValue = NSLocalizedString(@"Importing...", nil); + progressPanelCancelButton.enabled = YES; + + [self.window beginSheet:progressPanel + completionHandler:^(NSModalResponse returnCode) { }]; +} + +- (void) importDidProgress:(float) progress +{ + progressPanelBar.doubleValue = progress; +} + +- (void) importDidEnd:(BOOL) isCancelled + filesCopied:(int) count +{ + importer = nil; + NSLog(@"Import complete; %d files copied", count); + + [self.window endSheet:progressPanel]; + + if (isCancelled || count < 1) + return; + + [self rescanSets:self]; +} + #pragma mark - FBDropFileScrollView - (BOOL) isDropAcceptable:(NSArray *) paths @@ -117,12 +157,16 @@ __block BOOL acceptable = YES; NSSet *supportedFormats = self.appDelegate.supportedFormats; NSSet *supportedArchives = self.supportedRomSets; + NSString *romPath = self.appDelegate.romPath; [paths enumerateObjectsUsingBlock:^(NSString *path, NSUInteger idx, BOOL *stop) { NSString *filename = path.lastPathComponent; + NSString *parent = path.stringByDeletingLastPathComponent.stringByResolvingSymlinksInPath; + // Check extension && archive name if (![supportedFormats containsObject:filename.pathExtension] - || ![supportedArchives containsObject:filename.stringByDeletingPathExtension]) { + || ![supportedArchives containsObject:filename.stringByDeletingPathExtension] + || [parent isEqualToString:romPath]) { acceptable = NO; *stop = YES; } @@ -133,21 +177,14 @@ - (void) dropDidComplete:(NSArray *) paths { - // FIXME + [self importFiles:paths]; } #pragma mark - Actions - (void) rescanSets:(id) sender { - @synchronized (self) { - if (!scanner) { - scanner = [FBScanner new]; - scanner.rootPath = AppDelegate.sharedInstance.romPath; - scanner.delegate = self; - [scanner start]; - } - } + [self initiateScan]; } - (void) cancelProgress:(id) sender @@ -155,9 +192,8 @@ progressPanelCancelButton.enabled = NO; progressPanelLabel.stringValue = NSLocalizedString(@"Cancelling...", nil); - @synchronized (self) { - [scanner cancel]; - } + [importer cancel]; + [scanner cancel]; } - (void) launchSet:(id) sender @@ -179,6 +215,9 @@ - (void) reloadSets:(NSArray *) romSets { + // Save current selection + NSArray *selection = romSetTreeController.selectionIndexPaths; + // Clear the master list [(NSMutableArray *) _romSets removeAllObjects]; @@ -211,6 +250,9 @@ }]; [romSetTreeController rearrangeObjects]; + + // Restore selection + romSetTreeController.selectionIndexPaths = selection; } - (NSString *) setCachePath @@ -231,4 +273,29 @@ return set; } +- (void) importFiles:(NSArray *) files +{ + if (scanner || importer) + return; + + importer = [FBImporter new]; + importer.destinationPath = AppDelegate.sharedInstance.romPath; + importer.sourcePaths = files; + importer.delegate = self; + + [importer start]; +} + +- (void) initiateScan +{ + if (scanner || importer) + return; + + scanner = [FBScanner new]; + scanner.rootPath = AppDelegate.sharedInstance.romPath; + scanner.delegate = self; + + [scanner start]; +} + @end diff --git a/src/burner/macos/FBImporter.h b/src/burner/macos/FBImporter.h new file mode 100644 index 000000000..d442f0c48 --- /dev/null +++ b/src/burner/macos/FBImporter.h @@ -0,0 +1,28 @@ +// +// FBImporter.h +// Emulator +// +// Created by Akop Karapetyan on 12/02/19. +// Copyright © 2019 Akop Karapetyan. All rights reserved. +// + +#import + +@protocol FBImporterDelegate + +@optional +- (void) importDidStart; +- (void) importDidProgress:(float) progress; +- (void) importDidEnd:(BOOL) isCancelled + filesCopied:(int) count; + +@end + +@interface FBImporter : NSThread + +@property NSArray *sourcePaths; +@property NSString *destinationPath; + +@property (nonatomic, weak) id delegate; + +@end diff --git a/src/burner/macos/FBImporter.m b/src/burner/macos/FBImporter.m new file mode 100644 index 000000000..3c96f24fe --- /dev/null +++ b/src/burner/macos/FBImporter.m @@ -0,0 +1,74 @@ +// +// FBImporter.m +// Emulator +// +// Created by Akop Karapetyan on 12/02/19. +// Copyright © 2019 Akop Karapetyan. All rights reserved. +// + +#import "FBImporter.h" + +#pragma mark - FBImporter + +@implementation FBImporter +{ +} + +- (instancetype) init +{ + if (self = [super init]) { + } + return self; +} + +#pragma mark - NSThread + +- (void) main +{ + NSArray *sourcePaths = [NSArray arrayWithArray:_sourcePaths]; + NSString *destinationPath = _destinationPath; + + if (!sourcePaths || sourcePaths.count == 0 || !destinationPath) + return; + + id del = _delegate; + if ([del respondsToSelector:@selector(importDidStart)]) + dispatch_async(dispatch_get_main_queue(), ^{ [del importDidStart]; }); + + __block int filesCopied = 0; + [sourcePaths enumerateObjectsUsingBlock:^(NSString *source, NSUInteger idx, BOOL *stop) { + NSString *sourceFilename = source.lastPathComponent; + NSURL *destinationUrl = [NSURL fileURLWithPath:[destinationPath stringByAppendingPathComponent:sourceFilename]]; + + // FIXME... + NSError *error = nil; + // Trash any existing file + [NSFileManager.defaultManager trashItemAtURL:destinationUrl + resultingItemURL:nil + error:&error]; + // Copy new file to destination + BOOL copyOK = [NSFileManager.defaultManager copyItemAtURL:[NSURL fileURLWithPath:source] + toURL:destinationUrl + error:&error]; + + if (self.isCancelled) + *stop = YES; + if (copyOK) + filesCopied++; + + id del = _delegate; + if ([del respondsToSelector:@selector(importDidProgress:)]) + dispatch_async(dispatch_get_main_queue(), ^{ + [del importDidProgress:(float) idx / sourcePaths.count]; + }); + }]; + + del = _delegate; + if ([del respondsToSelector:@selector(importDidEnd:filesCopied:)]) + dispatch_async(dispatch_get_main_queue(), ^{ + [del importDidEnd:self.isCancelled + filesCopied:filesCopied]; + }); +} + +@end diff --git a/src/burner/macos/FBScanner.h b/src/burner/macos/FBScanner.h index 4546a6c65..82d35ec36 100644 --- a/src/burner/macos/FBScanner.h +++ b/src/burner/macos/FBScanner.h @@ -24,7 +24,7 @@ @optional - (void) scanDidStart; -- (void) progressDidUpdate:(float) progress; +- (void) scanDidProgress:(float) progress; - (void) scanDidEnd:(NSArray *) romSets; @end diff --git a/src/burner/macos/FBScanner.mm b/src/burner/macos/FBScanner.mm index 2aa7278c3..681c0c941 100644 --- a/src/burner/macos/FBScanner.mm +++ b/src/burner/macos/FBScanner.mm @@ -88,9 +88,9 @@ continue; del = _delegate; - if ([del respondsToSelector:@selector(progressDidUpdate:)]) + if ([del respondsToSelector:@selector(scanDidProgress:)]) dispatch_async(dispatch_get_main_queue(), ^{ - [del progressDidUpdate:(float)i/nBurnDrvCount]; + [del scanDidProgress:(float)i/nBurnDrvCount]; }); nBurnDrvActive = i;