mirror of
https://github.com/TomHarte/CLK.git
synced 2026-03-11 04:42:20 +00:00
Copy and paste to a mostly working substitution.
This commit is contained in:
@@ -72,23 +72,17 @@ class MachineDocument:
|
||||
self.configureAs(analyser)
|
||||
self.fileObserver = CSFileContentChangeObserver.init(url: url, handler: {
|
||||
DispatchQueue.main.async {
|
||||
// self.actionLock.lock()
|
||||
// self.drawLock.lock()
|
||||
|
||||
switch(self.machine.effectForFile(atURLDidChange: url)) {
|
||||
case .reinsertMedia: self.insertFile(url)
|
||||
case .restartMachine:
|
||||
let target = CSStaticAnalyser(fileAt: url)
|
||||
if let target = target {
|
||||
// self.configureAs(target)
|
||||
self.machine.substitute(target)
|
||||
}
|
||||
|
||||
case .none: fallthrough
|
||||
@unknown default: break
|
||||
}
|
||||
|
||||
// self.actionLock.unlock()
|
||||
// self.drawLock.unlock()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
|
||||
@@ -79,6 +79,8 @@ typedef NS_ENUM(NSInteger, CSMachineChangeEffect) {
|
||||
- (void)setMouseButton:(int)button isPressed:(BOOL)isPressed;
|
||||
- (void)addMouseMotionX:(CGFloat)deltaX y:(CGFloat)deltaY;
|
||||
|
||||
- (void)substitute:(nonnull CSStaticAnalyser *)machine;
|
||||
|
||||
@property (nonatomic, strong, nullable) CSAudioQueue *audioQueue;
|
||||
@property (nonatomic, readonly, nonnull) CSScanTargetView *view;
|
||||
@property (nonatomic, weak, nullable) id<CSMachineDelegate> delegate;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <atomic>
|
||||
#include <bitset>
|
||||
#include <locale>
|
||||
#include <memory>
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -50,6 +51,8 @@ struct MachineUpdater {
|
||||
MachineTypes::TimedMachine *timed_machine = nullptr;
|
||||
};
|
||||
|
||||
using Updater = Concurrency::AsyncTaskQueue<true, false, MachineUpdater>;
|
||||
|
||||
}
|
||||
|
||||
@interface CSMachine() <CSScanTargetViewDisplayLinkDelegate>
|
||||
@@ -123,7 +126,7 @@ struct ActivityObserver: public Activity::Observer {
|
||||
CSJoystickManager *_joystickManager;
|
||||
NSMutableArray<CSMachineLED *> *_leds;
|
||||
|
||||
Concurrency::AsyncTaskQueue<true, false, MachineUpdater> updater;
|
||||
std::unique_ptr<Updater> updater;
|
||||
Time::ScanSynchroniser _scanSynchroniser;
|
||||
|
||||
NSTimer *_joystickTimer;
|
||||
@@ -161,9 +164,11 @@ struct ActivityObserver: public Activity::Observer {
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
updater.performer.machine = _machine.get();
|
||||
if(updater.performer.machine) {
|
||||
updater.start();
|
||||
|
||||
updater = std::make_unique<Updater>();
|
||||
updater->performer.machine = _machine.get();
|
||||
if(updater->performer.machine) {
|
||||
updater->start();
|
||||
}
|
||||
|
||||
// Use the keyboard as a joystick if the machine has no keyboard, or if it has a 'non-exclusive' keyboard.
|
||||
@@ -191,6 +196,32 @@ struct ActivityObserver: public Activity::Observer {
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)substitute:(nonnull CSStaticAnalyser *)machine {
|
||||
[self stop];
|
||||
|
||||
Machine::Error error;
|
||||
ROM::Request missing_roms;
|
||||
_machine = Machine::MachineForTargets(_analyser.targets, CSROMFetcher(&missing_roms), error);
|
||||
|
||||
_view.scanTarget.scanTarget->will_change_owner();
|
||||
_machine->scan_producer()->set_scan_target(_view.scanTarget.scanTarget);
|
||||
|
||||
updater = std::make_unique<Updater>();
|
||||
updater->performer.machine = _machine.get();
|
||||
if(updater->performer.machine) {
|
||||
updater->start();
|
||||
}
|
||||
|
||||
Activity::Source *const activity_source = _machine->activity_source();
|
||||
if(activity_source) {
|
||||
_activityObserver.machine = self;
|
||||
activity_source->set_activity_observer(&_activityObserver);
|
||||
}
|
||||
|
||||
_speakerDelegate.machine = self;
|
||||
[self.delegate machineSpeakerDidChangeInputClock:self];
|
||||
}
|
||||
|
||||
- (void)speaker:(Outputs::Speaker::Speaker *)speaker didCompleteSamples:(const int16_t *)samples length:(int)length {
|
||||
assert(NSUInteger(length) == self.audioQueue.bufferSize*(speaker->get_is_stereo() ? 2 : 1));
|
||||
[self.audioQueue enqueueAudioBuffer:samples];
|
||||
@@ -511,7 +542,7 @@ struct ActivityObserver: public Activity::Observer {
|
||||
}
|
||||
|
||||
- (void)applyInputEvent:(dispatch_block_t)event {
|
||||
updater.enqueue([event] {
|
||||
updater->enqueue([event] {
|
||||
event();
|
||||
});
|
||||
}
|
||||
@@ -727,10 +758,10 @@ struct ActivityObserver: public Activity::Observer {
|
||||
- (void)audioQueueIsRunningDry:(nonnull CSAudioQueue *)audioQueue {
|
||||
__weak CSMachine *weakSelf = self;
|
||||
|
||||
updater.enqueue([weakSelf] {
|
||||
updater->enqueue([weakSelf] {
|
||||
CSMachine *const strongSelf = weakSelf;
|
||||
if(strongSelf) {
|
||||
strongSelf->updater.performer.timed_machine->flush_output(MachineTypes::TimedMachine::Output::Audio);
|
||||
strongSelf->updater->performer.timed_machine->flush_output(MachineTypes::TimedMachine::Output::Audio);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -738,7 +769,7 @@ struct ActivityObserver: public Activity::Observer {
|
||||
- (void)scanTargetViewDisplayLinkDidFire:(CSScanTargetView *)view now:(const CVTimeStamp *)now outputTime:(const CVTimeStamp *)outputTime {
|
||||
__weak CSMachine *weakSelf = self;
|
||||
|
||||
updater.enqueue([weakSelf] {
|
||||
updater->enqueue([weakSelf] {
|
||||
CSMachine *const strongSelf = weakSelf;
|
||||
if(!strongSelf) {
|
||||
return;
|
||||
@@ -746,7 +777,7 @@ struct ActivityObserver: public Activity::Observer {
|
||||
|
||||
// Grab a pointer to the timed machine from somewhere where it has already
|
||||
// been dynamically cast, to avoid that cost here.
|
||||
MachineTypes::TimedMachine *const timed_machine = strongSelf->updater.performer.timed_machine;
|
||||
MachineTypes::TimedMachine *const timed_machine = strongSelf->updater->performer.timed_machine;
|
||||
|
||||
// Definitely update video; update audio too if that pipeline is looking a little dry.
|
||||
auto outputs = MachineTypes::TimedMachine::Output::Video;
|
||||
@@ -785,7 +816,7 @@ struct ActivityObserver: public Activity::Observer {
|
||||
}
|
||||
|
||||
- (void)stop {
|
||||
updater.stop();
|
||||
updater->stop();
|
||||
}
|
||||
|
||||
+ (BOOL)attemptInstallROM:(NSURL *)url {
|
||||
|
||||
Reference in New Issue
Block a user