Module: Fidgit::Event
- Included in:
- Element
- Defined in:
- lib/fidgit/event.rb
Overview
Adds simple event handling methods to an object (subscribe/publish pattern).
Defined Under Namespace
Classes: Subscription
Class Method Summary collapse
-
.included(base) ⇒ Object
Add singleton methods to the class that includes Event.
- .new_event_handlers ⇒ Object
Instance Method Summary collapse
-
#events ⇒ Object
The list of events that this object can publish/subscribe.
-
#publish(event, *args) ⇒ Symbol?
Publish an event to all previously added handlers in the order they were added.
-
#subscribe(event, method = nil, &block) ⇒ Subscription
Definition of this the handler created by this subscription, to be used with #unsubscribe.
- #unsubscribe(*args) ⇒ Object
Class Method Details
.included(base) ⇒ Object
Add singleton methods to the class that includes Event.
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/fidgit/event.rb', line 141 def self.included(base) class << base def events # Copy the events already set up for your parent. @events ||= if superclass.respond_to? :events superclass.events.dup else [] end end def event(event) events.push event.to_sym unless events.include? event event end end end |
Instance Method Details
#events ⇒ Object
The list of events that this object can publish/subscribe.
136 137 138 |
# File 'lib/fidgit/event.rb', line 136 def events self.class.events end |
#publish(event, *args) ⇒ Symbol?
Publish an event to all previously added handlers in the order they were added. It will automatically call the publishing object with the method named after the event if it is defined (this will be done before the manually added handlers are called).
If any handler returns :handled, then no further handlers will be called.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/fidgit/event.rb', line 116 def publish(event, *args) raise ArgumentError, "#{self.class} does not handle #{event.inspect}" unless events.include? event # Do nothing if the object is disabled. return if respond_to?(:enabled?) and not enabled? if respond_to? event return :handled if send(event, self, *args) == :handled end if defined? @_event_handlers @_event_handlers[event].reverse_each do |handler| return :handled if handler.call(self, *args) == :handled end end nil end |
#subscribe(event, method = nil, &block) ⇒ Subscription
Returns Definition of this the handler created by this subscription, to be used with #unsubscribe.
51 52 53 54 55 56 57 58 59 60 |
# File 'lib/fidgit/event.rb', line 51 def subscribe(event, method = nil, &block) raise ArgumentError, "Expected method or block for event handler" unless !block.nil? ^ !method.nil? raise ArgumentError, "#{self.class} does not handle #{event.inspect}" unless events.include? event @_event_handlers ||= Event.new_event_handlers handler = method || block @_event_handlers[event] << handler Subscription.new self, event, handler end |
#unsubscribe(subscription) ⇒ Boolean #unsubscribe(handler) ⇒ Boolean #unsubscribe(event, handler) ⇒ Boolean
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/fidgit/event.rb', line 78 def unsubscribe(*args) @_event_handlers ||= Event.new_event_handlers case args.size when 1 case args.first when Subscription # Delete specific event handler. subscription = args.first raise ArgumentError, "Incorrect publisher for #{Subscription}: #{subscription.publisher}" unless subscription.publisher == self unsubscribe subscription.event, subscription.handler when Proc, Method # Delete first events that use the handler. handler = args.first !!@_event_handlers.find {|_, handlers| handlers.delete handler } else raise TypeError, "handler must be a #{Subscription}, Block or Method: #{args.first}" end when 2 event, handler = args raise TypeError, "event name must be a Symbol: #{event}" unless event.is_a? Symbol raise TypeError, "handler name must be a Proc/Method: #{handler}" unless handler.is_a? Proc or handler.is_a? Method !!@_event_handlers[event].delete(handler) else raise ArgumentError, "Requires 1..2 arguments, but received #{args.size} arguments" end end |