1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-12 15:31:09 +00:00

Moves the typer functionality behind a functionality-based naming scheme, eliminates its C-style memory management.

This commit is contained in:
Thomas Harte 2017-12-29 15:26:03 -05:00
parent 76af0228dd
commit d5b1a9d918
9 changed files with 31 additions and 41 deletions

View File

@ -902,7 +902,7 @@ class ConcreteMachine:
// Type whatever is required. // Type whatever is required.
if(target.loading_command.length()) { if(target.loading_command.length()) {
set_typer_for_string(target.loading_command.c_str()); type_string(target.loading_command);
} }
insert_media(target.media); insert_media(target.media);
@ -953,9 +953,9 @@ class ConcreteMachine:
// MARK: - Keyboard // MARK: - Keyboard
void set_typer_for_string(const char *string) override final { void type_string(const std::string &string) override final {
std::unique_ptr<CharacterMapper> mapper(new CharacterMapper()); std::unique_ptr<CharacterMapper> 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 { HalfCycles get_typer_delay() override final {

View File

@ -348,7 +348,7 @@ class ConcreteMachine:
void configure_as_target(const StaticAnalyser::Target &target) override final { void configure_as_target(const StaticAnalyser::Target &target) override final {
if(target.loading_command.length()) { if(target.loading_command.length()) {
set_typer_for_string(target.loading_command.c_str()); type_string(target.loading_command);
} }
switch(target.vic20.memory_model) { switch(target.vic20.memory_model) {
@ -653,9 +653,9 @@ class ConcreteMachine:
m6502_.set_irq_line(keyboard_via_.get_interrupt_line()); 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<CharacterMapper> mapper(new CharacterMapper()); std::unique_ptr<CharacterMapper> 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 { void tape_did_change_input(Storage::Tape::BinaryTapePlayer *tape) override final {

View File

@ -115,7 +115,7 @@ class ConcreteMachine:
void configure_as_target(const StaticAnalyser::Target &target) override final { void configure_as_target(const StaticAnalyser::Target &target) override final {
if(target.loading_command.length()) { 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) { if(target.acorn.should_shift_restart) {
@ -414,9 +414,9 @@ class ConcreteMachine:
return Cycles(625*128*2); // accept a new character every two frames 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<CharacterMapper> mapper(new CharacterMapper()); std::unique_ptr<CharacterMapper> 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 { KeyboardMapper &get_keyboard_mapper() override {

View File

@ -262,7 +262,7 @@ class ConcreteMachine:
} }
if(target.loading_command.length()) { 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) { if(target.oric.use_atmos_rom) {
@ -407,9 +407,9 @@ class ConcreteMachine:
} }
// for Utility::TypeRecipient::Delegate // 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<CharacterMapper> mapper(new CharacterMapper); std::unique_ptr<CharacterMapper> mapper(new CharacterMapper);
Utility::TypeRecipient::set_typer_for_string(string, std::move(mapper)); Utility::TypeRecipient::add_typer(string, std::move(mapper));
} }
// for Microdisc::Delegate // for Microdisc::Delegate

View File

@ -8,23 +8,22 @@
#include "Typer.hpp" #include "Typer.hpp"
#include <cstdlib> #include <sstream>
#include <cstring>
using namespace Utility; using namespace Utility;
Typer::Typer(const char *string, HalfCycles delay, HalfCycles frequency, std::unique_ptr<CharacterMapper> character_mapper, Delegate *delegate) : Typer::Typer(const std::string &string, HalfCycles delay, HalfCycles frequency, std::unique_ptr<CharacterMapper> character_mapper, Delegate *delegate) :
frequency_(frequency), frequency_(frequency),
counter_(-delay), counter_(-delay),
delegate_(delegate), delegate_(delegate),
character_mapper_(std::move(character_mapper)) { character_mapper_(std::move(character_mapper)) {
std::size_t string_size = std::strlen(string) + 3; std::ostringstream string_stream;
string_ = (char *)std::malloc(string_size); string_stream << Typer::BeginString << string << Typer::EndString;
snprintf(string_, string_size, "%c%s%c", Typer::BeginString, string, Typer::EndString); string_ = string_stream.str();
} }
void Typer::run_for(const HalfCycles duration) { void Typer::run_for(const HalfCycles duration) {
if(string_) { if(string_pointer_ < string_.size()) {
if(counter_ < 0 && counter_ + duration >= 0) { if(counter_ < 0 && counter_ + duration >= 0) {
if(!type_next_character()) { if(!type_next_character()) {
delegate_->typer_reset(this); delegate_->typer_reset(this);
@ -32,7 +31,7 @@ void Typer::run_for(const HalfCycles duration) {
} }
counter_ += duration; counter_ += duration;
while(string_ && counter_ > frequency_) { while(string_pointer_ < string_.size() && counter_ > frequency_) {
counter_ -= frequency_; counter_ -= frequency_;
if(!type_next_character()) { if(!type_next_character()) {
delegate_->typer_reset(this); delegate_->typer_reset(this);
@ -58,16 +57,10 @@ bool Typer::try_type_next_character() {
} }
bool Typer::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()) { if(!try_type_next_character()) {
phase_ = 0; phase_ = 0;
if(!string_[string_pointer_]) {
std::free(string_);
string_ = nullptr;
return false;
}
string_pointer_++; string_pointer_++;
} else { } else {
phase_++; phase_++;
@ -76,10 +69,6 @@ bool Typer::type_next_character() {
return true; return true;
} }
Typer::~Typer() {
std::free(string_);
}
// MARK: - Character mapper // MARK: - Character mapper
uint16_t *CharacterMapper::table_lookup_sequence_for_character(KeySequence *sequences, std::size_t length, char character) { uint16_t *CharacterMapper::table_lookup_sequence_for_character(KeySequence *sequences, std::size_t length, char character) {

View File

@ -10,6 +10,8 @@
#define Typer_hpp #define Typer_hpp
#include <memory> #include <memory>
#include <string>
#include "../KeyboardMachine.hpp" #include "../KeyboardMachine.hpp"
#include "../../ClockReceiver/ClockReceiver.hpp" #include "../../ClockReceiver/ClockReceiver.hpp"
@ -50,8 +52,7 @@ class Typer {
virtual void typer_reset(Typer *typer) = 0; virtual void typer_reset(Typer *typer) = 0;
}; };
Typer(const char *string, HalfCycles delay, HalfCycles frequency, std::unique_ptr<CharacterMapper> character_mapper, Delegate *delegate); Typer(const std::string &string, HalfCycles delay, HalfCycles frequency, std::unique_ptr<CharacterMapper> character_mapper, Delegate *delegate);
~Typer();
void run_for(const HalfCycles duration); void run_for(const HalfCycles duration);
bool type_next_character(); bool type_next_character();
@ -62,7 +63,7 @@ class Typer {
const char EndString = 0x03; // i.e. ASCII end of text const char EndString = 0x03; // i.e. ASCII end of text
private: private:
char *string_; std::string string_;
std::size_t string_pointer_ = 0; std::size_t string_pointer_ = 0;
HalfCycles frequency_; HalfCycles frequency_;
@ -82,7 +83,7 @@ class Typer {
class TypeRecipient: public Typer::Delegate { class TypeRecipient: public Typer::Delegate {
public: public:
/// Attaches a typer to this class that will type @c string using @c character_mapper as a source. /// 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<CharacterMapper> character_mapper) { void add_typer(const std::string &string, std::unique_ptr<CharacterMapper> character_mapper) {
typer_.reset(new Typer(string, get_typer_delay(), get_typer_frequency(), std::move(character_mapper), this)); 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 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. 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 Provided in order to conform to that part of the Typer::Delegate interface that goes above and

View File

@ -279,7 +279,7 @@ template<bool is_zx81> class ConcreteMachine:
Memory::Fuzz(ram_); Memory::Fuzz(ram_);
if(target.loading_command.length()) { if(target.loading_command.length()) {
set_typer_for_string(target.loading_command.c_str()); type_string(target.loading_command);
} }
insert_media(target.media); insert_media(target.media);
@ -293,9 +293,9 @@ template<bool is_zx81> class ConcreteMachine:
return !media.tapes.empty(); 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<CharacterMapper> mapper(new CharacterMapper(is_zx81_)); std::unique_ptr<CharacterMapper> 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. // Obtains the system ROMs.

View File

@ -190,7 +190,7 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg
- (void)paste:(NSString *)paste { - (void)paste:(NSString *)paste {
Utility::TypeRecipient *typeRecipient = _machine->type_recipient(); Utility::TypeRecipient *typeRecipient = _machine->type_recipient();
if(typeRecipient) if(typeRecipient)
typeRecipient->set_typer_for_string([paste UTF8String]); typeRecipient->type_string([paste UTF8String]);
} }
- (void)applyTarget:(const StaticAnalyser::Target &)target { - (void)applyTarget:(const StaticAnalyser::Target &)target {

View File

@ -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)) { if(event.key.keysym.sym == SDLK_v && (SDL_GetModState()&KMOD_CTRL) && (SDL_GetModState()&KMOD_SHIFT)) {
Utility::TypeRecipient *type_recipient = machine->type_recipient(); Utility::TypeRecipient *type_recipient = machine->type_recipient();
if(type_recipient) { if(type_recipient) {
type_recipient->set_typer_for_string(SDL_GetClipboardText()); type_recipient->type_string(SDL_GetClipboardText());
break; break;
} }
} }