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:
parent
76af0228dd
commit
d5b1a9d918
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user