Module: Eventable
- Defined in:
- lib/eventable/eventable.rb,
lib/eventable/errors.rb,
lib/eventable/version.rb
Overview
Incredibly simple framework for adding events
Defined Under Namespace
Modules: Errors, EventableEventMethods
Constant Summary collapse
- VERSION =
"0.2.1"
Instance Attribute Summary collapse
-
#callbacks ⇒ Object
readonly
Allows for dynamic discovery of hooked callbacks.
Class Method Summary collapse
-
.included(base) ⇒ Object
Add the #event method to the extending class not instances of that class.
Instance Method Summary collapse
- #events ⇒ Object
-
#fire_event(event, *return_value, &block) ⇒ Object
When the event happens the class where it happens runs this.
- #initialize(*args) ⇒ Object
-
#register_for_event(args) ⇒ Object
Allows an object to listen for an event and have a callback run when the event happens.
-
#unregister_for_event(args) ⇒ Object
Allows objects to stop listening to events.
Instance Attribute Details
#callbacks ⇒ Object (readonly)
Allows for dynamic discovery of hooked callbacks
26 27 28 |
# File 'lib/eventable/eventable.rb', line 26 def callbacks @callbacks end |
Class Method Details
.included(base) ⇒ Object
Add the #event method to the extending class not instances of that class
29 30 31 |
# File 'lib/eventable/eventable.rb', line 29 def self.included(base) base.extend(EventableEventMethods) end |
Instance Method Details
#events ⇒ Object
21 22 23 |
# File 'lib/eventable/eventable.rb', line 21 def events self.class.events end |
#fire_event(event, *return_value, &block) ⇒ Object
When the event happens the class where it happens runs this
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/eventable/eventable.rb', line 39 def fire_event(event, *return_value, &block) check_mutex @eventable_mutex.synchronize { return false unless @callbacks && @callbacks[event] && !@callbacks[event].empty? @callbacks[event].each do |listener_id, callbacks| begin listener = ObjectSpace._id2ref(listener_id) callbacks.each do |callback| Thread.new {listener.send callback, *return_value, &block} end rescue RangeError => re # Don't bubble up a missing recycled object, I don't care if it's not there, I just won't call it raise re unless re..match(/is recycled object/) end end } true end |
#initialize(*args) ⇒ Object
33 34 35 36 |
# File 'lib/eventable/eventable.rb', line 33 def initialize(*args) super @eventable_mutex = Mutex.new end |
#register_for_event(args) ⇒ Object
Allows an object to listen for an event and have a callback run when the event happens
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/eventable/eventable.rb', line 61 def register_for_event(args) [:event, :listener, :callback].each do |parameter| raise ArgumentError, "Missing parameter :#{parameter}" unless args[parameter] end # Make access to the callback array threadsafe check_mutex @eventable_mutex.synchronize { event = args[:event] raise Errors::UnknownEvent unless events.include? event @callbacks ||= {} @callbacks[event] ||= {} listener = args[:listener] listener_id = listener.object_id callback = args[:callback] # save the callback info without creating a reference to the object @callbacks[event][listener_id] ||= [] @callbacks[event][listener_id] << callback # will remove the object from the callback list if it is destroyed ObjectSpace.define_finalizer( listener, unregister_finalizer(event, listener_id, callback) ) } end |
#unregister_for_event(args) ⇒ Object
Allows objects to stop listening to events
92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/eventable/eventable.rb', line 92 def unregister_for_event(args) check_mutex @eventable_mutex.synchronize { event = args[:event] return unless @callbacks && @callbacks[event] listener_id = args[:listener_id] || args[:listener].object_id callback = args[:callback] @callbacks[event].delete_if do |listener, callbacks| callbacks.delete(callback) if listener == listener_id callbacks.empty? end } end |