redshift 1.3.22 → 1.3.23
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/.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?
|