class EventDispatcher::Dispatcher

Constants

Listener

Using Struct as data container for each listener.

Attributes

listeners[R]

Public Class Methods

new() click to toggle source
# File lib/event_dispatcher/dispatcher.rb, line 5
def initialize
   @listeners = {}
end

Public Instance Methods

add_listener(event_name, listener, priority = 0) click to toggle source

Connects a listener to the dispatcher so that it can be notified when an event is dispatched.

# File lib/event_dispatcher/dispatcher.rb, line 19
def add_listener(event_name, listener, priority = 0)
   raise ArgumentError.new("Priority must be a Fixnum") unless priority.is_a?(Fixnum)
   event_name = symbolize_key(event_name) 
   @listeners[event_name] ||= []
   @listeners[event_name] << Listener.new(listener, priority)

   sort_listeners!(event_name)
end
dispatch(event_name, event) click to toggle source

Notifies all listeners of the given event. The event instance is then passed to each listener of that event.

# File lib/event_dispatcher/dispatcher.rb, line 48
def dispatch(event_name, event)
   event_name = symbolize_key(event_name) 
   return unless @listeners.key?(event_name) && !event.nil?
   @listeners[event_name].each do |l|
      invoke_callable(l.listener, event)  
      # A Listener is able to tell the dispatcher to stop all propagation of the event to future listeners.
      break if event.respond_to?(:stop_propagation) && event.stop_propagation 
   end
end
has_listeners?(event_name) click to toggle source

Checks if the given event has some listeners that want to listen to.

# File lib/event_dispatcher/dispatcher.rb, line 10
def has_listeners?(event_name)
   event_name = symbolize_key(event_name) 
   @listeners.key?(event_name) && @listeners[event_name].size > 0  ? true : false
end
remove_listener!(event_name, listener) click to toggle source

Removes an event listener from the specified event.

# File lib/event_dispatcher/dispatcher.rb, line 29
def remove_listener!(event_name, listener)
   event_name = symbolize_key(event_name) 
   return unless @listeners.key?(event_name) && !listener.nil?
   @listeners[event_name].delete_if { |l| l.listener.eql?(listener) }

   sort_listeners!(event_name)
end
remove_listeners!(event_name = nil) click to toggle source

Removes a collection of event listeners attached to a specified event, or reset the entire container of listeners if no event is given.

# File lib/event_dispatcher/dispatcher.rb, line 38
def remove_listeners!(event_name = nil)
   if event_name.nil?
      @listeners.clear
   else 
       event_name = symbolize_key(event_name) 
       @listeners.delete(event_name) if @listeners.key?(event_name)
   end
end

Private Instance Methods

invoke_callable(callable, event) click to toggle source

Calls the listener instance method which is responsible of handling the event object.

# File lib/event_dispatcher/dispatcher.rb, line 70
def invoke_callable(callable, event)
   raise ArgumentError.new("Listener must be a block or a callable object's method") unless callable.respond_to?(:call)
   callable.call(event)   
end
sort_listeners!(event_name) click to toggle source

Sorts the list of listeners attached to given event by priority. The higher the priority, the earlier the listener is called.

# File lib/event_dispatcher/dispatcher.rb, line 65
def sort_listeners!(event_name)
   @listeners[event_name].sort_by! { |l| l.priority }
end
symbolize_key(key) click to toggle source

For better performance we convert each string key into symbol one.

# File lib/event_dispatcher/dispatcher.rb, line 60
def symbolize_key(key)
   key.to_sym rescue key
end