rwdmovies 0.6 → 0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. data/Readme.txt +47 -30
  2. data/code/ag1core/aa0begin.rb +18 -18
  3. data/code/ag1core/rwdtinkerversion.rb +15 -15
  4. data/code/xa5rwdtinkercallable/callable.rb +12 -12
  5. data/code/xb1rwdtinkerbackwindow/diagnostictab.rb +21 -21
  6. data/code/xb1rwdtinkerbackwindow/{lm1installapplet.rb → installapplet.rb} +21 -20
  7. data/code/xb1rwdtinkerbackwindow/{05listinstalledfiles.rb → listinstalledfiles.rb} +1 -1
  8. data/code/xb1rwdtinkerbackwindow/{ll5listzips.rb → listzips.rb} +9 -7
  9. data/code/xb1rwdtinkerbackwindow/loadconfigurationrecord.rb +32 -0
  10. data/code/xb1rwdtinkerbackwindow/loadconfigurationvariables.rb +13 -0
  11. data/code/xb1rwdtinkerbackwindow/{ll1openname.rb → openappletname.rb} +18 -18
  12. data/code/xb1rwdtinkerbackwindow/{mm1removeapplet.rb → removeapplet.rb} +28 -28
  13. data/code/xb1rwdtinkerbackwindow/rwdtinkerwin2version.rb +14 -14
  14. data/code/xb1rwdtinkerbackwindow/saveconfigurationrecord.rb +18 -0
  15. data/code/zz0applicationend/zz0end.rb +4 -4
  16. data/configuration/language.cnf +5 -0
  17. data/configuration/rwdmovies.cnf +0 -1
  18. data/configuration/rwdmoviesversion.cnf +2 -0
  19. data/configuration/rwdplayscriptsversion.cnf +2 -0
  20. data/configuration/rwdtinker.cnf +12 -0
  21. data/configuration/rwdtinkerversion.cnf +2 -0
  22. data/configuration/tinkerwin2variables.cnf +8 -0
  23. data/configuration/tinkerwin2version.cnf +3 -0
  24. data/ev/browser.rb +109 -109
  25. data/ev/ftools.rb +170 -170
  26. data/ev/net.rb +750 -750
  27. data/ev/ruby.rb +819 -819
  28. data/ev/rwd.rb +1848 -1848
  29. data/ev/sgml.rb +236 -236
  30. data/ev/thread.rb +63 -63
  31. data/ev/tree.rb +343 -343
  32. data/ev/xml.rb +4 -4
  33. data/gui/00coreguibegin/applicationguitop.rwd +4 -0
  34. data/gui/{ee1rwdmovies → frontwindow0/superant.com.rwdmovies}/1openmoviedata.rwd +0 -0
  35. data/gui/{ee1rwdmovies → frontwindow0/superant.com.rwdmovies}/2openmoviephoto.rwd +0 -0
  36. data/gui/{ee1rwdmovies → frontwindow0/superant.com.rwdmovies}/3listmoviegfiles.rwd +0 -0
  37. data/gui/{ee1rwdmovies → frontwindow0/superant.com.rwdmovies}/6editrecord.rwd +0 -0
  38. data/gui/{ee1rwdmovies → frontwindow0/superant.com.rwdmovies}/movieutilities.rwd +0 -0
  39. data/gui/{ee1rwdmovies → frontwindow0/superant.com.rwdmovies}/viewconfiguration.rwd +0 -0
  40. data/gui/{ll1selectiontabbegin → frontwindowselectionbegin/selectiontabbegin}/selectiontabbegin.rwd +16 -16
  41. data/gui/{ll5rwdtinkerwin2selectiontab → frontwindowselections/superant.com.rwdtinkerwin2selectiontab}/rwdwin2selectiontab.rwd +12 -12
  42. data/gui/{lz1selectiontabend/endselectiontab.rwd → frontwindowselectionzend/viewselectionzend/viewselectionend.rwd} +3 -3
  43. data/gui/{tt0documentsbegin → frontwindowtdocumentbegin/superant.com.documentsbegin}/tt0documentbegin.rwd +6 -6
  44. data/gui/{uu5rwddocuments → frontwindowtdocuments/superant.com.documents}/uu5documents.rwd +15 -15
  45. data/gui/{uv7rwdmovies → frontwindowtdocuments/superant.com.rwdmovies}/uv7docmovies.rwd +0 -0
  46. data/gui/{uu6rwdtinkerwin2documents → frontwindowtdocuments/superant.com.tinkerwin2documents}/uu5documents.rwd +6 -6
  47. data/gui/{ww0documentsend → frontwindowtdocumentzend/superant.com.documentsend}/ww0documentend.rwd +7 -7
  48. data/gui/{wz6finaltabs → frontwindowz1end/frontwindowend}/xx0rwdfirsttab.rwd +6 -6
  49. data/gui/{ya1helpaboutbegin → helpaboutbegin/superant.com.helpaboutbegin}/ya0helpscreenstart.rwd +3 -3
  50. data/gui/{yl2rwdmovieshelpabout → helpaboutinstalled/superant.com.rwdmovieshelpabout}/1movies.rwd +0 -0
  51. data/gui/{yl2rwdmovieshelpabout → helpaboutinstalled/superant.com.rwdmovieshelpabout}/2movies.rwd +0 -0
  52. data/gui/{yl2rwdmovieshelpabout → helpaboutinstalled/superant.com.rwdmovieshelpabout}/5version.rwd +0 -0
  53. data/gui/{yg6rwdwin2helpabout → helpaboutinstalled/superant.com.rwdwin2helpabout}/1appname.rwd +4 -4
  54. data/gui/{yg5rwdhelpabout → helpaboutinstalled/superant.com.rwdwin2helpabout}/3copyright.rwd +3 -3
  55. data/gui/{yg6rwdwin2helpabout → helpaboutinstalled/superant.com.rwdwin2helpabout}/5version.rwd +10 -10
  56. data/gui/{yg5rwdhelpabout → helpaboutinstalled/superant.com.tinkerhelpabout}/1appname.rwd +4 -4
  57. data/gui/{yg6rwdwin2helpabout → helpaboutinstalled/superant.com.tinkerhelpabout}/3copyright.rwd +3 -3
  58. data/gui/helpaboutinstalled/superant.com.tinkerhelpabout/5version.rwd +10 -0
  59. data/gui/helpaboutzend/superant.com.helpaboutend/helpscreenend.rwd +3 -0
  60. data/gui/{xx8rwdmoviespicture → tinkerbackwindows/superant.com.rwdmoviespicture}/xx8moviephotoview.rwd +0 -0
  61. data/gui/{xa5rwdtinkercallablewindow → tinkerbackwindows/superant.com.tinercallablewindow}/1appname.rwd +17 -17
  62. data/gui/{xa5rwdtinkercallablewindow → tinkerbackwindows/superant.com.tinercallablewindow}/9end.rwd +4 -4
  63. data/gui/{xb1rwdtinkerbackwindow → tinkerbackwindows/superant.com.tinkerbackwindow}/1appname.rwd +5 -5
  64. data/gui/{xb1rwdtinkerbackwindow → tinkerbackwindows/superant.com.tinkerbackwindow}/3arwddiagnostics.rwd +33 -33
  65. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/40editconfiguration.rwd +36 -0
  66. data/gui/{xb1rwdtinkerbackwindow/4arwdlistapplets.rwd → tinkerbackwindows/superant.com.tinkerbackwindow/50rwdlistapplets.rwd} +44 -44
  67. data/gui/{xb1rwdtinkerbackwindow/4arwdlistzips.rwd → tinkerbackwindows/superant.com.tinkerbackwindow/50rwdlistzips.rwd} +35 -35
  68. data/gui/{xb1rwdtinkerbackwindow/2tab1.rwd → tinkerbackwindows/superant.com.tinkerbackwindow/80tab1.rwd} +11 -11
  69. data/gui/{xb1rwdtinkerbackwindow → tinkerbackwindows/superant.com.tinkerbackwindow}/9backend.rwd +6 -6
  70. data/gui/{xa1versionwindow → tinkerbackwindows/superant.com.versionwindow}/1appname.rwd +19 -19
  71. data/gui/{za1applicationend → zzcoreguiend/tinkerapplicationguiend}/yy9rwdend.rwd +4 -4
  72. data/init.rb +233 -233
  73. data/installed/rwdtinkerwin2-0.5.inf +8 -8
  74. data/installed/rwdviewlogo-0.4.inf +4 -0
  75. data/lang/alanguagehashbegin.rb +4 -4
  76. data/lang/en/rwdcore/languagefile.rb +15 -15
  77. data/lang/es/rwdcore/languagefile-es.rb +14 -14
  78. data/lang/jp/rwdcore/languagefile.rb +9 -0
  79. data/lang/languagehash.rb +4 -4
  80. data/lang/nl/rwdcore/languagefile.rb +19 -0
  81. data/lang/templangfile.rb +15 -21
  82. data/lang/vlanguagehashend.rb +6 -6
  83. data/lang/wlocallangstart.rb +5 -5
  84. data/lang/xlocallangfile.rb +16 -10
  85. data/lang/zlocallangend.rb +2 -2
  86. data/lib/temp.rb +1 -1
  87. data/rwd_files/HowTo_Movies.txt +2 -0
  88. data/rwd_files/HowTo_Tinker.txt +318 -276
  89. data/rwd_files/HowTo_TinkerWin2.txt +202 -202
  90. data/rwd_files/Readme.txt +57 -57
  91. data/rwd_files/moviestmp.jpg +0 -0
  92. data/rwd_files/rdoc-style.css +174 -174
  93. data/rwd_files/rwdapplications.html +54 -54
  94. data/rwd_files/tinker.png +0 -0
  95. data/tests/rwdtinkertestEN.rb +163 -0
  96. data/tests/test.result +32 -0
  97. data/tests/totranslate.lang +93 -93
  98. data/zips/rwdahelloworld-0.5.zip +0 -0
  99. metadata +96 -75
  100. data/code/gh9calendar/gh9calendar.rb +0 -16
  101. data/configuration/aa0rwdframework.cnf +0 -14
  102. data/configuration/ab1tinkerwin2.cnf +0 -4
  103. data/gui/aa2core/aa0rwdtop.rwd +0 -4
  104. data/gui/yg5rwdhelpabout/5version.rwd +0 -10
  105. data/gui/yy5helpaboutend/helpscreenend.rwd +0 -3
  106. data/installed/rubyslippers-0.94.inf +0 -9
  107. data/installed/rwdcalendar-0.5.inf +0 -8
  108. data/lang/en/rwdcalendar/calendar-nl.rb +0 -6
  109. data/lang/es/rwdcalendar/calendar-nl.rb +0 -6
  110. data/lang/nl/rwdcalendar/calendar-nl.rb +0 -6
  111. data/lang/nl/rwdcore/languagefile-nl.rb +0 -4
  112. data/zips/rwdacalendar-0.5.zip +0 -0
  113. data/zips/rwdhelloworld-0.3.zip +0 -0
  114. data/zips/rwdwshell-0.91.zip +0 -0
  115. data/zips/wrubyslippers-0.93.zip +0 -0
data/ev/sgml.rb CHANGED
@@ -1,236 +1,236 @@
1
- require "ev/tree"
2
-
3
- class SGMLObject < TreeObject
4
- def to_s
5
- res = ""
6
-
7
- parsetree("prechildren_to_s", "postchildren_to_s", res)
8
-
9
- res
10
- end
11
-
12
- def to_h
13
- res = ""
14
-
15
- parsetree("prechildren_to_sgml", "postchildren_to_sgml", res)
16
-
17
- res
18
- end
19
- end
20
-
21
- class Text < SGMLObject
22
- def initialize(text)
23
- super()
24
- @text = text
25
- end
26
-
27
- def prechildren_to_s(res)
28
- #res << "#{CGI.unescapeHTML(@text)} "
29
- res << @text
30
- end
31
-
32
- def prechildren_to_sgml(res)
33
- #res << "#{CGI.unescapeHTML(@text)}"
34
- res << @text
35
- end
36
- end
37
-
38
- class Comment < SGMLObject
39
- def initialize(text)
40
- super()
41
- @text = text
42
- end
43
-
44
- def prechildren_to_sgml(res)
45
- res << "#{@text}"
46
- end
47
- end
48
-
49
- class Special < SGMLObject
50
- def initialize(text)
51
- super()
52
- @text = text
53
- end
54
-
55
- def prechildren_to_sgml(res)
56
- res << "#{@text}"
57
- end
58
- end
59
-
60
- class Instruction < SGMLObject
61
- def initialize(text)
62
- super()
63
- @text = text
64
- end
65
-
66
- def prechildren_to_sgml(res)
67
- res << "#{@text}"
68
- end
69
- end
70
-
71
- class Tag < SGMLObject
72
- attr_reader :args
73
- attr_writer :args
74
-
75
- def initialize(subtype, args={})
76
- super(subtype)
77
- @args = args
78
- @text = ""
79
- end
80
- end
81
-
82
- class OpenTag < Tag
83
- def initialize(*args)
84
- super
85
- @upordown = Down
86
- end
87
-
88
- def prechildren_to_sgml(res)
89
- a = [@subtype]
90
-
91
- @args.each do |k, v|
92
- if not v.include?("'")
93
- a << "#{k}='#{v}'"
94
- else
95
- if not v.include?('"')
96
- a << "#{k}=\"#{v}\""
97
- else
98
- a << "#{k}='#{v.gsub(/\'/, '"')}'"
99
- end
100
- end
101
- end
102
-
103
- res << "<#{a.join(" ")}>" + @text
104
- end
105
-
106
- def postchildren_to_sgml(res)
107
- res << "</#{@subtype}>" if @closed
108
- end
109
- end
110
-
111
- class CloseTag < Tag
112
- def initialize(*args)
113
- super
114
- @upordown = Dummy
115
- end
116
- end
117
-
118
- class SGML < Tree
119
- def initialize(*args)
120
- @tagcache = {}
121
-
122
- super
123
- end
124
-
125
- def buildobjects(string)
126
- @objects = []
127
-
128
- verwerk3 =
129
- lambda do |string|
130
- a = []
131
-
132
- string[1..-2].splitblocks(["'", "'"], ['"', '"']).collect do |type, s|
133
- case type
134
- when 0
135
- if self.class.to_s == "HTML"
136
- s.splitwords.each do |w|
137
- d = w.split("=", 2)
138
-
139
- if d.length == 1
140
- a << d[0]
141
- else
142
- a << d[0] if not d[0].nil? and not d[0].empty?
143
- a << "="
144
- a << d[1] if not d[1].nil? and not d[1].empty?
145
- end
146
- end
147
- else
148
- a.concat s.splitwords(["/", "="])
149
- end
150
- when 1, 2 then a << s
151
- end
152
- end
153
-
154
- open = false
155
- close = false
156
-
157
- a = a[0].splitwords("/") + a[1..-1]
158
-
159
- if a[0] == "/"
160
- close = true
161
- a.shift
162
- else
163
- open = true
164
- end
165
-
166
- if a[-1] == "/"
167
- close = true
168
- a.pop
169
- end
170
-
171
- tag = a.shift.downcase
172
- args = {}
173
-
174
- while not a.length.zero?
175
- if a.length >= 3 and a[1] == "="
176
- key = a.shift.downcase
177
- dummy = a.shift
178
- value = a.shift.noquotes
179
- args[key] = value
180
- else
181
- key = a.shift.downcase
182
- args[key] = ""
183
- end
184
- end
185
-
186
- [tag, args, open, close]
187
- end
188
-
189
- verwerk2 =
190
- lambda do |string|
191
- if @tagcache.include? string
192
- res = @tagcache[string]
193
- else
194
- res = verwerk3.call(string)
195
-
196
- @tagcache[string] = res
197
- end
198
-
199
- res
200
- end
201
-
202
- verwerk1 =
203
- lambda do |string|
204
- tag, args, open, close = verwerk2.call(string)
205
-
206
- @objects << OpenTag.new(tag.dup, args.dup) if open
207
- @objects << CloseTag.new(tag.dup, args.dup) if close
208
- end
209
-
210
- string.splitblocks(["<!--", "-->"], ["<!", ">"], ["<?", "?>"], ["<", ">"]).each do |type, s|
211
- case type
212
- when 0 then @objects << Text.new(s)
213
- when 1 then @objects << Comment.new(s)
214
- when 2 then @objects << Special.new(s)
215
- when 3 then @objects << Instruction.new(s)
216
- when 4 then verwerk1.call(s)
217
- end
218
- end
219
- end
220
-
221
- def to_s
222
- res = ""
223
-
224
- parsetree("prechildren_to_s", "postchildren_to_s", res)
225
-
226
- res
227
- end
228
-
229
- def to_h
230
- res = ""
231
-
232
- parsetree("prechildren_to_sgml", "postchildren_to_sgml", res)
233
-
234
- res
235
- end
236
- end
1
+ require "ev/tree"
2
+
3
+ class SGMLObject < TreeObject
4
+ def to_s
5
+ res = ""
6
+
7
+ parsetree("prechildren_to_s", "postchildren_to_s", res)
8
+
9
+ res
10
+ end
11
+
12
+ def to_h
13
+ res = ""
14
+
15
+ parsetree("prechildren_to_sgml", "postchildren_to_sgml", res)
16
+
17
+ res
18
+ end
19
+ end
20
+
21
+ class Text < SGMLObject
22
+ def initialize(text)
23
+ super()
24
+ @text = text
25
+ end
26
+
27
+ def prechildren_to_s(res)
28
+ #res << "#{CGI.unescapeHTML(@text)} "
29
+ res << @text
30
+ end
31
+
32
+ def prechildren_to_sgml(res)
33
+ #res << "#{CGI.unescapeHTML(@text)}"
34
+ res << @text
35
+ end
36
+ end
37
+
38
+ class Comment < SGMLObject
39
+ def initialize(text)
40
+ super()
41
+ @text = text
42
+ end
43
+
44
+ def prechildren_to_sgml(res)
45
+ res << "#{@text}"
46
+ end
47
+ end
48
+
49
+ class Special < SGMLObject
50
+ def initialize(text)
51
+ super()
52
+ @text = text
53
+ end
54
+
55
+ def prechildren_to_sgml(res)
56
+ res << "#{@text}"
57
+ end
58
+ end
59
+
60
+ class Instruction < SGMLObject
61
+ def initialize(text)
62
+ super()
63
+ @text = text
64
+ end
65
+
66
+ def prechildren_to_sgml(res)
67
+ res << "#{@text}"
68
+ end
69
+ end
70
+
71
+ class Tag < SGMLObject
72
+ attr_reader :args
73
+ attr_writer :args
74
+
75
+ def initialize(subtype, args={})
76
+ super(subtype)
77
+ @args = args
78
+ @text = ""
79
+ end
80
+ end
81
+
82
+ class OpenTag < Tag
83
+ def initialize(*args)
84
+ super
85
+ @upordown = Down
86
+ end
87
+
88
+ def prechildren_to_sgml(res)
89
+ a = [@subtype]
90
+
91
+ @args.each do |k, v|
92
+ if not v.include?("'")
93
+ a << "#{k}='#{v}'"
94
+ else
95
+ if not v.include?('"')
96
+ a << "#{k}=\"#{v}\""
97
+ else
98
+ a << "#{k}='#{v.gsub(/\'/, '"')}'"
99
+ end
100
+ end
101
+ end
102
+
103
+ res << "<#{a.join(" ")}>" + @text
104
+ end
105
+
106
+ def postchildren_to_sgml(res)
107
+ res << "</#{@subtype}>" if @closed
108
+ end
109
+ end
110
+
111
+ class CloseTag < Tag
112
+ def initialize(*args)
113
+ super
114
+ @upordown = Dummy
115
+ end
116
+ end
117
+
118
+ class SGML < Tree
119
+ def initialize(*args)
120
+ @tagcache = {}
121
+
122
+ super
123
+ end
124
+
125
+ def buildobjects(string)
126
+ @objects = []
127
+
128
+ verwerk3 =
129
+ lambda do |string|
130
+ a = []
131
+
132
+ string[1..-2].splitblocks(["'", "'"], ['"', '"']).collect do |type, s|
133
+ case type
134
+ when 0
135
+ if self.class.to_s == "HTML"
136
+ s.splitwords.each do |w|
137
+ d = w.split("=", 2)
138
+
139
+ if d.length == 1
140
+ a << d[0]
141
+ else
142
+ a << d[0] if not d[0].nil? and not d[0].empty?
143
+ a << "="
144
+ a << d[1] if not d[1].nil? and not d[1].empty?
145
+ end
146
+ end
147
+ else
148
+ a.concat s.splitwords(["/", "="])
149
+ end
150
+ when 1, 2 then a << s
151
+ end
152
+ end
153
+
154
+ open = false
155
+ close = false
156
+
157
+ a = a[0].splitwords("/") + a[1..-1]
158
+
159
+ if a[0] == "/"
160
+ close = true
161
+ a.shift
162
+ else
163
+ open = true
164
+ end
165
+
166
+ if a[-1] == "/"
167
+ close = true
168
+ a.pop
169
+ end
170
+
171
+ tag = a.shift.downcase
172
+ args = {}
173
+
174
+ while not a.length.zero?
175
+ if a.length >= 3 and a[1] == "="
176
+ key = a.shift.downcase
177
+ dummy = a.shift
178
+ value = a.shift.noquotes
179
+ args[key] = value
180
+ else
181
+ key = a.shift.downcase
182
+ args[key] = ""
183
+ end
184
+ end
185
+
186
+ [tag, args, open, close]
187
+ end
188
+
189
+ verwerk2 =
190
+ lambda do |string|
191
+ if @tagcache.include? string
192
+ res = @tagcache[string]
193
+ else
194
+ res = verwerk3.call(string)
195
+
196
+ @tagcache[string] = res
197
+ end
198
+
199
+ res
200
+ end
201
+
202
+ verwerk1 =
203
+ lambda do |string|
204
+ tag, args, open, close = verwerk2.call(string)
205
+
206
+ @objects << OpenTag.new(tag.dup, args.dup) if open
207
+ @objects << CloseTag.new(tag.dup, args.dup) if close
208
+ end
209
+
210
+ string.splitblocks(["<!--", "-->"], ["<!", ">"], ["<?", "?>"], ["<", ">"]).each do |type, s|
211
+ case type
212
+ when 0 then @objects << Text.new(s)
213
+ when 1 then @objects << Comment.new(s)
214
+ when 2 then @objects << Special.new(s)
215
+ when 3 then @objects << Instruction.new(s)
216
+ when 4 then verwerk1.call(s)
217
+ end
218
+ end
219
+ end
220
+
221
+ def to_s
222
+ res = ""
223
+
224
+ parsetree("prechildren_to_s", "postchildren_to_s", res)
225
+
226
+ res
227
+ end
228
+
229
+ def to_h
230
+ res = ""
231
+
232
+ parsetree("prechildren_to_sgml", "postchildren_to_sgml", res)
233
+
234
+ res
235
+ end
236
+ end
data/ev/thread.rb CHANGED
@@ -1,63 +1,63 @@
1
- require "ev/ruby"
2
- require "thread"
3
-
4
- class FakeThread
5
- def initialize(*args)
6
- yield(*args)
7
- end
8
-
9
- def join
10
- end
11
- end
12
-
13
- class ThreadLimiter
14
- def initialize(limit)
15
- @limit = limit
16
- @count = 0
17
- @threads = []
18
- @mutex = Mutex.new
19
- @cv = ConditionVariable.new
20
-
21
- every(1) do
22
- @mutex.synchronize do
23
- @threads.dup.each do |t|
24
- unless t.alive?
25
- $stderr.puts "Found dead thread."
26
-
27
- @threads.delete(t)
28
-
29
- @count -= 1
30
-
31
- @cv.signal
32
- end
33
- end
34
- end
35
- end
36
- end
37
-
38
- def wait
39
- if block_given?
40
- self.wait
41
- yield
42
- self.signal
43
- else
44
- @mutex.synchronize do
45
- @threads << Thread.current
46
-
47
- @count += 1
48
-
49
- @cv.wait(@mutex) if @count > @limit
50
- end
51
- end
52
- end
53
-
54
- def signal
55
- @mutex.synchronize do
56
- @threads.delete(Thread.current)
57
-
58
- @count -= 1
59
-
60
- @cv.signal
61
- end
62
- end
63
- end
1
+ require "ev/ruby"
2
+ require "thread"
3
+
4
+ class FakeThread
5
+ def initialize(*args)
6
+ yield(*args)
7
+ end
8
+
9
+ def join
10
+ end
11
+ end
12
+
13
+ class ThreadLimiter
14
+ def initialize(limit)
15
+ @limit = limit
16
+ @count = 0
17
+ @threads = []
18
+ @mutex = Mutex.new
19
+ @cv = ConditionVariable.new
20
+
21
+ every(1) do
22
+ @mutex.synchronize do
23
+ @threads.dup.each do |t|
24
+ unless t.alive?
25
+ $stderr.puts "Found dead thread."
26
+
27
+ @threads.delete(t)
28
+
29
+ @count -= 1
30
+
31
+ @cv.signal
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ def wait
39
+ if block_given?
40
+ self.wait
41
+ yield
42
+ self.signal
43
+ else
44
+ @mutex.synchronize do
45
+ @threads << Thread.current
46
+
47
+ @count += 1
48
+
49
+ @cv.wait(@mutex) if @count > @limit
50
+ end
51
+ end
52
+ end
53
+
54
+ def signal
55
+ @mutex.synchronize do
56
+ @threads.delete(Thread.current)
57
+
58
+ @count -= 1
59
+
60
+ @cv.signal
61
+ end
62
+ end
63
+ end