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 <sstream>
using namespace Utility;
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),
delegate_(delegate),
character_mapper_(std::move(character_mapper)) {
std::ostringstream string_stream;
string_stream << Typer::BeginString << string << Typer::EndString;
string_ = string_stream.str();
// Retain only those characters that actually map to something.
if(sequence_for_character(Typer::BeginString)) {
string_ += Typer::BeginString;
}
if(sequence_for_character(Typer::EndString)) {
string_ += Typer::EndString;
}
append(string);
}
void Typer::run_for(const HalfCycles duration) {
if(string_pointer_ < string_.size()) {
if(counter_ < 0 && counter_ + duration >= 0) {
if(!type_next_character()) {
delegate_->typer_reset(this);
}
}
if(string_pointer_ >= string_.size()) {
return;
}
counter_ += duration;
while(string_pointer_ < string_.size() && counter_ > frequency_) {
counter_ -= frequency_;
if(!type_next_character()) {
delegate_->typer_reset(this);
}
if(counter_ < 0 && counter_ + duration >= 0) {
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() {
uint16_t *sequence = character_mapper_->sequence_for_character(string_[string_pointer_]);
void Typer::append(const std::string &string) {
// 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) {
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;
}
@ -61,10 +95,10 @@ bool Typer::type_next_character() {
if(!try_type_next_character()) {
phase_ = 0;
string_pointer_++;
++string_pointer_;
if(string_pointer_ == string_.size()) return false;
} else {
phase_++;
++phase_;
}
return true;

View File

@ -51,14 +51,21 @@ class Typer {
public:
class Delegate: public KeyboardMachine::KeyActions {
public:
/// Informs the delegate that this typer has reached the end of its content.
virtual void typer_reset(Typer *typer) = 0;
};
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);
/// 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 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 EndString = 0x03; // i.e. ASCII end of text
@ -75,6 +82,7 @@ class Typer {
std::unique_ptr<CharacterMapper> character_mapper_;
bool try_type_next_character();
const uint16_t *sequence_for_character(char) const;
};
/*!