cw 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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,80 +1,74 @@
1
- # encoding: utf-8
1
+ # encoding: utf-8
2
+
3
+ module CWG
2
4
 
3
5
  class CwEncoding
4
6
 
7
+ ENCODINGS = {
8
+ 'a' => [:dot, :dash],
9
+ 'b' => [:dash, :dot, :dot, :dot],
10
+ 'c' => [:dash, :dot, :dash, :dot],
11
+ 'd' => [:dash, :dot, :dot],
12
+ 'e' => [:dot],
13
+ 'f' => [:dot, :dot, :dash, :dot],
14
+ 'g' => [:dash, :dash, :dot],
15
+ 'h' => [:dot, :dot, :dot, :dot],
16
+ 'i' => [:dot, :dot],
17
+ 'j' => [:dot, :dash, :dash, :dash],
18
+ 'k' => [:dash, :dot, :dash],
19
+ 'l' => [:dot, :dash, :dot, :dot],
20
+ 'm' => [:dash, :dash],
21
+ 'n' => [:dash, :dot],
22
+ 'o' => [:dash, :dash, :dash],
23
+ 'p' => [:dot, :dash, :dash, :dot],
24
+ 'q' => [:dash, :dash, :dot, :dash],
25
+ 'r' => [:dot, :dash, :dot],
26
+ 's' => [:dot, :dot, :dot],
27
+ 't' => [:dash],
28
+ 'u' => [:dot, :dot, :dash],
29
+ 'v' => [:dot, :dot, :dot, :dash],
30
+ 'w' => [:dot, :dash, :dash],
31
+ 'x' => [:dash, :dot, :dot, :dash],
32
+ 'y' => [:dash, :dot, :dash, :dash],
33
+ 'z' => [:dash, :dash, :dot, :dot],
34
+ '1' => [:dot, :dash, :dash, :dash, :dash],
35
+ '2' => [:dot, :dot, :dash, :dash, :dash],
36
+ '3' => [:dot, :dot, :dot, :dash, :dash],
37
+ '4' => [:dot, :dot, :dot, :dot, :dash],
38
+ '5' => [:dot, :dot, :dot, :dot, :dot],
39
+ '6' => [:dash, :dot, :dot, :dot, :dot],
40
+ '7' => [:dash, :dash, :dot, :dot, :dot],
41
+ '8' => [:dash, :dash, :dash, :dot, :dot],
42
+ '9' => [:dash, :dash, :dash, :dash, :dot],
43
+ '0' => [:dash, :dash, :dash, :dash, :dash],
44
+ '.' => [:dot, :dash, :dot, :dash, :dot, :dash],
45
+ ',' => [:dash, :dash, :dot, :dot, :dash, :dash],
46
+ '=' => [:dash, :dot, :dot,:dot, :dash],
47
+ '!' => [:dot, :dot, :dash, :dash, :dot],
48
+ '/' => [:dash, :dot, :dot, :dash, :dot],
49
+ '?' => [:dot, :dot, :dash, :dash, :dot, :dot],
50
+ ' ' => []
51
+ }
52
+
5
53
  def fetch char
6
- encode(char)
54
+ ENCODINGS[char]
7
55
  end
8
56
 
9
57
  def encodings
10
- @encodings ||= construct_encodings
11
- end
12
-
13
- def construct_encodings
14
- @encodings = encode_a_n().merge(encode_0_2);
15
- @encodings.merge!(encode_3_space)
16
- end
17
-
18
- def encode char
19
- encodings[char]
58
+ ENCODINGS
20
59
  end
21
60
 
22
- def encode_a_n
23
- {
24
- 'a' => [:dot, :dash],
25
- 'b' => [:dash, :dot, :dot, :dot],
26
- 'c' => [:dash, :dot, :dash, :dot],
27
- 'd' => [:dash, :dot, :dot],
28
- 'e' => [:dot],
29
- 'f' => [:dot, :dot, :dash, :dot],
30
- 'g' => [:dash, :dash, :dot],
31
- 'h' => [:dot, :dot, :dot, :dot],
32
- 'i' => [:dot, :dot],
33
- 'j' => [:dot, :dash, :dash, :dash],
34
- 'k' => [:dash, :dot, :dash],
35
- 'l' => [:dot, :dash, :dot, :dot],
36
- 'm' => [:dash, :dash],
37
- 'n' => [:dash, :dot]
38
- }
61
+ def match_elements arg
62
+ chars = []
63
+ ENCODINGS.each_pair do |key, value|
64
+ chars << key unless value.include?(:dot) if arg[0] == :dashes
65
+ chars << key unless value.include?(:dash) if arg[0] == :dots
66
+ chars << key if (value.size < arg[1] )if arg[0] == :less_than
67
+ chars << key if (value.size > arg[1] )if arg[0] == :greater_than
68
+ chars << key if (value.size == arg[1] )if arg[0] == :size
69
+ chars.delete(' ')
70
+ end
71
+ chars
39
72
  end
40
-
41
- def encode_0_2
42
- {
43
- 'o' => [:dash, :dash, :dash],
44
- 'p' => [:dot, :dash, :dash, :dot],
45
- 'q' => [:dash, :dash, :dot, :dash],
46
- 'r' => [:dot, :dash, :dot],
47
- 's' => [:dot, :dot, :dot],
48
- 't' => [:dash],
49
- 'u' => [:dot, :dot, :dash],
50
- 'v' => [:dot, :dot, :dot, :dash],
51
- 'w' => [:dot, :dash, :dash],
52
- 'x' => [:dash, :dot, :dot, :dash],
53
- 'y' => [:dash, :dot, :dash, :dash],
54
- 'z' => [:dash, :dash, :dot, :dot],
55
- '1' => [:dot, :dash, :dash, :dash, :dash],
56
- '2' => [:dot, :dot, :dash, :dash, :dash]
57
- }
58
- end
59
-
60
- def encode_3_space
61
- {
62
- '3' => [:dot, :dot, :dot, :dash, :dash],
63
- '4' => [:dot, :dot, :dot, :dot, :dash],
64
- '5' => [:dot, :dot, :dot, :dot, :dot],
65
- '6' => [:dash, :dot, :dot, :dot, :dot],
66
- '7' => [:dash, :dash, :dot, :dot, :dot],
67
- '8' => [:dash, :dash, :dash, :dot, :dot],
68
- '9' => [:dash, :dash, :dash, :dash, :dot],
69
- '0' => [:dash, :dash, :dash, :dash, :dash],
70
- '.' => [:dot, :dash, :dot, :dash, :dot, :dash],
71
- ',' => [:dash, :dash, :dot, :dot, :dash, :dash],
72
- '=' => [:dash, :dot, :dot,:dot, :dash],
73
- '!' => [:dot, :dot, :dash, :dash, :dot],
74
- '/' => [:dash, :dot, :dot, :dash, :dot],
75
- '?' => [:dot, :dot, :dash, :dash, :dot, :dot],
76
- ' ' => []
77
- }
78
- end
79
-
80
73
  end
74
+ end
@@ -1,107 +1,111 @@
1
1
  # encoding: utf-8
2
2
 
3
- class CwStream
3
+ module CWG
4
4
 
5
- include Element
5
+ class CwStream
6
6
 
7
- attr_accessor :active_region
8
- attr_accessor :stream
7
+ include Element
9
8
 
10
- def initialize
11
- @active_region = 6
12
- empty
13
- end
9
+ attr_accessor :active_region
10
+ attr_accessor :stream
14
11
 
15
- def empty
16
- @stream, @success, @first_element, @last_element = {},{}, 0, 0
17
- end
12
+ def initialize
13
+ @active_region = 6
14
+ empty
15
+ end
18
16
 
19
- def add_word word
20
- @stream[@last_element] = word.strip
21
- @success[@last_element] = nil
22
- inc_last_element
23
- end
17
+ def empty
18
+ @stream, @success, @first_element, @last_element = {},{}, 0, 0
19
+ end
24
20
 
25
- def add_char char
26
- @stream[@last_element] = char
27
- @success[@last_element] = nil
28
- inc_last_element
29
- end
21
+ def push word
22
+ @stream[@last_element] = word.strip
23
+ @success[@last_element] = nil
24
+ inc_last_element
25
+ end
30
26
 
31
- def mark(element, type)
32
- @success[element] = type
33
- end
27
+ def add_char char
28
+ @stream[@last_element] = char
29
+ @success[@last_element] = nil
30
+ inc_last_element
31
+ end
34
32
 
35
- def mark_success element
36
- mark element, true
37
- end
33
+ def mark(element, type)
34
+ @success[element] = type
35
+ end
38
36
 
39
- def mark_fail element
40
- mark element, false
41
- end
37
+ def mark_success element
38
+ mark element, true
39
+ end
42
40
 
43
- def stream_empty?
44
- @first_element == @last_element
45
- end
41
+ def mark_fail element
42
+ mark element, false
43
+ end
46
44
 
47
- def inactive_region
48
- stream_empty? ? nil : @last_element - @active_region - 1
49
- end
45
+ def stream_empty?
46
+ @first_element == @last_element
47
+ end
48
+
49
+ def inactive_region
50
+ stream_empty? ? nil : @last_element - @active_region - 1
51
+ end
50
52
 
51
- def fail_unmarked_inactive_elements
52
- if(( ! stream_empty?) && (count > @active_region))
53
- @first_element.upto(inactive_region) do |count|
54
- @success[count] = false unless @success[count] == true
53
+ def fail_unmarked_inactive_elements
54
+ if(( ! stream_empty?) && (count > @active_region))
55
+ @first_element.upto(inactive_region) do |count|
56
+ @success[count] = false unless @success[count] == true
57
+ end
55
58
  end
56
59
  end
57
- end
58
60
 
59
- def first
60
- @stream[@first_element]
61
- end
61
+ def first
62
+ @stream[@first_element]
63
+ end
62
64
 
63
- def pop
64
- unless stream_empty?
65
- ele = @first_element
66
- inc_first_element
67
- success = @success.delete(ele)
68
- success = success == nil ? false : success
69
- { :value => @stream.delete(ele),
70
- :success => success
71
- }
72
- else
73
- nil
65
+ def pop
66
+ unless stream_empty?
67
+ ele = @first_element
68
+ inc_first_element
69
+ success = @success.delete(ele)
70
+ success = success == nil ? false : success
71
+ { :value => @stream.delete(ele),
72
+ :success => success
73
+ }
74
+ else
75
+ nil
76
+ end
74
77
  end
75
- end
76
78
 
77
- # def pop_marked
78
- # return_val = {}
79
- # fail_unmarked_inactive_elements
80
- # @first_element.upto(@last_element) do |ele|
81
- # unless stream_empty?
82
- # if(ele < inactive_region)
83
- # val = pop
84
- #
85
- # return_val[ele] = {pop => @success[ele]}
86
- # elsif(@success[ele] == true || @success[ele] == false)
87
- # return_val[ele] = {pop => @success[ele]}
88
- # else
89
- # break
90
- # end
91
- # end
92
- # end
93
- # return_val == {} ? nil : return_val
94
- # end
95
-
96
- def pop_next_marked
97
- fail_unmarked_inactive_elements
98
- unless stream_empty?
99
- if(@first_element < inactive_region)
100
- pop
101
- elsif(@success[@first_element] == true || @success[@first_element] == false)
102
- pop
79
+ # def pop_marked
80
+ # return_val = {}
81
+ # fail_unmarked_inactive_elements
82
+ # @first_element.upto(@last_element) do |ele|
83
+ # unless stream_empty?
84
+ # if(ele < inactive_region)
85
+ # val = pop
86
+ #
87
+ # return_val[ele] = {pop => @success[ele]}
88
+ # elsif(@success[ele] == true || @success[ele] == false)
89
+ # return_val[ele] = {pop => @success[ele]}
90
+ # else
91
+ # break
92
+ # end
93
+ # end
94
+ # end
95
+ # return_val == {} ? nil : return_val
96
+ # end
97
+
98
+ def pop_next_marked
99
+ fail_unmarked_inactive_elements
100
+ unless stream_empty?
101
+ if(@first_element < inactive_region)
102
+ pop
103
+ elsif(@success[@first_element] == true || @success[@first_element] == false)
104
+ pop
105
+ end
103
106
  end
104
107
  end
108
+
105
109
  end
106
110
 
107
111
  end
@@ -1,36 +1,146 @@
1
1
  # encoding: utf-8
2
2
 
3
- class CWThreads
3
+ module CWG
4
4
 
5
- attr_accessor :threads
5
+ class CWThreads
6
6
 
7
- def initialize context, processes
8
- @context = context
9
- @processes = processes
10
- end
7
+ attr_reader :threads
8
+
9
+ def initialize context, processes
10
+ @context = context
11
+ @processes = processes
12
+ end
11
13
 
12
- def kill
13
- sleep 0.2
14
- if @threads.is_a?(Array)
15
- @threads.each do |th|
16
- th.exit if th.is_a? Thread
14
+ def start_threads
15
+ @threads = @processes.collect do |th|
16
+ {:thread =>
17
+ Thread.new do
18
+ @context.send th
19
+ end,
20
+ :name => th
21
+ }
17
22
  end
18
23
  end
19
- end
20
24
 
21
- def start_threads
22
- @threads = @processes.collect do |th|
23
- Thread.new{@context.send th}
25
+ def monitor_threads
26
+ exiting = false
27
+ loop do
28
+ sleep 0.5
29
+ @threads.each do |th|
30
+ if thread_false_or_nil?(th)
31
+ exiting = true
32
+ unless Cfg.config["exit"]
33
+ # puts "** #{th[:name].to_s.gsub('_',' ')} quit unexpectedly!**"
34
+ if th[:thread].backtrace
35
+ STDERR.puts th[:thread].backtrace.join("\n \\_ ")
36
+ end
37
+ end
38
+ end
39
+ end
40
+ # print_threads_status
41
+ exiting = true if(Cfg.config["exit"])
42
+ break if exiting
43
+ end
44
+ close_threads if exiting
24
45
  end
25
- end
26
46
 
27
- def wait_for_threads
28
- @threads.each { |th| th.join }
29
- end
47
+ def kill_thread thread
48
+ thread[:thread].kill
49
+ end
50
+
51
+ def kill_open_threads
52
+ @threads.each do |thread|
53
+ unless thread_false_or_nil?(thread)
54
+ kill_thread thread
55
+ end
56
+ end
57
+ end
58
+
59
+ def thread_false_or_nil? th
60
+ if(th[:thread].status == false)
61
+ return true
62
+ end
63
+
64
+ if(th[:thread].status.nil?)
65
+ return true
66
+ end
67
+ end
68
+
69
+ def wait_for_threads
70
+ Cfg.config.params["exit"] = false
71
+ loop do
72
+ alive = false
73
+ sleep 0.1
74
+ @threads.each { |th|
75
+ if thread_false_or_nil? th
76
+ elsif th[:name] != :monitor_keys_thread
77
+ alive = true
78
+ end
79
+ }
80
+ break unless alive
81
+ end
82
+ threads.each {|th|
83
+ if(th[:name] == :monitor_keys_thread)
84
+ kill_thread th
85
+ end
86
+ sleep 0.1
87
+ }
88
+ end
89
+
90
+ def print_threads_status
91
+ @threads.each do |thread|
92
+ puts "\r"
93
+ print "#{thread[:name]} = "
94
+ p thread[:thread].status
95
+ end
96
+ end
97
+
98
+ def kill_monitor_keys_thread_maybe thread
99
+ kill_thread(thread) unless thread_false_or_nil?(thread)
100
+ end
101
+
102
+ def any_thread_open?
103
+ @threads.each do |thread|
104
+ # print "status "
105
+ # p thread
106
+ if(thread[:name] == :monitor_keys_thread)
107
+ kill_monitor_keys_thread_maybe thread
108
+ else
109
+ unless thread_false_or_nil?(thread)
110
+ return true
111
+ end
112
+ end
113
+ end
114
+ nil
115
+ end
116
+
117
+ def force_kill
118
+ puts "exiting"
119
+ # puts "Forcing kill!\r"
120
+ kill_open_threads
121
+ # print_threads_status
122
+ system("stty -raw echo")
123
+ sleep 0.2
124
+ exit(1)
125
+ end
126
+
127
+ def close_threads
128
+ await_termination_count = 0
129
+ loop do
130
+ sleep 0.1
131
+ break unless any_thread_open?()
132
+ # print_threads_status
133
+ await_termination_count += 1
134
+ force_kill if(await_termination_count >= 30)
135
+ end
136
+ end
137
+
138
+ def run
139
+ start_threads
140
+ monitor_threads
141
+ system("stty -raw echo")
142
+ end
30
143
 
31
- def run
32
- start_threads
33
- wait_for_threads
34
144
  end
35
145
 
36
146
  end