From 152197cae707091f872e846caede27d1492a9899 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Thu, 3 Sep 2020 00:15:50 -0400 Subject: [PATCH] first pass at the ROM downloader. --- Ample.xcodeproj/project.pbxproj | 14 +++ Ample/AppDelegate.m | 10 +++ Ample/Base.lproj/DownloadWindow.xib | 70 +++++++++++++++ Ample/Base.lproj/MainMenu.xib | 6 ++ Ample/DownloadWindowController.h | 23 +++++ Ample/DownloadWindowController.m | 132 ++++++++++++++++++++++++++++ 6 files changed, 255 insertions(+) create mode 100644 Ample/Base.lproj/DownloadWindow.xib create mode 100644 Ample/DownloadWindowController.h create mode 100644 Ample/DownloadWindowController.m diff --git a/Ample.xcodeproj/project.pbxproj b/Ample.xcodeproj/project.pbxproj index 7df172c..b50e010 100644 --- a/Ample.xcodeproj/project.pbxproj +++ b/Ample.xcodeproj/project.pbxproj @@ -61,6 +61,10 @@ B63C1B8C24FF4BF700511A71 /* Ample.m in Sources */ = {isa = PBXBuildFile; fileRef = B63C1B8A24FF4BF700511A71 /* Ample.m */; }; B63C1B8E25004C6D00511A71 /* mame-data.tgz in Resources */ = {isa = PBXBuildFile; fileRef = B63C1B8D25004C6D00511A71 /* mame-data.tgz */; }; B63C1B90250088DD00511A71 /* roms.plist in Resources */ = {isa = PBXBuildFile; fileRef = B63C1B8F250088DC00511A71 /* roms.plist */; }; + B63C1B9425008A2700511A71 /* DownloadWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = B63C1B9225008A2700511A71 /* DownloadWindowController.m */; }; + B63C1B9525008A2700511A71 /* DownloadWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = B63C1B9225008A2700511A71 /* DownloadWindowController.m */; }; + B63C1B9625008A2700511A71 /* DownloadWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = B63C1B9325008A2700511A71 /* DownloadWindow.xib */; }; + B63C1B9725008A2700511A71 /* DownloadWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = B63C1B9325008A2700511A71 /* DownloadWindow.xib */; }; B64979C224EF6703008ABD20 /* MediaViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B64979C124EF6703008ABD20 /* MediaViewController.m */; }; B64E15A924EA1D5300E8AD3D /* MachineViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B64E15A824EA1D5300E8AD3D /* MachineViewController.m */; }; B65593B124ECB61800722E0C /* SlotViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B65593B024ECB61800722E0C /* SlotViewController.m */; }; @@ -233,6 +237,9 @@ B63C1B8A24FF4BF700511A71 /* Ample.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Ample.m; sourceTree = ""; }; B63C1B8D25004C6D00511A71 /* mame-data.tgz */ = {isa = PBXFileReference; lastKnownFileType = file; name = "mame-data.tgz"; path = "embedded/mame-data.tgz"; sourceTree = ""; }; B63C1B8F250088DC00511A71 /* roms.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = roms.plist; sourceTree = ""; }; + B63C1B9125008A2700511A71 /* DownloadWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DownloadWindowController.h; sourceTree = ""; }; + B63C1B9225008A2700511A71 /* DownloadWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DownloadWindowController.m; sourceTree = ""; }; + B63C1B9325008A2700511A71 /* DownloadWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = DownloadWindow.xib; path = Base.lproj/DownloadWindow.xib; sourceTree = ""; }; B64979C024EF6703008ABD20 /* MediaViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MediaViewController.h; sourceTree = ""; }; B64979C124EF6703008ABD20 /* MediaViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MediaViewController.m; sourceTree = ""; }; B64E15A724EA1D5300E8AD3D /* MachineViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MachineViewController.h; sourceTree = ""; }; @@ -383,6 +390,8 @@ B6BA257D24E99BE9005FB8FF /* Ample */ = { isa = PBXGroup; children = ( + B63C1B9125008A2700511A71 /* DownloadWindowController.h */, + B63C1B9225008A2700511A71 /* DownloadWindowController.m */, B6BA257E24E99BE9005FB8FF /* AppDelegate.h */, B6BA257F24E99BE9005FB8FF /* AppDelegate.m */, B63C1B8924FF4B7100511A71 /* Ample.h */, @@ -415,6 +424,7 @@ B6D6DE4224FAEE8900661A5F /* Nibs */ = { isa = PBXGroup; children = ( + B63C1B9325008A2700511A71 /* DownloadWindow.xib */, B66236BF24FDB7A6006CABD7 /* Credits.rtf */, B6D6DE3C24FADF8B00661A5F /* LaunchWindow.xib */, B6004DEF24FB05D600D38596 /* LogWindow.xib */, @@ -543,6 +553,7 @@ B6109A2B24F5F377005CB652 /* elppa.plist in Resources */, B63C1B8E25004C6D00511A71 /* mame-data.tgz in Resources */, B6109A3B24F5F377005CB652 /* apple2gsr1.plist in Resources */, + B63C1B9625008A2700511A71 /* DownloadWindow.xib in Resources */, B6D6DE3B24FACF4F00661A5F /* Defaults.plist in Resources */, B6109A2224F5F377005CB652 /* models.plist in Resources */, B6109A4024F5F377005CB652 /* craft2p.plist in Resources */, @@ -588,6 +599,7 @@ B6E4B5CE24FDE2670094A35C /* maxxi.plist in Resources */, B6E4B5CF24FDE2670094A35C /* apple2eefr.plist in Resources */, B6E4B5D124FDE2670094A35C /* spectred.plist in Resources */, + B63C1B9725008A2700511A71 /* DownloadWindow.xib in Resources */, B6E4B5D224FDE2670094A35C /* apple2cp.plist in Resources */, B6E4B5D324FDE2670094A35C /* MainMenu.xib in Resources */, B6E4B5D424FDE2670094A35C /* prav82.plist in Resources */, @@ -641,6 +653,7 @@ B6004DF024FB05D600D38596 /* LogWindowController.m in Sources */, B66236A924FD9A34006CABD7 /* PreferencesWindowController.m in Sources */, B65593B124ECB61800722E0C /* SlotViewController.m in Sources */, + B63C1B9425008A2700511A71 /* DownloadWindowController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -658,6 +671,7 @@ B6E4B5B624FDE2670094A35C /* LogWindowController.m in Sources */, B6E4B5B724FDE2670094A35C /* PreferencesWindowController.m in Sources */, B6E4B5B824FDE2670094A35C /* SlotViewController.m in Sources */, + B63C1B9525008A2700511A71 /* DownloadWindowController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Ample/AppDelegate.m b/Ample/AppDelegate.m index 265f239..b12e677 100644 --- a/Ample/AppDelegate.m +++ b/Ample/AppDelegate.m @@ -9,6 +9,7 @@ #import "AppDelegate.h" #import "LaunchWindowController.h" #import "PreferencesWindowController.h" +#import "DownloadWindowController.h" @interface AppDelegate () @property (weak) IBOutlet NSWindow *installWindow; @@ -18,6 +19,7 @@ @implementation AppDelegate { NSWindowController *_prefs; NSWindowController *_launcher; + NSWindowController *_downloader; } @@ -141,4 +143,12 @@ } +- (IBAction)downloadROMS:(id)sender { + + if (!_downloader) { + _downloader = [DownloadWindowController new]; + } + [_downloader showWindow: sender]; +} + @end diff --git a/Ample/Base.lproj/DownloadWindow.xib b/Ample/Base.lproj/DownloadWindow.xib new file mode 100644 index 0000000..997fa8e --- /dev/null +++ b/Ample/Base.lproj/DownloadWindow.xib @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Downloading %{value1}@ + + + + + + + + + + + + + + + + + + + + + diff --git a/Ample/Base.lproj/MainMenu.xib b/Ample/Base.lproj/MainMenu.xib index df0dea5..c84296c 100644 --- a/Ample/Base.lproj/MainMenu.xib +++ b/Ample/Base.lproj/MainMenu.xib @@ -31,6 +31,12 @@ + + + + + + diff --git a/Ample/DownloadWindowController.h b/Ample/DownloadWindowController.h new file mode 100644 index 0000000..2fd21d6 --- /dev/null +++ b/Ample/DownloadWindowController.h @@ -0,0 +1,23 @@ +// +// DownloadWindowController.h +// Ample +// +// Created by Kelvin Sherlock on 9/2/2020. +// Copyright © 2020 Kelvin Sherlock. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface DownloadWindowController : NSWindowController + +@property NSString *currentROM; +@property NSInteger currentCount; +@property NSInteger totalCount; +@property NSInteger errorCount; +@property BOOL active; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Ample/DownloadWindowController.m b/Ample/DownloadWindowController.m new file mode 100644 index 0000000..ba4fc34 --- /dev/null +++ b/Ample/DownloadWindowController.m @@ -0,0 +1,132 @@ +// +// DownloadWindowController.m +// Ample +// +// Created by Kelvin Sherlock on 9/2/2020. +// Copyright © 2020 Kelvin Sherlock. All rights reserved. +// + +#import "Ample.h" +#import "DownloadWindowController.h" + +@interface DownloadWindowController () + +@end + +@implementation DownloadWindowController { + + NSArray *_roms; + NSURL *_romFolder; + NSURL *_sourceURL; + NSURLSession *_session; + NSMutableSet *_tasks; +} + +-(NSString *)windowNibName { + return @"DownloadWindow"; +} + +- (void)windowDidLoad { + [super windowDidLoad]; + + // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. + + NSError *error = nil; + NSBundle *bundle = [NSBundle mainBundle]; + NSFileManager *fm = [NSFileManager defaultManager]; + + NSURL *url = [bundle URLForResource: @"roms" withExtension: @"plist"]; + + NSDictionary *d = [NSDictionary dictionaryWithContentsOfURL: url]; + + NSURL *sd = SupportDirectory(); + _romFolder = [sd URLByAppendingPathComponent: @"roms"]; + + [fm createDirectoryAtURL: _romFolder withIntermediateDirectories: YES attributes: nil error: &error]; + + + _roms = [d objectForKey: @"roms"]; + [self setCurrentROM: @""]; + [self setCurrentCount: 0]; + [self setTotalCount: [_roms count]]; + [self setErrorCount: 0]; + _sourceURL = [NSURL URLWithString: @"https://archive.org/download/mame0224_rom"]; // hardcoded.... + + + [self download]; +} + +-(void)download { + + NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; + _session = [NSURLSession sessionWithConfiguration: config delegate: self delegateQueue: nil]; + _tasks = [NSMutableSet setWithCapacity: [_roms count]]; + + // run in thread? + //unsigned count = 0; + for (NSString *s in _roms) { + + NSURLSessionDownloadTask *task; + NSString *path = [s stringByAppendingString: @".7z"]; // hardcoded. + NSURL *url = [_sourceURL URLByAppendingPathComponent: path]; + + task = [_session downloadTaskWithURL: url]; + [_tasks addObject: task]; + [task resume]; + + //++count; + //if (count >= 2) break; + } + [self setActive: YES]; + +} + +-(IBAction)cancel:(id)sender { + + for (NSURLSessionTask *task in _tasks) { + [task cancel]; + } + [_session invalidateAndCancel]; + _session = nil; + _tasks = nil; + [self setCurrentCount: 0]; + [self setActive: NO]; + +} + + +#pragma mark - NSURLSessionDelegate + +-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { + + + + dispatch_async(dispatch_get_main_queue(), ^(void){ + if (error) + [self setErrorCount: self->_errorCount + 1]; + else + [self setCurrentCount: self->_currentCount + 1]; + [self->_tasks removeObject: task]; + if (![self->_tasks anyObject]) { + [self setActive: NO]; + } + }); + +} + +- (void)URLSession:(NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(nonnull NSURL *)location { + + + // need to move to the destination directory... + // file deleted after this function returns, so can't move asynchronously. + NSFileManager *fm = [NSFileManager defaultManager]; + NSURL *src = [[downloadTask originalRequest] URL]; + NSURL *dest = [_romFolder URLByAppendingPathComponent: [src lastPathComponent]]; + NSError *error = nil; + + [fm moveItemAtURL: location toURL: dest error: &error]; + + NSLog(@"%@", src); +} +@end +