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 "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;
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
Loading…
x
Reference in New Issue
Block a user