Module: Volt::Eventable
- Included in:
- Channel, ChannelStub, ComponentNode, MessageBus::PeerToPeer, ReactiveArray, ServerSetup::App
- Defined in:
- lib/volt/reactive/eventable.rb
Overview
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!
Instance Method Summary collapse
-
#on(*events, &callback) ⇒ Object
Sets up a listener on the class the Eventable module was included in.
-
#remove_listener(event, listener) ⇒ Object
Stops the listener returned by calling .on(:event_name) Triggers #event_removed if there are no more listeners for that event.
-
#trigger!(event, *args) ⇒ Object
Triggers event on the class the module was includeded.
Instance Method Details
#on(*events, &callback) ⇒ Object
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.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# 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) ⇒ Object
Stops the listener returned by calling .on(:event_name) Triggers #event_removed if there are no more listeners for that event.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# 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) ⇒ Object
Triggers event on the class the module was includeded. Any .on listeners will have their block called passing in *args.
75 76 77 78 79 80 81 82 83 84 85 |
# 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 |