mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-28 07:29:45 +00:00
Moves responsibility for timed updates to CSMachine, which gives the CSHighPrecisionTimer a shot.
This commit is contained in:
parent
256f4a6679
commit
0f2783075f
@ -24,8 +24,6 @@ class MachineDocument:
|
||||
private let actionLock = NSLock()
|
||||
/// Ensures exclusive access between calls to machine.updateView and machine.drawView, and close().
|
||||
private let drawLock = NSLock()
|
||||
/// Ensures exclusive access to the best-effort updater.
|
||||
private let bestEffortLock = NSLock()
|
||||
|
||||
// MARK: - Machine details.
|
||||
|
||||
@ -43,9 +41,6 @@ class MachineDocument:
|
||||
/// The output audio queue, if any.
|
||||
private var audioQueue: CSAudioQueue!
|
||||
|
||||
/// The best-effort updater.
|
||||
private var bestEffortUpdater: CSBestEffortUpdater?
|
||||
|
||||
// MARK: - Main NIB connections.
|
||||
|
||||
/// The OpenGL view to receive this machine's display.
|
||||
@ -89,19 +84,14 @@ class MachineDocument:
|
||||
}
|
||||
|
||||
override func close() {
|
||||
machine.stop()
|
||||
|
||||
activityPanel?.setIsVisible(false)
|
||||
activityPanel = nil
|
||||
|
||||
optionsPanel?.setIsVisible(false)
|
||||
optionsPanel = nil
|
||||
|
||||
bestEffortLock.lock()
|
||||
if let bestEffortUpdater = bestEffortUpdater {
|
||||
bestEffortUpdater.flush()
|
||||
self.bestEffortUpdater = nil
|
||||
}
|
||||
bestEffortLock.unlock()
|
||||
|
||||
actionLock.lock()
|
||||
drawLock.lock()
|
||||
machine = nil
|
||||
@ -200,7 +190,6 @@ class MachineDocument:
|
||||
}
|
||||
|
||||
machine.delegate = self
|
||||
self.bestEffortUpdater = CSBestEffortUpdater()
|
||||
|
||||
// Callbacks from the OpenGL may come on a different thread, immediately following the .delegate set;
|
||||
// hence the full setup of the best-effort updater prior to setting self as a delegate.
|
||||
@ -220,7 +209,7 @@ class MachineDocument:
|
||||
openGLView.window!.makeFirstResponder(openGLView)
|
||||
|
||||
// Start forwarding best-effort updates.
|
||||
self.bestEffortUpdater!.setMachine(machine)
|
||||
machine.start()
|
||||
}
|
||||
}
|
||||
|
||||
@ -251,24 +240,11 @@ class MachineDocument:
|
||||
|
||||
/// Responds to the CSAudioQueueDelegate dry-queue warning message by requesting a machine update.
|
||||
final func audioQueueIsRunningDry(_ audioQueue: CSAudioQueue) {
|
||||
bestEffortLock.lock()
|
||||
bestEffortUpdater?.update(with: .audioNeeded)
|
||||
bestEffortLock.unlock()
|
||||
}
|
||||
|
||||
/// Responds to the CSOpenGLViewDelegate redraw message by requesting a machine update if this is a timed
|
||||
/// request, and ordering a redraw regardless of the motivation.
|
||||
final func openGLViewRedraw(_ view: CSOpenGLView, event redrawEvent: CSOpenGLViewRedrawEvent) {
|
||||
if redrawEvent == .timer {
|
||||
bestEffortLock.lock()
|
||||
if let bestEffortUpdater = bestEffortUpdater {
|
||||
bestEffortLock.unlock()
|
||||
bestEffortUpdater.update()
|
||||
} else {
|
||||
bestEffortLock.unlock()
|
||||
}
|
||||
}
|
||||
|
||||
if drawLock.try() {
|
||||
if redrawEvent == .timer {
|
||||
machine.updateView(forPixelSize: view.backingSize)
|
||||
|
@ -64,6 +64,9 @@ typedef NS_ENUM(NSInteger, CSMachineKeyboardInputMode) {
|
||||
|
||||
- (void)setView:(nullable CSOpenGLView *)view aspectRatio:(float)aspectRatio;
|
||||
|
||||
- (void)start;
|
||||
- (void)stop;
|
||||
|
||||
- (void)updateViewForPixelSize:(CGSize)pixelSize;
|
||||
- (void)drawViewForPixelSize:(CGSize)pixelSize;
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#import "CSMachine+Target.h"
|
||||
|
||||
#include "CSROMFetcher.hpp"
|
||||
#import "CSHighPrecisionTimer.h"
|
||||
|
||||
#include "MediaTarget.hpp"
|
||||
#include "JoystickMachine.hpp"
|
||||
@ -149,6 +150,8 @@ struct ActivityObserver: public Activity::Observer {
|
||||
std::bitset<65536> _depressedKeys;
|
||||
NSMutableArray<NSString *> *_leds;
|
||||
|
||||
CSHighPrecisionTimer *_timer;
|
||||
|
||||
std::unique_ptr<Outputs::Display::OpenGL::ScanTarget> _scanTarget;
|
||||
}
|
||||
|
||||
@ -326,7 +329,7 @@ struct ActivityObserver: public Activity::Observer {
|
||||
}
|
||||
|
||||
- (void)updateViewForPixelSize:(CGSize)pixelSize {
|
||||
_scanTarget->update((int)pixelSize.width, (int)pixelSize.height);
|
||||
self->_scanTarget->update((int)pixelSize.width, (int)pixelSize.height);
|
||||
|
||||
// @synchronized(self) {
|
||||
// const auto scan_status = _machine->crt_machine()->get_scan_status();
|
||||
@ -694,4 +697,17 @@ struct ActivityObserver: public Activity::Observer {
|
||||
return _leds;
|
||||
}
|
||||
|
||||
#pragma mark - Timer
|
||||
|
||||
- (void)start {
|
||||
_timer = [[CSHighPrecisionTimer alloc] initWithTask:^{
|
||||
self->_machine->crt_machine()->run_for(2500000.0 / 1000000000.0);
|
||||
} interval:2500000];
|
||||
}
|
||||
|
||||
- (void)stop {
|
||||
[_timer invalidate];
|
||||
_timer = nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
Loading…
Reference in New Issue
Block a user