1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-03-06 01:30:19 +00:00

Adds append and generally seeks to improve string accumulation.

This commit is contained in:
Thomas Harte 2020-02-29 17:34:21 -05:00
parent 5f8bb92f36
commit bd45c1c963
2 changed files with 64 additions and 22 deletions

View File

@ -8,8 +8,6 @@
#include "Typer.hpp" #include "Typer.hpp"
#include <sstream>
using namespace Utility; using namespace Utility;
Typer::Typer(const std::string &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) :
@ -17,33 +15,69 @@ Typer::Typer(const std::string &string, HalfCycles delay, HalfCycles frequency,
counter_(-delay), counter_(-delay),
delegate_(delegate), delegate_(delegate),
character_mapper_(std::move(character_mapper)) { character_mapper_(std::move(character_mapper)) {
std::ostringstream string_stream; // Retain only those characters that actually map to something.
string_stream << Typer::BeginString << string << Typer::EndString; if(sequence_for_character(Typer::BeginString)) {
string_ = string_stream.str(); string_ += Typer::BeginString;
}
if(sequence_for_character(Typer::EndString)) {
string_ += Typer::EndString;
}
append(string);
} }
void Typer::run_for(const HalfCycles duration) { void Typer::run_for(const HalfCycles duration) {
if(string_pointer_ < string_.size()) { if(string_pointer_ >= string_.size()) {
if(counter_ < 0 && counter_ + duration >= 0) { return;
if(!type_next_character()) { }
delegate_->typer_reset(this);
}
}
counter_ += duration; if(counter_ < 0 && counter_ + duration >= 0) {
while(string_pointer_ < string_.size() && counter_ > frequency_) { if(!type_next_character()) {
counter_ -= frequency_; delegate_->typer_reset(this);
if(!type_next_character()) { }
delegate_->typer_reset(this); }
}
counter_ += duration;
while(string_pointer_ < string_.size() && counter_ > frequency_) {
counter_ -= frequency_;
if(!type_next_character()) {
delegate_->typer_reset(this);
} }
} }
} }
bool Typer::try_type_next_character() { void Typer::append(const std::string &string) {
uint16_t *sequence = character_mapper_->sequence_for_character(string_[string_pointer_]); // Remove any characters that are already completely done;
// otherwise things may accumulate here indefinitely.
string_.erase(string_.begin(), string_.begin() + ssize_t(string_pointer_));
string_pointer_ = 0;
// If the final character in the string is not Typer::EndString
// then this machine doesn't need Begin and End, so don't worry about it.
ssize_t insertion_position = ssize_t(string_.size());
if(string_.back() == Typer::EndString) --insertion_position;
string_.reserve(string_.size() + string.size());
for(const char c : string) {
if(sequence_for_character(c)) {
string_.insert(string_.begin() + insertion_position, c);
++insertion_position;
}
}
}
const uint16_t *Typer::sequence_for_character(char c) const {
const uint16_t *const sequence = character_mapper_->sequence_for_character(c);
if(!sequence || sequence[0] == KeyboardMachine::MappedMachine::KeyNotMapped) { if(!sequence || sequence[0] == KeyboardMachine::MappedMachine::KeyNotMapped) {
return nullptr;
}
return sequence;
}
bool Typer::try_type_next_character() {
const uint16_t *const sequence = sequence_for_character(string_[string_pointer_]);
if(!sequence) {
return false; return false;
} }
@ -61,10 +95,10 @@ bool Typer::type_next_character() {
if(!try_type_next_character()) { if(!try_type_next_character()) {
phase_ = 0; phase_ = 0;
string_pointer_++; ++string_pointer_;
if(string_pointer_ == string_.size()) return false; if(string_pointer_ == string_.size()) return false;
} else { } else {
phase_++; ++phase_;
} }
return true; return true;

View File

@ -51,14 +51,21 @@ class Typer {
public: public:
class Delegate: public KeyboardMachine::KeyActions { class Delegate: public KeyboardMachine::KeyActions {
public: public:
/// Informs the delegate that this typer has reached the end of its content.
virtual void typer_reset(Typer *typer) = 0; virtual void typer_reset(Typer *typer) = 0;
}; };
Typer(const std::string &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);
/// Advances for @c duration.
void run_for(const HalfCycles duration); void run_for(const HalfCycles duration);
/// Types the next character now, if there is one.
/// @returns @c true if there was anything left to type; @c false otherwise.
bool type_next_character(); bool type_next_character();
bool is_completed();
/// Adds the contents of @c str to the end of the current string.
void append(const std::string &str);
const char BeginString = 0x02; // i.e. ASCII start of text const char BeginString = 0x02; // i.e. ASCII start of text
const char EndString = 0x03; // i.e. ASCII end of text const char EndString = 0x03; // i.e. ASCII end of text
@ -75,6 +82,7 @@ class Typer {
std::unique_ptr<CharacterMapper> character_mapper_; std::unique_ptr<CharacterMapper> character_mapper_;
bool try_type_next_character(); bool try_type_next_character();
const uint16_t *sequence_for_character(char) const;
}; };
/*! /*!