methodmissing-channel 1.0.0 → 1.0.1
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/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
|