event_driven 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f700fc113b0a05226ca3483f2905312423026723
4
+ data.tar.gz: 2aff47b0bb76b3563b6988ca14475ddae554f458
5
+ SHA512:
6
+ metadata.gz: 075c186eec05ecb0834c8c2d5ddc2aedf325f905a326ba91058f6af624afafc14dd6da19c35dd47057937febc22b31212097cd041e284486e9957449f3a2838f
7
+ data.tar.gz: d916097a4b2032bc9f52158c39dcc311abdee03fbd0f9db0857947b86caf32f71aa3ca87870e8587397e39f2a14152e8624905830ee3b51faf2ed3f0057fca51
data/README.md ADDED
@@ -0,0 +1,65 @@
1
+ # EventDriven
2
+
3
+ Provides a basic ruby port of Symfony's EventDispatacher component.
4
+
5
+ Eventing allows connecting two components of an application without coupling between them.
6
+
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'event_driven'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install event_driven
23
+
24
+ ## Usage
25
+
26
+ Basic event usage:
27
+
28
+ ```ruby
29
+ # Creating a custom event class
30
+ class PartyInvitation < EventDriven::Event
31
+ attr_reader :message
32
+
33
+ def initialize(message)
34
+ @message = message
35
+ end
36
+ end
37
+
38
+ # Any ruby object that implements #call can be used as a listener
39
+ handler = -> (event, event_name) do
40
+ puts "#{event_name} - message #{event.message}"
41
+ end
42
+
43
+ # Creating a dispatcher
44
+ dispatcher = EventDriven::Dispatcher.new
45
+
46
+ # Add a listener to any event name
47
+ dispatcher.add_listener(event_name: :party_time, listener: handler)
48
+
49
+ # Fire an event to let other parts of the system know it happened
50
+
51
+ party_anouncement = PartyInvitation.new("It's party time!")
52
+
53
+ dispatcher.dispatch(event_name: :party_time, event: party_anouncement)
54
+ ```
55
+
56
+ ## Development
57
+
58
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
59
+
60
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
61
+
62
+ ## Contributing
63
+
64
+ Bug reports and pull requests are welcome on GitHub at https://github.com/emerson-h/event_driven.
65
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,7 @@
1
+ require 'event_driven/version'
2
+ require 'event_driven/dispatcher'
3
+ require 'event_driven/event'
4
+
5
+ # A port of Symfony's EventDispatcher {https://github.com/symfony/event-dispatcher}
6
+ module EventDriven
7
+ end
@@ -0,0 +1,97 @@
1
+ module EventDriven
2
+ # A basic event dispatcher
3
+ class Dispatcher
4
+ attr_reader :events, :sorted_listeners
5
+ private :events, :sorted_listeners
6
+
7
+ def initialize
8
+ @events = Hash.new do |hash, event_name|
9
+ hash[event_name] = Hash.new do |events_by_priority, priority|
10
+ events_by_priority[priority] = Array.new
11
+ end
12
+ end
13
+ @sorted_listeners = Hash.new do |hash, event_name|
14
+ hash[event_name] = Array.new
15
+ end
16
+ end
17
+
18
+ # Adds a listener to a specific event
19
+ #
20
+ # @param event_name [String, Symbol] the name of the desired event
21
+ # @param listener [Callable] the listener to add to the event. Should implement #call, which will be invoked with
22
+ # event and event_name when an event is dispatched
23
+ # @param priority [Fixnum] optional
24
+ def add_listener(event_name:, listener:, priority: 0)
25
+ events[event_name][priority] << listener
26
+ update_sorted_listeners(event_name)
27
+ end
28
+
29
+
30
+ # Does an event have any listeners
31
+ #
32
+ # @param event_name [String, Symbol] the name of the desired event
33
+ #
34
+ # @return [Boolean] true if there are listeners
35
+ def listeners_for?(event_name)
36
+ events[event_name].any? do |events_by_priority|
37
+ events_by_priority.length > 0
38
+ end
39
+ end
40
+
41
+ # Get the priority a listener has for a given event name
42
+ #
43
+ # @param event_name [String, Symbol] the name of the desired event
44
+ # @param listener [Callable] the desired listener
45
+ #
46
+ # @return [Fixnum, nil] returns the priority or nil if the listener is not subscribed to the event
47
+ def priority(event_name:, listener:)
48
+ prioritized_events = events[event_name]
49
+ prioritized_events.each_pair do |priority, listeners|
50
+ return priority if listeners.include?(listener)
51
+ end
52
+ end
53
+
54
+ # Dispatches the passed event to all subscribed listeners in priority order
55
+ #
56
+ # @param event_name [String, Symbol] the name of the event being dispatched
57
+ # @param event [EventDriven::Event] the event to dispatch along with the name
58
+ #
59
+ # @return [void]
60
+ def dispatch(event_name:, event: EventDriven::Event.new)
61
+ listeners_for(event_name).each do |listener|
62
+ listener.call(event, event_name) unless event.stopped?
63
+ end
64
+ end
65
+
66
+ # All of the listeners for the passed event name
67
+ #
68
+ # @param event_name [String, Symbol] the name of the desired event
69
+ #
70
+ # @return [Array<Callable>] the listeners for the provided event sorted by priority
71
+ def listeners_for(event_name)
72
+ unless sorted_listeners.has_key?(event_name)
73
+ update_sorted_listeners(event_name)
74
+ end
75
+ sorted_listeners[event_name]
76
+ end
77
+
78
+ # Removes a listener from a specified event name
79
+ #
80
+ # @param event_name [String, Symbol] the name of the desired event
81
+ # @param listener [Callable] the listener to remove
82
+ #
83
+ # @return [void]
84
+ def remove_listener(event_name:, listener:)
85
+ events[event_name].each_value do |listeners|
86
+ listeners.delete(listener)
87
+ end
88
+ update_sorted_listeners(event_name)
89
+ end
90
+
91
+ private def update_sorted_listeners(event_name)
92
+ sorted_listeners.delete(event_name)
93
+ sorted_pair_iterator = events[event_name].each_pair.sort { |pair_a, pair_b| -pair_a[0] <=> -pair_b[0] }
94
+ sorted_listeners[event_name] = sorted_pair_iterator.map { |priority_listeners_list| priority_listeners_list[1..-1] }.flatten
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,18 @@
1
+ module EventDriven
2
+ # The most basic event. Does not store information, but allows clients to stop propagation
3
+ class Event
4
+ # Stops the event from being sent to other listeners
5
+ #
6
+ # @return [void]
7
+ def stop_propagation
8
+ @stopped = true
9
+ end
10
+
11
+ # Whether the event has been stopped
12
+ #
13
+ # @return [Boolean] true if the event was stopped
14
+ def stopped?
15
+ !!@stopped
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module EventDriven
2
+ VERSION = '1.0.0'
3
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: event_driven
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Emerson Huitt
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-06-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: Provides a dispatch system, a basic event class, and a basic listener
56
+ implementation
57
+ email:
58
+ - emerson.huitt@scimedsolutions.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - README.md
64
+ - Rakefile
65
+ - lib/event_driven.rb
66
+ - lib/event_driven/dispatcher.rb
67
+ - lib/event_driven/event.rb
68
+ - lib/event_driven/version.rb
69
+ homepage: https://github.com/emerson-h
70
+ licenses: []
71
+ metadata: {}
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubyforge_project:
88
+ rubygems_version: 2.2.2
89
+ signing_key:
90
+ specification_version: 4
91
+ summary: EventDriven is a port of symfony/event-dispatcher, and provides a set of
92
+ tools for interacting with events in a system
93
+ test_files: []