diff --git a/ActivityObserver/ActivityObserver.hpp b/Activity/Observer.hpp similarity index 90% rename from ActivityObserver/ActivityObserver.hpp rename to Activity/Observer.hpp index 48115e374..6cf99095e 100644 --- a/ActivityObserver/ActivityObserver.hpp +++ b/Activity/Observer.hpp @@ -1,16 +1,18 @@ // -// Header.h +// ActivityObserver.h // Clock Signal // // Created by Thomas Harte on 07/05/2018. // Copyright © 2018 Thomas Harte. All rights reserved. // -#ifndef Header_h -#define Header_h +#ifndef ActivityObserver_h +#define ActivityObserver_h #include +namespace Activity { + /*! Provides a purely virtual base class for anybody that wants to receive notifications of 'activity' — any feedback from an emulated system which a user could perceive other than @@ -19,7 +21,7 @@ So: status LEDs, drive activity, etc. A receiver may choose to make appropriate noises and/or to show or unshow status indicators. */ -class ActivityObserver { +class Observer { public: /// Announces to the receiver that there is an LED of name @c name. virtual void register_led(const std::string &name) = 0; @@ -44,4 +46,6 @@ class ActivityObserver { }; -#endif /* Header_h */ +} + +#endif /* ActivityObserver_h */ diff --git a/Machines/ActivitySource.hpp b/Activity/Source.hpp similarity index 60% rename from Machines/ActivitySource.hpp rename to Activity/Source.hpp index 2747ebf00..9db6b7a53 100644 --- a/Machines/ActivitySource.hpp +++ b/Activity/Source.hpp @@ -9,13 +9,13 @@ #ifndef ActivitySource_h #define ActivitySource_h -#include "../ActivityObserver/ActivityObserver.hpp" +#include "Observer.hpp" -namespace ActivitySource { +namespace Activity { -class Machine { +class Source { public: - virtual void set_activity_observer(ActivityObserver *receiver) = 0; + virtual void set_activity_observer(Observer *observer) = 0; }; } diff --git a/Analyser/Dynamic/MultiMachine/MultiMachine.cpp b/Analyser/Dynamic/MultiMachine/MultiMachine.cpp index 6343bcc1c..5f7a92f29 100644 --- a/Analyser/Dynamic/MultiMachine/MultiMachine.cpp +++ b/Analyser/Dynamic/MultiMachine/MultiMachine.cpp @@ -22,7 +22,7 @@ MultiMachine::MultiMachine(std::vector> &&machin crt_machine_.set_delegate(this); } -ActivitySource::Machine *MultiMachine::activity_source() { +Activity::Source *MultiMachine::activity_source() { return nullptr; // TODO } diff --git a/Analyser/Dynamic/MultiMachine/MultiMachine.hpp b/Analyser/Dynamic/MultiMachine/MultiMachine.hpp index 9b4124cca..f1a8ea845 100644 --- a/Analyser/Dynamic/MultiMachine/MultiMachine.hpp +++ b/Analyser/Dynamic/MultiMachine/MultiMachine.hpp @@ -50,7 +50,7 @@ class MultiMachine: public ::Machine::DynamicMachine, public MultiCRTMachine::De static bool would_collapse(const std::vector> &machines); MultiMachine(std::vector> &&machines); - ActivitySource::Machine *activity_source() override; + Activity::Source *activity_source() override; ConfigurationTarget::Machine *configuration_target() override; CRTMachine::Machine *crt_machine() override; JoystickMachine::Machine *joystick_machine() override; diff --git a/Machines/DynamicMachine.hpp b/Machines/DynamicMachine.hpp index 2b51c5e60..a8f2595b5 100644 --- a/Machines/DynamicMachine.hpp +++ b/Machines/DynamicMachine.hpp @@ -10,7 +10,7 @@ #define DynamicMachine_h #include "../Configurable/Configurable.hpp" -#include "ActivitySource.hpp" +#include "../Activity/Source.hpp" #include "ConfigurationTarget.hpp" #include "CRTMachine.hpp" #include "JoystickMachine.hpp" @@ -26,7 +26,7 @@ namespace Machine { struct DynamicMachine { virtual ~DynamicMachine() {} - virtual ActivitySource::Machine *activity_source() = 0; + virtual Activity::Source *activity_source() = 0; virtual ConfigurationTarget::Machine *configuration_target() = 0; virtual CRTMachine::Machine *crt_machine() = 0; virtual JoystickMachine::Machine *joystick_machine() = 0; diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index 9b4c18762..103c2f855 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -8,7 +8,7 @@ #include "Electron.hpp" -#include "../ActivitySource.hpp" +#include "../../Activity/Source.hpp" #include "../ConfigurationTarget.hpp" #include "../CRTMachine.hpp" #include "../KeyboardMachine.hpp" @@ -47,7 +47,7 @@ class ConcreteMachine: public CPU::MOS6502::BusHandler, public Tape::Delegate, public Utility::TypeRecipient, - public ActivitySource::Machine { + public Activity::Source { public: ConcreteMachine() : m6502_(*this), @@ -480,7 +480,7 @@ class ConcreteMachine: return selection_set; } - void set_activity_observer(ActivityObserver *observer) override { + void set_activity_observer(Activity::Observer *observer) override { activity_observer_ = observer; if(activity_observer_) { activity_observer_->register_led(caps_led); @@ -578,7 +578,7 @@ class ConcreteMachine: // MARK: - Caps Lock status and the activity observer. const std::string caps_led = "CAPS"; bool caps_led_state_ = false; - ActivityObserver *activity_observer_ = nullptr; + Activity::Observer *activity_observer_ = nullptr; }; } diff --git a/Machines/Electron/Plus3.cpp b/Machines/Electron/Plus3.cpp index 95178291a..1338bd11d 100644 --- a/Machines/Electron/Plus3.cpp +++ b/Machines/Electron/Plus3.cpp @@ -53,3 +53,8 @@ void Plus3::set_motor_on(bool on) { // writing state, so plenty of work to do in general here. get_drive().set_motor_on(on); } + +void Plus3::set_activity_observer(Activity::Observer *observer) { + drives_[0]->set_activity_observer(observer, "Drive 1", true); + drives_[1]->set_activity_observer(observer, "Drive 2", true); +} diff --git a/Machines/Electron/Plus3.hpp b/Machines/Electron/Plus3.hpp index 71b8b1c4b..d5bf1a7c9 100644 --- a/Machines/Electron/Plus3.hpp +++ b/Machines/Electron/Plus3.hpp @@ -10,6 +10,7 @@ #define Plus3_hpp #include "../../Components/1770/1770.hpp" +#include "../../Activity/Observer.hpp" namespace Electron { @@ -19,6 +20,7 @@ class Plus3 : public WD::WD1770 { void set_disk(std::shared_ptr disk, int drive); void set_control_register(uint8_t control); + void set_activity_observer(Activity::Observer *observer); private: void set_control_register(uint8_t control, uint8_t changes); diff --git a/Machines/Utility/TypedDynamicMachine.hpp b/Machines/Utility/TypedDynamicMachine.hpp index 07084b035..db3632733 100644 --- a/Machines/Utility/TypedDynamicMachine.hpp +++ b/Machines/Utility/TypedDynamicMachine.hpp @@ -25,8 +25,8 @@ template class TypedDynamicMachine: public ::Machine::DynamicMachine return *this; } - ActivitySource::Machine *activity_source() override { - return get(); + Activity::Source *activity_source() override { + return get(); } ConfigurationTarget::Machine *configuration_target() override { diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 6a98f57b7..cab4b4feb 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -697,8 +697,6 @@ 4B055ABE1FAE98000060FFFF /* MachineForTarget.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MachineForTarget.cpp; sourceTree = ""; }; 4B055ABF1FAE98000060FFFF /* MachineForTarget.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MachineForTarget.hpp; sourceTree = ""; }; 4B055AF01FAE9C080060FFFF /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; - 4B055C1E20A113B00014E5AB /* ActivityObserver.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ActivityObserver.hpp; sourceTree = ""; }; - 4B055C1F20A1166A0014E5AB /* ActivitySource.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ActivitySource.hpp; sourceTree = ""; }; 4B0783591FC11D10001D12BB /* Configurable.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Configurable.cpp; sourceTree = ""; }; 4B08A2741EE35D56008B7065 /* Z80InterruptTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80InterruptTests.swift; sourceTree = ""; }; 4B08A2761EE39306008B7065 /* TestMachine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestMachine.h; sourceTree = ""; }; @@ -865,6 +863,8 @@ 4B5073051DDD3B9400C48FBD /* ArrayBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayBuilder.cpp; sourceTree = ""; }; 4B5073061DDD3B9400C48FBD /* ArrayBuilder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ArrayBuilder.hpp; sourceTree = ""; }; 4B5073091DDFCFDF00C48FBD /* ArrayBuilderTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ArrayBuilderTests.mm; sourceTree = ""; }; + 4B51F70920A521D700AFA2C1 /* Source.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Source.hpp; sourceTree = ""; }; + 4B51F70A20A521D700AFA2C1 /* Observer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Observer.hpp; sourceTree = ""; }; 4B54C0BB1F8D8E790050900F /* KeyboardMachine.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = KeyboardMachine.cpp; sourceTree = ""; }; 4B54C0BD1F8D8F450050900F /* Keyboard.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Keyboard.cpp; path = Oric/Keyboard.cpp; sourceTree = ""; }; 4B54C0BE1F8D8F450050900F /* Keyboard.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = Keyboard.hpp; path = Oric/Keyboard.hpp; sourceTree = ""; }; @@ -1498,15 +1498,6 @@ path = ../SDL; sourceTree = ""; }; - 4B055C1D20A113B00014E5AB /* ActivityObserver */ = { - isa = PBXGroup; - children = ( - 4B055C1E20A113B00014E5AB /* ActivityObserver.hpp */, - ); - name = ActivityObserver; - path = ../../ActivityObserver; - sourceTree = ""; - }; 4B0CCC411C62D0B3001CAC5F /* CRT */ = { isa = PBXGroup; children = ( @@ -1972,6 +1963,16 @@ path = 1540; sourceTree = ""; }; + 4B51F70820A521D700AFA2C1 /* Activity */ = { + isa = PBXGroup; + children = ( + 4B51F70920A521D700AFA2C1 /* Source.hpp */, + 4B51F70A20A521D700AFA2C1 /* Observer.hpp */, + ); + name = Activity; + path = ../../Activity; + sourceTree = ""; + }; 4B55CE551C3B7D360093A61B /* Documents */ = { isa = PBXGroup; children = ( @@ -2708,7 +2709,7 @@ isa = PBXGroup; children = ( 4BC76E6A1C98F43700E6EF73 /* Accelerate.framework */, - 4B055C1D20A113B00014E5AB /* ActivityObserver */, + 4B51F70820A521D700AFA2C1 /* Activity */, 4B8944E2201967B4007DE474 /* Analyser */, 4BB73EA01B587A5100552FC2 /* Clock Signal */, 4BB73EB51B587A5100552FC2 /* Clock SignalTests */, @@ -2812,7 +2813,6 @@ isa = PBXGroup; children = ( 4B54C0BB1F8D8E790050900F /* KeyboardMachine.cpp */, - 4B055C1F20A1166A0014E5AB /* ActivitySource.hpp */, 4BA9C3CF1D8164A9002DDB61 /* ConfigurationTarget.hpp */, 4B046DC31CFE651500E9E45E /* CRTMachine.hpp */, 4BBB709C2020109C002FE009 /* DynamicMachine.hpp */, diff --git a/Storage/Disk/Drive.cpp b/Storage/Disk/Drive.cpp index d62654171..8f5648b12 100644 --- a/Storage/Disk/Drive.cpp +++ b/Storage/Disk/Drive.cpp @@ -88,6 +88,14 @@ bool Drive::get_is_ready() { void Drive::set_motor_on(bool motor_is_on) { motor_is_on_ = motor_is_on; + + if(observer_) { + observer_->set_drive_motor_status(drive_name_, motor_is_on_); + if(announce_motor_led_) { + observer_->set_led_status(drive_name_, motor_is_on_); + } + } + if(!motor_is_on) { ready_index_count_ = 0; if(disk_) disk_->flush_tracks(); @@ -265,3 +273,19 @@ void Drive::end_writing() { invalidate_track(); } } + +void Drive::set_activity_observer(Activity::Observer *observer, const std::string &name, bool add_motor_led) { + observer_ = observer; + announce_motor_led_ = add_motor_led; + if(observer) { + drive_name_ = name; + + observer->register_drive(drive_name_); + observer->set_drive_motor_status(drive_name_, motor_is_on_); + + if(add_motor_led) { + observer->register_led(drive_name_); + observer->set_led_status(drive_name_, motor_is_on_); + } + } +} diff --git a/Storage/Disk/Drive.hpp b/Storage/Disk/Drive.hpp index be32071e7..e10ab4099 100644 --- a/Storage/Disk/Drive.hpp +++ b/Storage/Disk/Drive.hpp @@ -14,6 +14,7 @@ #include "Track/PCMPatchedTrack.hpp" #include "../TimedEventLoop.hpp" +#include "../../Activity/Observer.hpp" #include "../../ClockReceiver/Sleeper.hpp" #include @@ -122,6 +123,10 @@ class Drive: public Sleeper, public TimedEventLoop { // As per Sleeper. bool is_sleeping(); + /// Adds an activity observer; it'll be notified of disk activity. + /// The caller can specify whether to add an LED based on disk motor. + void set_activity_observer(Activity::Observer *observer, const std::string &name, bool add_motor_led); + private: // Drives contain an entire disk; from that a certain track // will be currently under the head. @@ -189,6 +194,11 @@ class Drive: public Sleeper, public TimedEventLoop { void setup_track(); void invalidate_track(); + + // Activity observer description. + Activity::Observer *observer_ = nullptr; + std::string drive_name_; + bool announce_motor_led_ = false; };