From d5b1a9d9187d02e325f461e70fdac61387414c76 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 29 Dec 2017 15:26:03 -0500 Subject: [PATCH] Moves the typer functionality behind a functionality-based naming scheme, eliminates its C-style memory management. --- Machines/AmstradCPC/AmstradCPC.cpp | 6 ++--- Machines/Commodore/Vic-20/Vic20.cpp | 6 ++--- Machines/Electron/Electron.cpp | 6 ++--- Machines/Oric/Oric.cpp | 6 ++--- Machines/Utility/Typer.cpp | 27 ++++++------------- Machines/Utility/Typer.hpp | 11 ++++---- Machines/ZX8081/ZX8081.cpp | 6 ++--- .../Mac/Clock Signal/Machine/CSMachine.mm | 2 +- OSBindings/SDL/main.cpp | 2 +- 9 files changed, 31 insertions(+), 41 deletions(-) diff --git a/Machines/AmstradCPC/AmstradCPC.cpp b/Machines/AmstradCPC/AmstradCPC.cpp index c666d295c..3faa8397c 100644 --- a/Machines/AmstradCPC/AmstradCPC.cpp +++ b/Machines/AmstradCPC/AmstradCPC.cpp @@ -902,7 +902,7 @@ class ConcreteMachine: // Type whatever is required. if(target.loading_command.length()) { - set_typer_for_string(target.loading_command.c_str()); + type_string(target.loading_command); } insert_media(target.media); @@ -953,9 +953,9 @@ class ConcreteMachine: // MARK: - Keyboard - void set_typer_for_string(const char *string) override final { + void type_string(const std::string &string) override final { std::unique_ptr mapper(new CharacterMapper()); - Utility::TypeRecipient::set_typer_for_string(string, std::move(mapper)); + Utility::TypeRecipient::add_typer(string, std::move(mapper)); } HalfCycles get_typer_delay() override final { diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index 6d8e70ceb..c1b5825e6 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -348,7 +348,7 @@ class ConcreteMachine: void configure_as_target(const StaticAnalyser::Target &target) override final { if(target.loading_command.length()) { - set_typer_for_string(target.loading_command.c_str()); + type_string(target.loading_command); } switch(target.vic20.memory_model) { @@ -653,9 +653,9 @@ class ConcreteMachine: m6502_.set_irq_line(keyboard_via_.get_interrupt_line()); } - void set_typer_for_string(const char *string) override final { + void type_string(const std::string &string) override final { std::unique_ptr mapper(new CharacterMapper()); - Utility::TypeRecipient::set_typer_for_string(string, std::move(mapper)); + Utility::TypeRecipient::add_typer(string, std::move(mapper)); } void tape_did_change_input(Storage::Tape::BinaryTapePlayer *tape) override final { diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index ec56ccc1b..738b820d3 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -115,7 +115,7 @@ class ConcreteMachine: void configure_as_target(const StaticAnalyser::Target &target) override final { if(target.loading_command.length()) { - set_typer_for_string(target.loading_command.c_str()); + type_string(target.loading_command); } if(target.acorn.should_shift_restart) { @@ -414,9 +414,9 @@ class ConcreteMachine: return Cycles(625*128*2); // accept a new character every two frames } - void set_typer_for_string(const char *string) override final { + void type_string(const std::string &string) override final { std::unique_ptr mapper(new CharacterMapper()); - Utility::TypeRecipient::set_typer_for_string(string, std::move(mapper)); + Utility::TypeRecipient::add_typer(string, std::move(mapper)); } KeyboardMapper &get_keyboard_mapper() override { diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index dc07c1e15..63e7abb5c 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -262,7 +262,7 @@ class ConcreteMachine: } if(target.loading_command.length()) { - set_typer_for_string(target.loading_command.c_str()); + type_string(target.loading_command); } if(target.oric.use_atmos_rom) { @@ -407,9 +407,9 @@ class ConcreteMachine: } // for Utility::TypeRecipient::Delegate - void set_typer_for_string(const char *string) override final { + void type_string(const std::string &string) override final { std::unique_ptr mapper(new CharacterMapper); - Utility::TypeRecipient::set_typer_for_string(string, std::move(mapper)); + Utility::TypeRecipient::add_typer(string, std::move(mapper)); } // for Microdisc::Delegate diff --git a/Machines/Utility/Typer.cpp b/Machines/Utility/Typer.cpp index 4160af136..09aa5585c 100644 --- a/Machines/Utility/Typer.cpp +++ b/Machines/Utility/Typer.cpp @@ -8,23 +8,22 @@ #include "Typer.hpp" -#include -#include +#include using namespace Utility; -Typer::Typer(const char *string, HalfCycles delay, HalfCycles frequency, std::unique_ptr character_mapper, Delegate *delegate) : +Typer::Typer(const std::string &string, HalfCycles delay, HalfCycles frequency, std::unique_ptr character_mapper, Delegate *delegate) : frequency_(frequency), counter_(-delay), delegate_(delegate), character_mapper_(std::move(character_mapper)) { - std::size_t string_size = std::strlen(string) + 3; - string_ = (char *)std::malloc(string_size); - snprintf(string_, string_size, "%c%s%c", Typer::BeginString, string, Typer::EndString); + std::ostringstream string_stream; + string_stream << Typer::BeginString << string << Typer::EndString; + string_ = string_stream.str(); } void Typer::run_for(const HalfCycles duration) { - if(string_) { + if(string_pointer_ < string_.size()) { if(counter_ < 0 && counter_ + duration >= 0) { if(!type_next_character()) { delegate_->typer_reset(this); @@ -32,7 +31,7 @@ void Typer::run_for(const HalfCycles duration) { } counter_ += duration; - while(string_ && counter_ > frequency_) { + while(string_pointer_ < string_.size() && counter_ > frequency_) { counter_ -= frequency_; if(!type_next_character()) { delegate_->typer_reset(this); @@ -58,16 +57,10 @@ bool Typer::try_type_next_character() { } bool Typer::type_next_character() { - if(string_ == nullptr) return false; + if(string_pointer_ == string_.size()) return false; if(!try_type_next_character()) { phase_ = 0; - if(!string_[string_pointer_]) { - std::free(string_); - string_ = nullptr; - return false; - } - string_pointer_++; } else { phase_++; @@ -76,10 +69,6 @@ bool Typer::type_next_character() { return true; } -Typer::~Typer() { - std::free(string_); -} - // MARK: - Character mapper uint16_t *CharacterMapper::table_lookup_sequence_for_character(KeySequence *sequences, std::size_t length, char character) { diff --git a/Machines/Utility/Typer.hpp b/Machines/Utility/Typer.hpp index 78f3e1668..2a7f22fc7 100644 --- a/Machines/Utility/Typer.hpp +++ b/Machines/Utility/Typer.hpp @@ -10,6 +10,8 @@ #define Typer_hpp #include +#include + #include "../KeyboardMachine.hpp" #include "../../ClockReceiver/ClockReceiver.hpp" @@ -50,8 +52,7 @@ class Typer { virtual void typer_reset(Typer *typer) = 0; }; - Typer(const char *string, HalfCycles delay, HalfCycles frequency, std::unique_ptr character_mapper, Delegate *delegate); - ~Typer(); + Typer(const std::string &string, HalfCycles delay, HalfCycles frequency, std::unique_ptr character_mapper, Delegate *delegate); void run_for(const HalfCycles duration); bool type_next_character(); @@ -62,7 +63,7 @@ class Typer { const char EndString = 0x03; // i.e. ASCII end of text private: - char *string_; + std::string string_; std::size_t string_pointer_ = 0; HalfCycles frequency_; @@ -82,7 +83,7 @@ class Typer { class TypeRecipient: public Typer::Delegate { public: /// Attaches a typer to this class that will type @c string using @c character_mapper as a source. - void set_typer_for_string(const char *string, std::unique_ptr character_mapper) { + void add_typer(const std::string &string, std::unique_ptr character_mapper) { typer_.reset(new Typer(string, get_typer_delay(), get_typer_frequency(), std::move(character_mapper), this)); } @@ -90,7 +91,7 @@ class TypeRecipient: public Typer::Delegate { Provided as a hook for subclasses to implement so that external callers can install a typer without needing inside knowledge as to where the character mapper comes from. */ - virtual void set_typer_for_string(const char *string) = 0; + virtual void type_string(const std::string &) = 0; /*! Provided in order to conform to that part of the Typer::Delegate interface that goes above and diff --git a/Machines/ZX8081/ZX8081.cpp b/Machines/ZX8081/ZX8081.cpp index 34ae4f312..3061726af 100644 --- a/Machines/ZX8081/ZX8081.cpp +++ b/Machines/ZX8081/ZX8081.cpp @@ -279,7 +279,7 @@ template class ConcreteMachine: Memory::Fuzz(ram_); if(target.loading_command.length()) { - set_typer_for_string(target.loading_command.c_str()); + type_string(target.loading_command); } insert_media(target.media); @@ -293,9 +293,9 @@ template class ConcreteMachine: return !media.tapes.empty(); } - void set_typer_for_string(const char *string) override final { + void type_string(const std::string &string) override final { std::unique_ptr mapper(new CharacterMapper(is_zx81_)); - Utility::TypeRecipient::set_typer_for_string(string, std::move(mapper)); + Utility::TypeRecipient::add_typer(string, std::move(mapper)); } // Obtains the system ROMs. diff --git a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm index 9d8d25de5..fdf230241 100644 --- a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm +++ b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm @@ -190,7 +190,7 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg - (void)paste:(NSString *)paste { Utility::TypeRecipient *typeRecipient = _machine->type_recipient(); if(typeRecipient) - typeRecipient->set_typer_for_string([paste UTF8String]); + typeRecipient->type_string([paste UTF8String]); } - (void)applyTarget:(const StaticAnalyser::Target &)target { diff --git a/OSBindings/SDL/main.cpp b/OSBindings/SDL/main.cpp index 4704b8106..03d6575cd 100644 --- a/OSBindings/SDL/main.cpp +++ b/OSBindings/SDL/main.cpp @@ -441,7 +441,7 @@ int main(int argc, char *argv[]) { if(event.key.keysym.sym == SDLK_v && (SDL_GetModState()&KMOD_CTRL) && (SDL_GetModState()&KMOD_SHIFT)) { Utility::TypeRecipient *type_recipient = machine->type_recipient(); if(type_recipient) { - type_recipient->set_typer_for_string(SDL_GetClipboardText()); + type_recipient->type_string(SDL_GetClipboardText()); break; } }