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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.cw_config +18 -0
  3. data/.gitignore +10 -1
  4. data/LICENSE +2 -1
  5. data/README.md +212 -96
  6. data/Rakefile +15 -2
  7. data/VERSION +1 -1
  8. data/Vagrantfile +45 -0
  9. data/cw.gemspec +6 -1
  10. data/data/text/book_to_read.txt +4 -0
  11. data/data/text/english.txt +10000 -0
  12. data/example.rb +172 -106
  13. data/lib/cw.rb +10 -126
  14. data/lib/cw/alphabet.rb +53 -46
  15. data/lib/cw/audio_player.rb +83 -72
  16. data/lib/cw/book.rb +160 -185
  17. data/lib/cw/book_details.rb +38 -49
  18. data/lib/cw/cl.rb +101 -95
  19. data/lib/cw/common_words.rb +76 -0
  20. data/lib/cw/config.rb +50 -0
  21. data/lib/cw/current_word.rb +23 -24
  22. data/lib/cw/cw_dsl.rb +264 -131
  23. data/lib/cw/cw_encoding.rb +63 -69
  24. data/lib/cw/cw_stream.rb +86 -82
  25. data/lib/cw/cw_threads.rb +132 -22
  26. data/lib/cw/element.rb +60 -54
  27. data/lib/cw/file_details.rb +26 -11
  28. data/lib/cw/key_input.rb +53 -35
  29. data/lib/cw/numbers.rb +26 -19
  30. data/lib/cw/os.rb +13 -0
  31. data/lib/cw/play.rb +92 -0
  32. data/lib/cw/print.rb +102 -100
  33. data/lib/cw/process.rb +3 -0
  34. data/lib/cw/progress.rb +20 -17
  35. data/lib/cw/randomize.rb +56 -52
  36. data/lib/cw/repeat_word.rb +59 -66
  37. data/lib/cw/reveal.rb +32 -31
  38. data/lib/cw/rss.rb +52 -48
  39. data/lib/cw/sentence.rb +83 -76
  40. data/lib/cw/speak.rb +8 -4
  41. data/lib/cw/spoken.rb +8 -4
  42. data/lib/cw/str.rb +62 -30
  43. data/lib/cw/test_letters.rb +20 -28
  44. data/lib/cw/test_words.rb +25 -31
  45. data/lib/cw/tester.rb +219 -226
  46. data/lib/cw/text_helpers.rb +19 -15
  47. data/lib/cw/timing.rb +63 -67
  48. data/lib/cw/tone_generator.rb +176 -153
  49. data/lib/cw/tone_helpers.rb +15 -23
  50. data/lib/cw/voice.rb +12 -8
  51. data/lib/cw/words.rb +136 -106
  52. data/run_script_tests.rb +165 -0
  53. data/test/my_words.txt +1 -0
  54. data/test/test_common_words.rb +71 -0
  55. data/test/test_config.rb +98 -0
  56. data/test/test_current_word.rb +62 -0
  57. data/test/test_cw.rb +87 -120
  58. data/test/test_cw_threads.rb +123 -0
  59. data/test/test_filtering.rb +439 -0
  60. data/test/test_params.rb +28 -0
  61. data/test/test_play.rb +51 -0
  62. data/test/test_stream.rb +83 -83
  63. data/test/test_tester.rb +9 -27
  64. data/test/test_timing.rb +212 -0
  65. metadata +94 -12
  66. data/lib/cw/config_file.rb +0 -69
  67. data/lib/cw/monitor_keys.rb +0 -37
  68. data/lib/cw/params.rb +0 -104
@@ -1,275 +1,268 @@
1
1
  # encoding: utf-8
2
2
 
3
- module Tester
4
-
5
- def quit? ; @quit ; end
6
- def quit ; @quit = true ; end
7
- def global_quit? ; @global_quit ; end
8
- def global_quit ; @global_quit = true ; end
9
- def print ; @print ||= Print.new ; end
10
- def timing ; @timing ||= Timing.new ; end
11
- def audio ; @audio ||= AudioPlayer.new ; end
12
- def kill_threads ; @threads.kill ; end
13
- def space ; ' ' ; end
14
- def empty_string ; '' ; end
15
- def spawn_play(cmd) ; Process.spawn(cmd) ; 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 quit_key_input? ; key_input.quit_input? ; end
22
- def stream ; @stream ||= CwStream.new ; end
23
- def reset_stdin ; key_input.reset_stdin ; end
24
- def current_word ; @current_word ||= CurrentWord.new ; end
25
- def init_char_timer ; timing.init_char_timer ; end
26
- def audio_still_playing? ; audio.still_playing? ; end
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
- def do_events
55
- sleep 0.005
56
- end
57
-
58
- def process_letters letr
59
- loop do
60
- do_events
61
- if self.class == Book
62
- process_space_maybe(letr) unless @book_details.args[:output] == :letter
63
- process_word_maybe
64
- break if change_repeat_or_quit?
65
- break if timing.char_delay_timeout?
66
- else
67
- process_space_maybe(letr) if(self.class == TestWords)
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
- def process_words words
76
- book_class = (self.class == Book)
77
- (words.to_s + space).each_char do |letr|
78
- process_letter letr
79
- if book_class
80
- stream.add_char(letr) if @book_details.args[:output] == :letter
81
- else
82
- stream.add_char(letr) if(self.class == TestLetters)
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
- def print_words words
92
- timing.init_char_timer
93
- process_words words
94
- end
63
+ def print_words words
64
+ timing.init_char_timer
65
+ process_words words
66
+ end
95
67
 
96
- def process_word_maybe
97
- print_marked_maybe
98
- process_input_word_maybe
99
- end
68
+ def process_word_maybe
69
+ print_marked_maybe
70
+ process_input_word_maybe
71
+ end
100
72
 
101
- def play_words_thread
102
- play_words_until_quit
103
- print "\n\rplay has quit " if @debug
104
- end
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
- def print_words_thread
107
- print_words_until_quit
108
- kill_threads
109
- print "\n\rprint has quit " if @debug
110
- end
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
- def print_words_until_quit
113
- sync_with_audio_player
114
- print_words @words
115
- print_words_exit unless @print_letters
116
- quit
117
- end
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
- def print_failed_exit_words
120
- until stream.stream_empty?
121
- print.fail stream.pop[:value]
95
+ def failed?
96
+ @failed
122
97
  end
123
- end
124
98
 
125
- def print_words_exit
126
- timing.init_print_words_timeout
127
- loop do
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
- def audio_stop
139
- audio.stop if audio_still_playing?
140
- end
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
- def wait_player_startup_delay
143
- audio.startup_delay
144
- end
117
+ def audio_stop
118
+ play.stop if play.still_playing?
119
+ end
145
120
 
146
- def sync_with_audio_player
147
- wait_for_start_sync
148
- wait_player_startup_delay
149
- end
121
+ def sync_with_audio_player
122
+ wait_for_start_sync
123
+ play.wait_player_startup_delay
124
+ end
150
125
 
151
- def check_quit_key_input
152
- if quit_key_input?
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
- def push_letter_to_current_word letr
161
- current_word.push_letter letr
162
- end
130
+ def get_word_last_char
131
+ @input_word.split(//).last(1).first
132
+ end
163
133
 
164
- def get_word_last_char
165
- @input_word.split(//).last(1).first
166
- end
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
- def word_proc_timeout(arg = :status)
169
- if arg == :init
170
- @wp_timeout = Time.now + 5
171
- else
172
- return true if(Time.now > @wp_timeout)
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
- def wait_for_no_word_process
178
- word_proc_timeout(:init)
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
- def complete_word?
186
- get_word_last_char == space
187
- end
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
- def move_word_to_process
190
- wait_for_no_word_process
191
- @process_input_word, @input_word = @input_word, ''
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
- def start_sync?
196
- if @start_sync
197
- @start_sync = nil
198
- true
199
- else
200
- nil
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
- def sleep_char_delay letr
205
- timing.append_char_delay letr, Params.wpm, Params.effective_wpm
206
- end
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
- def wait_for_start_sync
209
- until start_sync?
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
- def process_space_maybe letr
216
- if letr == space
217
- stream.add_word current_word.strip
218
- current_word.clear
219
- letr.clear
220
- print.success space if print_letters?
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
- def print_letters?
225
- @print_letters && ! quit?
226
- end
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
- def sync_with_play
229
- loop do
230
- break if sentence_index_current?
231
- break if quit?
232
- sleep 0.015
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
- def sync_with_print
237
- loop do
238
- make_sentence_index_current if ! sentence_index_current?
239
- break if sentence_index_current?
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
- def monitor_keys_thread
246
- monitor_keys
247
- print "\n\rmonitor keys has quit " if @debug
248
- end
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
- def thread_processes
251
- [:monitor_keys_thread,
252
- :play_words_thread,
253
- :print_words_thread]
254
- end
230
+ def thread_processes
231
+ [
232
+ :monitor_keys_thread,
233
+ :play_words_thread,
234
+ :print_words_thread
235
+ ]
236
+ end
255
237
 
256
- def run words
257
- @words = words
258
- words.double_words if Params.double_words
259
- @threads = CWThreads.new(self, thread_processes)
260
- @threads.run
261
- reset_stdin
262
- print.newline
263
- end
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
- def monitor_keys
266
- loop do
267
- get_key_input
268
- check_quit_key_input
269
- break if quit?
270
- # check_sentence_navigation key_chr
271
- build_word_maybe
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