redshift 1.3.22 → 1.3.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.bnsignore +27 -0
  2. data/RELEASE-NOTES +6 -0
  3. data/bench/aug17-ruby19.bench +86 -0
  4. data/bench/aug17.bench +86 -0
  5. data/bench/aug7.bench +86 -0
  6. data/bench/bench +4 -1
  7. data/bench/prof.html +0 -0
  8. data/ext/redshift/buffer/buffer.c +3 -1
  9. data/ext/redshift/dvector/dvector.c +236 -0
  10. data/ext/redshift/dvector/dvector.h +36 -0
  11. data/ext/redshift/dvector/dvector.rb +33 -0
  12. data/ext/redshift/dvector/extconf.rb +2 -0
  13. data/lib/redshift/redshift.rb +1 -1
  14. data/lib/redshift/target/c/component-gen.rb +17 -23
  15. data/lib/redshift/target/c/flow-gen.rb +2 -2
  16. data/lib/redshift/target/c/flow/algebraic.rb +1 -1
  17. data/lib/redshift/target/c/flow/delay.rb +1 -1
  18. data/lib/redshift/target/c/flow/derivative.rb +1 -1
  19. data/lib/redshift/target/c/flow/rk4.rb +1 -1
  20. data/lib/redshift/target/c/library.rb +5 -0
  21. data/lib/redshift/target/c/world-gen.rb +130 -127
  22. data/lib/redshift/util/isaac.rb +2 -2
  23. data/lib/redshift/util/random.rb +1 -1
  24. data/lib/redshift/world.rb +11 -6
  25. data/test/test_discrete.rb +1 -1
  26. data/test/test_discrete_isolated.rb +1 -1
  27. data/test/test_dvector.rb +110 -0
  28. data/test/test_flow.rb +1 -1
  29. data/test/test_flow_link.rb +1 -1
  30. data/test/test_flow_sub.rb +1 -1
  31. data/test/test_flow_trans.rb +3 -3
  32. data/test/test_inherit_event.rb +1 -1
  33. data/test/test_inherit_flow.rb +1 -1
  34. data/test/test_inherit_link.rb +1 -1
  35. data/test/test_inherit_state.rb +1 -1
  36. data/test/test_inherit_transition.rb +1 -1
  37. data/test/test_setup.rb +1 -1
  38. data/test/test_strict_continuity.rb +1 -1
  39. data/test/test_world.rb +4 -4
  40. metadata +22 -8
@@ -0,0 +1,36 @@
1
+ #ifndef dvector_h
2
+ #define dvector_h
3
+
4
+ #include <ruby.h>
5
+
6
+ typedef struct {
7
+ long len;
8
+ long capa;
9
+ VALUE *ptr;
10
+ } RS_DVector;
11
+
12
+ extern void rs_dv_grow(RS_DVector *dv);
13
+ extern void rs_dv_shrink(RS_DVector *dv);
14
+
15
+ inline static RS_DVector *rs_dv(VALUE obj)
16
+ {
17
+ return (RS_DVector *)DATA_PTR(obj);
18
+ }
19
+
20
+ inline static void rs_dv_push(RS_DVector *dv, VALUE val)
21
+ {
22
+ if (dv->len == dv->capa) {
23
+ rs_dv_grow(dv);
24
+ }
25
+ dv->ptr[dv->len++] = val;
26
+ }
27
+
28
+ inline static VALUE rs_dv_pop(RS_DVector *dv)
29
+ {
30
+ if (dv->len == 0) {
31
+ return Qnil;
32
+ }
33
+ return dv->ptr[--dv->len];
34
+ }
35
+
36
+ #endif
@@ -0,0 +1,33 @@
1
+ module RedShift; end
2
+
3
+ # A linear collection of objects, like Array.
4
+ #
5
+ # Intended primarily for access from C code, using the inline
6
+ # rs_dv_push() and rs_dv_pop() functions.
7
+ #
8
+ # Implements some of the same methods as Array, but not all.
9
+ #
10
+ # Like an Array, a DVector grows implicitly as elements are
11
+ # pushed. But unlike an Array, a DVector shrinks only explicitly.
12
+ # This is to minimize realloc() calls when a DVector rapidly
13
+ # grows and shrinks.
14
+
15
+ class RedShift::DVector
16
+ include Enumerable
17
+ require 'redshift/dvector/dvector.so'
18
+
19
+ def self.[](*elts)
20
+ new elts
21
+ end
22
+
23
+ def initialize(elts=nil)
24
+ push(*elts) if elts
25
+ end
26
+
27
+ def inspect; to_a.inspect; end
28
+ def to_s; to_a.to_s; end
29
+
30
+ def dup
31
+ self.class.new to_a
32
+ end
33
+ end
@@ -0,0 +1,2 @@
1
+ require 'mkmf'
2
+ create_makefile 'dvector'
@@ -70,7 +70,7 @@ end
70
70
  module RedShift
71
71
  include Math
72
72
 
73
- VERSION = '1.3.22'
73
+ VERSION = '1.3.23'
74
74
 
75
75
  Infinity = Math::Infinity
76
76
 
@@ -4,8 +4,6 @@ module RedShift
4
4
  # just so we can call shadow_struct_name on it
5
5
  end
6
6
 
7
- HAVE_DEFINE_METHOD = Module.private_instance_methods.include?("define_method")
8
-
9
7
  class Component
10
8
  include CShadow
11
9
  shadow_library RedShift.library
@@ -738,17 +736,13 @@ module RedShift
738
736
  g
739
737
 
740
738
  when Proc
741
- if HAVE_DEFINE_METHOD
742
- meth = Component.make_guard_method_name
743
- class_eval do
744
- define_method(meth, &g)
745
- end
746
- ## Currently, methods defined with define_method are a little
747
- ## slower to invoke in ruby.
748
- meth
749
- else
750
- g # a proc is slower than a method when called from step_discrete
739
+ meth = Component.make_guard_method_name
740
+ class_eval do
741
+ define_method(meth, &g)
751
742
  end
743
+ ## Currently, methods defined with define_method are a little
744
+ ## slower to invoke in ruby.
745
+ meth
752
746
 
753
747
  when String
754
748
  define_guard(g)
@@ -944,8 +938,8 @@ module RedShift
944
938
  idx_ary = rb_funcall(shadow->cont_state->self, #{svi}, 0);
945
939
  Check_Type(idx_ary, T_ARRAY); //## debug only
946
940
 
947
- count = RARRAY(idx_ary)->len;
948
- indexes = RARRAY(idx_ary)->ptr;
941
+ count = RARRAY_LEN(idx_ary);
942
+ indexes = RARRAY_PTR(idx_ary);
949
943
 
950
944
  for (i = 0; i < count; i++) {
951
945
  idx = NUM2INT(indexes[i]);
@@ -1084,7 +1078,7 @@ module RedShift
1084
1078
  }
1085
1079
 
1086
1080
  library.define(:s_init_flow).instance_eval do
1087
- arguments "void (*fn)()", "char *fname", "char *inspect_str", "int alg"
1081
+ arguments "void (*fn)()", "const char *fname", "const char *inspect_str", "int alg"
1088
1082
 
1089
1083
  fw_ssn = Component::FlowWrapper.shadow_struct_name
1090
1084
  fw_cname = library.declare_class Component::FlowWrapper
@@ -1106,7 +1100,7 @@ module RedShift
1106
1100
  end
1107
1101
 
1108
1102
  library.define(:s_init_guard).instance_eval do
1109
- arguments "void (*fn)()", "char *fname", "char *inspect_str", "int strict"
1103
+ arguments "int (*fn)()", "const char *fname", "const char *inspect_str", "int strict"
1110
1104
 
1111
1105
  gw_ssn = Component::GuardWrapper.shadow_struct_name
1112
1106
  gw_cname = library.declare_class Component::GuardWrapper
@@ -1128,7 +1122,7 @@ module RedShift
1128
1122
  end
1129
1123
 
1130
1124
  library.define(:s_init_expr).instance_eval do
1131
- arguments "void (*fn)()", "char *fname", "char *inspect_str"
1125
+ arguments "double (*fn)()", "const char *fname", "const char *inspect_str"
1132
1126
 
1133
1127
  ew_ssn = Component::ExprWrapper.shadow_struct_name
1134
1128
  ew_cname = library.declare_class Component::ExprWrapper
@@ -1210,10 +1204,11 @@ module RedShift
1210
1204
  long count;
1211
1205
  VALUE *flows;
1212
1206
  int has_diff;
1213
- struct RArray *ary;
1214
1207
  int flags;
1215
1208
  }.tabto(0)
1216
1209
 
1210
+ include("dvector/dvector.h")
1211
+
1217
1212
  body %{
1218
1213
  var_count = shadow->var_count;
1219
1214
  vars = (ContVar *)&FIRST_CONT_VAR(shadow);
@@ -1222,8 +1217,7 @@ module RedShift
1222
1217
  shadow->outgoing = rb_funcall(shadow->self,
1223
1218
  #{declare_symbol :outgoing_transition_data}, 0);
1224
1219
 
1225
- ary = RARRAY(shadow->outgoing);
1226
- flags = FIX2INT(ary->ptr[ary->len-1]);
1220
+ flags = FIX2INT(RARRAY_PTR(shadow->outgoing)[RARRAY_LEN(shadow->outgoing)-1]);
1227
1221
  shadow->strict = flags & 0x01;
1228
1222
  shadow->sleepable = !!(flags & 0x02);
1229
1223
 
@@ -1236,8 +1230,8 @@ module RedShift
1236
1230
 
1237
1231
  if (flow_array != Qnil) {
1238
1232
  #{"Check_Type(flow_array, T_ARRAY);\n" if $REDSHIFT_DEBUG}
1239
- count = RARRAY(flow_array)->len;
1240
- flows = RARRAY(flow_array)->ptr;
1233
+ count = RARRAY_LEN(flow_array);
1234
+ flows = RARRAY_PTR(flow_array);
1241
1235
 
1242
1236
  if (count > var_count)
1243
1237
  rs_raise(#{declare_class IndexError}, shadow->self,
@@ -1287,7 +1281,7 @@ module RedShift
1287
1281
  if (has_diff && !shadow->has_diff) {
1288
1282
  if (!shadow->diff_list) {
1289
1283
  if (shadow->world->diff_list) { //# 0 if loading
1290
- rb_ary_push(shadow->world->diff_list, shadow->self);
1284
+ rs_dv_push(rs_dv(shadow->world->diff_list), shadow->self);
1291
1285
  }
1292
1286
  shadow->diff_list = 1;
1293
1287
  }
@@ -110,7 +110,7 @@ module RedShift; class Flow
110
110
  VALUE event_values, event_val;
111
111
  event_values = shadow->event_values;
112
112
  assert(event_values != Qnil);
113
- event_val = RARRAY(event_values)->ptr[#{event_idx}];
113
+ event_val = RARRAY_PTR(event_values)[#{event_idx}];
114
114
  #{var_cname} = NUM2DBL(event_val);
115
115
  }
116
116
 
@@ -311,7 +311,7 @@ module RedShift; class Flow
311
311
  rs_raise(#{exc_nil}, ct->shadow->self, #{msg_nil.inspect});
312
312
  event_values = ct->#{link_cname}->event_values;
313
313
  assert(event_values != Qnil);
314
- event_val = RARRAY(event_values)->ptr[#{event_idx}];
314
+ event_val = RARRAY_PTR(event_values)[#{event_idx}];
315
315
  return NUM2DBL(event_val);
316
316
  }
317
317
  }
@@ -65,7 +65,7 @@ module RedShift; class AlgebraicFlow
65
65
 
66
66
  default:
67
67
  rb_raise(#{declare_class RuntimeError},
68
- "Bad rk_level, %d!", shadow->world->rk_level);
68
+ "Bad rk_level, %ld!", shadow->world->rk_level);
69
69
  }
70
70
 
71
71
  shadow->world->alg_nest--;
@@ -153,7 +153,7 @@ module RedShift; class DelayFlow
153
153
 
154
154
  default:
155
155
  rb_raise(#{declare_class RuntimeError},
156
- "Bad rk_level, %d!", shadow->world->rk_level);
156
+ "Bad rk_level, %ld!", shadow->world->rk_level);
157
157
  }
158
158
 
159
159
  shadow->world->rk_level++;
@@ -84,7 +84,7 @@ module RedShift; class DerivativeFlow
84
84
 
85
85
  default:
86
86
  rb_raise(#{declare_class RuntimeError},
87
- "Bad rk_level, %d!", shadow->world->rk_level);
87
+ "Bad rk_level, %ld!", shadow->world->rk_level);
88
88
  }
89
89
 
90
90
  shadow->world->rk_level++;
@@ -64,7 +64,7 @@ module RedShift; class RK4DifferentialFlow
64
64
 
65
65
  default:
66
66
  rb_raise(#{declare_class RuntimeError},
67
- "Bad rk_level, %d!", shadow->world->rk_level);
67
+ "Bad rk_level, %ld!", shadow->world->rk_level);
68
68
  }
69
69
 
70
70
  shadow->world->rk_level++;
@@ -22,9 +22,14 @@ module RedShift
22
22
  end
23
23
 
24
24
  include_file.include '<math.h>'
25
+
26
+ base = File.expand_path("../../../..", __FILE__)
27
+ ext_rs = File.join(base, "ext/redshift")
28
+ include_dirs << ext_rs
25
29
  end
26
30
 
27
31
  # Call this to link with external libraries. See examples/external-lib.rb.
32
+ # Note also include_dirs array.
28
33
  def link_with *libs
29
34
  (@link_libs ||= []) << libs
30
35
  end
@@ -5,14 +5,15 @@ class World
5
5
  shadow_library RedShift.library
6
6
  shadow_library_file "World"
7
7
  shadow_library_source_file.include(Component.shadow_library_include_file)
8
+ shadow_library_source_file.include("dvector/dvector.h")
8
9
 
9
10
  shadow_library_include_file.declare :step_discrete_macros => '
10
11
  #define INT2BOOL(i) (i ? Qtrue : Qfalse)
11
12
 
12
13
  #define SWAP_VALUE(v, w) {VALUE ___tmp = v; v = w; w = ___tmp;}
13
14
 
14
- #define EACH_COMP_DO(lc) \\
15
- for (list = RARRAY(lc), list_i = list->len - 1; \\
15
+ #define EACH_COMP_DO(lc) \\
16
+ for (list = rs_dv(lc), list_i = list->len - 1; \\
16
17
  list_i >= 0 && ( \\
17
18
  comp = list->ptr[list_i], \\
18
19
  comp_shdw = get_shadow(comp), \\
@@ -23,7 +24,7 @@ class World
23
24
  '.tabto(0)
24
25
  # Note: EACH_COMP_DO(lc) block may use move_comp and remove_comp
25
26
  # but it should (re)move none or all. Must have declarations for comp
26
- # comp_shdw, list, and list_i in scope.
27
+ # comp_shdw, list, and list_i in scope. lc must be a DVector.
27
28
 
28
29
  shadow_library_include_file.declare :cv_cache_entry => %{
29
30
  typedef struct {
@@ -60,19 +61,19 @@ class World
60
61
  sub.shadow_library_file file_name
61
62
  end
62
63
 
63
- shadow_attr_accessor :curr_A => Array
64
- shadow_attr_accessor :curr_P => Array
65
- shadow_attr_accessor :curr_CR => Array
66
- shadow_attr_accessor :curr_S => Array
67
- shadow_attr_accessor :next_S => Array
68
- shadow_attr_accessor :curr_T => Array
69
- shadow_attr_accessor :active_E => Array
70
- shadow_attr_accessor :prev_active_E => Array
71
- shadow_attr_accessor :awake => Array
72
- shadow_attr_accessor :prev_awake => Array
73
- shadow_attr_accessor :strict_sleep => Array
74
- shadow_attr_accessor :inert => Array
75
- shadow_attr_accessor :diff_list => Array
64
+ shadow_attr_accessor :curr_A => DVector
65
+ shadow_attr_accessor :curr_P => DVector
66
+ shadow_attr_accessor :curr_CR => DVector
67
+ shadow_attr_accessor :curr_S => DVector
68
+ shadow_attr_accessor :next_S => DVector
69
+ shadow_attr_accessor :curr_T => DVector
70
+ shadow_attr_accessor :active_E => DVector
71
+ shadow_attr_accessor :prev_active_E => DVector
72
+ shadow_attr_accessor :awake => DVector
73
+ shadow_attr_accessor :prev_awake => DVector
74
+ shadow_attr_accessor :strict_sleep => DVector
75
+ shadow_attr_accessor :inert => DVector
76
+ shadow_attr_accessor :diff_list => DVector
76
77
  shadow_attr_accessor :queue_sleep => Hash
77
78
  protected \
78
79
  :curr_A, :curr_P, :curr_CR, :curr_T,
@@ -191,7 +192,7 @@ class World
191
192
 
192
193
  define_c_method :step_continuous do
193
194
  declare :locals => %{
194
- VALUE comp_rb_ary[2], *comp_ary;
195
+ VALUE comp_dvector[2], *comp_ary;
195
196
  long len;
196
197
  long var_count;
197
198
  ContVar *var, *end_var;
@@ -199,11 +200,11 @@ class World
199
200
  ComponentShadow *comp_shdw;
200
201
  }.tabto(0)
201
202
  body %{
202
- comp_rb_ary[0] = shadow->awake;
203
- comp_rb_ary[1] = shadow->inert;
203
+ comp_dvector[0] = shadow->awake;
204
+ comp_dvector[1] = shadow->inert;
204
205
  for (li = 0; li < 2; li++) {
205
- len = RARRAY(comp_rb_ary[li])->len;
206
- comp_ary = RARRAY(comp_rb_ary[li])->ptr;
206
+ len = rs_dv(comp_dvector[li])->len;
207
+ comp_ary = rs_dv(comp_dvector[li])->ptr;
207
208
  for (ci = 0; ci < len; ci++) {
208
209
  Data_Get_Struct(comp_ary[ci], ComponentShadow, comp_shdw);
209
210
  var_count = comp_shdw->var_count;
@@ -221,8 +222,8 @@ class World
221
222
  }
222
223
 
223
224
  for (shadow->rk_level = 1; shadow->rk_level <= 3; shadow->rk_level++) {
224
- len = RARRAY(shadow->diff_list)->len;
225
- comp_ary = RARRAY(shadow->diff_list)->ptr;
225
+ len = rs_dv(shadow->diff_list)->len;
226
+ comp_ary = rs_dv(shadow->diff_list)->ptr;
226
227
  for (ci = 0; ci < len; ci++) {
227
228
  Data_Get_Struct(comp_ary[ci], ComponentShadow, comp_shdw);
228
229
 
@@ -231,7 +232,7 @@ class World
231
232
  comp_ary[ci] = comp_ary[len-1];
232
233
  ci--;
233
234
  }
234
- len = RARRAY(shadow->diff_list)->len = len-1;
235
+ len = rs_dv(shadow->diff_list)->len = len-1;
235
236
  comp_shdw->diff_list = 0;
236
237
  }
237
238
  else {
@@ -252,8 +253,8 @@ class World
252
253
 
253
254
  shadow->rk_level = 4;
254
255
  for (li = 0; li < 2; li++) {
255
- len = RARRAY(comp_rb_ary[li])->len;
256
- comp_ary = RARRAY(comp_rb_ary[li])->ptr;
256
+ len = rs_dv(comp_dvector[li])->len;
257
+ comp_ary = rs_dv(comp_dvector[li])->ptr;
257
258
  for (ci = 0; ci < len; ci++) {
258
259
  Data_Get_Struct(comp_ary[ci], ComponentShadow, comp_shdw);
259
260
  var_count = comp_shdw->var_count;
@@ -310,84 +311,80 @@ class World
310
311
  VALUE *ptr;
311
312
  long len;
312
313
  long i;
313
- struct RArray *list;
314
+ RS_DVector *list;
314
315
  int list_i;
315
316
  int did_reset;
316
317
  }.tabto(0)
317
318
 
318
319
  insteval_proc = declare_symbol :insteval_proc
319
- capa = RUBY_VERSION.to_f >= 1.7 ? "aux.capa" : "capa"
320
320
  epi = Component::EventPhaseItem
321
321
  spi = Component::SyncPhaseItem
322
322
 
323
323
  parent.declare :step_discrete_subs => %{
324
324
  inline static VALUE cur_syncs(ComponentShadow *comp_shdw)
325
325
  {
326
- VALUE syncs = RARRAY(comp_shdw->trans)->ptr[#{Transition::S_IDX}];
326
+ VALUE syncs = RARRAY_PTR(comp_shdw->trans)[#{Transition::S_IDX}];
327
327
  assert(syncs == Qnil || RBASIC(syncs)->klass == SyncClass);
328
328
  return syncs;
329
329
  }
330
330
  inline static VALUE cur_actions(ComponentShadow *comp_shdw)
331
331
  {
332
- VALUE actions = RARRAY(comp_shdw->trans)->ptr[#{Transition::A_IDX}];
332
+ VALUE actions = RARRAY_PTR(comp_shdw->trans)[#{Transition::A_IDX}];
333
333
  assert(actions == Qnil || RBASIC(actions)->klass == ActionClass);
334
334
  return actions;
335
335
  }
336
336
  inline static VALUE cur_posts(ComponentShadow *comp_shdw)
337
337
  {
338
- VALUE posts = RARRAY(comp_shdw->trans)->ptr[#{Transition::P_IDX}];
338
+ VALUE posts = RARRAY_PTR(comp_shdw->trans)[#{Transition::P_IDX}];
339
339
  assert(posts == Qnil || RBASIC(posts)->klass == PostClass);
340
340
  return posts;
341
341
  }
342
342
  inline static VALUE cur_events(ComponentShadow *comp_shdw)
343
343
  {
344
- VALUE events = RARRAY(comp_shdw->trans)->ptr[#{Transition::E_IDX}];
344
+ VALUE events = RARRAY_PTR(comp_shdw->trans)[#{Transition::E_IDX}];
345
345
  assert(events == Qnil || RBASIC(events)->klass == EventClass);
346
346
  return events;
347
347
  }
348
348
  inline static VALUE cur_resets(ComponentShadow *comp_shdw)
349
349
  {
350
- VALUE resets = RARRAY(comp_shdw->trans)->ptr[#{Transition::R_IDX}];
350
+ VALUE resets = RARRAY_PTR(comp_shdw->trans)[#{Transition::R_IDX}];
351
351
  assert(resets == Qnil || RBASIC(resets)->klass == ResetClass);
352
352
  return resets;
353
353
  }
354
354
  inline static VALUE cur_connects(ComponentShadow *comp_shdw)
355
355
  {
356
- VALUE connects = RARRAY(comp_shdw->trans)->ptr[#{Transition::C_IDX}];
356
+ VALUE connects = RARRAY_PTR(comp_shdw->trans)[#{Transition::C_IDX}];
357
357
  assert(connects == Qnil || RBASIC(connects)->klass == ConnectClass);
358
358
  return connects;
359
359
  }
360
360
  inline static void move_comp(VALUE comp, VALUE list, VALUE next_list)
361
361
  {
362
- struct RArray *nl = RARRAY(next_list);
363
- assert(RARRAY(list)->ptr[RARRAY(list)->len-1] == comp);
364
- if (nl->len == nl->#{capa})
365
- rb_ary_store(next_list, nl->len, comp);
366
- else
367
- nl->ptr[nl->len++] = comp;
368
- --RARRAY(list)->len;
362
+ RS_DVector *dv = rs_dv(next_list);
363
+ assert(rs_dv(list)->ptr[rs_dv(list)->len-1] == comp);
364
+ rs_dv_push(dv, comp);
365
+ --rs_dv(list)->len;
369
366
  }
370
367
  inline static void move_comp_to_hash(VALUE comp, VALUE list, VALUE hash)
371
368
  {
372
- struct RArray *l = RARRAY(list);
373
- assert(l->ptr[l->len-1] == comp);
369
+ RS_DVector *dv = rs_dv(list);
370
+ assert(dv->ptr[dv->len-1] == comp);
374
371
  rb_hash_aset(hash, comp, Qtrue);
375
- --l->len;
372
+ --dv->len;
376
373
  }
377
374
  inline static void move_all_comps(VALUE list, VALUE next_list)
378
375
  { //## this could be faster using memcpy
379
- struct RArray *l = RARRAY(list);
380
- while (l->len)
381
- move_comp(l->ptr[l->len-1], list, next_list);
376
+ RS_DVector *dv = rs_dv(list);
377
+ while (dv->len)
378
+ move_comp(dv->ptr[dv->len-1], list, next_list);
382
379
  }
383
380
  inline static void remove_comp(VALUE comp, VALUE list,
384
381
  #{World.shadow_struct_name} *shadow)
385
382
  {
386
383
  ComponentShadow *comp_shdw = get_shadow(comp);
387
- assert(RARRAY(list)->ptr[RARRAY(list)->len-1] == comp);
384
+ assert(rs_dv(list)->ptr[rs_dv(list)->len-1] == comp);
388
385
  assert(comp_shdw->world == shadow);
389
386
  comp_shdw->world = 0;
390
- --RARRAY(list)->len;
387
+ --rs_dv(list)->len;
391
388
  //%% hook_remove_comp(comp_shdw->self);
392
389
  }
393
390
  inline static double eval_expr(VALUE comp, VALUE expr)
@@ -425,8 +422,8 @@ class World
425
422
  int i;
426
423
  VALUE kl;
427
424
  assert(BUILTIN_TYPE(guards) == T_ARRAY);
428
- for (i = 0; i < RARRAY(guards)->len; i++) {
429
- VALUE guard = RARRAY(guards)->ptr[i];
425
+ for (i = 0; i < RARRAY_LEN(guards); i++) {
426
+ VALUE guard = RARRAY_PTR(guards)[i];
430
427
 
431
428
  if (SYMBOL_P(guard)) {
432
429
  if (!RTEST(rb_funcall(comp, SYM2ID(guard), 0)))
@@ -449,8 +446,8 @@ class World
449
446
  case T_ARRAY:
450
447
  kl = RBASIC(guard)->klass;
451
448
  if (kl == QMatchClass) {
452
- int len = RARRAY(guard)->len;
453
- VALUE *ptr = RARRAY(guard)->ptr;
449
+ int len = RARRAY_LEN(guard);
450
+ VALUE *ptr = RARRAY_PTR(guard);
454
451
  assert(len > 0);
455
452
  VALUE queue_name = ptr[0];
456
453
  VALUE queue = rb_funcall(comp, SYM2ID(queue_name), 0);
@@ -480,11 +477,11 @@ class World
480
477
  VALUE syncs = cur_syncs(comp_shdw);
481
478
  assert(RTEST(syncs));
482
479
 
483
- for (i = RARRAY(syncs)->len - 1; i >= 0; i--) {
484
- VALUE sync = RARRAY(syncs)->ptr[i];
485
- assert(RARRAY(sync)->len == 3);
486
- int link_offset = FIX2INT(RARRAY(sync)->ptr[#{spi::LINK_OFFSET_IDX}]);
487
- VALUE event = RARRAY(sync)->ptr[#{spi::EVENT_IDX}];
480
+ for (i = RARRAY_LEN(syncs) - 1; i >= 0; i--) {
481
+ VALUE sync = RARRAY_PTR(syncs)[i];
482
+ assert(RARRAY_LEN(sync) == 3);
483
+ int link_offset = FIX2INT(RARRAY_PTR(sync)[#{spi::LINK_OFFSET_IDX}]);
484
+ VALUE event = RARRAY_PTR(sync)[#{spi::EVENT_IDX}];
488
485
  ComponentShadow *link_shdw =
489
486
  *(ComponentShadow **)(((char *)comp_shdw) + link_offset);
490
487
 
@@ -496,11 +493,11 @@ class World
496
493
  int found = 0;
497
494
  VALUE link_events = cur_events(link_shdw);
498
495
  if (RTEST(link_events)) {
499
- VALUE *ptr = RARRAY(link_events)->ptr;
500
- long len = RARRAY(link_events)->len;
496
+ VALUE *ptr = RARRAY_PTR(link_events);
497
+ long len = RARRAY_LEN(link_events);
501
498
 
502
499
  for (j = len; j > 0; j--, ptr++) {
503
- VALUE link_event = RARRAY(*ptr)->ptr[#{epi::E_IDX}];
500
+ VALUE link_event = RARRAY_PTR(*ptr)[#{epi::E_IDX}];
504
501
  if (link_event == event) {
505
502
  found = 1;
506
503
  break;
@@ -525,14 +522,14 @@ class World
525
522
  int has_events = RTEST(events);
526
523
 
527
524
  if (has_events) {
528
- VALUE *ptr = RARRAY(events)->ptr;
529
- long len = RARRAY(events)->len;
525
+ VALUE *ptr = RARRAY_PTR(events);
526
+ long len = RARRAY_LEN(events);
530
527
  int i;
531
528
  VALUE comp = comp_shdw->self;
532
529
 
533
530
  for (i = len; i > 0; i--, ptr++) {
534
- int event_idx = FIX2INT(RARRAY(*ptr)->ptr[#{epi::I_IDX}]);
535
- VALUE event_val = RARRAY(*ptr)->ptr[#{epi::V_IDX}];
531
+ int event_idx = FIX2INT(RARRAY_PTR(*ptr)[#{epi::I_IDX}]);
532
+ VALUE event_val = RARRAY_PTR(*ptr)[#{epi::V_IDX}];
536
533
 
537
534
  //## maybe this distinction should be made clear in the array
538
535
  //## itself, with a numeric switch, say.
@@ -542,9 +539,9 @@ class World
542
539
  else if (rb_obj_is_kind_of(event_val, ExprWrapperClass))
543
540
  event_val = rb_float_new(eval_expr(comp, event_val));
544
541
 
545
- //%% hook_eval_event(comp, RARRAY(*ptr)->ptr[#{epi::E_IDX}],
542
+ //%% hook_eval_event(comp, RARRAY_PTR(*ptr)[#{epi::E_IDX}],
546
543
  //%% event_val);
547
- RARRAY(comp_shdw->next_event_values)->ptr[event_idx] = event_val;
544
+ RARRAY_PTR(comp_shdw->next_event_values)[event_idx] = event_val;
548
545
  }
549
546
  }
550
547
 
@@ -711,12 +708,12 @@ class World
711
708
  if (!RTEST(resets))
712
709
  return 0;
713
710
 
714
- cont_resets = RARRAY(resets)->ptr[0];
711
+ cont_resets = RARRAY_PTR(resets)[0];
715
712
  has_cont_resets = RTEST(cont_resets);
716
713
 
717
714
  if (has_cont_resets) {
718
- VALUE *ptr = RARRAY(cont_resets)->ptr;
719
- long len = RARRAY(cont_resets)->len;
715
+ VALUE *ptr = RARRAY_PTR(cont_resets);
716
+ long len = RARRAY_LEN(cont_resets);
720
717
  int i;
721
718
  VALUE comp = comp_shdw->self;
722
719
  ContVar *var = (ContVar *)&FIRST_CONT_VAR(comp_shdw);
@@ -724,6 +721,7 @@ class World
724
721
 
725
722
  for (i = 0; i < len; i++, var++, ptr++) {
726
723
  VALUE reset = *ptr;
724
+ VALUE class_name;
727
725
  if (reset == Qnil) {
728
726
  var->reset = 0;
729
727
  }
@@ -736,25 +734,25 @@ class World
736
734
 
737
735
  switch(TYPE(reset)) {
738
736
  case T_FLOAT:
739
- new_value = RFLOAT(reset)->value;
737
+ new_value = RFLOAT_VALUE(reset);
740
738
  break;
741
739
  default:
742
740
  if (RBASIC(reset)->klass == rb_cProc) {
743
741
  VALUE val = rb_funcall(comp, #{insteval_proc}, 1, reset);
744
742
  switch(TYPE(val)) {
745
743
  case T_FLOAT:
746
- new_value = RFLOAT(val)->value;
744
+ new_value = RFLOAT_VALUE(val);
747
745
  break;
748
746
  case T_FIXNUM:
749
747
  new_value = FIX2INT(val);
750
748
  break;
751
749
  default:
750
+ class_name = rb_funcall(
751
+ rb_funcall(val, #{declare_symbol :class}, 0),
752
+ #{declare_symbol :to_s}, 0);
752
753
  rs_raise(#{declare_class VarTypeError}, comp,
753
754
  "tried to reset cont var with %s.",
754
- STR2CSTR(rb_funcall(
755
- rb_funcall(val, #{declare_symbol :class}, 0),
756
- #{declare_symbol :to_s},
757
- 0))
755
+ StringValuePtr(class_name)
758
756
  );
759
757
  }
760
758
  }
@@ -789,25 +787,25 @@ class World
789
787
  if (!RTEST(resets))
790
788
  return 0;
791
789
 
792
- const_resets = RARRAY(resets)->ptr[1];
793
- link_resets = RARRAY(resets)->ptr[2];
790
+ const_resets = RARRAY_PTR(resets)[1];
791
+ link_resets = RARRAY_PTR(resets)[2];
794
792
  has_const_resets = RTEST(const_resets);
795
793
  has_link_resets = RTEST(link_resets);
796
794
  comp = comp_shdw->self;
797
795
 
798
796
  if (has_const_resets) {
799
- VALUE *ptr = RARRAY(const_resets)->ptr;
800
- long len = RARRAY(const_resets)->len;
797
+ VALUE *ptr = RARRAY_PTR(const_resets);
798
+ long len = RARRAY_LEN(const_resets);
801
799
 
802
800
  for (i = 0; i < len; i++) {
803
801
  VALUE pair = ptr[i];
804
- int offset = NUM2INT(RARRAY(pair)->ptr[0]);
805
- VALUE reset = RARRAY(pair)->ptr[1];
802
+ int offset = NUM2INT(RARRAY_PTR(pair)[0]);
803
+ VALUE reset = RARRAY_PTR(pair)[1];
806
804
  double new_value;
807
805
 
808
806
  switch(TYPE(reset)) {
809
807
  case T_FLOAT:
810
- new_value = RFLOAT(reset)->value;
808
+ new_value = RFLOAT_VALUE(reset);
811
809
  break;
812
810
  default:
813
811
  if (RBASIC(reset)->klass == rb_cProc)
@@ -818,7 +816,7 @@ class World
818
816
  }
819
817
 
820
818
  //%% hook_eval_reset_constant(comp,
821
- //%% RARRAY(pair)->ptr[2], rb_float_new(new_value));
819
+ //%% RARRAY_PTR(pair)[2], rb_float_new(new_value));
822
820
  cache_new_constant_value(
823
821
  (double *)((char *)comp_shdw + offset),
824
822
  new_value, shadow);
@@ -826,13 +824,13 @@ class World
826
824
  }
827
825
 
828
826
  if (has_link_resets) {
829
- VALUE *ptr = RARRAY(link_resets)->ptr;
830
- long len = RARRAY(link_resets)->len;
827
+ VALUE *ptr = RARRAY_PTR(link_resets);
828
+ long len = RARRAY_LEN(link_resets);
831
829
 
832
830
  for (i = 0; i < len; i++) {
833
831
  VALUE pair = ptr[i];
834
- int offset = NUM2INT(RARRAY(pair)->ptr[0]);
835
- VALUE reset = RARRAY(pair)->ptr[1];
832
+ int offset = NUM2INT(RARRAY_PTR(pair)[0]);
833
+ VALUE reset = RARRAY_PTR(pair)[1];
836
834
  VALUE new_value;
837
835
 
838
836
  if (rb_obj_is_kind_of(reset, ExprWrapperClass)) {
@@ -852,19 +850,23 @@ class World
852
850
  }
853
851
 
854
852
  if (!NIL_P(new_value) &&
855
- rb_obj_is_kind_of(new_value, RARRAY(pair)->ptr[3]) != Qtrue) {
853
+ rb_obj_is_kind_of(new_value, RARRAY_PTR(pair)[3]) != Qtrue) {
856
854
  VALUE to_s = #{declare_symbol :to_s};
855
+ VALUE s1 = rb_funcall(RARRAY_PTR(pair)[2], to_s, 0);
856
+ VALUE s2 = rb_funcall(RARRAY_PTR(pair)[3], to_s, 0);
857
+ VALUE s3 = rb_funcall(
858
+ rb_funcall(new_value, #{declare_symbol :class}, 0), to_s, 0);
859
+
857
860
  rs_raise(#{declare_class LinkTypeError}, comp_shdw->self,
858
861
  "tried to reset %s, which is declared %s, with %s.",
859
- STR2CSTR(rb_funcall(RARRAY(pair)->ptr[2], to_s, 0)),
860
- STR2CSTR(rb_funcall(RARRAY(pair)->ptr[3], to_s, 0)),
861
- STR2CSTR(rb_funcall(
862
- rb_funcall(new_value, #{declare_symbol :class}, 0), to_s, 0))
862
+ StringValuePtr(s1),
863
+ StringValuePtr(s2),
864
+ StringValuePtr(s3)
863
865
  );
864
866
  }
865
867
 
866
868
  //%% hook_eval_reset_link(comp,
867
- //%% RARRAY(pair)->ptr[2], (VALUE)new_value);
869
+ //%% RARRAY_PTR(pair)[2], (VALUE)new_value);
868
870
  cache_new_link(
869
871
  (ComponentShadow **)((char *)comp_shdw + offset),
870
872
  new_value, shadow);
@@ -884,13 +886,13 @@ class World
884
886
  else {
885
887
  int i;
886
888
  VALUE comp = comp_shdw->self;
887
- VALUE *ptr = RARRAY(connects)->ptr;
888
- long len = RARRAY(connects)->len;
889
+ VALUE *ptr = RARRAY_PTR(connects);
890
+ long len = RARRAY_LEN(connects);
889
891
 
890
892
  for (i = 0; i < len; i++) {
891
893
  VALUE pair = ptr[i];
892
- VALUE input_var = RARRAY(pair)->ptr[0];
893
- VALUE connect_spec = RARRAY(pair)->ptr[1];
894
+ VALUE input_var = RARRAY_PTR(pair)[0];
895
+ VALUE connect_spec = RARRAY_PTR(pair)[1];
894
896
  VALUE input_port;
895
897
  VALUE other_port;
896
898
 
@@ -925,11 +927,11 @@ class World
925
927
  if (!RTEST(resets))
926
928
  return 0;
927
929
 
928
- cont_resets = RARRAY(resets)->ptr[0];
930
+ cont_resets = RARRAY_PTR(resets)[0];
929
931
  var = (ContVar *)&FIRST_CONT_VAR(comp_shdw);
930
932
  did_reset = 0;
931
933
 
932
- len = RARRAY(cont_resets)->len;
934
+ len = RARRAY_LEN(cont_resets);
933
935
  for (i = len; i > 0; i--, var++) {
934
936
  if (var->reset) {
935
937
  var->reset = 0;
@@ -948,8 +950,8 @@ class World
948
950
 
949
951
  assert(RTEST(actions));
950
952
 
951
- for (i = 0; i < RARRAY(actions)->len; i++) {
952
- VALUE val = RARRAY(actions)->ptr[i];
953
+ for (i = 0; i < RARRAY_LEN(actions); i++) {
954
+ VALUE val = RARRAY_PTR(actions)[i];
953
955
  //%% hook_call_action(comp, val);
954
956
 
955
957
  if (SYMBOL_P(val))
@@ -959,8 +961,8 @@ class World
959
961
  //## this tech. could be applied in EVENT and RESET.
960
962
  //## also, component-gen can make use of this optimization
961
963
  //## for procs, using code similar to that for guards.
962
- //# rb_obj_instance_eval(1, &RARRAY(actions)->ptr[i], comp);
963
- //# rb_iterate(my_instance_eval, comp, call_block, RARRAY(actions)->ptr[i]);
964
+ //# rb_obj_instance_eval(1, &RARRAY_PTR(actions)[i], comp);
965
+ //# rb_iterate(my_instance_eval, comp, call_block, RARRAY_PTR(actions)[i]);
964
966
  }
965
967
  }
966
968
 
@@ -1034,7 +1036,7 @@ class World
1034
1036
  {
1035
1037
  VALUE comp;
1036
1038
  ComponentShadow *comp_shdw;
1037
- struct RArray *list;
1039
+ RS_DVector *list;
1038
1040
  int list_i;
1039
1041
  VALUE *ptr;
1040
1042
  long len, cur;
@@ -1045,7 +1047,7 @@ class World
1045
1047
  if (shadow->discrete_step == 0)
1046
1048
  comp_shdw->checked = 0;
1047
1049
 
1048
- len = RARRAY(comp_shdw->outgoing)->len - 1; //# last is flags
1050
+ len = RARRAY_LEN(comp_shdw->outgoing) - 1; //# last is flags
1049
1051
  cur = len;
1050
1052
 
1051
1053
  if (len == 0) {
@@ -1053,7 +1055,7 @@ class World
1053
1055
  continue;
1054
1056
  }
1055
1057
 
1056
- ptr = RARRAY(comp_shdw->outgoing)->ptr;
1058
+ ptr = RARRAY_PTR(comp_shdw->outgoing);
1057
1059
  if (sync_retry)
1058
1060
  cur -= 4 * comp_shdw->tmp.trans.idx;
1059
1061
  else
@@ -1102,14 +1104,14 @@ class World
1102
1104
  comp_shdw->checked = 1;
1103
1105
  }
1104
1106
  }
1105
- assert(RARRAY(shadow->prev_awake)->len == 0);
1107
+ assert(rs_dv(shadow->prev_awake)->len == 0);
1106
1108
  }
1107
1109
 
1108
1110
  inline static void do_sync_phase(#{World.shadow_struct_name} *shadow)
1109
1111
  {
1110
1112
  VALUE comp;
1111
1113
  ComponentShadow *comp_shdw;
1112
- struct RArray *list;
1114
+ RS_DVector *list;
1113
1115
  int list_i;
1114
1116
  int changed;
1115
1117
 
@@ -1126,7 +1128,7 @@ class World
1126
1128
  }
1127
1129
  }
1128
1130
 
1129
- assert(RARRAY(shadow->curr_S)->len == 0);
1131
+ assert(rs_dv(shadow->curr_S)->len == 0);
1130
1132
  SWAP_VALUE(shadow->curr_S, shadow->next_S);
1131
1133
  //%% hook_sync_step(shadow->curr_S, INT2BOOL(changed));
1132
1134
  } while (changed);
@@ -1163,7 +1165,7 @@ class World
1163
1165
 
1164
1166
  SWAP_VALUE(shadow->prev_awake, shadow->awake);
1165
1167
 
1166
- while (RARRAY(shadow->prev_awake)->len) {
1168
+ while (rs_dv(shadow->prev_awake)->len) {
1167
1169
  //%% hook_enter_guard_phase();
1168
1170
  check_guards(shadow, sync_retry);
1169
1171
  //%% hook_leave_guard_phase();
@@ -1174,7 +1176,7 @@ class World
1174
1176
  sync_retry = 1;
1175
1177
  }
1176
1178
 
1177
- if (!RARRAY(shadow->curr_T)->len) {
1179
+ if (!rs_dv(shadow->curr_T)->len) {
1178
1180
  //%% hook_end_step();
1179
1181
  break; //# out of main loop
1180
1182
  }
@@ -1182,7 +1184,7 @@ class World
1182
1184
  EACH_COMP_DO(shadow->curr_T) {
1183
1185
  //%% hook_begin_eval_events(comp);
1184
1186
  if (eval_events(comp_shdw, shadow))
1185
- rb_ary_push(shadow->active_E, comp);
1187
+ rs_dv_push(rs_dv(shadow->active_E), comp);
1186
1188
  //%% hook_end_eval_events(comp);
1187
1189
  }
1188
1190
 
@@ -1192,22 +1194,22 @@ class World
1192
1194
  //%% hook_export_events(comp, comp_shdw->event_values);
1193
1195
  }
1194
1196
  SWAP_VALUE(shadow->active_E, shadow->prev_active_E);
1195
- assert(RARRAY(shadow->active_E)->len == 0);
1197
+ assert(rs_dv(shadow->active_E)->len == 0);
1196
1198
 
1197
1199
  //%% hook_enter_eval_phase();
1198
1200
  EACH_COMP_DO(shadow->curr_T) {
1199
1201
  //%% hook_begin_eval_resets(comp);
1200
1202
  if (eval_continuous_resets(comp_shdw, shadow))
1201
- rb_ary_push(shadow->curr_CR, comp);
1203
+ rs_dv_push(rs_dv(shadow->curr_CR), comp);
1202
1204
  eval_constant_resets(comp_shdw, shadow);
1203
1205
  eval_port_connects(comp_shdw, shadow);
1204
1206
  //%% hook_end_eval_resets(comp);
1205
1207
 
1206
1208
  if (RTEST(cur_actions(comp_shdw)))
1207
- rb_ary_push(shadow->curr_A, comp);
1209
+ rs_dv_push(rs_dv(shadow->curr_A), comp);
1208
1210
 
1209
1211
  if (RTEST(cur_posts(comp_shdw)))
1210
- rb_ary_push(shadow->curr_P, comp);
1212
+ rs_dv_push(rs_dv(shadow->curr_P), comp);
1211
1213
  }
1212
1214
  //%% hook_leave_eval_phase();
1213
1215
 
@@ -1215,7 +1217,7 @@ class World
1215
1217
  EACH_COMP_DO(shadow->curr_A) {
1216
1218
  do_actions(comp_shdw, cur_actions(comp_shdw), shadow);
1217
1219
  }
1218
- RARRAY(shadow->curr_A)->len = 0;
1220
+ rs_dv(shadow->curr_A)->len = 0;
1219
1221
  //%% hook_leave_action_phase();
1220
1222
 
1221
1223
  //%% hook_begin_parallel_assign();
@@ -1223,7 +1225,7 @@ class World
1223
1225
  EACH_COMP_DO(shadow->curr_CR) {
1224
1226
  did_reset = assign_new_cont_values(comp_shdw) || did_reset;
1225
1227
  }
1226
- RARRAY(shadow->curr_CR)->len = 0;
1228
+ rs_dv(shadow->curr_CR)->len = 0;
1227
1229
  did_reset = assign_new_constant_values(shadow) || did_reset;
1228
1230
  did_reset = assign_new_links(shadow) || did_reset;
1229
1231
  did_reset = assign_new_ports(shadow) || did_reset;
@@ -1233,7 +1235,7 @@ class World
1233
1235
  EACH_COMP_DO(shadow->curr_P) {
1234
1236
  do_actions(comp_shdw, cur_posts(comp_shdw), shadow);
1235
1237
  }
1236
- RARRAY(shadow->curr_P)->len = 0;
1238
+ rs_dv(shadow->curr_P)->len = 0;
1237
1239
  //%% hook_leave_post_phase();
1238
1240
 
1239
1241
  EACH_COMP_DO(shadow->curr_T) {
@@ -1264,15 +1266,15 @@ class World
1264
1266
  else
1265
1267
  move_comp(comp, shadow->curr_T, shadow->awake);
1266
1268
  }
1267
- assert(RARRAY(shadow->curr_T)->len == 0);
1268
- assert(RARRAY(shadow->prev_awake)->len == 0);
1269
+ assert(rs_dv(shadow->curr_T)->len == 0);
1270
+ assert(rs_dv(shadow->prev_awake)->len == 0);
1269
1271
 
1270
1272
  //# Clear event values.
1271
1273
  EACH_COMP_DO(shadow->prev_active_E) {
1272
- rb_mem_clear(RARRAY(comp_shdw->event_values)->ptr,
1273
- RARRAY(comp_shdw->event_values)->len);
1274
+ rb_mem_clear(RARRAY_PTR(comp_shdw->event_values),
1275
+ RARRAY_LEN(comp_shdw->event_values));
1274
1276
  }
1275
- RARRAY(shadow->prev_active_E)->len = 0;
1277
+ rs_dv(shadow->prev_active_E)->len = 0;
1276
1278
 
1277
1279
  //%% hook_end_step();
1278
1280
  }
@@ -1302,9 +1304,10 @@ class World
1302
1304
 
1303
1305
  cl.class_eval do
1304
1306
  shadow_library_source_file.include(Component.shadow_library_include_file)
1307
+ shadow_library_source_file.include("dvector/dvector.h")
1305
1308
 
1306
1309
  if (instance_methods(false) + protected_instance_methods(false) +
1307
- private_instance_methods(false)).include?("step_discrete")
1310
+ private_instance_methods(false)).grep(/^step_discrete$/).size > 0
1308
1311
  warn "Redefining step_discrete in #{self}"
1309
1312
  end
1310
1313
 
@@ -1315,7 +1318,7 @@ class World
1315
1318
  # at this point, we know the file is complete
1316
1319
  file_str = meth.parent.to_s
1317
1320
 
1318
- known_hooks ||= file_str.scan(hook)
1321
+ known_hooks ||= file_str.scan(hook).map {|s|s.to_sym}
1319
1322
  unknown_hooks = cl_hooks - known_hooks
1320
1323
 
1321
1324
  unless unknown_hooks.empty?