redshift 1.3.16 → 1.3.17

Sign up to get free protection for your applications and to get access to all the features.
data/RELEASE-NOTES CHANGED
@@ -1,3 +1,11 @@
1
+ redshift 1.3.17
2
+
3
+ - added shell example with plotting and tk animation
4
+
5
+ - added supporting libs for tk and for irb shells
6
+
7
+ - delay buffer automatically rotates around offset when dumping to array
8
+
1
9
  redshift 1.3.16
2
10
 
3
11
  - added util dir and modified requires to use libs from there
data/examples/shell.rb ADDED
@@ -0,0 +1,224 @@
1
+ # Shows how to use a customized IRB shell to handle Ctrl-C interrupts
2
+
3
+ require 'redshift'
4
+ require 'redshift/mixins/irb-shell'
5
+ include RedShift
6
+
7
+ require 'redshift/util/plot'
8
+ include Plot::PlotUtils
9
+
10
+ # Adds an interactive ruby shell with plotting and animation commands.
11
+ module ShellWorld
12
+ include RedShift::Shellable
13
+
14
+ def help
15
+ puts <<-END
16
+ The current object is #{self.inspect}. Some commands:
17
+
18
+ q -- quit
19
+ sh! -- enter a system command shell
20
+ t.plot -- plot recent history of t (try t=components[0])
21
+ plot -- plot recent history of all T instances
22
+ run N -- run quickly for N time steps (integer)
23
+ evolve T -- run quickly for T seconds (float)
24
+ tk -- turn on Tk window
25
+ tk false -- turn off Tk window
26
+
27
+ Local vars persist between interrupts.
28
+ Continue slow execution by pressing Ctrl-D (maybe Ctrl-Z on windows).
29
+ Press Ctrl-C again to break into the shell.
30
+ END
31
+ end
32
+
33
+ def sh!
34
+ system ENV['SHELL'] || default_shell
35
+ end
36
+
37
+ def default_shell
38
+ puts "No SHELL environment variable, trying /bin/bash"
39
+ "/bin/bash"
40
+ end
41
+
42
+ def next_id
43
+ @next_id ||= 1
44
+ @next_id += 1
45
+ end
46
+
47
+ def plot
48
+ gnuplot do |plot|
49
+ plot.command 'set title "recent history"'
50
+ plot.command "set xrange [*:*]"
51
+ plot.command "set yrange [*:*]"
52
+ grep(T) do |t|
53
+ t.add_history_to_plot(plot)
54
+ end
55
+ end
56
+ nil
57
+ end
58
+
59
+ def before_shell
60
+ @tkar.catch_up_within 0 if @tkar
61
+ puts "\nStopped #{self.inspect}"
62
+ end
63
+
64
+ def after_shell
65
+ @tkar.catch_up_within 0 if @tkar
66
+ puts "\nRunning #{self.inspect}"
67
+ end
68
+
69
+ def dragger id, x, y
70
+ @th ||= {}
71
+ t = @th[id] ||= grep(T).find {|t| t.id == id}
72
+ t.x, t.y = x, y
73
+ end
74
+
75
+ def tk turn_on = true
76
+ require 'redshift/util/tkar-driver'
77
+ if turn_on
78
+ if not @tkar or @tkar.closed?
79
+ @tkar = TkarDriver.new(method :dragger) do |pipe|
80
+ pipe.puts <<-END
81
+ title Animation example
82
+ background gray95
83
+ height 600
84
+ width 600
85
+ view_at -50 -50
86
+ zoom_to 4
87
+
88
+ shape cone \ arc5,5,10,10,fc:yellow,oc:black,extent:30,start:165,style:pieslice \
89
+ text2,2,anchor:c,justify:center,width:100,text:*0,fc:blue
90
+
91
+ shape circle oval*0,*0,*1,*1,oc:red
92
+ END
93
+ ## the view_at seems to be needed to overcome a little
94
+ ## centering bug in tkar
95
+
96
+ (1..10).each do |i|
97
+ pipe.puts "add circle #{next_id} - 0 0 0 0 #{5*i} #{-5*i}"
98
+ end
99
+
100
+ grep(T) do |t|
101
+ pipe.puts t.tk_add
102
+ end
103
+ end
104
+
105
+ tk_update
106
+ end
107
+
108
+ elsif not turn_on and @tkar
109
+ @tkar.close
110
+ @tkar = nil
111
+ end
112
+ @tkar
113
+ end
114
+
115
+ def tk_update
116
+ @tkar and @tkar.update do |pipe|
117
+ grep(T) do |t|
118
+ pipe.puts t.tk_update
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ class T < Component
125
+ attr_accessor :name, :id
126
+
127
+ default do
128
+ @id = world.next_id
129
+ end
130
+
131
+ flow do
132
+ diff " x' = -y "
133
+ diff " y' = x "
134
+
135
+ alg " r = atan2(x, -y) " # atan2(y', x'): angle of velocity vector
136
+
137
+ # A simple, but crude, way to store recent history of a var
138
+ delay " z = x ", :by => 10
139
+ end
140
+
141
+ def history
142
+ ts = world.time_step
143
+ t0 = world.clock - z_delay
144
+ data = []
145
+ z_buffer_data.each_with_index do |xi, i|
146
+ if i % 4 == 0 # skip the integrator steps
147
+ time = t0 + (i/4)*ts
148
+ data << [time, xi] if time >= 0
149
+ end
150
+ end
151
+ data << [world.clock, x]
152
+ data
153
+ end
154
+
155
+ def add_history_to_plot(plot)
156
+ plot.add history, "using 1:2 title \"#{name}.x\" with lines"
157
+ end
158
+
159
+ def plot
160
+ gnuplot do |plot|
161
+ plot.command 'set title "recent history"'
162
+ plot.command "set xrange [*:*]"
163
+ plot.command "set yrange [*:*]"
164
+ add_history_to_plot(plot)
165
+ end
166
+ nil
167
+ end
168
+
169
+ # return string that adds an instance of the shape with label t.name,
170
+ # position based on (x, y), and
171
+ # rotation based on (x', y')
172
+ def tk_add
173
+ "add cone #{id} - 10 #{x} #{y} #{r}\n" +
174
+ "param #{id} 0 #{name}"
175
+ end
176
+
177
+ # emit string representing current state
178
+ def tk_update
179
+ "moveto #{id} #{x} #{y}\n" +
180
+ "rot #{id} #{r}"
181
+ end
182
+ end
183
+
184
+ w = World.new
185
+ w.time_step = 0.01
186
+ w.extend ShellWorld
187
+
188
+ w.create T do |t|
189
+ t.name = "a"
190
+ t.x = 40
191
+ t.y = 0
192
+ end
193
+ w.create T do |t|
194
+ t.name = "b"
195
+ t.x = 0
196
+ t.y = 20
197
+ end
198
+
199
+ if false
200
+ (1..10).each do |i|
201
+ w.create T do |t|
202
+ t.name = "c#{i}"
203
+ t.x = i*5
204
+ t.y = i*5
205
+ end
206
+ end
207
+ end
208
+
209
+ puts "^C to break into shell; 'help' for shell help"
210
+
211
+ if ARGV.delete "-t"
212
+ w.tk
213
+ end
214
+
215
+ start_in_shell = ARGV.delete "-s"
216
+ w.shell.run if start_in_shell
217
+
218
+ loop do
219
+ w.evolve 100000000 do
220
+ puts "clock: #{w.clock}"
221
+ w.tk_update
222
+ sleep 0.01
223
+ end
224
+ end
@@ -0,0 +1,151 @@
1
+ require 'irb'
2
+ require 'irb/completion'
3
+
4
+ class Object
5
+ include IRB::ExtendCommandBundle
6
+ # so that Marshal.dump still works, even when doing ">> irb obj"
7
+ end
8
+
9
+ def IRB.parse_opts
10
+ # Don't touch ARGV, which belongs to the app which called this module.
11
+ end
12
+
13
+ class RedShift::IRBShell
14
+ @@irb_setup_done = false
15
+
16
+ # +args+ are binding, self (both optional)
17
+ def initialize(*args)
18
+ ## maybe set some opts here, as in parse_opts in irb/init.rb?
19
+
20
+ unless @@irb_setup_done
21
+ @@irb_setup_done = true
22
+
23
+ conf = IRB.conf
24
+
25
+ if File.directory?("tmp")
26
+ conf[:HISTORY_FILE] = "tmp/.redshift_irb_shell_history"
27
+ else
28
+ conf[:HISTORY_FILE] = ".redshift_irb_shell_history"
29
+ end
30
+
31
+ IRB.setup nil
32
+
33
+ at_exit do
34
+ IRB.irb_at_exit
35
+ end
36
+ end
37
+
38
+ workspace = IRB::WorkSpace.new(*args)
39
+
40
+ if conf[:SCRIPT] ## normally, set by parse_opts
41
+ @irb = IRB::Irb.new(workspace, conf[:SCRIPT])
42
+ else
43
+ @irb = IRB::Irb.new(workspace)
44
+ end
45
+
46
+ conf[:IRB_RC].call(@irb.context) if conf[:IRB_RC]
47
+ conf[:MAIN_CONTEXT] = @irb.context
48
+ end
49
+
50
+ def run
51
+ @interrupt_requests = nil
52
+
53
+ trap("INT") do
54
+ @irb.signal_handle
55
+ end
56
+
57
+ begin
58
+ catch(:IRB_EXIT) do
59
+ @irb.eval_input
60
+ end
61
+ ensure
62
+ install_interrupt_handler
63
+ end
64
+ end
65
+
66
+ def install_interrupt_handler
67
+ unless @interrupt_requests
68
+ @interrupt_requests = 0
69
+ trap("INT") do
70
+ @interrupt_requests += 1
71
+ if @interrupt_requests == 2
72
+ puts "\nType one more ^C to abort, or wait for RedShift shell."
73
+ elsif @interrupt_requests >= 3
74
+ exit!
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ def handle_interrupt after = nil
81
+ if @interrupt_requests && @interrupt_requests > 0
82
+ yield if block_given?
83
+ run
84
+ true
85
+ else
86
+ false
87
+ end
88
+ end
89
+ end
90
+
91
+ # extend a World instance with this (or include in a World subclass)
92
+ module RedShift::Shellable
93
+ def shell
94
+ @shell ||= RedShift::IRBShell.new(binding, self)
95
+ end
96
+
97
+ def run(*)
98
+ shell.install_interrupt_handler
99
+ super
100
+ end
101
+
102
+ def step(*)
103
+ super do
104
+ yield self if block_given?
105
+ if shell.handle_interrupt {before_shell}
106
+ after_shell
107
+ return
108
+ end
109
+ end
110
+ end
111
+
112
+ # Override to complete some action before dropping into shell.
113
+ def before_shell
114
+ end
115
+
116
+ # Override to complete some action after leaving shell.
117
+ def after_shell
118
+ end
119
+
120
+ # Typically, call this in a rescue clause, if you to let the user
121
+ # examine state and possibly continue:
122
+ #
123
+ # rescue ... => e
124
+ # require 'redshift/mixins/irb-shell'
125
+ # world.extend RedShift::IRBShell
126
+ # world.recoverable_error e, "Assertion failure", e.backtrace
127
+ #
128
+ def recoverable_error e, msg = "Error", bt = []
129
+ puts "#{msg} at time #{clock}"
130
+ puts "From " + bt[0..2].join("\n ") unless bt.empty
131
+ puts " ..." if bt.length > 3
132
+ shell.run
133
+ end
134
+
135
+ private
136
+ def q
137
+ exit
138
+ end
139
+
140
+ ## commands:
141
+ ## step [n] {block}
142
+ ## step_until/while
143
+ ## continue -- safer than ^D, does step_discrete in case of changes
144
+ ## step_continuous
145
+ ## step_discrete [n]
146
+ ## break [class/component/transition/comp.event/condition]
147
+ ## until step_until, stops inside step_discrete
148
+ ## clear
149
+ ##
150
+ ## customize prompt
151
+ end
@@ -33,7 +33,7 @@ end
33
33
  module RedShift
34
34
  include Math
35
35
 
36
- VERSION = '1.3.16'
36
+ VERSION = '1.3.17'
37
37
 
38
38
  Infinity = Math::Infinity
39
39
 
@@ -211,7 +211,11 @@ module FlowSyntax
211
211
 
212
212
  def initialize block
213
213
  @flows = []
214
- instance_eval(&block)
214
+ val = instance_eval(&block)
215
+ if val.kind_of? String and val =~ /=/
216
+ warn "Equation appears to be missing a specifier (alg, diff, etc.):" +
217
+ val
218
+ end
215
219
  end
216
220
 
217
221
  def algebraic(*equations)
@@ -224,7 +228,7 @@ module FlowSyntax
224
228
  end
225
229
 
226
230
  def euler(*equations)
227
- for equation in equations
231
+ equations.each do |equation|
228
232
  unless equation =~ /^\s*(\w+)\s*'\s*=\s*(.+)/m
229
233
  raise SyntaxError, "parse error in\n\t#{equation}."
230
234
  end
@@ -233,7 +237,7 @@ module FlowSyntax
233
237
  end
234
238
 
235
239
  def rk4(*equations)
236
- for equation in equations
240
+ equations.each do |equation|
237
241
  unless equation =~ /^\s*(\w+)\s*'\s*=\s*(.+)/m
238
242
  raise SyntaxError, "parse error in\n\t#{equation}."
239
243
  end
@@ -252,7 +256,7 @@ module FlowSyntax
252
256
  ## rename 'feedback'?
253
257
  end
254
258
  feedback = opts[:feedback]
255
- for equation in equations
259
+ equations.each do |equation|
256
260
  unless equation =~ /^\s*(\w+)\s*=\s*(.+)'\s*\z/m
257
261
  raise SyntaxError, "parse error in\n\t#{equation}."
258
262
  end
@@ -8,10 +8,72 @@ class RedShift::Library
8
8
  include_file.declare :Buffer => %{
9
9
  typedef struct {
10
10
  long len;
11
+ long offset;
11
12
  double *ptr;
12
13
  } Buffer;
13
14
  }.tabto(0)
14
15
 
16
+ source_file.define_c_function(:buffer_init).instance_eval {
17
+ arguments "Buffer *buf", "long len", "double fill"
18
+ scope :extern
19
+ body %{
20
+ int i;
21
+ buf->ptr = ALLOC_N(double, len);
22
+ buf->len = len;
23
+ buf->offset = 0;
24
+ for (i=0; i<len; i++) {
25
+ buf->ptr[i] = fill;
26
+ }
27
+ }
28
+ }
29
+
30
+ source_file.define_c_function(:buffer_resize).instance_eval {
31
+ arguments "Buffer *buf", "long len"
32
+ scope :extern
33
+ body %{
34
+ long i;
35
+ long old_len = buf->len;
36
+ long offset = buf->offset;
37
+ double *ptr = buf->ptr;
38
+ double *dst, *src;
39
+ double fill;
40
+
41
+ if (len < old_len) {
42
+ if (offset < len) {
43
+ dst = ptr + offset;
44
+ src = ptr + offset + old_len - len;
45
+ memmove(dst, src, (len - offset) * sizeof(double));
46
+ }
47
+ else {
48
+ dst = ptr;
49
+ src = ptr + offset - len;
50
+ offset = 0;
51
+ memmove(dst, src, len * sizeof(double));
52
+ }
53
+ REALLOC_N(ptr, double, len);
54
+ // ## maybe better: don't release space, just use less of it
55
+ }
56
+ else if (len > old_len) {
57
+ REALLOC_N(ptr, double, len);
58
+
59
+ fill = ptr[offset];
60
+ dst = ptr + offset + len - old_len;
61
+ src = ptr + offset;
62
+ memmove(dst, src, (old_len - offset) * sizeof(double));
63
+
64
+ for (i = 0; i < len - old_len; i++) {
65
+ ptr[offset + i] = fill;
66
+ }
67
+ }
68
+ else
69
+ return;
70
+
71
+ buf->len = len;
72
+ buf->offset = offset;
73
+ buf->ptr = ptr;
74
+ }
75
+ }
76
+
15
77
  source_file.define_c_function(:buffer_inhale_array).instance_eval {
16
78
  arguments "Buffer *buf", "VALUE ary"
17
79
  scope :extern
@@ -28,6 +90,7 @@ class RedShift::Library
28
90
  buf->ptr = ALLOC_N(double, size);
29
91
  }
30
92
  buf->len = size;
93
+ buf->offset = 0;
31
94
 
32
95
  for (i = 0; i < size; i++) {
33
96
  buf->ptr[i] = NUM2DBL(RARRAY(ary)->ptr[i]);
@@ -42,13 +105,17 @@ class RedShift::Library
42
105
  scope :extern
43
106
  declare :size => "int size",
44
107
  :i => "int i",
108
+ :j => "int j",
45
109
  :ary => "VALUE ary"
46
110
  body %{
47
111
  size = buf->len;
48
112
  ary = rb_ary_new2(size);
49
113
  RARRAY(ary)->len = size;
50
- for (i = 0; i < size; i++) {
51
- RARRAY(ary)->ptr[i] = rb_float_new(buf->ptr[i]);
114
+ for (i = buf->offset, j=0; i < size; i++, j++) {
115
+ RARRAY(ary)->ptr[j] = rb_float_new(buf->ptr[i]);
116
+ }
117
+ for (i = 0; i < buf->offset; i++, j++) {
118
+ RARRAY(ary)->ptr[j] = rb_float_new(buf->ptr[i]);
52
119
  }
53
120
  }
54
121
  }
@@ -17,13 +17,11 @@ module RedShift; class DelayFlow
17
17
  RedShift.library.define_buffer
18
18
 
19
19
  bufname = "#{var_name}_buffer_data"
20
- offsetname = "#{var_name}_buffer_offset"
21
20
  delayname = "#{var_name}_delay"
22
21
  tsname = "#{var_name}_time_step"
23
22
 
24
23
  cl.class_eval do
25
24
  shadow_attr_accessor bufname => "Buffer #{bufname}"
26
- shadow_attr_accessor offsetname => "long #{offsetname}"
27
25
  shadow_attr_accessor delayname => "double #{delayname}"
28
26
  # delay should be set only using the expr designated in :by => "expr"
29
27
  shadow_attr tsname => "double #{tsname}"
@@ -50,7 +48,7 @@ module RedShift; class DelayFlow
50
48
 
51
49
  ContVar *var;
52
50
  double *ptr;
53
- long i, len, offset, steps;
51
+ long len, offset, steps;
54
52
  double delay, fill;
55
53
  }
56
54
  setup :shadow => %{
@@ -77,7 +75,7 @@ module RedShift; class DelayFlow
77
75
  switch (shadow->world->rk_level) {
78
76
  case 0:
79
77
  ptr = shadow->#{bufname}.ptr;
80
- offset = shadow->#{offsetname};
78
+ offset = shadow->#{bufname}.offset;
81
79
 
82
80
  if (shadow->world->time_step != shadow->#{tsname}) {
83
81
  if (shadow->#{tsname} == 0.0)
@@ -106,57 +104,17 @@ module RedShift; class DelayFlow
106
104
  #{flow.translate(self, "fill", 0, cl).join("
107
105
  ")};
108
106
 
109
- ptr = ALLOC_N(double, len);
110
- shadow->#{bufname}.ptr = ptr;
111
- shadow->#{bufname}.len = len;
112
- shadow->#{offsetname} = 0;
113
- shadow->#{delayname} = delay;
114
-
115
- for (i=0; i<len; i++) {
116
- ptr[i] = fill;
117
- }
107
+ buffer_init(&shadow->#{bufname}, len, fill);
118
108
  }
119
109
  else { // # delay != shadow->#{delayname}
120
- long old_len = shadow->#{bufname}.len;
121
- double *dst, *src;
122
-
123
- if (delay < shadow->#{delayname}) {
124
- if (offset < len) {
125
- dst = ptr + offset;
126
- src = ptr + offset + old_len - len;
127
- }
128
- else {
129
- dst = ptr;
130
- src = ptr + offset - len;
131
- offset = 0;
132
- }
133
- memmove(dst, src, (len - offset) * sizeof(double));
134
- REALLOC_N(ptr, double, len);
135
- // ## maybe better: don't release space, just use less of it
136
- }
137
- else { // # delay > shadow->#{delayname}
138
- REALLOC_N(ptr, double, len);
139
-
140
- fill = ptr[offset];
141
- dst = ptr + offset + len - old_len;
142
- src = ptr + offset;
143
- memmove(dst, src, (old_len - offset) * sizeof(double));
144
-
145
- for (i = 0; i < len - old_len; i++) {
146
- ptr[offset + i] = fill;
147
- }
148
- }
149
-
150
- shadow->#{bufname}.ptr = ptr;
151
- shadow->#{bufname}.len = len;
152
- shadow->#{offsetname} = offset;
153
- shadow->#{delayname} = delay;
110
+ buffer_resize(&shadow->#{bufname}, len);
154
111
  }
112
+
113
+ shadow->#{delayname} = delay;
114
+ ptr = shadow->#{bufname}.ptr;
115
+ offset = shadow->#{bufname}.offset;
155
116
  }
156
117
 
157
- offset = (offset + 4) % len;
158
- shadow->#{offsetname} = offset;
159
-
160
118
  var->value_0 = ptr[offset];
161
119
  var->value_1 = ptr[offset + 1];
162
120
  var->value_2 = ptr[offset + 2];
@@ -173,7 +131,7 @@ module RedShift; class DelayFlow
173
131
  case 3:
174
132
  ptr = shadow->#{bufname}.ptr;
175
133
  len = shadow->#{bufname}.len;
176
- offset = shadow->#{offsetname};
134
+ offset = shadow->#{bufname}.offset;
177
135
 
178
136
  #{flow.translate(self, "ptr[offset+1]", 1, cl).join("
179
137
  ")};
@@ -182,7 +140,9 @@ module RedShift; class DelayFlow
182
140
  #{flow.translate(self, "ptr[offset+3]", 3, cl).join("
183
141
  ")};
184
142
 
185
- var->value_0 = ptr[(offset + 4) % len];
143
+ offset = (offset + 4) % len;
144
+ var->value_0 = ptr[offset];
145
+ shadow->#{bufname}.offset = offset;
186
146
  break;
187
147
 
188
148
  default:
@@ -0,0 +1,93 @@
1
+ # Manages interface to external animation process.
2
+ # Depends on:
3
+ # gem install tkar
4
+ # See also:
5
+ # http://tkar.rubyforge.org
6
+ class TkarDriver
7
+ # +dragger+ is a callable object that takes (id, x, y) and should
8
+ # move object id to (x,y)
9
+ def initialize dragger
10
+ @dragger = dragger
11
+ cmd =
12
+ case RUBY_PLATFORM
13
+ when /mswin/
14
+ "tkar --radians 2>nul"
15
+ else
16
+ # Use setsid so that ^C doesn't kill it
17
+ "setsid tkar --radians 2>/dev/null"
18
+ end
19
+
20
+ @pipe = IO.popen(cmd, "w+")
21
+ yield @pipe if block_given?
22
+
23
+ @buf = 0
24
+ update
25
+ end
26
+
27
+ # never let the simulation get more than this many steps ahead
28
+ MAX_LAG = 10
29
+
30
+ # let the visualization lag by this many steps, or more
31
+ MIN_LAG = 5
32
+
33
+ def close
34
+ if @pipe
35
+ @pipe.close
36
+ @pipe = nil
37
+ end
38
+ end
39
+
40
+ def closed?
41
+ return true if not @pipe or @pipe.closed?
42
+
43
+ begin
44
+ @pipe.puts " " # no-op
45
+ @pipe.flush
46
+ rescue Errno::EPIPE
47
+ close
48
+ true
49
+ else
50
+ @pipe.closed?
51
+ end
52
+ end
53
+
54
+ # :yields: pipe
55
+ def update
56
+ return unless @pipe
57
+
58
+ yield @pipe if block_given?
59
+
60
+ @pipe.puts "update"
61
+ @pipe.flush
62
+ @buf += 1
63
+ if @buf > MAX_LAG
64
+ catch_up_within MIN_LAG
65
+ end
66
+ rescue Errno::EPIPE
67
+ close
68
+ end
69
+
70
+ def catch_up_within steps
71
+ return unless @pipe
72
+
73
+ while @buf > steps || (steps==0 && select([@pipe],[],[],0))
74
+ ## alternately: if steps==0, send "echo ..." and wait for ...
75
+ case line=@pipe.gets
76
+ when nil
77
+ close
78
+ return
79
+ when /^update$/
80
+ @buf -= 1
81
+ when /^drag (\S+) (\S+) (\S+)/
82
+ drag_parms = $1.to_i, $2.to_f, $3.to_f
83
+ when /^drop/
84
+ @dragger[*drag_parms] if @dragger
85
+ ## TODO: handle dropping on another object
86
+ else
87
+ puts "tkar: #{line}"
88
+ end
89
+ end
90
+ rescue Errno::EPIPE
91
+ close
92
+ end
93
+ end
@@ -38,7 +38,7 @@ class World
38
38
  end
39
39
 
40
40
  def [](idx)
41
- warn "World#[] is deprecated"
41
+ warn "#{self.class}#[] is deprecated"
42
42
  to_a[idx] ## very inefficient
43
43
  end
44
44
 
data/rakefile CHANGED
@@ -31,6 +31,8 @@ END
31
31
  test.files = Dir["test/test_*.rb"]
32
32
  }
33
33
 
34
+ task 'gem:release' => 'rubyforge:release' # to release to rubyforge as well
35
+
34
36
  task :release => ["rubyforge:release", "rubyforge:doc_release"]
35
37
 
36
38
  # EOF
data/test/test_delay.rb CHANGED
@@ -142,4 +142,6 @@ class TestDelay < Test::Unit::TestCase
142
142
  #puts "%5.3f: %5.3f" % [c.x, c.xd]
143
143
  end
144
144
  end
145
+
146
+ ## TODO: test variable delay
145
147
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redshift
3
3
  version: !ruby/object:Gem::Version
4
- hash: 59
4
+ hash: 57
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 3
9
- - 16
10
- version: 1.3.16
9
+ - 17
10
+ version: 1.3.17
11
11
  platform: ruby
12
12
  authors:
13
13
  - Joel VanderWerf
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-06-06 00:00:00 -07:00
18
+ date: 2010-06-13 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -40,12 +40,12 @@ dependencies:
40
40
  requirements:
41
41
  - - ">="
42
42
  - !ruby/object:Gem::Version
43
- hash: 17
43
+ hash: 27
44
44
  segments:
45
45
  - 3
46
46
  - 4
47
- - 3
48
- version: 3.4.3
47
+ - 6
48
+ version: 3.4.6
49
49
  type: :development
50
50
  version_requirements: *id002
51
51
  description: |
@@ -96,6 +96,7 @@ files:
96
96
  - examples/reset-with-event-val.rb
97
97
  - examples/scheduler.rb
98
98
  - examples/set-dest.rb
99
+ - examples/shell.rb
99
100
  - examples/simulink/README
100
101
  - examples/simulink/delay.mdl
101
102
  - examples/simulink/derivative.mdl
@@ -110,6 +111,7 @@ files:
110
111
  - lib/redshift.rb
111
112
  - lib/redshift/component.rb
112
113
  - lib/redshift/meta.rb
114
+ - lib/redshift/mixins/irb-shell.rb
113
115
  - lib/redshift/mixins/zeno-debugger.rb
114
116
  - lib/redshift/port.rb
115
117
  - lib/redshift/queue.rb
@@ -136,6 +138,7 @@ files:
136
138
  - lib/redshift/util/plot.rb
137
139
  - lib/redshift/util/random.rb
138
140
  - lib/redshift/util/superhash.rb
141
+ - lib/redshift/util/tkar-driver.rb
139
142
  - lib/redshift/util/tracer.rb
140
143
  - lib/redshift/util/tracer/trace.rb
141
144
  - lib/redshift/util/tracer/var.rb