mirror of
https://github.com/TomHarte/CLK.git
synced 2025-04-07 16:37:24 +00:00
Exposes a list of machine LEDs to Swift.
Also gets explicit about nullability on the Objective-C side.
This commit is contained in:
parent
3da1d5700c
commit
5a56d8a5d0
@ -102,7 +102,7 @@ class MachineDocument:
|
||||
}
|
||||
}
|
||||
|
||||
func machineSpeakerDidChangeInputClock(_ machine: CSMachine!) {
|
||||
func machineSpeakerDidChangeInputClock(_ machine: CSMachine) {
|
||||
setupAudioQueueClockRate()
|
||||
}
|
||||
|
||||
@ -147,6 +147,7 @@ class MachineDocument:
|
||||
self.machine = machine
|
||||
self.optionsPanelNibName = analysis.optionsPanelNibName
|
||||
setupMachineOutput()
|
||||
setupActivityDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,4 +291,43 @@ class MachineDocument:
|
||||
}
|
||||
return super.validateUserInterfaceItem(item)
|
||||
}
|
||||
|
||||
// MARK: Activity display.
|
||||
func setupActivityDisplay() {
|
||||
return
|
||||
|
||||
if machine.leds.count > 0 {
|
||||
let panel = NSPanel()
|
||||
panel.title = "Activity"
|
||||
panel.styleMask = .hudWindow
|
||||
panel.setIsVisible(true)
|
||||
|
||||
for name in machine.leds {
|
||||
let button = NSButton()
|
||||
button.title = name
|
||||
button.setButtonType(.radio)
|
||||
button.translatesAutoresizingMaskIntoConstraints = false
|
||||
button.isEnabled = false
|
||||
// button.color
|
||||
panel.contentView?.addSubview(button)
|
||||
|
||||
let views = ["button": button]
|
||||
let horizontalConstraints =
|
||||
NSLayoutConstraint.constraints(
|
||||
withVisualFormat: "H:|-[button]-|",
|
||||
options: NSLayoutConstraint.FormatOptions(rawValue: 0),
|
||||
metrics: nil,
|
||||
views: views)
|
||||
let verticalConstraints =
|
||||
NSLayoutConstraint.constraints(
|
||||
withVisualFormat: "V:|-[button]-|",
|
||||
options: NSLayoutConstraint.FormatOptions(rawValue: 0),
|
||||
metrics: nil,
|
||||
views: views)
|
||||
|
||||
panel.contentView?.addConstraints(horizontalConstraints)
|
||||
panel.contentView?.addConstraints(verticalConstraints)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
@class CSMachine;
|
||||
@protocol CSMachineDelegate
|
||||
- (void)machineSpeakerDidChangeInputClock:(CSMachine *)machine;
|
||||
- (void)machineSpeakerDidChangeInputClock:(nonnull CSMachine *)machine;
|
||||
@end
|
||||
|
||||
typedef NS_ENUM(NSInteger, CSMachineVideoSignal) {
|
||||
@ -35,32 +35,32 @@ typedef NS_ENUM(NSInteger, CSMachineKeyboardInputMode) {
|
||||
|
||||
@interface CSMachine : NSObject
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
- (nonnull instancetype)init NS_UNAVAILABLE;
|
||||
/*!
|
||||
Initialises an instance of CSMachine.
|
||||
|
||||
@param result The CSStaticAnalyser result that describes the machine needed.
|
||||
*/
|
||||
- (instancetype)initWithAnalyser:(CSStaticAnalyser *)result NS_DESIGNATED_INITIALIZER;
|
||||
- (nullable instancetype)initWithAnalyser:(nonnull CSStaticAnalyser *)result NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
- (void)runForInterval:(NSTimeInterval)interval;
|
||||
|
||||
- (float)idealSamplingRateFromRange:(NSRange)range;
|
||||
- (void)setAudioSamplingRate:(float)samplingRate bufferSize:(NSUInteger)bufferSize;
|
||||
|
||||
- (void)setView:(CSOpenGLView *)view aspectRatio:(float)aspectRatio;
|
||||
- (void)setView:(nullable CSOpenGLView *)view aspectRatio:(float)aspectRatio;
|
||||
- (void)drawViewForPixelSize:(CGSize)pixelSize onlyIfDirty:(BOOL)onlyIfDirty;
|
||||
|
||||
- (void)setKey:(uint16_t)key characters:(NSString *)characters isPressed:(BOOL)isPressed;
|
||||
- (void)setKey:(uint16_t)key characters:(nullable NSString *)characters isPressed:(BOOL)isPressed;
|
||||
- (void)clearAllKeys;
|
||||
|
||||
@property (nonatomic, strong) CSAudioQueue *audioQueue;
|
||||
@property (nonatomic, readonly) CSOpenGLView *view;
|
||||
@property (nonatomic, weak) id<CSMachineDelegate> delegate;
|
||||
@property (nonatomic, strong, nullable) CSAudioQueue *audioQueue;
|
||||
@property (nonatomic, readonly, nonnull) CSOpenGLView *view;
|
||||
@property (nonatomic, weak, nullable) id<CSMachineDelegate> delegate;
|
||||
|
||||
@property (nonatomic, readonly) NSString *userDefaultsPrefix;
|
||||
@property (nonatomic, readonly, nonnull) NSString *userDefaultsPrefix;
|
||||
|
||||
- (void)paste:(NSString *)string;
|
||||
- (void)paste:(nonnull NSString *)string;
|
||||
|
||||
@property (nonatomic, assign) BOOL useFastLoadingHack;
|
||||
@property (nonatomic, assign) CSMachineVideoSignal videoSignal;
|
||||
@ -73,8 +73,11 @@ typedef NS_ENUM(NSInteger, CSMachineKeyboardInputMode) {
|
||||
@property (nonatomic, readonly) BOOL hasJoystick;
|
||||
@property (nonatomic, assign) CSMachineKeyboardInputMode inputMode;
|
||||
|
||||
// LED list.
|
||||
@property (nonatomic, readonly, nonnull) NSArray<NSString *> *leds;
|
||||
|
||||
// Special-case accessors; undefined behaviour if accessed for a machine not of the corresponding type.
|
||||
@property (nonatomic, readonly) CSAtari2600 *atari2600;
|
||||
@property (nonatomic, readonly) CSZX8081 *zx8081;
|
||||
@property (nonatomic, readonly, nullable) CSAtari2600 *atari2600;
|
||||
@property (nonatomic, readonly, nullable) CSZX8081 *zx8081;
|
||||
|
||||
@end
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "MachineForTarget.hpp"
|
||||
#include "StandardOptions.hpp"
|
||||
#include "Typer.hpp"
|
||||
#include "../../../../Activity/Observer.hpp"
|
||||
|
||||
#import "CSStaticAnalyser+TargetVector.h"
|
||||
#import "NSBundle+DataResource.h"
|
||||
@ -28,6 +29,7 @@
|
||||
@interface CSMachine() <CSFastLoading>
|
||||
- (void)speaker:(Outputs::Speaker::Speaker *)speaker didCompleteSamples:(const int16_t *)samples length:(int)length;
|
||||
- (void)speakerDidChangeInputClock:(Outputs::Speaker::Speaker *)speaker;
|
||||
- (void)addLED:(NSString *)led;
|
||||
@end
|
||||
|
||||
struct LockProtectedDelegate {
|
||||
@ -50,14 +52,36 @@ struct SpeakerDelegate: public Outputs::Speaker::Speaker::Delegate, public LockP
|
||||
}
|
||||
};
|
||||
|
||||
struct ActivityObserver: public Activity::Observer {
|
||||
void register_led(const std::string &name) override {
|
||||
[machine addLED:[NSString stringWithUTF8String:name.c_str()]];
|
||||
}
|
||||
|
||||
void register_drive(const std::string &name) override {
|
||||
}
|
||||
|
||||
void set_led_status(const std::string &name, bool lit) override {
|
||||
}
|
||||
|
||||
void announce_drive_event(const std::string &name, DriveEvent event) override {
|
||||
}
|
||||
|
||||
void set_drive_motor_status(const std::string &name, bool is_on) override {
|
||||
}
|
||||
|
||||
__unsafe_unretained CSMachine *machine;
|
||||
};
|
||||
|
||||
@implementation CSMachine {
|
||||
SpeakerDelegate _speakerDelegate;
|
||||
ActivityObserver _activityObserver;
|
||||
NSLock *_delegateMachineAccessLock;
|
||||
|
||||
CSStaticAnalyser *_analyser;
|
||||
std::unique_ptr<Machine::DynamicMachine> _machine;
|
||||
|
||||
std::bitset<65536> _depressedKeys;
|
||||
NSMutableArray<NSString *> *_leds;
|
||||
}
|
||||
|
||||
- (instancetype)initWithAnalyser:(CSStaticAnalyser *)result {
|
||||
@ -71,6 +95,13 @@ struct SpeakerDelegate: public Outputs::Speaker::Speaker::Delegate, public LockP
|
||||
|
||||
_inputMode = _machine->keyboard_machine() ? CSMachineKeyboardInputModeKeyboard : CSMachineKeyboardInputModeJoystick;
|
||||
|
||||
_leds = [[NSMutableArray alloc] init];
|
||||
Activity::Source *const activity_source = _machine->activity_source();
|
||||
if(activity_source) {
|
||||
_activityObserver.machine = self;
|
||||
activity_source->set_activity_observer(&_activityObserver);
|
||||
}
|
||||
|
||||
_delegateMachineAccessLock = [[NSLock alloc] init];
|
||||
|
||||
_speakerDelegate.machine = self;
|
||||
@ -408,4 +439,14 @@ struct SpeakerDelegate: public Outputs::Speaker::Speaker::Delegate, public LockP
|
||||
return !!_machine->keyboard_machine();
|
||||
}
|
||||
|
||||
#pragma mark - Activity observation
|
||||
|
||||
- (void)addLED:(NSString *)led {
|
||||
[_leds addObject:led];
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)leds {
|
||||
return _leds;
|
||||
}
|
||||
|
||||
@end
|
||||
|
Loading…
x
Reference in New Issue
Block a user