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:
parent
5f8bb92f36
commit
bd45c1c963
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
Loading…
x
Reference in New Issue
Block a user