cw 0.2.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.cw_config +18 -0
- data/.gitignore +10 -1
- data/LICENSE +2 -1
- data/README.md +212 -96
- data/Rakefile +15 -2
- data/VERSION +1 -1
- data/Vagrantfile +45 -0
- data/cw.gemspec +6 -1
- data/data/text/book_to_read.txt +4 -0
- data/data/text/english.txt +10000 -0
- data/example.rb +172 -106
- data/lib/cw.rb +10 -126
- data/lib/cw/alphabet.rb +53 -46
- data/lib/cw/audio_player.rb +83 -72
- data/lib/cw/book.rb +160 -185
- data/lib/cw/book_details.rb +38 -49
- data/lib/cw/cl.rb +101 -95
- data/lib/cw/common_words.rb +76 -0
- data/lib/cw/config.rb +50 -0
- data/lib/cw/current_word.rb +23 -24
- data/lib/cw/cw_dsl.rb +264 -131
- data/lib/cw/cw_encoding.rb +63 -69
- data/lib/cw/cw_stream.rb +86 -82
- data/lib/cw/cw_threads.rb +132 -22
- data/lib/cw/element.rb +60 -54
- data/lib/cw/file_details.rb +26 -11
- data/lib/cw/key_input.rb +53 -35
- data/lib/cw/numbers.rb +26 -19
- data/lib/cw/os.rb +13 -0
- data/lib/cw/play.rb +92 -0
- data/lib/cw/print.rb +102 -100
- data/lib/cw/process.rb +3 -0
- data/lib/cw/progress.rb +20 -17
- data/lib/cw/randomize.rb +56 -52
- data/lib/cw/repeat_word.rb +59 -66
- data/lib/cw/reveal.rb +32 -31
- data/lib/cw/rss.rb +52 -48
- data/lib/cw/sentence.rb +83 -76
- data/lib/cw/speak.rb +8 -4
- data/lib/cw/spoken.rb +8 -4
- data/lib/cw/str.rb +62 -30
- data/lib/cw/test_letters.rb +20 -28
- data/lib/cw/test_words.rb +25 -31
- data/lib/cw/tester.rb +219 -226
- data/lib/cw/text_helpers.rb +19 -15
- data/lib/cw/timing.rb +63 -67
- data/lib/cw/tone_generator.rb +176 -153
- data/lib/cw/tone_helpers.rb +15 -23
- data/lib/cw/voice.rb +12 -8
- data/lib/cw/words.rb +136 -106
- data/run_script_tests.rb +165 -0
- data/test/my_words.txt +1 -0
- data/test/test_common_words.rb +71 -0
- data/test/test_config.rb +98 -0
- data/test/test_current_word.rb +62 -0
- data/test/test_cw.rb +87 -120
- data/test/test_cw_threads.rb +123 -0
- data/test/test_filtering.rb +439 -0
- data/test/test_params.rb +28 -0
- data/test/test_play.rb +51 -0
- data/test/test_stream.rb +83 -83
- data/test/test_tester.rb +9 -27
- data/test/test_timing.rb +212 -0
- metadata +94 -12
- data/lib/cw/config_file.rb +0 -69
- data/lib/cw/monitor_keys.rb +0 -37
- data/lib/cw/params.rb +0 -104
data/lib/cw/alphabet.rb
CHANGED
@@ -1,66 +1,73 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
3
|
+
module CWG
|
4
4
|
|
5
|
-
class Alphabet
|
5
|
+
#class Alphabet provides alphabet generation functionality
|
6
6
|
|
7
|
-
|
8
|
-
# == Parameters:
|
9
|
-
# options::
|
10
|
-
# An optional hash containg options:
|
11
|
-
# :reverse - reverse alphabet
|
12
|
-
# :shuffle - shuffle alphabet
|
13
|
-
# :include - include only these letters of the alphabet
|
14
|
-
# :exclude - exclude these letters from the alphabet
|
7
|
+
class Alphabet
|
15
8
|
|
16
|
-
|
17
|
-
|
18
|
-
|
9
|
+
# initialize class Alphabet
|
10
|
+
# == Parameters:
|
11
|
+
# options::
|
12
|
+
# An optional hash containg options:
|
13
|
+
# :reverse - reverse alphabet
|
14
|
+
# :shuffle - shuffle alphabet
|
15
|
+
# :include - include only these letters of the alphabet
|
16
|
+
# :exclude - exclude these letters from the alphabet
|
19
17
|
|
20
|
-
|
18
|
+
def initialize(options = {})
|
19
|
+
@options = options
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
'abcdefghijklmnopqrstuvwxyz'
|
24
|
-
end
|
22
|
+
# return string containing alphabet
|
25
23
|
|
26
|
-
|
24
|
+
def alphabet
|
25
|
+
'abcdefghijklmnopqrstuvwxyz'
|
26
|
+
end
|
27
27
|
|
28
|
-
|
29
|
-
@letters.reverse! if @options[:reverse]
|
30
|
-
end
|
28
|
+
# reverse alphabet if :reverse option defined
|
31
29
|
|
32
|
-
|
30
|
+
def reverse_alphabet_maybe
|
31
|
+
@letters.reverse! if @options[:reverse]
|
32
|
+
end
|
33
33
|
|
34
|
-
|
35
|
-
@letters = @letters.split('').shuffle.join if @options[:shuffle]
|
36
|
-
end
|
34
|
+
# shuffle alphabet if :shuffle option defined
|
37
35
|
|
38
|
-
|
36
|
+
def shuffle_alphabet_maybe
|
37
|
+
unless(ENV["CW_ENV"] == "test")
|
38
|
+
@letters = @letters.split('').shuffle.join if @options[:shuffle]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# include letters passed in as string if :include defined
|
39
43
|
|
40
|
-
|
41
|
-
|
42
|
-
|
44
|
+
def include_letters
|
45
|
+
if @options[:include]
|
46
|
+
@letters = @options[:include]
|
47
|
+
end
|
43
48
|
end
|
44
|
-
end
|
45
49
|
|
46
|
-
|
50
|
+
# exclude letters passed in as string if :exclude defined
|
47
51
|
|
48
|
-
|
49
|
-
|
50
|
-
|
52
|
+
def exclude_letters
|
53
|
+
if @options[:exclude]
|
54
|
+
@letters.tr!(@options[:exclude],'')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# generate alphabet with options acted upon
|
59
|
+
# == Returns:
|
60
|
+
# alphabet or filtered alphabet
|
61
|
+
|
62
|
+
def generate
|
63
|
+
@letters = alphabet
|
64
|
+
include_letters
|
65
|
+
exclude_letters
|
66
|
+
shuffle_alphabet_maybe
|
67
|
+
reverse_alphabet_maybe
|
68
|
+
@letters.split('').join(' ')
|
51
69
|
end
|
52
|
-
end
|
53
70
|
|
54
|
-
# generate alphabet with options acted upon
|
55
|
-
# == Returns:
|
56
|
-
# alphabet or filtered alphabet
|
57
|
-
|
58
|
-
def generate
|
59
|
-
@letters = alphabet
|
60
|
-
include_letters
|
61
|
-
exclude_letters
|
62
|
-
shuffle_alphabet_maybe
|
63
|
-
reverse_alphabet_maybe
|
64
|
-
@letters.split('').join(' ')
|
65
71
|
end
|
72
|
+
|
66
73
|
end
|
data/lib/cw/audio_player.rb
CHANGED
@@ -1,95 +1,106 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
3
|
+
require 'timeout'
|
4
|
+
require 'os'
|
4
5
|
|
5
|
-
|
6
|
+
module CWG
|
6
7
|
|
7
|
-
|
8
|
-
#todo if Params.play_command
|
9
|
-
#todo @play_command = Params.play_command
|
10
|
-
#todo end
|
11
|
-
#todo end
|
8
|
+
class AudioPlayer
|
12
9
|
|
13
|
-
|
14
|
-
@tone ||= ToneGenerator.new
|
15
|
-
end
|
10
|
+
include CWG::OStest
|
16
11
|
|
17
|
-
|
18
|
-
|
19
|
-
|
12
|
+
def tone
|
13
|
+
@tone ||= ToneGenerator.new
|
14
|
+
end
|
20
15
|
|
21
|
-
|
22
|
-
|
23
|
-
|
16
|
+
def os_play_command
|
17
|
+
if is_mac?
|
18
|
+
'afplay'
|
19
|
+
elsif is_posix?
|
20
|
+
'ossplay'
|
21
|
+
else
|
22
|
+
puts 'Error - play_command required in .cw_config'
|
23
|
+
exit 1
|
24
|
+
end
|
25
|
+
end
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
def play_command
|
28
|
+
if Cfg.config["play_command"].nil?
|
29
|
+
Cfg.config.params["play_command"] =
|
30
|
+
os_play_command
|
31
|
+
end
|
32
|
+
Cfg.config["play_command"]
|
33
|
+
end
|
28
34
|
|
29
|
-
|
30
|
-
|
31
|
-
|
35
|
+
def play_filename_for_ebook2cw
|
36
|
+
@play_filename ||= File.expand_path(Cfg.config["audio_filename"], audio_dir)
|
37
|
+
end
|
32
38
|
|
33
|
-
|
34
|
-
|
35
|
-
File.open(temp_filename_for_ebook2cw, 'w') do |file|
|
36
|
-
file.print words
|
39
|
+
def audio_dir
|
40
|
+
Cfg.config["audio_dir"]
|
37
41
|
end
|
38
|
-
cl = Cl.new.cl_full(temp_filename_for_ebook2cw)
|
39
|
-
! @dry_run ? `#{cl}` : cl
|
40
|
-
File.delete(temp_filename_for_ebook2cw)
|
41
|
-
File.rename(play_filename_for_ebook2cw + '0000.mp3', play_filename_for_ebook2cw)
|
42
|
-
end
|
43
42
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
cl = Cl.new.cl_echo(words)
|
48
|
-
! @dry_run ? `#{cl}` : cl
|
49
|
-
File.rename(play_filename + '0000.mp3', play_filename)
|
50
|
-
end
|
43
|
+
def temp_filename_for_ebook2cw
|
44
|
+
File.expand_path("tempxxxx.txt", audio_dir)
|
45
|
+
end
|
51
46
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
47
|
+
def convert_book words
|
48
|
+
words = words.delete("\n")
|
49
|
+
File.open(temp_filename_for_ebook2cw, 'w') do |file|
|
50
|
+
file.print words
|
51
|
+
end
|
52
|
+
cl = Cl.new.cl_full(temp_filename_for_ebook2cw)
|
53
|
+
! @dry_run ? `#{cl}` : cl
|
54
|
+
File.delete(temp_filename_for_ebook2cw)
|
55
|
+
File.rename(play_filename_for_ebook2cw + '0000.mp3', play_filename_for_ebook2cw)
|
56
|
+
end
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
#FIXME dry_run
|
59
|
+
def convert_words_with_ebook2cw words
|
60
|
+
words = words.delete("\n")
|
61
|
+
cl = Cl.new.cl_echo(words)
|
62
|
+
! @dry_run ? `#{cl}` : cl
|
63
|
+
File.rename(play_filename + '0000.mp3', play_filename)
|
64
|
+
end
|
61
65
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
66
|
+
def convert_words words
|
67
|
+
tone.generate words unless Cfg.config["use_ebook2cw"]
|
68
|
+
convert_words_with_ebook2cw words if Cfg.config["use_ebook2cw"]
|
69
|
+
end
|
67
70
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
Process.wait(@pid)
|
72
|
-
rescue
|
73
|
-
# puts 'Error: Failed to kill pid ' + @pid.to_s
|
74
|
-
exit 1
|
71
|
+
def play_filename
|
72
|
+
return play_filename_for_ebook2cw if Cfg.config["use_ebook2cw"]
|
73
|
+
tone.play_filename
|
75
74
|
end
|
76
|
-
end
|
77
75
|
|
78
|
-
|
79
|
-
|
80
|
-
|
76
|
+
#FIXME dry_run
|
77
|
+
def play
|
78
|
+
cmd = play_command + ' ' + play_filename
|
79
|
+
@pid = ! @dry_run ? Process.spawn(cmd) : cmd
|
80
|
+
Process.waitpid(@pid)
|
81
|
+
end
|
81
82
|
|
82
|
-
|
83
|
-
|
84
|
-
|
83
|
+
def stop
|
84
|
+
begin
|
85
|
+
Process.kill(:TERM, @pid)
|
86
|
+
Process.wait(@pid)
|
87
|
+
rescue
|
88
|
+
end
|
89
|
+
end
|
85
90
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
return ps.include? tone.play_filename unless Params.use_ebook2cw
|
90
|
-
end
|
91
|
+
def play_tone tone
|
92
|
+
`#{play_command + ' ' + tone}`
|
93
|
+
end
|
91
94
|
|
92
|
-
|
93
|
-
|
95
|
+
def play_cmd_for_ps
|
96
|
+
'[' << play_command[0] << ']' << play_command[1..-1]
|
97
|
+
end
|
98
|
+
|
99
|
+
def still_playing?
|
100
|
+
cl = "ps -eo pid,args | grep #{play_cmd_for_ps}"
|
101
|
+
ps = `#{cl}`
|
102
|
+
return ps.include?("#{play_filename_for_ebook2cw}") if Cfg.config["use_ebook2cw"]
|
103
|
+
return ps.include?(tone.play_filename) unless Cfg.config["use_ebook2cw"]
|
104
|
+
end
|
94
105
|
end
|
95
106
|
end
|
data/lib/cw/book.rb
CHANGED
@@ -1,227 +1,202 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
include Tester
|
6
|
-
|
7
|
-
def initialize book_details
|
8
|
-
# prn.print_advice('Test Words')
|
9
|
-
@book_details = book_details
|
10
|
-
@print_letters = Params.print_letters
|
11
|
-
super()
|
12
|
-
read_book book_location
|
13
|
-
find_sentences
|
14
|
-
# print_book_advice
|
15
|
-
end
|
3
|
+
module CWG
|
16
4
|
|
17
|
-
|
18
|
-
def find_sentences ; sentence.find_all ; end
|
19
|
-
def raw_text ; sentence.text ; end
|
20
|
-
def read_book(book) ; sentence.read_book(book) ; end
|
21
|
-
def next_sentence ; sentence.next ; end
|
22
|
-
def change_sentence ; sentence.change ; end
|
23
|
-
def change_sentence? ; sentence.change? ; end
|
24
|
-
def repeat_sentence? ; sentence.repeat? ; end
|
25
|
-
def current_sentence ; sentence.current ; end
|
26
|
-
def current_sentence_ary ; sentence.current_to_array ; end
|
27
|
-
def sentence_index ; sentence.index ; end
|
28
|
-
def play_repeat_tone ; audio_play_tone @repeat_tone ; end
|
29
|
-
def audio_play_tone t ; audio.play_tone(t) ; end
|
30
|
-
def play_r_tone ; audio_play_tone @r_tone ; end
|
31
|
-
def complete_word? ; get_word_last_char == space ; end
|
32
|
-
def audio_stop ; audio.stop if audio_still_playing?; end
|
33
|
-
def book_location ; @book_details.book_location ; end
|
34
|
-
def print_letters? ; @print_letters && ! quit? ; end
|
35
|
-
def reset_sentence_flags ; sentence.reset_flags ; end
|
36
|
-
def audio_play_sentence ; audio.play ; end
|
37
|
-
def print_book_advice ; print.print_advice('Play Book') ; end
|
38
|
-
|
39
|
-
def convert
|
40
|
-
book = @sentence.all.join
|
41
|
-
audio.convert_book(book)
|
42
|
-
end
|
5
|
+
class Book < Tester
|
43
6
|
|
44
|
-
|
45
|
-
sentence.change_or_repeat?
|
46
|
-
end
|
7
|
+
include FileDetails
|
47
8
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
9
|
+
def initialize book_details
|
10
|
+
init_filenames
|
11
|
+
@book_details = book_details
|
12
|
+
read_book book_location
|
13
|
+
find_sentences
|
53
14
|
end
|
54
|
-
false
|
55
|
-
end
|
56
15
|
|
57
|
-
|
58
|
-
sentence.
|
59
|
-
|
16
|
+
def sentence ; @sentence ||= Sentence.new ; end
|
17
|
+
def find_sentences ; sentence.find_all ; end
|
18
|
+
def read_book(book) ; sentence.read_book(book) ; end
|
19
|
+
def play_repeat_tone ; play.audio.play_tone @repeat_tone ; end
|
20
|
+
def complete_word? ; get_word_last_char == ' ' ; end
|
21
|
+
def book_location ; @book_details.book_location ; end
|
22
|
+
def print_book_advice ; print.print_advice('Play Book') ; end
|
23
|
+
|
24
|
+
def convert
|
25
|
+
book = @sentence.all.join
|
26
|
+
play.audio.convert_book(book)
|
27
|
+
end
|
60
28
|
|
61
|
-
|
62
|
-
|
63
|
-
|
29
|
+
def change_or_repeat_sentence?
|
30
|
+
sentence.change_or_repeat?
|
31
|
+
end
|
64
32
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
33
|
+
def change_repeat_or_quit?
|
34
|
+
if(change_or_repeat_sentence? || quit?)
|
35
|
+
sentence.index += 1
|
36
|
+
write_book_progress
|
37
|
+
return true
|
38
|
+
end
|
39
|
+
false
|
40
|
+
end
|
69
41
|
|
70
|
-
|
71
|
-
|
72
|
-
|
42
|
+
def check_sentence_navigation chr
|
43
|
+
sentence.check_sentence_navigation chr
|
44
|
+
end
|
73
45
|
|
74
|
-
|
75
|
-
|
76
|
-
|
46
|
+
def progress_file
|
47
|
+
File.expand_path(@progress_file, @text_folder)
|
48
|
+
end
|
77
49
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
check_quit_key_input
|
82
|
-
break if quit?
|
83
|
-
check_sentence_navigation key_chr
|
84
|
-
build_word_maybe
|
50
|
+
def get_book_progress
|
51
|
+
sentence.read_progress progress_file
|
52
|
+
@current_sentence_index = sentence.index
|
85
53
|
end
|
86
|
-
end
|
87
54
|
|
88
|
-
|
89
|
-
|
90
|
-
if @book_details.args[:output] == :letter
|
91
|
-
stream.match_first_active_element @process_input_word # .strip #todo
|
92
|
-
else
|
93
|
-
stream.match_last_active_element @process_input_word.strip #todo
|
94
|
-
end
|
95
|
-
@process_input_word = @word_to_process = nil
|
55
|
+
def write_book_progress
|
56
|
+
sentence.write_progress progress_file
|
96
57
|
end
|
97
|
-
end
|
98
58
|
|
99
|
-
|
100
|
-
|
101
|
-
@input_word << key_chr if is_relevant_char?
|
102
|
-
if @book_details.args[:output] == :letter
|
103
|
-
move_word_to_process if is_relevant_char? #todo
|
104
|
-
else
|
105
|
-
move_word_to_process if complete_word?
|
59
|
+
def audio_play_repeat_tone_maybe
|
60
|
+
play_repeat_tone if sentence.repeat?
|
106
61
|
end
|
107
|
-
end
|
108
62
|
|
109
|
-
|
110
|
-
|
111
|
-
|
63
|
+
def process_input_word_maybe
|
64
|
+
if @word_to_process
|
65
|
+
if @book_details.args[:output] == :letter
|
66
|
+
stream.match_first_active_element @process_input_word # .strip #todo
|
67
|
+
else
|
68
|
+
stream.match_last_active_element @process_input_word.strip #todo
|
69
|
+
end
|
70
|
+
@process_input_word = @word_to_process = nil
|
71
|
+
end
|
72
|
+
end
|
112
73
|
|
113
|
-
|
114
|
-
|
115
|
-
|
74
|
+
def build_word_maybe
|
75
|
+
@input_word ||= ''
|
76
|
+
@input_word << key_chr if is_relevant_char?
|
77
|
+
if @book_details.args[:output] == :letter
|
78
|
+
move_word_to_process if is_relevant_char? #todo
|
79
|
+
else
|
80
|
+
move_word_to_process if complete_word?
|
81
|
+
end
|
82
|
+
end
|
116
83
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
start_sync
|
121
|
-
end
|
84
|
+
def compile_sentence
|
85
|
+
play.audio.convert_words(sentence.current + ' ')
|
86
|
+
end
|
122
87
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
88
|
+
def compile_and_play
|
89
|
+
compile_sentence
|
90
|
+
play.start_sync()
|
91
|
+
play.audio.play
|
92
|
+
end
|
127
93
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
94
|
+
# def change_and_kill_audio
|
95
|
+
# sentence.change
|
96
|
+
# play.stop
|
97
|
+
# end
|
98
|
+
|
99
|
+
def next_sentence_or_quit?
|
100
|
+
sleep 0.01 if play.still_playing?
|
101
|
+
sentence.next unless play.still_playing?
|
102
|
+
if change_repeat_or_quit?
|
103
|
+
play.stop
|
104
|
+
# quit #todo
|
105
|
+
sentence.change unless quit?
|
106
|
+
# change_and_kill_audio
|
107
|
+
#todo prn.newline unless quit?
|
108
|
+
return true
|
109
|
+
end
|
136
110
|
end
|
137
|
-
end
|
138
111
|
|
139
|
-
|
140
|
-
|
141
|
-
|
112
|
+
def await_next_sentence_or_quit
|
113
|
+
loop do
|
114
|
+
break if next_sentence_or_quit?
|
115
|
+
sleep 0.01
|
116
|
+
end
|
142
117
|
end
|
143
|
-
end
|
144
118
|
|
145
|
-
|
146
|
-
|
147
|
-
|
119
|
+
def quit_or_process_input?
|
120
|
+
quit? || @word_to_process
|
121
|
+
end
|
148
122
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
123
|
+
def process_letter letr
|
124
|
+
current_word.process_letter letr
|
125
|
+
sleep_char_delay letr
|
126
|
+
end
|
153
127
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
128
|
+
def print_marked_maybe
|
129
|
+
@popped = stream.pop_next_marked
|
130
|
+
if @book_details.args[:output] == :letter
|
131
|
+
print.char_result(@popped) if(@popped && ! print_letters?) #todo
|
132
|
+
else
|
133
|
+
print.results(@popped) if(@popped && ! print_letters?)
|
134
|
+
end
|
160
135
|
end
|
161
|
-
end
|
162
136
|
|
163
|
-
|
164
|
-
|
165
|
-
|
137
|
+
def print_words_for_current_sentence
|
138
|
+
print_words(sentence.current)
|
139
|
+
end
|
166
140
|
|
167
|
-
|
168
|
-
|
169
|
-
|
141
|
+
def make_sentence_index_current
|
142
|
+
@current_sentence_index = sentence.index
|
143
|
+
end
|
170
144
|
|
171
|
-
|
172
|
-
|
173
|
-
|
145
|
+
def sentence_index_current?
|
146
|
+
@current_sentence_index && (@current_sentence_index == sentence.index)
|
147
|
+
end
|
174
148
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
149
|
+
def play_sentences_until_quit
|
150
|
+
get_book_progress
|
151
|
+
|
152
|
+
loop do
|
153
|
+
check_sentence_count
|
154
|
+
sync_with_print
|
155
|
+
audio_play_repeat_tone_maybe
|
156
|
+
sentence.reset_flags
|
157
|
+
compile_and_play
|
158
|
+
await_next_sentence_or_quit
|
159
|
+
break if quit?
|
160
|
+
end
|
161
|
+
print_words_exit
|
162
|
+
end
|
188
163
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
reset_stdin
|
194
|
-
|
164
|
+
def check_sentence_count
|
165
|
+
if @book_details.session_finished?
|
166
|
+
play.stop
|
167
|
+
quit
|
168
|
+
# reset_stdin
|
169
|
+
# kill_threads
|
170
|
+
end
|
195
171
|
end
|
196
|
-
end
|
197
172
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
173
|
+
def print_sentences_until_quit
|
174
|
+
loop do
|
175
|
+
check_sentence_count
|
176
|
+
sync_with_play
|
177
|
+
break if quit?
|
178
|
+
sync_with_audio_player
|
179
|
+
print_words_for_current_sentence
|
180
|
+
end
|
206
181
|
end
|
207
|
-
end
|
208
182
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
183
|
+
def play_sentences_thread
|
184
|
+
play_sentences_until_quit
|
185
|
+
print "\n\rplay has quit " if @debug
|
186
|
+
exit!
|
187
|
+
end
|
214
188
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
189
|
+
def print_sentences_thread
|
190
|
+
print_sentences_until_quit
|
191
|
+
print "\n\rprint has quit " if @debug
|
192
|
+
exit!
|
193
|
+
end
|
220
194
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
195
|
+
def thread_processes
|
196
|
+
[:monitor_keys_thread,
|
197
|
+
:play_sentences_thread,
|
198
|
+
:print_sentences_thread
|
199
|
+
]
|
200
|
+
end
|
225
201
|
end
|
226
|
-
|
227
202
|
end
|