1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-02 16:04:59 +00:00
CLK/Machines/Utility/Typer.cpp

91 lines
2.2 KiB
C++
Raw Normal View History

//
// Typer.cpp
// Clock Signal
//
// Created by Thomas Harte on 19/06/2016.
// Copyright © 2016 Thomas Harte. All rights reserved.
//
#include "Typer.hpp"
#include <cstdlib>
#include <cstring>
using namespace Utility;
Typer::Typer(const char *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);
}
void Typer::run_for(const HalfCycles duration) {
2017-03-26 18:34:47 +00:00
if(string_) {
if(counter_ < 0 && counter_ + duration >= 0) {
if(!type_next_character()) {
delegate_->typer_reset(this);
}
}
counter_ += duration;
2017-03-26 18:34:47 +00:00
while(string_ && counter_ > frequency_) {
counter_ -= frequency_;
2017-03-26 18:34:47 +00:00
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_]);
if(!sequence || sequence[0] == KeyboardMachine::Machine::KeyNotMapped) {
return false;
}
if(!phase_) delegate_->clear_all_keys();
else {
delegate_->set_key_state(sequence[phase_ - 1], true);
return sequence[phase_] != KeyboardMachine::Machine::KeyEndSequence;
}
return true;
}
2017-03-26 18:34:47 +00:00
bool Typer::type_next_character() {
if(string_ == nullptr) return false;
if(!try_type_next_character()) {
phase_ = 0;
2017-03-26 18:34:47 +00:00
if(!string_[string_pointer_]) {
std::free(string_);
string_ = nullptr;
return false;
}
string_pointer_++;
2017-03-26 18:34:47 +00:00
} else {
phase_++;
}
return true;
}
2017-03-26 18:34:47 +00:00
Typer::~Typer() {
std::free(string_);
}
// MARK: - Character mapper
uint16_t *CharacterMapper::table_lookup_sequence_for_character(KeySequence *sequences, std::size_t length, char character) {
std::size_t ucharacter = static_cast<std::size_t>((unsigned char)character);
if(ucharacter > (length / sizeof(KeySequence))) return nullptr;
if(sequences[ucharacter][0] == KeyboardMachine::Machine::KeyNotMapped) return nullptr;
return sequences[ucharacter];
}