From 67c5f6b7cb1698377ab949f3a742361f42394aa1 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 21 Jul 2019 22:05:22 -0400 Subject: [PATCH] Ensures the missing ROM list bubbles up to Swift. --- .../Documents/MachineDocument.swift | 5 +- .../Mac/Clock Signal/Machine/CSMachine.h | 11 ++- .../Mac/Clock Signal/Machine/CSMachine.mm | 77 ++++++++++++++++++- 3 files changed, 89 insertions(+), 4 deletions(-) diff --git a/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift b/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift index c4b42aa0a..d9962a42f 100644 --- a/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift +++ b/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift @@ -153,11 +153,14 @@ class MachineDocument: // MARK: configuring func configureAs(_ analysis: CSStaticAnalyser) { - if let machine = CSMachine(analyser: analysis) { + let missingROMs = NSMutableArray() + if let machine = CSMachine(analyser: analysis, missingROMs: missingROMs) { self.machine = machine self.optionsPanelNibName = analysis.optionsPanelNibName setupMachineOutput() setupActivityDisplay() + } else { + Swift.print(missingROMs) } } diff --git a/OSBindings/Mac/Clock Signal/Machine/CSMachine.h b/OSBindings/Mac/Clock Signal/Machine/CSMachine.h index 5f1bd5da0..0a6e7496c 100644 --- a/OSBindings/Mac/Clock Signal/Machine/CSMachine.h +++ b/OSBindings/Mac/Clock Signal/Machine/CSMachine.h @@ -33,6 +33,13 @@ typedef NS_ENUM(NSInteger, CSMachineKeyboardInputMode) { CSMachineKeyboardInputModeJoystick }; +@interface CSMissingROM: NSObject +@property (nonatomic, readonly, nonnull) NSString *fileName; +@property (nonatomic, readonly, nullable) NSString *descriptiveName; +@property (nonatomic, readonly) NSUInteger size; +@property (nonatomic, readonly, nonnull) NSArray *crc32s; +@end + // Deliberately low; to ensure CSMachine has been declared as an @class already. #import "CSAtari2600.h" #import "CSZX8081.h" @@ -45,8 +52,10 @@ typedef NS_ENUM(NSInteger, CSMachineKeyboardInputMode) { Initialises an instance of CSMachine. @param result The CSStaticAnalyser result that describes the machine needed. + @param missingROMs An array that is filled with a list of ROMs that the machine requested but which + were not found; populated only if this `init` has failed. */ -- (nullable instancetype)initWithAnalyser:(nonnull CSStaticAnalyser *)result NS_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithAnalyser:(nonnull CSStaticAnalyser *)result missingROMs:(nullable inout NSMutableArray *)missingROMs NS_DESIGNATED_INITIALIZER; - (void)runForInterval:(NSTimeInterval)interval; diff --git a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm index 1aa0fab1f..59476a9c0 100644 --- a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm +++ b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm @@ -74,6 +74,58 @@ struct ActivityObserver: public Activity::Observer { __unsafe_unretained CSMachine *machine; }; +@interface CSMissingROM (Mutability) +@property (nonatomic, nonnull, copy) NSString *fileName; +@property (nonatomic, nullable, copy) NSString *descriptiveName; +@property (nonatomic, readwrite) NSUInteger size; +@property (nonatomic, copy) NSArray *crc32s; +@end + +@implementation CSMissingROM { + NSString *_fileName; + NSString *_descriptiveName; + NSUInteger _size; + NSArray *_crc32s; +} + +- (NSString *)fileName { + return _fileName; +} + +- (void)setFileName:(NSString *)fileName { + _fileName = [fileName copy]; +} + +- (NSString *)descriptiveName { + return _descriptiveName; +} + +- (void)setDescriptiveName:(NSString *)descriptiveName { + _descriptiveName = [descriptiveName copy]; +} + +- (NSUInteger)size { + return _size; +} + +- (void)setSize:(NSUInteger)size { + _size = size; +} + +- (NSArray *)crc32s { + return _crc32s; +} + +- (void)setCrc32s:(NSArray *)crc32s { + _crc32s = [crc32s copy]; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"%@/%@, %@ bytes, CRCs: %@", _fileName, _descriptiveName, @(_size), _crc32s]; +} + +@end + @implementation CSMachine { SpeakerDelegate _speakerDelegate; ActivityObserver _activityObserver; @@ -90,7 +142,7 @@ struct ActivityObserver: public Activity::Observer { std::unique_ptr _scanTarget; } -- (instancetype)initWithAnalyser:(CSStaticAnalyser *)result { +- (instancetype)initWithAnalyser:(CSStaticAnalyser *)result missingROMs:(inout NSMutableArray *)missingROMs { self = [super init]; if(self) { _analyser = result; @@ -98,7 +150,28 @@ struct ActivityObserver: public Activity::Observer { Machine::Error error; std::vector missing_roms; _machine.reset(Machine::MachineForTargets(_analyser.targets, CSROMFetcher(&missing_roms), error)); - if(!_machine) return nil; + if(!_machine) { + for(const auto &missing_rom : missing_roms) { + CSMissingROM *rom = [[CSMissingROM alloc] init]; + + // Copy/convert the primitive fields. + rom.fileName = [NSString stringWithUTF8String:missing_rom.file_name.c_str()]; + rom.descriptiveName = [NSString stringWithUTF8String:missing_rom.descriptive_name.c_str()]; + rom.size = missing_rom.size; + + // Convert the CRC list. + NSMutableArray *crc32s = [[NSMutableArray alloc] init]; + for(const auto &crc : missing_rom.crc32s) { + [crc32s addObject:@(crc)]; + } + rom.crc32s = [crc32s copy]; + + // Add to the missing list. + [missingROMs addObject:rom]; + } + + return nil; + } _inputMode = (_machine->keyboard_machine() && _machine->keyboard_machine()->get_keyboard().is_exclusive())