eventable 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.DS_Store +0 -0
- data/README.markdown +16 -1
- data/eventable.gemspec +6 -1
- data/example/example_output.txt +56 -0
- data/example/simple_output.txt +2 -0
- data/lib/.DS_Store +0 -0
- data/lib/eventable/eventable.rb +26 -26
- data/lib/eventable/version.rb +1 -1
- data/spec/.DS_Store +0 -0
- data/spec/eventable/eventable_spec.rb +70 -38
- data/vendor/.DS_Store +0 -0
- metadata +22 -5
data/.DS_Store
ADDED
Binary file
|
data/README.markdown
CHANGED
@@ -4,7 +4,7 @@ An incredibly simple way to add events to your classes.
|
|
4
4
|
|
5
5
|
##Description##
|
6
6
|
|
7
|
-
Provides an easy to use and understand event model. Other systems did way too much for my needs
|
7
|
+
Provides an easy to use and understand event model. Other systems did way too much for my needs: I didn't need to monitor network IO ports, I didn't want a central loop that polled IO, I just wanted a simple way to add real, non-polled events to a class and to register other classes to listen for those events.
|
8
8
|
|
9
9
|
If you want a simple way to add events to your classes without a bunch of other unrelated IO stuff this is the solution for you. (If you want to monitor IO events check out EventMachine)
|
10
10
|
|
@@ -16,6 +16,10 @@ Eventable will even automatically remove registered listeners when they get garb
|
|
16
16
|
|
17
17
|
Eventable also allows for more fine-grain control than Observable. You can register for specific events instead of just saying, "Hey, let me know when anything changes."
|
18
18
|
|
19
|
+
##Concurrency considerations##
|
20
|
+
|
21
|
+
Events and threads do not scale well past a certain point but that's OK; they aren't meant to. They are meant for fast, simple communication beteen processes not large distributed processes like serving websites on massive server farms. If you need a solution that scales well to large distributed systems check out the Actor concurrency model.
|
22
|
+
|
19
23
|
##Install##
|
20
24
|
|
21
25
|
`$ gem install eventable`
|
@@ -165,6 +169,17 @@ This example shows you how you might actually use it in a multi-threaded environ
|
|
165
169
|
|
166
170
|
##Version History##
|
167
171
|
|
172
|
+
**2011.06.28**
|
173
|
+
Ver: 0.1.3
|
174
|
+
|
175
|
+
Updates:
|
176
|
+
|
177
|
+
Callbacks are now threaded:
|
178
|
+
This patches one of the last concurrency issues; if a callback takes a long time or hangs it won't affect any other callbacks or events that need to fire.
|
179
|
+
|
180
|
+
It's your responsiblity to make sure your callback works, as long as it does the callback thread will go out of scope (unless you retain it) and everyone is happy.
|
181
|
+
|
182
|
+
**2011.06.17**
|
168
183
|
Ver: 0.1.2
|
169
184
|
|
170
185
|
Design updates/fixes:
|
data/eventable.gemspec
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
$:.push File.expand_path("../lib", __FILE__)
|
3
3
|
# Kludge for older RubyGems not handling unparsable dates gracefully
|
4
4
|
# (psych 1.2.0 gem wouldn't build on test system so we're stuck with syck)
|
5
|
-
YAML::ENGINE.yamler = 'syck'
|
5
|
+
YAML::ENGINE.yamler = 'syck'
|
6
|
+
|
6
7
|
require "rubygems"
|
7
8
|
require "eventable/version"
|
8
9
|
|
@@ -14,8 +15,12 @@ Gem::Specification.new do |s|
|
|
14
15
|
s.homepage = "http://mikbe.tk/projects#eventable"
|
15
16
|
s.summary = %q{An incredibly simple and easy to use event mixin module.}
|
16
17
|
s.description = %q{Provides an easy to use and understand event model. If you want a simple, light-weight way to add events to your classes this is the solution for you.}
|
18
|
+
s.license = 'MIT'
|
19
|
+
|
20
|
+
s.required_ruby_version = ">= 1.9.2"
|
17
21
|
|
18
22
|
s.add_development_dependency('rspec', "~>2.6")
|
23
|
+
s.add_development_dependency('bundler', "~>1.0")
|
19
24
|
|
20
25
|
s.files = `git ls-files`.split("\n")
|
21
26
|
s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
@@ -0,0 +1,56 @@
|
|
1
|
+
[1] did some stuff, sleeping
|
2
|
+
[1, 932]: do_somestuff
|
3
|
+
firing :stuff_happens
|
4
|
+
[1] stuff_happened callback: 824
|
5
|
+
firing :other_stuff_happens
|
6
|
+
[n/a] same_stuff_happened callback: n/a
|
7
|
+
[1, 932]: do_somestuff
|
8
|
+
firing :stuff_happens
|
9
|
+
[1] stuff_happened callback: 407
|
10
|
+
[1, 932]: do_somestuff
|
11
|
+
firing :stuff_happens
|
12
|
+
[1] stuff_happened callback: 841
|
13
|
+
firing :other_stuff_happens
|
14
|
+
[n/a] same_stuff_happened callback: n/a
|
15
|
+
[1, 932]: do_somestuff
|
16
|
+
firing :stuff_happens
|
17
|
+
[1] stuff_happened callback: 779
|
18
|
+
[1] slept
|
19
|
+
[2] did some stuff, sleeping
|
20
|
+
firing :other_stuff_happens
|
21
|
+
[n/a] same_stuff_happened callback: n/a
|
22
|
+
[1, 932]: do_somestuff
|
23
|
+
firing :stuff_happens
|
24
|
+
[1] stuff_happened callback: 252
|
25
|
+
[2, 316]: do_somestuff
|
26
|
+
firing :stuff_happens
|
27
|
+
[2] stuff_happened callback: 174
|
28
|
+
firing :other_stuff_happens
|
29
|
+
[n/a] same_stuff_happened callback: n/a
|
30
|
+
[2, 316]: do_somestuff
|
31
|
+
firing :stuff_happens
|
32
|
+
[2] stuff_happened callback: 193
|
33
|
+
[1, 932]: do_somestuff
|
34
|
+
firing :stuff_happens
|
35
|
+
[1] stuff_happened callback: 535
|
36
|
+
[2] slept
|
37
|
+
[3] did some stuff, sleeping
|
38
|
+
firing :other_stuff_happens
|
39
|
+
[n/a] same_stuff_happened callback: n/a
|
40
|
+
[2, 316]: do_somestuff
|
41
|
+
firing :stuff_happens
|
42
|
+
[2] stuff_happened callback: 420
|
43
|
+
[3, 748]: do_somestuff
|
44
|
+
firing :stuff_happens
|
45
|
+
[3] stuff_happened callback: 545
|
46
|
+
[2, 316]: do_somestuff
|
47
|
+
firing :stuff_happens
|
48
|
+
[2] stuff_happened callback: 471
|
49
|
+
[3, 748]: do_somestuff
|
50
|
+
firing :stuff_happens
|
51
|
+
[2, 316]: do_somestuff
|
52
|
+
[3] stuff_happened callback: 266
|
53
|
+
firing :stuff_happens
|
54
|
+
[2] stuff_happened callback: 481
|
55
|
+
[3] slept
|
56
|
+
all done
|
data/lib/.DS_Store
ADDED
Binary file
|
data/lib/eventable/eventable.rb
CHANGED
@@ -3,40 +3,40 @@ require 'thread'
|
|
3
3
|
# Incredibly simple framework for adding events
|
4
4
|
module Eventable
|
5
5
|
|
6
|
-
|
7
|
-
attr_reader :callbacks
|
6
|
+
module EventableEventMethods
|
8
7
|
|
9
|
-
# Add the #event method to the extending class not instances of that class
|
10
|
-
def self.included(base)
|
11
|
-
base.extend(EventableClassMethods)
|
12
|
-
end
|
13
|
-
|
14
|
-
module EventableClassMethods
|
15
|
-
|
16
8
|
# register an event
|
17
9
|
def event(event_name)
|
18
10
|
@eventable_events ||= []
|
19
11
|
@eventable_events << event_name unless @eventable_events.include? event_name
|
20
12
|
end
|
21
|
-
|
13
|
+
|
22
14
|
# returns a list of registered events
|
23
15
|
def events
|
24
16
|
@eventable_events.clone
|
25
17
|
end
|
26
|
-
|
18
|
+
|
27
19
|
end
|
28
20
|
|
29
21
|
def events
|
30
22
|
self.class.events
|
31
23
|
end
|
32
|
-
|
24
|
+
|
25
|
+
# Allows for dynamic discovery of hooked callbacks
|
26
|
+
attr_reader :callbacks
|
27
|
+
|
28
|
+
# Add the #event method to the extending class not instances of that class
|
29
|
+
def self.included(base)
|
30
|
+
base.extend(EventableEventMethods)
|
31
|
+
end
|
32
|
+
|
33
33
|
def initialize
|
34
|
+
super
|
34
35
|
@eventable_mutex = Mutex.new
|
35
36
|
end
|
36
|
-
|
37
|
+
|
37
38
|
# When the event happens the class where it happens runs this
|
38
39
|
def fire_event(event, *return_value, &block)
|
39
|
-
# We don't want the callback array being altered when we're trying to read it
|
40
40
|
check_mutex
|
41
41
|
@eventable_mutex.synchronize {
|
42
42
|
|
@@ -45,7 +45,9 @@ module Eventable
|
|
45
45
|
@callbacks[event].each do |listener_id, callbacks|
|
46
46
|
begin
|
47
47
|
listener = ObjectSpace._id2ref(listener_id)
|
48
|
-
callbacks.each
|
48
|
+
callbacks.each do |callback|
|
49
|
+
Thread.new {listener.send callback, *return_value, &block}
|
50
|
+
end
|
49
51
|
rescue RangeError => re
|
50
52
|
# Don't bubble up a missing recycled object, I don't care if it's not there, I just won't call it
|
51
53
|
raise re unless re.message.match(/is recycled object/)
|
@@ -61,19 +63,19 @@ module Eventable
|
|
61
63
|
raise ArgumentError, "Missing parameter :#{parameter}" unless args[parameter]
|
62
64
|
end
|
63
65
|
|
64
|
-
|
65
|
-
raise Errors::UnknownEvent unless events.include? event
|
66
|
-
|
67
|
-
# Make access to the callback cache threadsafe
|
66
|
+
# Make access to the callback array threadsafe
|
68
67
|
check_mutex
|
69
68
|
@eventable_mutex.synchronize {
|
69
|
+
event = args[:event]
|
70
|
+
raise Errors::UnknownEvent unless events.include? event
|
71
|
+
|
70
72
|
@callbacks ||= {}
|
71
73
|
@callbacks[event] ||= {}
|
72
|
-
|
74
|
+
|
73
75
|
listener = args[:listener]
|
74
76
|
listener_id = listener.object_id
|
75
77
|
callback = args[:callback]
|
76
|
-
|
78
|
+
|
77
79
|
# save the callback info without creating a reference to the object
|
78
80
|
@callbacks[event][listener_id] ||= []
|
79
81
|
@callbacks[event][listener_id] << callback
|
@@ -92,7 +94,7 @@ module Eventable
|
|
92
94
|
@eventable_mutex.synchronize {
|
93
95
|
event = args[:event]
|
94
96
|
return unless @callbacks && @callbacks[event]
|
95
|
-
|
97
|
+
|
96
98
|
listener_id = args[:listener_id] || args[:listener].object_id
|
97
99
|
callback = args[:callback]
|
98
100
|
@callbacks[event].delete_if do |listener, callbacks|
|
@@ -103,7 +105,7 @@ module Eventable
|
|
103
105
|
end
|
104
106
|
|
105
107
|
private
|
106
|
-
|
108
|
+
|
107
109
|
def check_mutex
|
108
110
|
raise Errors::SuperNotCalledInInitialize, "You must include super in your class's initialize method" unless @eventable_mutex
|
109
111
|
end
|
@@ -113,7 +115,5 @@ module Eventable
|
|
113
115
|
def unregister_finalizer(event, listener_id, callback)
|
114
116
|
proc {unregister_for_event(event: event, listener_id: listener_id, callback: callback)}
|
115
117
|
end
|
116
|
-
|
117
|
-
end
|
118
|
-
|
119
118
|
|
119
|
+
end
|
data/lib/eventable/version.rb
CHANGED
data/spec/.DS_Store
ADDED
Binary file
|
@@ -1,5 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
# Callbacks are threaded to avoid blocking so tests need to wait for the callback to be scheduled and run
|
4
|
+
CALLBACK_WAIT = 0.01
|
5
|
+
|
3
6
|
describe Eventable do
|
4
7
|
|
5
8
|
before(:each) do
|
@@ -15,8 +18,8 @@ describe Eventable do
|
|
15
18
|
include Eventable
|
16
19
|
event :do_stuff
|
17
20
|
end
|
18
|
-
|
19
|
-
|
21
|
+
f = Foo.new
|
22
|
+
f.fire_event(:do_stuff)
|
20
23
|
}.should_not raise_error
|
21
24
|
end
|
22
25
|
|
@@ -33,7 +36,7 @@ describe Eventable do
|
|
33
36
|
f.fire_event(:do_stuff)
|
34
37
|
}.should_not raise_error
|
35
38
|
end
|
36
|
-
|
39
|
+
|
37
40
|
it "should raise an error if super is not called in initialize" do
|
38
41
|
lambda{
|
39
42
|
class Foo
|
@@ -46,7 +49,7 @@ describe Eventable do
|
|
46
49
|
f.fire_event(:do_stuff)
|
47
50
|
}.should raise_error(Eventable::Errors::SuperNotCalledInInitialize)
|
48
51
|
end
|
49
|
-
|
52
|
+
|
50
53
|
end
|
51
54
|
|
52
55
|
context "when specifiying an event" do
|
@@ -54,7 +57,7 @@ describe Eventable do
|
|
54
57
|
it 'should list the event from the class' do
|
55
58
|
EventClass.events.should include(:stuff_happens)
|
56
59
|
end
|
57
|
-
|
60
|
+
|
58
61
|
it 'should list more than one event' do
|
59
62
|
EventClass.events.should include(:other_stuff_happens)
|
60
63
|
end
|
@@ -62,42 +65,39 @@ describe Eventable do
|
|
62
65
|
it 'should list the event from an instance of the class' do
|
63
66
|
@evented.events.should include(:stuff_happens)
|
64
67
|
end
|
65
|
-
|
68
|
+
|
66
69
|
it 'should list more than one event from an instance' do
|
67
70
|
@evented.events.should include(:other_stuff_happens)
|
68
71
|
end
|
69
72
|
|
70
73
|
it "should not add an event that's already been added" do
|
71
74
|
eval %{
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
75
|
+
class EventClass
|
76
|
+
include Eventable
|
77
|
+
event :stuff_happens
|
78
|
+
end
|
76
79
|
}
|
77
80
|
EventClass.events.count.should == 2
|
78
81
|
end
|
79
82
|
|
80
83
|
it "should not add events to other classes" do
|
81
84
|
eval %{
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
85
|
+
class EventClass2
|
86
|
+
include Eventable
|
87
|
+
event :some_other_event
|
88
|
+
end
|
86
89
|
}
|
87
90
|
EventClass.events.should_not include(:some_other_event)
|
88
91
|
end
|
89
|
-
|
92
|
+
|
90
93
|
it "should not allow its event list to be altered external" do
|
91
94
|
events = EventClass.events
|
92
95
|
events.pop
|
93
96
|
events.should_not == EventClass.events
|
94
97
|
end
|
95
|
-
|
96
|
-
it "should allow multiple classes to use the mixin" do
|
97
|
-
end
|
98
|
-
|
98
|
+
|
99
99
|
end
|
100
|
-
|
100
|
+
|
101
101
|
context "when registering for an event" do
|
102
102
|
|
103
103
|
context "and there is a missing parameter" do
|
@@ -141,7 +141,7 @@ describe Eventable do
|
|
141
141
|
@evented.register_for_event(event: :other_stuff_happens, listener: @listener, callback: :callback)
|
142
142
|
@evented.callbacks.count.should == 2
|
143
143
|
end
|
144
|
-
|
144
|
+
|
145
145
|
it "should not add a callback that's already been added" do
|
146
146
|
@evented.register_for_event(event: :stuff_happens, listener: @listener, callback: :callback)
|
147
147
|
@evented.register_for_event(event: :stuff_happens, listener: @listener, callback: :callback)
|
@@ -159,6 +159,7 @@ describe Eventable do
|
|
159
159
|
@evented.register_for_event(event: :stuff_happens, listener: @listener, callback: :callback)
|
160
160
|
@evented.register_for_event(event: :stuff_happens, listener: @listener, callback: :callback2)
|
161
161
|
@evented.do_event
|
162
|
+
sleep(CALLBACK_WAIT)
|
162
163
|
@listener.callback?.should be_true
|
163
164
|
@listener.callback2?.should be_true
|
164
165
|
end
|
@@ -167,6 +168,7 @@ describe Eventable do
|
|
167
168
|
# should be a no brainer because a class is an object too, but just to be sure
|
168
169
|
@evented.register_for_event(event: :stuff_happens, listener: ListenClass, callback: :class_callback)
|
169
170
|
@evented.do_event
|
171
|
+
sleep(CALLBACK_WAIT)
|
170
172
|
ListenClass.class_callback?.should be_true
|
171
173
|
end
|
172
174
|
|
@@ -180,6 +182,7 @@ describe Eventable do
|
|
180
182
|
@evented.register_for_event(event: :stuff_happens, listener: @listener, callback: :callback)
|
181
183
|
another_evented.register_for_event(event: :stuff_happens, listener: another_listener, callback: :callback)
|
182
184
|
@evented.do_event
|
185
|
+
sleep(CALLBACK_WAIT)
|
183
186
|
@listener.callback?.should be_true
|
184
187
|
another_listener.callback?.should_not be_true
|
185
188
|
end
|
@@ -191,6 +194,7 @@ describe Eventable do
|
|
191
194
|
another_evented.register_for_event(event: :stuff_happens, listener: another_listener, callback: :callback2)
|
192
195
|
@evented.do_event
|
193
196
|
another_evented.do_event
|
197
|
+
sleep(CALLBACK_WAIT)
|
194
198
|
@listener.callback?.should be_true
|
195
199
|
another_listener.callback2?.should be_true
|
196
200
|
end
|
@@ -198,28 +202,28 @@ describe Eventable do
|
|
198
202
|
end
|
199
203
|
|
200
204
|
end
|
201
|
-
|
205
|
+
|
202
206
|
context "when unregistering for an event" do
|
203
207
|
|
204
208
|
it "should not throw an error if unregistering for an event you weren't registered for" do
|
205
209
|
# Is this supporting sloppy programming(bad) or lazy programming(good)?
|
206
210
|
lambda{@evented.unregister_for_event(event: :stuff_happens, listener: @listener, callback: :callback)}.should_not raise_error
|
207
211
|
end
|
208
|
-
|
212
|
+
|
209
213
|
it "should remove a callback" do
|
210
214
|
@evented.register_for_event(event: :stuff_happens, listener: @listener, callback: :callback)
|
211
215
|
@evented.callbacks[:stuff_happens].keys.should include(@listener.object_id) # <= just to be sure...
|
212
216
|
@evented.unregister_for_event(event: :stuff_happens, listener: @listener, callback: :callback)
|
213
217
|
@evented.callbacks[:stuff_happens].keys.should_not include(@listener.object_id)
|
214
218
|
end
|
215
|
-
|
219
|
+
|
216
220
|
it "should not call a callback that has been removed" do
|
217
221
|
@evented.register_for_event(event: :stuff_happens, listener: @listener, callback: :callback)
|
218
222
|
@evented.unregister_for_event(event: :stuff_happens, listener: @listener, callback: :callback)
|
219
223
|
@evented.do_event
|
220
224
|
@listener.callback?.should_not be_true
|
221
225
|
end
|
222
|
-
|
226
|
+
|
223
227
|
it "should automatically remove callbacks to objects that are garbage collected" do
|
224
228
|
listener_object_id = nil
|
225
229
|
(0..1).each do
|
@@ -230,7 +234,7 @@ describe Eventable do
|
|
230
234
|
GC.start
|
231
235
|
@evented.callbacks[:stuff_happens].keys.should_not include(listener_object_id)
|
232
236
|
end
|
233
|
-
|
237
|
+
|
234
238
|
end
|
235
239
|
|
236
240
|
context "when an event is fired" do
|
@@ -249,39 +253,40 @@ describe Eventable do
|
|
249
253
|
@evented.do_event
|
250
254
|
lambda{@evented.do_event}.should_not raise_error
|
251
255
|
end
|
252
|
-
|
256
|
+
|
253
257
|
it "should call back the specified method when the event is fired" do
|
254
258
|
@evented.register_for_event(event: :stuff_happens, listener: @listener, callback: :callback)
|
255
259
|
@evented.do_event
|
260
|
+
sleep(CALLBACK_WAIT)
|
256
261
|
@listener.callback?.should be_true
|
257
262
|
end
|
258
|
-
|
263
|
+
|
259
264
|
it "should not call back the wrong method when the event is fired" do
|
260
265
|
@evented.register_for_event(event: :stuff_happens, listener: @listener, callback: :callback)
|
261
266
|
@evented.do_event
|
262
267
|
@listener.callback2?.should_not be_true
|
263
268
|
end
|
264
|
-
|
269
|
+
|
265
270
|
it "should call back more than one class" do
|
266
271
|
listener2 = ListenClass.new
|
267
|
-
|
272
|
+
|
268
273
|
@evented.register_for_event(event: :stuff_happens, listener: @listener, callback: :callback)
|
269
274
|
@evented.register_for_event(event: :stuff_happens, listener: listener2, callback: :callback2)
|
270
|
-
|
275
|
+
|
271
276
|
@evented.do_event
|
272
|
-
|
277
|
+
sleep(CALLBACK_WAIT)
|
273
278
|
@listener.callback?.should be_true
|
274
279
|
listener2.callback2?.should be_true
|
275
280
|
end
|
276
281
|
|
277
282
|
it "should not call back the wrong method when using multiple classes" do
|
278
283
|
listener2 = ListenClass.new
|
279
|
-
|
284
|
+
|
280
285
|
@evented.register_for_event(event: :stuff_happens, listener: @listener, callback: :callback)
|
281
286
|
@evented.register_for_event(event: :stuff_happens, listener: listener2, callback: :callback2)
|
282
|
-
|
287
|
+
|
283
288
|
@evented.do_event
|
284
|
-
|
289
|
+
sleep(CALLBACK_WAIT)
|
285
290
|
@listener.callback2?.should_not be_true
|
286
291
|
listener2.callback?.should_not be_true
|
287
292
|
end
|
@@ -292,6 +297,7 @@ describe Eventable do
|
|
292
297
|
@evented.register_for_event(event: :stuff_happens, listener: @listener, callback: :callback_with_args)
|
293
298
|
a, b, c = rand(100), rand(100), rand(100)
|
294
299
|
@evented.do_event_with_args(a,b,c)
|
300
|
+
sleep(CALLBACK_WAIT)
|
295
301
|
@listener.callback_with_args?.should == [a,b,c]
|
296
302
|
end
|
297
303
|
|
@@ -299,6 +305,7 @@ describe Eventable do
|
|
299
305
|
@evented.register_for_event(event: :stuff_happens, listener: @listener, callback: :callback_with_block)
|
300
306
|
block = proc {"a block"}
|
301
307
|
@evented.do_event_with_block(&block)
|
308
|
+
sleep(CALLBACK_WAIT)
|
302
309
|
@listener.callback_with_block?.should == block
|
303
310
|
end
|
304
311
|
|
@@ -306,17 +313,42 @@ describe Eventable do
|
|
306
313
|
@evented.register_for_event(event: :stuff_happens, listener: @listener, callback: :callback_with_args_and_block)
|
307
314
|
a, b, c, block = rand(100), rand(100), rand(100), proc {"a block"}
|
308
315
|
@evented.do_event_with_args_and_block(a,b,c,&block)
|
316
|
+
sleep(CALLBACK_WAIT)
|
309
317
|
@listener.callback_with_args_and_block?.should == [a,b,c,block]
|
310
318
|
end
|
311
319
|
|
312
320
|
end
|
313
|
-
|
321
|
+
|
322
|
+
context "when multithreading" do
|
323
|
+
|
324
|
+
it "should not block on callbacks" do
|
325
|
+
bc = BlockingClass.new
|
326
|
+
@evented.register_for_event(event: :stuff_happens, listener: bc, callback: :blocking_call)
|
327
|
+
start_time = Time.now
|
328
|
+
@evented.do_event
|
329
|
+
sleep(CALLBACK_WAIT * 2) # Just to make sure the event cycle starts
|
330
|
+
Time.now.should_not > start_time + 1
|
331
|
+
end
|
332
|
+
|
333
|
+
end
|
334
|
+
|
314
335
|
end
|
315
336
|
|
316
337
|
end
|
317
338
|
|
318
339
|
# Test classes
|
319
340
|
|
341
|
+
class BlockingClass
|
342
|
+
def blocking_call
|
343
|
+
# I don't know how long this will take but it's a lot longer than 1 second
|
344
|
+
1000000000.times { Math.sqrt(98979872938749283749729384792734927) }
|
345
|
+
non_blocking_call
|
346
|
+
end
|
347
|
+
def non_blocking_call
|
348
|
+
"all done"
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
320
352
|
class EventClass
|
321
353
|
include Eventable
|
322
354
|
event :stuff_happens
|
@@ -339,7 +371,7 @@ class AnotherEventClass
|
|
339
371
|
include Eventable
|
340
372
|
event :stuff_happens
|
341
373
|
event :different_happens
|
342
|
-
|
374
|
+
|
343
375
|
def do_event(event=:stuff_happens)
|
344
376
|
fire_event(event)
|
345
377
|
end
|
@@ -391,7 +423,7 @@ class AnotherListenClass
|
|
391
423
|
def callback
|
392
424
|
@callback = true
|
393
425
|
end
|
394
|
-
|
426
|
+
def callback2?
|
395
427
|
@callback2
|
396
428
|
end
|
397
429
|
def callback2
|
data/vendor/.DS_Store
ADDED
Binary file
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: eventable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.1.
|
5
|
+
version: 0.1.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Mike Bethany
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-06-
|
13
|
+
date: 2011-06-29 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|
@@ -23,6 +23,17 @@ dependencies:
|
|
23
23
|
version: "2.6"
|
24
24
|
type: :development
|
25
25
|
version_requirements: *id001
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: bundler
|
28
|
+
prerelease: false
|
29
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: "1.0"
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id002
|
26
37
|
description: Provides an easy to use and understand event model. If you want a simple, light-weight way to add events to your classes this is the solution for you.
|
27
38
|
email:
|
28
39
|
- mikbe.tk@gmail.com
|
@@ -33,6 +44,7 @@ extensions: []
|
|
33
44
|
extra_rdoc_files: []
|
34
45
|
|
35
46
|
files:
|
47
|
+
- .DS_Store
|
36
48
|
- .gitignore
|
37
49
|
- Gemfile
|
38
50
|
- LICENSE.txt
|
@@ -41,16 +53,21 @@ files:
|
|
41
53
|
- autotest/discover.rb
|
42
54
|
- eventable.gemspec
|
43
55
|
- example/example.rb
|
56
|
+
- example/example_output.txt
|
44
57
|
- example/simple_example.rb
|
58
|
+
- example/simple_output.txt
|
59
|
+
- lib/.DS_Store
|
45
60
|
- lib/eventable.rb
|
46
61
|
- lib/eventable/errors.rb
|
47
62
|
- lib/eventable/eventable.rb
|
48
63
|
- lib/eventable/version.rb
|
64
|
+
- spec/.DS_Store
|
49
65
|
- spec/eventable/eventable_spec.rb
|
50
66
|
- spec/spec_helper.rb
|
67
|
+
- vendor/.DS_Store
|
51
68
|
homepage: http://mikbe.tk/projects#eventable
|
52
|
-
licenses:
|
53
|
-
|
69
|
+
licenses:
|
70
|
+
- MIT
|
54
71
|
post_install_message:
|
55
72
|
rdoc_options: []
|
56
73
|
|
@@ -61,7 +78,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
61
78
|
requirements:
|
62
79
|
- - ">="
|
63
80
|
- !ruby/object:Gem::Version
|
64
|
-
version:
|
81
|
+
version: 1.9.2
|
65
82
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
83
|
none: false
|
67
84
|
requirements:
|