From 4758bc861589fe1f99b8cf01bad0cf810cd492fd Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 30 Apr 2021 21:37:41 -0400 Subject: [PATCH] Attempts to support insertion of states into existing windows. --- .../Documents/MachineDocument.swift | 31 ++++++++++++++++--- .../Machine/StaticAnalyser/CSStaticAnalyser.h | 2 ++ .../StaticAnalyser/CSStaticAnalyser.mm | 4 +++ .../Clock Signal/ScanTarget/CSScanTarget.h | 2 ++ .../Clock Signal/ScanTarget/CSScanTarget.mm | 4 +++ .../Mac/Clock Signal/Views/CSScanTargetView.h | 6 ++++ .../Mac/Clock Signal/Views/CSScanTargetView.m | 4 +++ 7 files changed, 48 insertions(+), 5 deletions(-) diff --git a/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift b/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift index 855c5c23e..122bbe61a 100644 --- a/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift +++ b/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift @@ -137,6 +137,9 @@ class MachineDocument: func configureAs(_ analysis: CSStaticAnalyser) { self.machineDescription = analysis + actionLock.lock() + drawLock.lock() + let missingROMs = NSMutableArray() if let machine = CSMachine(analyser: analysis, missingROMs: missingROMs) { self.machine = machine @@ -147,9 +150,11 @@ class MachineDocument: // Store the selected machine and list of missing ROMs, and // show the missing ROMs dialogue. self.missingROMs = missingROMs.map({$0 as! CSMissingROM}) - requestRoms() } + + actionLock.unlock() + drawLock.unlock() } enum InteractionMode { @@ -280,8 +285,7 @@ class MachineDocument: /// Delegate message to receive drag and drop files. final func scanTargetView(_ view: CSScanTargetView, didReceiveFileAt URL: URL) { - let mediaSet = CSMediaSet(fileAt: URL) - mediaSet.apply(to: self.machine) + insertFile(URL) } /// Action for the insert menu command; displays an NSOpenPanel and then segues into the same process @@ -292,13 +296,30 @@ class MachineDocument: openPanel.beginSheetModal(for: self.windowControllers[0].window!) { (response) in if response == .OK { for url in openPanel.urls { - let mediaSet = CSMediaSet(fileAt: url) - mediaSet.apply(to: self.machine) + self.insertFile(url) } } } } + private func insertFile(_ URL: URL) { + // Try to insert media. + let mediaSet = CSMediaSet(fileAt: URL) + if !mediaSet.empty { + mediaSet.apply(to: self.machine) + return + } + + // Failing that see whether a new machine is required. + // TODO. + if let newMachine = CSStaticAnalyser(fileAt: URL) { + machine?.stop() + self.interactionMode = .notStarted + self.scanTargetView.willChangeScanTargetOwner() + configureAs(newMachine) + } + } + // MARK: - Input Management. /// Upon a resign key, immediately releases all ongoing input mechanisms — any currently pressed keys, diff --git a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.h b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.h index 62df779b9..e82adb720 100644 --- a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.h +++ b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.h @@ -114,6 +114,8 @@ typedef int Kilobytes; - (instancetype)initWithFileAtURL:(NSURL *)url; - (void)applyToMachine:(CSMachine *)machine; +@property(nonatomic, readonly) BOOL empty; + @end NS_ASSUME_NONNULL_END diff --git a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm index 8f4c693b4..acc8dd852 100644 --- a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm +++ b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm @@ -309,4 +309,8 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K [machine applyMedia:_media]; } +- (BOOL)empty { + return _media.empty(); +} + @end diff --git a/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.h b/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.h index 993e1fd04..2e0998c4c 100644 --- a/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.h +++ b/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.h @@ -22,4 +22,6 @@ - (nonnull NSBitmapImageRep *)imageRepresentation; +- (void)willChangeOwner; + @end diff --git a/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm b/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm index 75d5c66fd..2c304da1d 100644 --- a/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm +++ b/OSBindings/Mac/Clock Signal/ScanTarget/CSScanTarget.mm @@ -1143,6 +1143,10 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget; return &_scanTarget; } +- (void)willChangeOwner { + _scanTarget.ScanTarget::will_change_owner(); +} + - (NSBitmapImageRep *)imageRepresentation { // Create an NSBitmapRep as somewhere to copy pixel data to. NSBitmapImageRep *const result = diff --git a/OSBindings/Mac/Clock Signal/Views/CSScanTargetView.h b/OSBindings/Mac/Clock Signal/Views/CSScanTargetView.h index 58917f785..330e24b99 100644 --- a/OSBindings/Mac/Clock Signal/Views/CSScanTargetView.h +++ b/OSBindings/Mac/Clock Signal/Views/CSScanTargetView.h @@ -162,4 +162,10 @@ */ @property(nonatomic, readonly, nonnull) CSScanTarget *scanTarget; +/*! + Indicates that the enclosed scan target is about to be handed off to a new owner; + exactly identical to calling scanTarget.will_change_owner(). +*/ +- (void)willChangeScanTargetOwner; + @end diff --git a/OSBindings/Mac/Clock Signal/Views/CSScanTargetView.m b/OSBindings/Mac/Clock Signal/Views/CSScanTargetView.m index 65ed41fb1..1fe1ebbb6 100644 --- a/OSBindings/Mac/Clock Signal/Views/CSScanTargetView.m +++ b/OSBindings/Mac/Clock Signal/Views/CSScanTargetView.m @@ -129,6 +129,10 @@ static CVReturn DisplayLinkCallback(__unused CVDisplayLinkRef displayLink, const return _scanTarget; } +- (void)willChangeScanTargetOwner { + [_scanTarget willChangeOwner]; +} + - (void)updateBacking { [_scanTarget updateFrameBuffer]; }