first pass at the ROM downloader.

This commit is contained in:
Kelvin Sherlock 2020-09-03 00:15:50 -04:00
parent e73ff01c00
commit 152197cae7
6 changed files with 255 additions and 0 deletions

View File

@ -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 = "<group>"; };
B63C1B8D25004C6D00511A71 /* mame-data.tgz */ = {isa = PBXFileReference; lastKnownFileType = file; name = "mame-data.tgz"; path = "embedded/mame-data.tgz"; sourceTree = "<group>"; };
B63C1B8F250088DC00511A71 /* roms.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = roms.plist; sourceTree = "<group>"; };
B63C1B9125008A2700511A71 /* DownloadWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DownloadWindowController.h; sourceTree = "<group>"; };
B63C1B9225008A2700511A71 /* DownloadWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DownloadWindowController.m; sourceTree = "<group>"; };
B63C1B9325008A2700511A71 /* DownloadWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = DownloadWindow.xib; path = Base.lproj/DownloadWindow.xib; sourceTree = "<group>"; };
B64979C024EF6703008ABD20 /* MediaViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MediaViewController.h; sourceTree = "<group>"; };
B64979C124EF6703008ABD20 /* MediaViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MediaViewController.m; sourceTree = "<group>"; };
B64E15A724EA1D5300E8AD3D /* MachineViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MachineViewController.h; sourceTree = "<group>"; };
@ -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;
};

View File

@ -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

View File

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="DownloadWindowController">
<connections>
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Downloads" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="480" height="157"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="480" height="157"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rg5-Qf-4Mw">
<rect key="frame" x="404" y="19" width="56" height="23"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<buttonCell key="cell" type="roundTextured" title="Cancel" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="i6Z-OM-lqE">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent">.</string>
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</buttonCell>
<connections>
<action selector="cancel:" target="-2" id="gJ0-aE-RVh"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MWc-ih-Sp1">
<rect key="frame" x="18" y="121" width="442" height="16"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Downloading" id="dZt-4d-PYZ">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="-2" name="displayPatternValue1" keyPath="self.currentROM" id="FsR-wQ-zks">
<dictionary key="options">
<string key="NSDisplayPattern">Downloading %{value1}@</string>
</dictionary>
</binding>
</connections>
</textField>
<progressIndicator wantsLayer="YES" fixedFrame="YES" maxValue="100" style="bar" translatesAutoresizingMaskIntoConstraints="NO" id="Odp-OZ-ggl">
<rect key="frame" x="20" y="94" width="438" height="20"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<connections>
<binding destination="-2" name="maxValue" keyPath="self.totalCount" id="hpx-zN-odo"/>
<binding destination="-2" name="value" keyPath="self.currentCount" previousBinding="hpx-zN-odo" id="dd9-45-gfI"/>
</connections>
</progressIndicator>
</subviews>
</view>
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections>
<point key="canvasLocation" x="135" y="85.5"/>
</window>
</objects>
</document>

View File

@ -31,6 +31,12 @@
<action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
</connections>
</menuItem>
<menuItem title="Download ROMs…" id="St3-qR-2Y8">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="downloadROMS:" target="Voe-Tx-rLC" id="jFm-nv-kRC"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW">
<connections>

View File

@ -0,0 +1,23 @@
//
// DownloadWindowController.h
// Ample
//
// Created by Kelvin Sherlock on 9/2/2020.
// Copyright © 2020 Kelvin Sherlock. All rights reserved.
//
#import <Cocoa/Cocoa.h>
NS_ASSUME_NONNULL_BEGIN
@interface DownloadWindowController : NSWindowController <NSURLSessionTaskDelegate, NSURLSessionDownloadDelegate>
@property NSString *currentROM;
@property NSInteger currentCount;
@property NSInteger totalCount;
@property NSInteger errorCount;
@property BOOL active;
@end
NS_ASSUME_NONNULL_END

View File

@ -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