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