events 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/events.rb +23 -10
  2. data/test/event_emitter_test.rb +13 -0
  3. metadata +4 -4
@@ -31,8 +31,16 @@ module Events # :nodoc:
31
31
  module Emitter
32
32
  DEFAULT_MAX_LISTENERS = 10
33
33
 
34
+ class Listeners < Array
35
+ attr_accessor :warned
36
+ end
37
+
38
+ class OnceWrapper < Proc
39
+ attr_accessor :original
40
+ end
41
+
34
42
  def max_listeners
35
- @max_listeners || DEFAULT_MAX_LISTENERS
43
+ (defined?(@max_listeners) ? @max_listeners : DEFAULT_MAX_LISTENERS) || 0
36
44
  end
37
45
  private :max_listeners
38
46
 
@@ -54,7 +62,7 @@ module Events # :nodoc:
54
62
  # manipulated, e.g. to remove listeners.
55
63
  #
56
64
  def listeners(event)
57
- (@listeners ||= Hash.new {|hash, key| hash[key] = []})[event]
65
+ (@listeners ||= Hash.new {|hash, key| hash[key] = Listeners.new})[event]
58
66
  end
59
67
 
60
68
  # :call-seq: emitter.emit(event[, arguments...]) -> bool
@@ -97,15 +105,12 @@ module Events # :nodoc:
97
105
  event_listeners = listeners(event)
98
106
 
99
107
  current = event_listeners.length
100
- if max_listeners && max_listeners > 0 && current > max_listeners &&
101
- (!event_listeners.respond_to?(:warned?) || !event_listeners.warned?)
108
+ if max_listeners > 0 && current > max_listeners && !event_listeners.warned
102
109
  warn(caller[1] +
103
110
  ": warning: possible EventEmitter memory leak detected. " <<
104
111
  "#{current} listeners added. " <<
105
112
  "Use Emitter#max_listeners = n to increase limit.")
106
- def event_listeners.warned?
107
- true
108
- end
113
+ event_listeners.warned = true
109
114
  end
110
115
 
111
116
  event_listeners.push(listener)
@@ -123,10 +128,16 @@ module Events # :nodoc:
123
128
  # end
124
129
  #
125
130
  def once(event, proc=nil, &block)
126
- once = Proc.new do |*args|
131
+ listener = proc || block
132
+ unless listener.respond_to?(:call)
133
+ raise ArgumentError.new("Listener must respond to #call")
134
+ end
135
+ once = OnceWrapper.new do |*args|
127
136
  remove_listener(event, once)
128
- (proc || block).call(args)
137
+ listener.call(args)
129
138
  end
139
+ once.original = listener
140
+
130
141
  add_listener(event, once)
131
142
  end
132
143
 
@@ -136,7 +147,9 @@ module Events # :nodoc:
136
147
  #
137
148
  def remove_listener(event, proc)
138
149
  if @listeners && @listeners.key?(event)
139
- @listeners[event].delete(proc)
150
+ @listeners[event].delete_if do |lis|
151
+ lis == proc || lis.respond_to?(:original) && lis.original == proc
152
+ end
140
153
  @listeners.delete(event) if @listeners[event].empty?
141
154
  end
142
155
  self
@@ -27,6 +27,11 @@ class TestEventEmitter < Test::Unit::TestCase
27
27
 
28
28
  e.emit(:hello, "a", "b")
29
29
 
30
+
31
+ # just make sure that this doesn't raise:
32
+ f = Events::EventEmitter.new
33
+ assert_nothing_raised {f.max_listeners = 0}
34
+
30
35
  assert_equal([:hello], events_new_listener_emited)
31
36
  assert_equal(1, times_hello_emited)
32
37
  end
@@ -137,6 +142,14 @@ class TestEventEmitter < Test::Unit::TestCase
137
142
  e.emit(:hello, "a", "b")
138
143
  e.emit(:hello, "a", "b")
139
144
 
145
+ remove = Proc.new do
146
+ flunk("once->foo should not be emitted")
147
+ end
148
+
149
+ e.once(:foo, remove)
150
+ e.remove_listener(:foo, remove)
151
+ e.emit(:foo)
152
+
140
153
  assert_equal(1, times_hello_emited)
141
154
  end
142
155
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: events
3
3
  version: !ruby/object:Gem::Version
4
- hash: 51
4
+ hash: 49
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 4
10
- version: 0.9.4
9
+ - 5
10
+ version: 0.9.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matthew Sadler
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-05 00:00:00 +00:00
18
+ date: 2011-04-11 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies: []
21
21