redshift 1.3.16 → 1.3.17

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.
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