events 0.9.3 → 0.9.4

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 +60 -25
  2. data/readme.rdoc +7 -0
  3. metadata +4 -4
@@ -1,19 +1,6 @@
1
1
  module Events # :nodoc:
2
2
  UncaughtError = Class.new(StandardError)
3
3
 
4
- class OnceProxy # :nodoc:
5
- attr_reader :event, :caller, :delegate
6
-
7
- def initialize(event, caller, delegate)
8
- @event, @caller, @delegate = event, caller, delegate
9
- end
10
-
11
- def call(*args)
12
- caller.remove_listener(event, self)
13
- delegate.call(*args)
14
- end
15
- end
16
-
17
4
  # The Events::Emitter mixin provides a clone of the Node.js EventEmitter API
18
5
  # for Ruby.
19
6
  #
@@ -42,6 +29,24 @@ module Events # :nodoc:
42
29
  # they raise an Events::UncaughtError exception.
43
30
  #
44
31
  module Emitter
32
+ DEFAULT_MAX_LISTENERS = 10
33
+
34
+ def max_listeners
35
+ @max_listeners || DEFAULT_MAX_LISTENERS
36
+ end
37
+ private :max_listeners
38
+
39
+ # :call-seq: emitter.max_listeners = integer -> integer
40
+ #
41
+ # By default an EventEmitter will print a warning if more than 10 listeners
42
+ # are added to it. This is a useful default which helps finding memory
43
+ # leaks. Obviously not all Emitters should be limited to 10. This method
44
+ # allows that to be increased. Set to zero for unlimited.
45
+ #
46
+ def max_listeners=(value)
47
+ @max_listeners = value
48
+ end
49
+ alias set_max_listeners max_listeners=
45
50
 
46
51
  # :call-seq: emitter.listeners(event) -> array
47
52
  #
@@ -57,16 +62,18 @@ module Events # :nodoc:
57
62
  # Execute each of the listeners in order with the supplied arguments.
58
63
  #
59
64
  def emit(event, *args)
60
- listeners = listeners(event).dup
65
+ listeners = @listeners && @listeners.key?(event) && @listeners[event]
61
66
 
62
- if event == :error && listeners.empty?
67
+ if event == :error && (!listeners || listeners.empty?)
63
68
  raise args.first if args.first.kind_of?(Exception)
64
69
  raise Events::UncaughtError.new("Uncaught, unspecified 'error' event.")
70
+ elsif listeners
71
+ listeners.dup.each do |listener|
72
+ listener.call(*args)
73
+ end.any?
74
+ else
75
+ false
65
76
  end
66
-
67
- listeners.each do |listener|
68
- listener.call(*args)
69
- end.any?
70
77
  end
71
78
 
72
79
  # :call-seq: emitter.on(event) {|args...| block} -> emitter
@@ -81,13 +88,31 @@ module Events # :nodoc:
81
88
  # with a #call method).
82
89
  #
83
90
  def add_listener(event, proc=nil, &block)
84
- emit(:new_listener, event, proc || block)
85
- listeners(event).push(proc || block)
91
+ listener = proc || block
92
+ unless listener.respond_to?(:call)
93
+ raise ArgumentError.new("Listener must respond to #call")
94
+ end
95
+ emit(:new_listener, event, listener)
96
+
97
+ event_listeners = listeners(event)
98
+
99
+ current = event_listeners.length
100
+ if max_listeners && max_listeners > 0 && current > max_listeners &&
101
+ (!event_listeners.respond_to?(:warned?) || !event_listeners.warned?)
102
+ warn(caller[1] +
103
+ ": warning: possible EventEmitter memory leak detected. " <<
104
+ "#{current} listeners added. " <<
105
+ "Use Emitter#max_listeners = n to increase limit.")
106
+ def event_listeners.warned?
107
+ true
108
+ end
109
+ end
110
+
111
+ event_listeners.push(listener)
86
112
  self
87
113
  end
88
114
  alias on add_listener
89
115
 
90
-
91
116
  # :call-seq: emitter.once(event) {|args...| block} -> emitter
92
117
  # emitter.once(event, proc) -> emitter
93
118
  #
@@ -98,7 +123,11 @@ module Events # :nodoc:
98
123
  # end
99
124
  #
100
125
  def once(event, proc=nil, &block)
101
- add_listener(event, OnceProxy.new(event, self, proc || block))
126
+ once = Proc.new do |*args|
127
+ remove_listener(event, once)
128
+ (proc || block).call(args)
129
+ end
130
+ add_listener(event, once)
102
131
  end
103
132
 
104
133
  # :call-seq: emitter.remove_listener(event, proc) -> emitter
@@ -106,7 +135,10 @@ module Events # :nodoc:
106
135
  # Remove a listener from the listener array for the specified event.
107
136
  #
108
137
  def remove_listener(event, proc)
109
- listeners(event).delete(proc)
138
+ if @listeners && @listeners.key?(event)
139
+ @listeners[event].delete(proc)
140
+ @listeners.delete(event) if @listeners[event].empty?
141
+ end
110
142
  self
111
143
  end
112
144
 
@@ -115,7 +147,10 @@ module Events # :nodoc:
115
147
  # Removes all listeners from the listener array for the specified event.
116
148
  #
117
149
  def remove_all_listeners(event)
118
- listeners(event).clear
150
+ if @listeners && @listeners.key?(event)
151
+ @listeners[event].clear
152
+ @listeners.delete(event)
153
+ end
119
154
  self
120
155
  end
121
156
  end
@@ -49,6 +49,13 @@ first time the event is fired, after which it is removed.
49
49
 
50
50
  Remove a listener from the listener array for the specified event.
51
51
 
52
+ emitter.max_listeners = n
53
+
54
+ By default an EventEmitter will print a warning if more than 10 listeners
55
+ are added to it. This is a useful default which helps finding memory
56
+ leaks. Obviously not all Emitters should be limited to 10. This method
57
+ allows that to be increased. Set to zero for unlimited.
58
+
52
59
  emitter.listeners(event)
53
60
 
54
61
  Returns an array of listeners for the specified event. This array can be
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: 61
4
+ hash: 51
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 3
10
- version: 0.9.3
9
+ - 4
10
+ version: 0.9.4
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-01-30 00:00:00 +00:00
18
+ date: 2011-02-05 00:00:00 +00:00
19
19
  default_executable:
20
20
  dependencies: []
21
21