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.
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<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 {

View File

@ -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<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 {

View File

@ -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<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 {

View File

@ -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<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

View File

@ -8,23 +8,22 @@
#include "Typer.hpp"
#include <cstdlib>
#include <cstring>
#include <sstream>
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),
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) {

View File

@ -10,6 +10,8 @@
#define Typer_hpp
#include <memory>
#include <string>
#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<CharacterMapper> character_mapper, Delegate *delegate);
~Typer();
Typer(const std::string &string, HalfCycles delay, HalfCycles frequency, std::unique_ptr<CharacterMapper> 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<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));
}
@ -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

View File

@ -279,7 +279,7 @@ template<bool is_zx81> 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<bool is_zx81> 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<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.

View File

@ -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 {

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)) {
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;
}
}