lib/ably/modules/event_emitter.rb in ably-0.7.2 vs lib/ably/modules/event_emitter.rb in ably-0.7.4
- old
+ new
@@ -1,12 +1,16 @@
+require 'ably/modules/safe_yield'
+
module Ably
module Modules
# EventEmitter provides methods to attach to public events and trigger events on any class instance
#
# EventEmitter are typically used for public interfaces, and as such, may be overriden in
# the classes to enforce `event` names match expected values.
#
+ # @note This module requires that the method #logger is defined.
+ #
# @example
# class Example
# include Modules::EventEmitter
# end
#
@@ -14,10 +18,12 @@
# event_emitter.on(:signal) { |name| puts "Signal #{name} received" }
# event_emitter.trigger :signal, "Test"
# #=> "Signal Test received"
#
module EventEmitter
+ include Ably::Modules::SafeYield
+
module ClassMethods
attr_reader :event_emitter_coerce_proc
# Configure included EventEmitter
#
@@ -47,10 +53,19 @@
event_names.each do |event_name|
callbacks[callbacks_event_coerced(event_name)] << proc_for_block(block)
end
end
+ # Equivalent of {#on} but any exception raised in a block will bubble up and cause this client library to fail.
+ # This method should only be used internally by the client library.
+ # @api private
+ def unsafe_on(*event_names, &block)
+ event_names.each do |event_name|
+ callbacks[callbacks_event_coerced(event_name)] << proc_for_block(block, unsafe: true)
+ end
+ end
+
# On receiving an event maching the event_name, call the provided block only once and remove the registered callback
#
# @param [Array<String>] event_names event name
#
# @return [void]
@@ -58,16 +73,29 @@
event_names.each do |event_name|
callbacks[callbacks_event_coerced(event_name)] << proc_for_block(block, delete_once_run: true)
end
end
+ # Equivalent of {#once} but any exception raised in a block will bubble up and cause this client library to fail.
+ # This method should only be used internally by the client library.
+ # @api private
+ def unsafe_once(*event_names, &block)
+ event_names.each do |event_name|
+ callbacks[callbacks_event_coerced(event_name)] << proc_for_block(block, delete_once_run: true, unsafe: true)
+ end
+ end
+
# Trigger an event with event_name that will in turn call all matching callbacks setup with `on`
def trigger(event_name, *args)
callbacks[callbacks_event_coerced(event_name)].
clone.
select do |proc_hash|
- proc_hash[:trigger_proc].call(*args)
+ if proc_hash[:unsafe]
+ proc_hash[:trigger_proc].call *args
+ else
+ safe_yield proc_hash[:trigger_proc], *args
+ end
end.each do |callback|
callbacks[callbacks_event_coerced(event_name)].delete callback
end
end
@@ -106,10 +134,11 @@
{
trigger_proc: Proc.new do |*args|
block.call *args
true if options[:delete_once_run]
end,
- block: block
+ block: block,
+ unsafe: options[:unsafe]
}
end
def callbacks
@callbacks ||= Hash.new { |hash, key| hash[key] = [] }