lib/cw/tester.rb
# encoding: utf-8
module CW
class Tester
def quit ; Cfg.config.params["quit"] = true ; end
def quit? ; Cfg.get_param("quit") ; end
def exit! ; Cfg.config.params["exit"] = true ; end
def exit? ; Cfg.get_param("exit") ; end
def print ; @print ||= Print.new ; end
def play ; @play ||= Play.new(@words) ; end
def timing ; @timing ||= Timing.new ; end
# def audio ; @audio ||= AudioPlayer.new ; end
def kill_threads ; @threads.kill ; end
# def start_sync ; @start_sync = true ; end
def get_key_input ; key_input.read ; end
def key_chr ; key_input.char ; end
def key_input ; @key_input ||= KeyInput.new ; end
def is_relevant_char? ; key_input.is_relevant_char? ; end
def stream ; @stream ||= Stream.new ; end
def reset_stdin ; key_input.reset_stdin ; end
def current_word ; @current_word ||= CurrentWord.new ; end
def init_char_timer ; timing.init_char_timer ; end
def do_events
sleep 0.005
end
def process_letters letr
loop do
do_events
if self.class == Book
process_space_maybe(letr) unless @book_details.args[:output] == :letter
process_word_maybe
break if change_repeat_or_quit?
break if timing.char_delay_timeout?
else
process_space_maybe(letr) if(self.class == TestWords)
process_space_maybe(letr) if(self.class == Reveal)
process_word_maybe
break if timing.char_delay_timeout?
end
end
end
def process_words words
book_class = (self.class == Book)
(words.to_s + ' ').each_char do |letr|
process_letter letr
if book_class
stream.add_char(letr) if @book_details.args[:output] == :letter
else
stream.add_char(letr) if(self.class == TestLetters)
end
process_letters letr
print.success letr if print_letters?
break if(book_class && change_repeat_or_quit?)
break if ((! book_class) && quit?)
end
end
def print_words words
timing.init_char_timer
process_words words
end
def process_word_maybe
print_marked_maybe
process_input_word_maybe
end
def print_words_until_quit
@failed = false
sync_with_audio_player
print_words @words
print_words_exit
quit
end
def print_failed_exit_words
until stream.stream_empty?
print.fail stream.pop[:value]
end
print.reset
end
def finish?
return true if stream.stream_empty?
return true if timing.print_words_timeout?
return true if quit?
false
end
def failed?
@failed
end
def failed!
@failed = true
end
def print_words_exit
return if Cfg.config["print_letters"]
timing.init_print_words_timeout
loop do
process_word_maybe
if finish?
break
end
sleep 0.01
end
failed! unless stream.stream_empty?
print_failed_exit_words unless self.class == RepeatWord
end
def audio_stop
play.stop if play.still_playing?
end
def sync_with_audio_player
wait_for_start_sync
play.wait_player_startup_delay
end
def push_letter_to_current_word letr
current_word.push_letter letr
end
def get_word_last_char
@input_word.split(//).last(1).first
end
def word_proc_timeout(arg = :status)
if arg == :init
@wp_timeout = Time.now + 5
else
return true if(Time.now > @wp_timeout)
end
return false
end
def wait_for_no_word_process
word_proc_timeout(:init)
while @word_to_process
sleep 0.01
if word_proc_timeout
# Kernel.exit(1)
end
end
end
def complete_word?
get_word_last_char == ' '
end
def move_word_to_process
wait_for_no_word_process
@process_input_word, @input_word = @input_word, ''
@word_to_process = true
end
def sleep_char_delay letr
timing.append_char_delay letr, Cfg.config["wpm"], Cfg.config["effective_wpm"]
end
def wait_for_start_sync
timeout = Time.now + 5
until play.start_sync?
sleep 0.001
break if quit?
if timeout < Time.now
exit!
Kernel.exit 1
end
end
end
def process_space_maybe letr
if letr == ' '
stream.push current_word.strip
current_word.clear
letr.clear
print.success ' ' if print_letters?
end
end
def print_letters?
Cfg.config["print_letters"] #&& ! quit?
end
def sync_with_play
loop do
break if sentence_index_current?
break if quit?
sleep 0.015
end
end
def sync_with_print
loop do
make_sentence_index_current if ! sentence_index_current?
break if sentence_index_current?
break if quit?
sleep 0.015
break
end
end
def play_words_thread
# p @words
play.play_words_until_quit
print "\n\rplay has quit " if @debug
exit!
end
def print_words_thread
print_words_until_quit
print "\n\rprint has quit " if @debug
exit!
end
def monitor_keys_thread
monitor_keys
@key_input = nil
print "\n\rmonitor keys has quit " if @debug
exit!
end
def cw_threads
@cw_threads ||= Threads.new(self, thread_processes)
end
def thread_processes
[
:monitor_keys_thread,
:play_words_thread,
:print_words_thread
]
end
def run words
@words = words
cw_threads.run
@play = nil
reset_stdin
print.newline
end
def monitor_keys
loop do
key_input.read
break if quit_key_input?
break if quit?
break if exit?
check_sentence_navigation(key_chr) if self.class == Book
build_word_maybe
end
end
def quit_key_input?
if key_input.quit_input?
play.stop
exit!
quit
play.stop
true
end
end
end
end