diff --git a/OSBindings/Mac/Clock Signal/Base.lproj/Activity.xib b/OSBindings/Mac/Clock Signal/Base.lproj/Activity.xib
index 2f3e6e302..3385e40c0 100644
--- a/OSBindings/Mac/Clock Signal/Base.lproj/Activity.xib
+++ b/OSBindings/Mac/Clock Signal/Base.lproj/Activity.xib
@@ -28,7 +28,7 @@
-
+
@@ -43,7 +43,7 @@
-
+
@@ -58,7 +58,7 @@
-
+
@@ -73,7 +73,7 @@
-
+
diff --git a/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift b/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift
index b3b6330c6..b04ae9304 100644
--- a/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift
+++ b/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift
@@ -304,7 +304,15 @@ class MachineDocument:
}
// MARK: Activity display.
- fileprivate var activityLevelIndicators: [String: NSLevelIndicator] = [:]
+ class LED {
+ let levelIndicator: NSLevelIndicator
+ init(levelIndicator: NSLevelIndicator) {
+ self.levelIndicator = levelIndicator
+ }
+ var isLit = false
+ var isBlinking = false
+ }
+ fileprivate var leds: [String: LED] = [:]
func setupActivityDisplay() {
var leds = machine.leds
if leds.count > 0 {
@@ -337,9 +345,39 @@ class MachineDocument:
activityIndicators[c].removeFromSuperview()
}
- // Apply labels.
+ // Apply labels and create leds entries.
for c in 0 ..< leds.count {
textFields[c].stringValue = leds[c]
+ self.leds[leds[c]] = LED(levelIndicator: activityIndicators[c])
+ }
+ }
+ }
+
+ func machine(_ machine: CSMachine, ledShouldBlink ledName: String) {
+ // If there is such an LED, switch it off for 0.03 of a second; if it's meant
+ // to be off at the end of that, leave it off. Don't allow the blinks to
+ // pile up — allow there to be only one in flight at a time.
+ if let led = leds[ledName] {
+ DispatchQueue.main.async {
+ if !led.isBlinking {
+ led.levelIndicator.floatValue = 0.0
+ led.isBlinking = true
+
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.03) {
+ led.levelIndicator.floatValue = led.isLit ? 1.0 : 0.0
+ led.isBlinking = false
+ }
+ }
+ }
+ }
+ }
+
+ func machine(_ machine: CSMachine, led ledName: String, didChangeToLit isLit: Bool) {
+ // If there is such an LED, switch it appropriately.
+ if let led = leds[ledName] {
+ DispatchQueue.main.async {
+ led.levelIndicator.floatValue = isLit ? 1.0 : 0.0
+ led.isLit = isLit
}
}
}
diff --git a/OSBindings/Mac/Clock Signal/Machine/CSMachine.h b/OSBindings/Mac/Clock Signal/Machine/CSMachine.h
index 670a446ce..0f6bb7636 100644
--- a/OSBindings/Mac/Clock Signal/Machine/CSMachine.h
+++ b/OSBindings/Mac/Clock Signal/Machine/CSMachine.h
@@ -16,6 +16,8 @@
@class CSMachine;
@protocol CSMachineDelegate
- (void)machineSpeakerDidChangeInputClock:(nonnull CSMachine *)machine;
+- (void)machine:(nonnull CSMachine *)machine led:(nonnull NSString *)led didChangeToLit:(BOOL)isLit;
+- (void)machine:(nonnull CSMachine *)machine ledShouldBlink:(nonnull NSString *)led;
@end
typedef NS_ENUM(NSInteger, CSMachineVideoSignal) {
diff --git a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm
index 910773d5a..ee3335573 100644
--- a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm
+++ b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm
@@ -61,9 +61,11 @@ struct ActivityObserver: public Activity::Observer {
}
void set_led_status(const std::string &name, bool lit) override {
+ [machine.delegate machine:machine led:[NSString stringWithUTF8String:name.c_str()] didChangeToLit:lit];
}
void announce_drive_event(const std::string &name, DriveEvent event) override {
+ [machine.delegate machine:machine ledShouldBlink:[NSString stringWithUTF8String:name.c_str()]];
}
void set_drive_motor_status(const std::string &name, bool is_on) override {