redshift 1.3.22 → 1.3.23
Sign up to get free protection for your applications and to get access to all the features.
- data/.bnsignore +27 -0
- data/RELEASE-NOTES +6 -0
- data/bench/aug17-ruby19.bench +86 -0
- data/bench/aug17.bench +86 -0
- data/bench/aug7.bench +86 -0
- data/bench/bench +4 -1
- data/bench/prof.html +0 -0
- data/ext/redshift/buffer/buffer.c +3 -1
- data/ext/redshift/dvector/dvector.c +236 -0
- data/ext/redshift/dvector/dvector.h +36 -0
- data/ext/redshift/dvector/dvector.rb +33 -0
- data/ext/redshift/dvector/extconf.rb +2 -0
- data/lib/redshift/redshift.rb +1 -1
- data/lib/redshift/target/c/component-gen.rb +17 -23
- data/lib/redshift/target/c/flow-gen.rb +2 -2
- data/lib/redshift/target/c/flow/algebraic.rb +1 -1
- data/lib/redshift/target/c/flow/delay.rb +1 -1
- data/lib/redshift/target/c/flow/derivative.rb +1 -1
- data/lib/redshift/target/c/flow/rk4.rb +1 -1
- data/lib/redshift/target/c/library.rb +5 -0
- data/lib/redshift/target/c/world-gen.rb +130 -127
- data/lib/redshift/util/isaac.rb +2 -2
- data/lib/redshift/util/random.rb +1 -1
- data/lib/redshift/world.rb +11 -6
- data/test/test_discrete.rb +1 -1
- data/test/test_discrete_isolated.rb +1 -1
- data/test/test_dvector.rb +110 -0
- data/test/test_flow.rb +1 -1
- data/test/test_flow_link.rb +1 -1
- data/test/test_flow_sub.rb +1 -1
- data/test/test_flow_trans.rb +3 -3
- data/test/test_inherit_event.rb +1 -1
- data/test/test_inherit_flow.rb +1 -1
- data/test/test_inherit_link.rb +1 -1
- data/test/test_inherit_state.rb +1 -1
- data/test/test_inherit_transition.rb +1 -1
- data/test/test_setup.rb +1 -1
- data/test/test_strict_continuity.rb +1 -1
- data/test/test_world.rb +4 -4
- 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
|
data/lib/redshift/redshift.rb
CHANGED
@@ -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
|
-
|
742
|
-
|
743
|
-
|
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 =
|
948
|
-
indexes =
|
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 "
|
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 "
|
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
|
-
|
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 =
|
1240
|
-
flows =
|
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
|
-
|
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 =
|
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 =
|
314
|
+
event_val = RARRAY_PTR(event_values)[#{event_idx}];
|
315
315
|
return NUM2DBL(event_val);
|
316
316
|
}
|
317
317
|
}
|
@@ -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 =
|
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 =>
|
64
|
-
shadow_attr_accessor :curr_P =>
|
65
|
-
shadow_attr_accessor :curr_CR =>
|
66
|
-
shadow_attr_accessor :curr_S =>
|
67
|
-
shadow_attr_accessor :next_S =>
|
68
|
-
shadow_attr_accessor :curr_T =>
|
69
|
-
shadow_attr_accessor :active_E =>
|
70
|
-
shadow_attr_accessor :prev_active_E =>
|
71
|
-
shadow_attr_accessor :awake =>
|
72
|
-
shadow_attr_accessor :prev_awake =>
|
73
|
-
shadow_attr_accessor :strict_sleep =>
|
74
|
-
shadow_attr_accessor :inert =>
|
75
|
-
shadow_attr_accessor :diff_list =>
|
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
|
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
|
-
|
203
|
-
|
203
|
+
comp_dvector[0] = shadow->awake;
|
204
|
+
comp_dvector[1] = shadow->inert;
|
204
205
|
for (li = 0; li < 2; li++) {
|
205
|
-
len =
|
206
|
-
comp_ary =
|
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 =
|
225
|
-
comp_ary =
|
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 =
|
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 =
|
256
|
-
comp_ary =
|
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
|
-
|
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 =
|
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 =
|
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 =
|
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 =
|
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 =
|
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 =
|
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
|
-
|
363
|
-
assert(
|
364
|
-
|
365
|
-
|
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
|
-
|
373
|
-
assert(
|
369
|
+
RS_DVector *dv = rs_dv(list);
|
370
|
+
assert(dv->ptr[dv->len-1] == comp);
|
374
371
|
rb_hash_aset(hash, comp, Qtrue);
|
375
|
-
--
|
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
|
-
|
380
|
-
while (
|
381
|
-
move_comp(
|
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(
|
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
|
-
--
|
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 <
|
429
|
-
VALUE guard =
|
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 =
|
453
|
-
VALUE *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 =
|
484
|
-
VALUE sync =
|
485
|
-
assert(
|
486
|
-
int link_offset = FIX2INT(
|
487
|
-
VALUE event =
|
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 =
|
500
|
-
long 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 =
|
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 =
|
529
|
-
long 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(
|
535
|
-
VALUE event_val =
|
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,
|
542
|
+
//%% hook_eval_event(comp, RARRAY_PTR(*ptr)[#{epi::E_IDX}],
|
546
543
|
//%% event_val);
|
547
|
-
|
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 =
|
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 =
|
719
|
-
long 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 =
|
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 =
|
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
|
-
|
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 =
|
793
|
-
link_resets =
|
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 =
|
800
|
-
long 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(
|
805
|
-
VALUE reset =
|
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 =
|
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
|
-
//%%
|
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 =
|
830
|
-
long 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(
|
835
|
-
VALUE reset =
|
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,
|
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
|
-
|
860
|
-
|
861
|
-
|
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
|
-
//%%
|
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 =
|
888
|
-
long 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 =
|
893
|
-
VALUE connect_spec =
|
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 =
|
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 =
|
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 <
|
952
|
-
VALUE val =
|
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, &
|
963
|
-
//# rb_iterate(my_instance_eval, comp, call_block,
|
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
|
-
|
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 =
|
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 =
|
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(
|
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
|
-
|
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(
|
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 (
|
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 (!
|
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
|
-
|
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(
|
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
|
-
|
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
|
-
|
1209
|
+
rs_dv_push(rs_dv(shadow->curr_A), comp);
|
1208
1210
|
|
1209
1211
|
if (RTEST(cur_posts(comp_shdw)))
|
1210
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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(
|
1268
|
-
assert(
|
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(
|
1273
|
-
|
1274
|
+
rb_mem_clear(RARRAY_PTR(comp_shdw->event_values),
|
1275
|
+
RARRAY_LEN(comp_shdw->event_values));
|
1274
1276
|
}
|
1275
|
-
|
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)).
|
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?
|