module Volt::Eventable

Include Eventable to add a basic event/trigger system to a class. Listeners can be added with on(event_name) { … } Events can be triggered with trigger!

Public Instance Methods

on(*events, &callback) click to toggle source

Sets up a listener on the class the Eventable module was included in. event should be a string or symbol. When something calls trigger!(event_name) on the class, it will trigger any listener with the same event name.

returns: a listener that has a remove method to stop the listener.

# File lib/volt/reactive/eventable.rb, line 47
def on(*events, &callback)
  fail '.on requires an event' if events.size == 0

  listener = Listener.new(self, events, callback)

  @listeners ||= {}

  events.each do |event|
    event             = event.to_sym
    @listeners[event] ||= []
    @listeners[event] << listener

    first_for_event = @listeners[event].size == 1
    first           = first_for_event && @listeners.size == 1

    # Let the included class know that an event was registered. (if it cares)
    if self.respond_to?(:event_added)
      # call event added passing the event, the scope, and a boolean if it
      # is the first time this event has been added.
      event_added(event, first, first_for_event)
    end
  end

  listener
end
remove_listener(event, listener) click to toggle source

Stops the listener returned by calling .on(:event_name) Triggers event_removed if there are no more listeners for that event.

# File lib/volt/reactive/eventable.rb, line 89
def remove_listener(event, listener)
  event = event.to_sym

  fail "Unable to delete #{event} from #{inspect}" unless @listeners && @listeners[event]

  @listeners[event].delete(listener)

  last_for_event = @listeners[event].size == 0

  if last_for_event
    # No registered listeners now on this event
    @listeners.delete(event)
  end

  last = last_for_event && @listeners.size == 0

  # Let the class we're included on know that we removed a listener (if it cares)
  if self.respond_to?(:event_removed)
    # Pass in the event and a boolean indicating if it is the last event
    event_removed(event, last, last_for_event)
  end
end
trigger!(event, *args) click to toggle source

Triggers event on the class the module was includeded. Any .on listeners will have their block called passing in *args.

# File lib/volt/reactive/eventable.rb, line 75
def trigger!(event, *args)
  event = event.to_sym

  if @listeners && @listeners[event]
    # TODO: We have to dup here because one trigger might remove another
    @listeners[event].dup.each do |listener|
      # Call the event on each listener
      listener.call(*args)
    end
  end
end