diff --git a/Machines/AmstradCPC/AmstradCPC.cpp b/Machines/AmstradCPC/AmstradCPC.cpp index 71e659ab3..9a8fa5f0e 100644 --- a/Machines/AmstradCPC/AmstradCPC.cpp +++ b/Machines/AmstradCPC/AmstradCPC.cpp @@ -786,7 +786,7 @@ template class ConcreteMachine: public CRTMachine::Machine, public MediaTarget::Machine, public KeyboardMachine::MappedMachine, - public Utility::TypeRecipient, + public Utility::TypeRecipient, public CPU::Z80::BusHandler, public ClockingHint::Observer, public Configurable::Device, @@ -1079,11 +1079,7 @@ template class ConcreteMachine: // MARK: - Keyboard void type_string(const std::string &string) final { - if(typer_) { - typer_->append(string); - } else { - Utility::TypeRecipient::add_typer(string, std::make_unique()); - } + Utility::TypeRecipient::add_typer(string); } HalfCycles get_typer_delay() final { diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index 072d8612a..beebf4b35 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -287,7 +287,7 @@ class ConcreteMachine: public Configurable::Device, public CPU::MOS6502::BusHandler, public MOS::MOS6522::IRQDelegatePortHandler::Delegate, - public Utility::TypeRecipient, + public Utility::TypeRecipient, public Storage::Tape::BinaryTapePlayer::Delegate, public Machine, public ClockingHint::Observer, @@ -645,11 +645,7 @@ class ConcreteMachine: } void type_string(const std::string &string) final { - if(typer_) { - typer_->append(string); - } else { - Utility::TypeRecipient::add_typer(string, std::make_unique()); - } + Utility::TypeRecipient::add_typer(string); } void tape_did_change_input(Storage::Tape::BinaryTapePlayer *tape) final { diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index 7bf5d5505..76a3d8fff 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -46,7 +46,7 @@ class ConcreteMachine: public Configurable::Device, public CPU::MOS6502::BusHandler, public Tape::Delegate, - public Utility::TypeRecipient, + public Utility::TypeRecipient, public Activity::Source { public: ConcreteMachine(const Analyser::Static::Acorn::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) : @@ -413,11 +413,7 @@ class ConcreteMachine: } void type_string(const std::string &string) final { - if(typer_) { - typer_->append(string); - } else { - Utility::TypeRecipient::add_typer(string, std::make_unique()); - } + Utility::TypeRecipient::add_typer(string); } KeyboardMapper *get_keyboard_mapper() final { diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index b25162f6e..081d9ef58 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -224,7 +224,6 @@ template class Co public Configurable::Device, public CPU::MOS6502::BusHandler, public MOS::MOS6522::IRQDelegatePortHandler::Delegate, - public Utility::TypeRecipient, public Storage::Tape::BinaryTapePlayer::Delegate, public DiskController::Delegate, public ClockingHint::Observer, diff --git a/Machines/Utility/Typer.cpp b/Machines/Utility/Typer.cpp index fcad3a060..a1a85aa88 100644 --- a/Machines/Utility/Typer.cpp +++ b/Machines/Utility/Typer.cpp @@ -10,11 +10,11 @@ using namespace Utility; -Typer::Typer(const std::string &string, HalfCycles delay, HalfCycles frequency, std::unique_ptr character_mapper, Delegate *delegate) : +Typer::Typer(const std::string &string, HalfCycles delay, HalfCycles frequency, CharacterMapper &character_mapper, Delegate *delegate) : frequency_(frequency), counter_(-delay), delegate_(delegate), - character_mapper_(std::move(character_mapper)) { + character_mapper_(character_mapper) { // Retain only those characters that actually map to something. if(sequence_for_character(Typer::BeginString)) { string_ += Typer::BeginString; @@ -71,7 +71,7 @@ void Typer::append(const std::string &string) { } const uint16_t *Typer::sequence_for_character(char c) const { - const uint16_t *const sequence = character_mapper_->sequence_for_character(c); + const uint16_t *const sequence = character_mapper_.sequence_for_character(c); if(!sequence || sequence[0] == KeyboardMachine::MappedMachine::KeyNotMapped) { return nullptr; } @@ -94,7 +94,7 @@ uint16_t Typer::try_type_next_character() { // be clear. if(phase_ == 1) { delegate_->clear_all_keys(); - if(character_mapper_->needs_pause_after_reset_all_keys() || + if(character_mapper_.needs_pause_after_reset_all_keys() || (string_pointer_ > 0 && string_[string_pointer_ - 1] == string_[string_pointer_])) { return 0xffff; // Arbitrarily. Anything non-zero will do. } @@ -124,7 +124,7 @@ bool Typer::type_next_character() { if(string_pointer_ == string_.size()) return false; } - if(character_mapper_->needs_pause_after_key(key_pressed)) { + if(character_mapper_.needs_pause_after_key(key_pressed)) { break; } } diff --git a/Machines/Utility/Typer.hpp b/Machines/Utility/Typer.hpp index 19b872a9f..31ef4ec5a 100644 --- a/Machines/Utility/Typer.hpp +++ b/Machines/Utility/Typer.hpp @@ -67,7 +67,7 @@ class Typer { virtual void typer_reset(Typer *typer) = 0; }; - Typer(const std::string &string, HalfCycles delay, HalfCycles frequency, std::unique_ptr character_mapper, Delegate *delegate); + Typer(const std::string &string, HalfCycles delay, HalfCycles frequency, CharacterMapper &character_mapper, Delegate *delegate); /// Advances for @c duration. void run_for(const HalfCycles duration); @@ -91,7 +91,7 @@ class Typer { int phase_ = 0; Delegate *delegate_; - std::unique_ptr character_mapper_; + CharacterMapper &character_mapper_; uint16_t try_type_next_character(); const uint16_t *sequence_for_character(char) const; @@ -101,11 +101,18 @@ class Typer { Provides a default base class for type recipients: classes that want to attach a single typer at a time and which may or may not want to nominate an initial delay and typing frequency. */ +template class TypeRecipient: public Typer::Delegate { protected: + template TypeRecipient(Args&&... args) : character_mapper(std::forward(args)...) {} + /// Attaches a typer to this class that will type @c string using @c character_mapper as a source. - void add_typer(const std::string &string, std::unique_ptr character_mapper) { - typer_ = std::make_unique(string, get_typer_delay(), get_typer_frequency(), std::move(character_mapper), this); + void add_typer(const std::string &string) { + if(!typer_) { + typer_ = std::make_unique(string, get_typer_delay(), get_typer_frequency(), character_mapper, this); + } else { + typer_->append(string); + } } /*! @@ -128,6 +135,7 @@ class TypeRecipient: public Typer::Delegate { private: std::unique_ptr previous_typer_; + CMApper character_mapper; }; } diff --git a/Machines/ZX8081/ZX8081.cpp b/Machines/ZX8081/ZX8081.cpp index c628a74ce..d82777bfe 100644 --- a/Machines/ZX8081/ZX8081.cpp +++ b/Machines/ZX8081/ZX8081.cpp @@ -62,11 +62,12 @@ template class ConcreteMachine: public MediaTarget::Machine, public KeyboardMachine::MappedMachine, public Configurable::Device, - public Utility::TypeRecipient, + public Utility::TypeRecipient, public CPU::Z80::BusHandler, public Machine { public: ConcreteMachine(const Analyser::Static::ZX8081::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) : + Utility::TypeRecipient(is_zx81), z80_(*this), tape_player_(ZX8081ClockRate), ay_(GI::AY38910::Personality::AY38910, audio_queue_), @@ -340,11 +341,7 @@ template class ConcreteMachine: } void type_string(const std::string &string) final { - if(typer_) { - typer_->append(string); - } else { - Utility::TypeRecipient::add_typer(string, std::make_unique(is_zx81)); - } + Utility::TypeRecipient::add_typer(string); } // MARK: - Keyboard