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/tester.rb
CHANGED
@@ -1,275 +1,268 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
module
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
def add_space words
|
29
|
-
str = ''
|
30
|
-
words.to_array.collect { |word| str << word + space}
|
31
|
-
str
|
32
|
-
end
|
33
|
-
|
34
|
-
def audio_play
|
35
|
-
audio.convert_words add_space @words
|
36
|
-
start_sync
|
37
|
-
audio.play
|
38
|
-
end
|
39
|
-
|
40
|
-
def play_words_until_quit
|
41
|
-
audio_play
|
42
|
-
play_words_exit unless @print_letters
|
43
|
-
end
|
44
|
-
|
45
|
-
def play_words_exit
|
46
|
-
timing.init_play_words_timeout
|
47
|
-
loop do
|
48
|
-
break if quit?
|
49
|
-
break if timing.play_words_timeout?
|
50
|
-
sleep 0.01
|
3
|
+
module CWG
|
4
|
+
|
5
|
+
class Tester
|
6
|
+
|
7
|
+
def quit ; Cfg.config.params["quit"] = true ; end
|
8
|
+
def quit? ; Cfg.get_param("quit") ; end
|
9
|
+
def exit! ; Cfg.config.params["exit"] = true ; end
|
10
|
+
def exit? ; Cfg.get_param("exit") ; end
|
11
|
+
def print ; @print ||= Print.new ; end
|
12
|
+
def play ; @play ||= Play.new(@words) ; end
|
13
|
+
def timing ; @timing ||= Timing.new ; end
|
14
|
+
# def audio ; @audio ||= AudioPlayer.new ; end
|
15
|
+
def kill_threads ; @threads.kill ; end
|
16
|
+
# def start_sync ; @start_sync = true ; end
|
17
|
+
def get_key_input ; key_input.read ; end
|
18
|
+
def key_chr ; key_input.char ; end
|
19
|
+
def key_input ; @key_input ||= KeyInput.new ; end
|
20
|
+
def is_relevant_char? ; key_input.is_relevant_char? ; end
|
21
|
+
def stream ; @stream ||= CwStream.new ; end
|
22
|
+
def reset_stdin ; key_input.reset_stdin ; end
|
23
|
+
def current_word ; @current_word ||= CurrentWord.new ; end
|
24
|
+
def init_char_timer ; timing.init_char_timer ; end
|
25
|
+
|
26
|
+
def do_events
|
27
|
+
sleep 0.005
|
51
28
|
end
|
52
|
-
end
|
53
29
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
process_space_maybe(letr) if(self.class == Reveal)
|
69
|
-
process_word_maybe
|
70
|
-
break if timing.char_delay_timeout?
|
30
|
+
def process_letters letr
|
31
|
+
loop do
|
32
|
+
do_events
|
33
|
+
if self.class == Book
|
34
|
+
process_space_maybe(letr) unless @book_details.args[:output] == :letter
|
35
|
+
process_word_maybe
|
36
|
+
break if change_repeat_or_quit?
|
37
|
+
break if timing.char_delay_timeout?
|
38
|
+
else
|
39
|
+
process_space_maybe(letr) if(self.class == TestWords)
|
40
|
+
process_space_maybe(letr) if(self.class == Reveal)
|
41
|
+
process_word_maybe
|
42
|
+
break if timing.char_delay_timeout?
|
43
|
+
end
|
71
44
|
end
|
72
45
|
end
|
73
|
-
end
|
74
46
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
47
|
+
def process_words words
|
48
|
+
book_class = (self.class == Book)
|
49
|
+
(words.to_s + ' ').each_char do |letr|
|
50
|
+
process_letter letr
|
51
|
+
if book_class
|
52
|
+
stream.add_char(letr) if @book_details.args[:output] == :letter
|
53
|
+
else
|
54
|
+
stream.add_char(letr) if(self.class == TestLetters)
|
55
|
+
end
|
56
|
+
process_letters letr
|
57
|
+
print.success letr if print_letters?
|
58
|
+
break if(book_class && change_repeat_or_quit?)
|
59
|
+
break if ((! book_class) && quit?)
|
83
60
|
end
|
84
|
-
process_letters letr
|
85
|
-
print.success letr if print_letters?
|
86
|
-
break if(book_class && change_repeat_or_quit?)
|
87
|
-
break if ((! book_class) && quit?)
|
88
61
|
end
|
89
|
-
end
|
90
62
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
63
|
+
def print_words words
|
64
|
+
timing.init_char_timer
|
65
|
+
process_words words
|
66
|
+
end
|
95
67
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
68
|
+
def process_word_maybe
|
69
|
+
print_marked_maybe
|
70
|
+
process_input_word_maybe
|
71
|
+
end
|
100
72
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
73
|
+
def print_words_until_quit
|
74
|
+
@failed = false
|
75
|
+
sync_with_audio_player
|
76
|
+
print_words @words
|
77
|
+
print_words_exit
|
78
|
+
quit
|
79
|
+
end
|
105
80
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
81
|
+
def print_failed_exit_words
|
82
|
+
until stream.stream_empty?
|
83
|
+
print.fail stream.pop[:value]
|
84
|
+
end
|
85
|
+
print.reset
|
86
|
+
end
|
111
87
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
88
|
+
def finish?
|
89
|
+
return true if stream.stream_empty?
|
90
|
+
return true if timing.print_words_timeout?
|
91
|
+
return true if quit?
|
92
|
+
false
|
93
|
+
end
|
118
94
|
|
119
|
-
|
120
|
-
|
121
|
-
print.fail stream.pop[:value]
|
95
|
+
def failed?
|
96
|
+
@failed
|
122
97
|
end
|
123
|
-
end
|
124
98
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
process_word_maybe
|
129
|
-
break if stream.stream_empty?
|
130
|
-
break if timing.print_words_timeout?
|
131
|
-
break if quit?
|
132
|
-
sleep 0.01
|
133
|
-
end
|
134
|
-
@failed = true unless stream.stream_empty?
|
135
|
-
print_failed_exit_words unless @repeat_word
|
136
|
-
end
|
99
|
+
def failed!
|
100
|
+
@failed = true
|
101
|
+
end
|
137
102
|
|
138
|
-
|
139
|
-
|
140
|
-
|
103
|
+
def print_words_exit
|
104
|
+
return if Cfg.config["print_letters"]
|
105
|
+
timing.init_print_words_timeout
|
106
|
+
loop do
|
107
|
+
process_word_maybe
|
108
|
+
if finish?
|
109
|
+
break
|
110
|
+
end
|
111
|
+
sleep 0.01
|
112
|
+
end
|
113
|
+
failed! unless stream.stream_empty?
|
114
|
+
print_failed_exit_words unless self.class == RepeatWord
|
115
|
+
end
|
141
116
|
|
142
|
-
|
143
|
-
|
144
|
-
|
117
|
+
def audio_stop
|
118
|
+
play.stop if play.still_playing?
|
119
|
+
end
|
145
120
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
121
|
+
def sync_with_audio_player
|
122
|
+
wait_for_start_sync
|
123
|
+
play.wait_player_startup_delay
|
124
|
+
end
|
150
125
|
|
151
|
-
|
152
|
-
|
153
|
-
quit
|
154
|
-
global_quit
|
155
|
-
audio_stop
|
156
|
-
true
|
126
|
+
def push_letter_to_current_word letr
|
127
|
+
current_word.push_letter letr
|
157
128
|
end
|
158
|
-
end
|
159
129
|
|
160
|
-
|
161
|
-
|
162
|
-
|
130
|
+
def get_word_last_char
|
131
|
+
@input_word.split(//).last(1).first
|
132
|
+
end
|
163
133
|
|
164
|
-
|
165
|
-
|
166
|
-
|
134
|
+
def word_proc_timeout(arg = :status)
|
135
|
+
if arg == :init
|
136
|
+
@wp_timeout = Time.now + 5
|
137
|
+
else
|
138
|
+
return true if(Time.now > @wp_timeout)
|
139
|
+
end
|
140
|
+
return false
|
141
|
+
end
|
167
142
|
|
168
|
-
|
169
|
-
|
170
|
-
@
|
171
|
-
|
172
|
-
|
143
|
+
def wait_for_no_word_process
|
144
|
+
word_proc_timeout(:init)
|
145
|
+
while @word_to_process
|
146
|
+
sleep 0.01
|
147
|
+
if word_proc_timeout
|
148
|
+
# Kernel.exit(1)
|
149
|
+
end
|
150
|
+
end
|
173
151
|
end
|
174
|
-
return false
|
175
|
-
end
|
176
152
|
|
177
|
-
|
178
|
-
|
179
|
-
while @word_to_process
|
180
|
-
sleep 0.01
|
181
|
-
exit(1) if word_proc_timeout
|
153
|
+
def complete_word?
|
154
|
+
get_word_last_char == ' '
|
182
155
|
end
|
183
|
-
end
|
184
156
|
|
185
|
-
|
186
|
-
|
187
|
-
|
157
|
+
def move_word_to_process
|
158
|
+
wait_for_no_word_process
|
159
|
+
@process_input_word, @input_word = @input_word, ''
|
160
|
+
@word_to_process = true
|
161
|
+
end
|
188
162
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
@word_to_process = true
|
193
|
-
end
|
163
|
+
def sleep_char_delay letr
|
164
|
+
timing.append_char_delay letr, Cfg.config["wpm"], Cfg.config["effective_wpm"]
|
165
|
+
end
|
194
166
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
167
|
+
def wait_for_start_sync
|
168
|
+
timeout = Time.now + 5
|
169
|
+
until play.start_sync?
|
170
|
+
sleep 0.001
|
171
|
+
break if quit?
|
172
|
+
if timeout < Time.now
|
173
|
+
exit!
|
174
|
+
Kernel.exit 1
|
175
|
+
end
|
176
|
+
end
|
201
177
|
end
|
202
|
-
end
|
203
178
|
|
204
|
-
|
205
|
-
|
206
|
-
|
179
|
+
def process_space_maybe letr
|
180
|
+
if letr == ' '
|
181
|
+
stream.push current_word.strip
|
182
|
+
current_word.clear
|
183
|
+
letr.clear
|
184
|
+
print.success ' ' if print_letters?
|
185
|
+
end
|
186
|
+
end
|
207
187
|
|
208
|
-
|
209
|
-
|
210
|
-
sleep 0.001
|
211
|
-
break if quit?
|
188
|
+
def print_letters?
|
189
|
+
Cfg.config["print_letters"] #&& ! quit?
|
212
190
|
end
|
213
|
-
end
|
214
191
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
192
|
+
def sync_with_play
|
193
|
+
loop do
|
194
|
+
break if sentence_index_current?
|
195
|
+
break if quit?
|
196
|
+
sleep 0.015
|
197
|
+
end
|
221
198
|
end
|
222
|
-
end
|
223
199
|
|
224
|
-
|
225
|
-
|
226
|
-
|
200
|
+
def sync_with_print
|
201
|
+
loop do
|
202
|
+
make_sentence_index_current if ! sentence_index_current?
|
203
|
+
break if sentence_index_current?
|
204
|
+
break if quit?
|
205
|
+
sleep 0.015
|
206
|
+
break
|
207
|
+
end
|
208
|
+
end
|
227
209
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
210
|
+
def play_words_thread
|
211
|
+
# p @words
|
212
|
+
play.play_words_until_quit
|
213
|
+
print "\n\rplay has quit " if @debug
|
214
|
+
exit!
|
233
215
|
end
|
234
|
-
end
|
235
216
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
break if quit?
|
241
|
-
sleep 0.015
|
217
|
+
def print_words_thread
|
218
|
+
print_words_until_quit
|
219
|
+
print "\n\rprint has quit " if @debug
|
220
|
+
exit!
|
242
221
|
end
|
243
|
-
end
|
244
222
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
223
|
+
def monitor_keys_thread
|
224
|
+
monitor_keys
|
225
|
+
@key_input = nil
|
226
|
+
print "\n\rmonitor keys has quit " if @debug
|
227
|
+
exit!
|
228
|
+
end
|
249
229
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
230
|
+
def thread_processes
|
231
|
+
[
|
232
|
+
:monitor_keys_thread,
|
233
|
+
:play_words_thread,
|
234
|
+
:print_words_thread
|
235
|
+
]
|
236
|
+
end
|
255
237
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
238
|
+
def run words
|
239
|
+
@words = words
|
240
|
+
@cw_threads = CWThreads.new(self, thread_processes)
|
241
|
+
@cw_threads.run
|
242
|
+
@play = nil
|
243
|
+
reset_stdin
|
244
|
+
print.newline
|
245
|
+
end
|
264
246
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
247
|
+
def monitor_keys
|
248
|
+
loop do
|
249
|
+
key_input.read
|
250
|
+
break if quit_key_input?
|
251
|
+
break if quit?
|
252
|
+
break if exit?
|
253
|
+
check_sentence_navigation(key_chr) if self.class == Book
|
254
|
+
build_word_maybe
|
255
|
+
end
|
272
256
|
end
|
273
|
-
end
|
274
257
|
|
258
|
+
def quit_key_input?
|
259
|
+
if key_input.quit_input?
|
260
|
+
play.stop
|
261
|
+
exit!
|
262
|
+
quit
|
263
|
+
play.stop
|
264
|
+
true
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
275
268
|
end
|