methodmissing-channel 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +2 -1
- data/Rakefile +2 -1
- data/bench/bench.rb +1 -1
- data/bench/ruby_channel.rb +9 -2
- data/channel.gemspec +1 -1
- data/ext/channel/channel.c +38 -11
- metadata +3 -2
data/README
CHANGED
@@ -32,7 +32,7 @@ Caveats :
|
|
32
32
|
Examples :
|
33
33
|
|
34
34
|
counter = 0
|
35
|
-
ch = Channel.new.subscribe{|obj|
|
35
|
+
ch = Channel.new.subscribe{|obj| counter += obj }
|
36
36
|
ch << 3
|
37
37
|
ch << -2
|
38
38
|
counter #=> 1
|
@@ -41,6 +41,7 @@ Todo :
|
|
41
41
|
|
42
42
|
* A deferrable mode that notifies on a background thread
|
43
43
|
* More flexible notification mechanism through integration with http://github.com/methodmissing/callback/tree/master
|
44
|
+
* Filters
|
44
45
|
|
45
46
|
To run the test suite:
|
46
47
|
|
data/Rakefile
CHANGED
data/bench/bench.rb
CHANGED
data/bench/ruby_channel.rb
CHANGED
@@ -1,12 +1,19 @@
|
|
1
1
|
class RubyChannel
|
2
|
-
def initialize
|
2
|
+
def initialize(size = 1,defer = false)
|
3
|
+
@size = size
|
3
4
|
@subscribers = []
|
5
|
+
@defer = defer
|
4
6
|
end
|
5
7
|
def subscribe(&b)
|
8
|
+
raise ArgumentError.new("Maximum number of subscribers exceeded!") unless @subscribers.size < @size
|
6
9
|
@subscribers << b
|
7
10
|
self
|
8
11
|
end
|
9
12
|
def <<(o)
|
10
|
-
@
|
13
|
+
unless @defer
|
14
|
+
@subscribers.each { |s| s.call(o) }
|
15
|
+
else
|
16
|
+
Thread.new{ @subscribers.each { |s| s.call(o) } }
|
17
|
+
end
|
11
18
|
end
|
12
19
|
end
|
data/channel.gemspec
CHANGED
data/ext/channel/channel.c
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
#include "ruby.h"
|
2
2
|
|
3
3
|
typedef struct {
|
4
|
-
|
5
|
-
|
4
|
+
int size;
|
5
|
+
int defer;
|
6
|
+
int sbs;
|
6
7
|
VALUE *subscribers;
|
7
8
|
} RChannel;
|
8
9
|
|
@@ -33,6 +34,7 @@ channel_alloc( VALUE klass )
|
|
33
34
|
RChannel* chs;
|
34
35
|
ch = Data_Make_Struct(klass, RChannel, mark_channel, free_channel, chs);
|
35
36
|
chs->size = 0;
|
37
|
+
chs->defer = 0;
|
36
38
|
chs->sbs = 0;
|
37
39
|
chs->subscribers = 0;
|
38
40
|
|
@@ -40,7 +42,7 @@ channel_alloc( VALUE klass )
|
|
40
42
|
}
|
41
43
|
|
42
44
|
static VALUE
|
43
|
-
rb_channel_new(VALUE ch, int size)
|
45
|
+
rb_channel_new(VALUE ch, int size, int defer)
|
44
46
|
{
|
45
47
|
RChannel* chs = GetChannelStruct(ch);
|
46
48
|
if (size < 0 || size > MAX_CHANNEL_SIZE){
|
@@ -48,6 +50,7 @@ rb_channel_new(VALUE ch, int size)
|
|
48
50
|
}
|
49
51
|
if (size == 0) size++;
|
50
52
|
chs->size = size;
|
53
|
+
chs->defer = defer;
|
51
54
|
chs->subscribers = ALLOC_N(VALUE, size);
|
52
55
|
return ch;
|
53
56
|
}
|
@@ -55,11 +58,12 @@ rb_channel_new(VALUE ch, int size)
|
|
55
58
|
static VALUE
|
56
59
|
rb_channel_initialize( int argc, VALUE *argv, VALUE ch )
|
57
60
|
{
|
58
|
-
VALUE size;
|
59
|
-
int channel_size;
|
60
|
-
rb_scan_args(argc, argv, "
|
61
|
+
VALUE size, defer;
|
62
|
+
int channel_size, def;
|
63
|
+
rb_scan_args(argc, argv, "02", &size, &defer);
|
61
64
|
channel_size = NIL_P(size) ? 0 : FIX2INT(size);
|
62
|
-
|
65
|
+
def = (defer == Qtrue) ? 1 : 0;
|
66
|
+
return rb_channel_new(ch, channel_size, def);
|
63
67
|
}
|
64
68
|
|
65
69
|
static VALUE
|
@@ -76,25 +80,47 @@ rb_channel_subscribers( VALUE ch )
|
|
76
80
|
return INT2FIX(chs->sbs);
|
77
81
|
}
|
78
82
|
|
83
|
+
static VALUE
|
84
|
+
rb_channel_deferrable_p( VALUE ch )
|
85
|
+
{
|
86
|
+
RChannel* chs = GetChannelStruct(ch);
|
87
|
+
return (chs->defer == 1) ? Qtrue : Qfalse;
|
88
|
+
}
|
89
|
+
|
79
90
|
static VALUE
|
80
91
|
rb_channel_subscribe( int argc, VALUE *argv, VALUE ch )
|
81
92
|
{
|
82
93
|
VALUE cb;
|
83
94
|
RChannel* chs = GetChannelStruct(ch);
|
84
95
|
if (!rb_block_given_p()) rb_raise(rb_eArgError, "Block callback required!");
|
96
|
+
if (chs->sbs == chs->size) rb_raise(rb_eArgError, "Maximum number of subscribers exceeded!");
|
85
97
|
cb = rb_block_proc();
|
86
98
|
chs->subscribers[chs->sbs] = cb;
|
87
99
|
chs->sbs++;
|
88
100
|
return ch;
|
89
101
|
}
|
90
102
|
|
103
|
+
static void
|
104
|
+
rb_channel_push0( RChannel* chs, VALUE *ch, VALUE *obj )
|
105
|
+
{
|
106
|
+
int i;
|
107
|
+
for (i=0; i < chs->sbs; i++) {
|
108
|
+
rb_funcall(chs->subscribers[i],id_call,1,*obj);
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
91
112
|
static VALUE
|
92
113
|
rb_channel_push( VALUE ch, VALUE obj )
|
93
114
|
{
|
94
|
-
|
95
|
-
RChannel* chs = GetChannelStruct(ch);
|
96
|
-
|
97
|
-
|
115
|
+
void *args[3];
|
116
|
+
RChannel* chs = GetChannelStruct(ch);
|
117
|
+
if (chs->defer == 1){
|
118
|
+
args[0] = chs;
|
119
|
+
args[1] = &ch;
|
120
|
+
args[2] = &obj;
|
121
|
+
rb_thread_create( rb_channel_push0, &args);
|
122
|
+
}else{
|
123
|
+
rb_channel_push0(chs,&ch,&obj);
|
98
124
|
}
|
99
125
|
return ch;
|
100
126
|
}
|
@@ -110,6 +136,7 @@ Init_channel()
|
|
110
136
|
rb_define_method(rb_cChannel,"initialize", rb_channel_initialize, -1);
|
111
137
|
rb_define_method(rb_cChannel,"size", rb_channel_size, 0);
|
112
138
|
rb_define_method(rb_cChannel,"subscribers", rb_channel_subscribers, 0);
|
139
|
+
rb_define_method(rb_cChannel,"deferrable?", rb_channel_deferrable_p, 0);
|
113
140
|
rb_define_method(rb_cChannel,"subscribe", rb_channel_subscribe, -1);
|
114
141
|
rb_define_method(rb_cChannel,"<<", rb_channel_push, 1);
|
115
142
|
}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: methodmissing-channel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Lourens Naud\xC3\xA9 (methodmissing)"
|
@@ -32,6 +32,7 @@ files:
|
|
32
32
|
- channel.gemspec
|
33
33
|
has_rdoc: true
|
34
34
|
homepage: http://github.com/methodmissing/channel
|
35
|
+
licenses:
|
35
36
|
post_install_message:
|
36
37
|
rdoc_options:
|
37
38
|
- --main
|
@@ -53,7 +54,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
54
|
requirements: []
|
54
55
|
|
55
56
|
rubyforge_project:
|
56
|
-
rubygems_version: 1.
|
57
|
+
rubygems_version: 1.3.5
|
57
58
|
signing_key:
|
58
59
|
specification_version: 2
|
59
60
|
summary: Native MRI channel
|