u-observers 0.2.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a74f927670b4695760167dbbc2c1758cedbe112233b22d938cbcd79083cd8526
4
- data.tar.gz: b268b6f4b5d9c92469c20c8ba891bc12146fa52b09e6a44ccb664c6155d9b45f
3
+ metadata.gz: 20e65a3bddc28ca3121413e665f084f096c7b266304d9c486bc2d7c9b618ab8a
4
+ data.tar.gz: 455304b5999249cd475f5df8a44e0d855333ccf208f41d9cd98c7cfe1bba3cac
5
5
  SHA512:
6
- metadata.gz: b1830ebe8c59bd1f7fe66588d2b6b5b8839b487af1fe3c75a876eecc28773996e86dbd61a65af44c28c1b29bbe1a9497a9a234801d50ec19b53878b43f85bc89
7
- data.tar.gz: 4d7d0b6289ed0045e85e4edbacd6482d11c5577932f215cab19f0885c7049a20ad2015ceffaea21e1d6a7459727dd64f370cd4555e45b97d78b2c6b1a5e31575
6
+ metadata.gz: 9fe33fb9bc6bcb060f32329e28774abb6a7b546e178e531d045043889db64c403afd00171351e733df33cc812e84763c9aaf47f89c82dc6cd37264ab8ba8fd04
7
+ data.tar.gz: af195ddbdacb7e811f8c30d45d389d4b9472df7d06966009740e8cf4400676add7d80cda18db166795fafe27ae82277ed1930a2c72053bf427f4fefe424c37bc
@@ -2,23 +2,27 @@ require 'micro/observers/version'
2
2
 
3
3
  module Micro
4
4
  module Observers
5
+ require 'micro/observers/utils'
6
+ require 'micro/observers/events_or_actions'
5
7
  require 'micro/observers/manager'
6
8
 
7
9
  module ClassMethods
8
- def call_observers(with: :call)
9
- proc do |object|
10
- Array(with)
11
- .each { |action| object.observers.call(action: action) }
12
- end
10
+ def notify_observers!(with:)
11
+ proc { |object| with.each { |evt_or_act| object.observers.notify(evt_or_act) } }
13
12
  end
14
13
 
15
- def notify_observers(with: :call)
16
- call_observers(with: with)
14
+ def notify_observers(*events)
15
+ notify_observers!(with: EventsOrActions[events])
16
+ end
17
+
18
+ def call_observers(options = Utils::EMPTY_HASH)
19
+ notify_observers!(with: EventsOrActions.fetch_actions(options))
17
20
  end
18
21
  end
19
22
 
20
23
  def self.included(base)
21
24
  base.extend(ClassMethods)
25
+ base.send(:private_class_method, :notify_observers!)
22
26
  end
23
27
 
24
28
  def observers
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro
4
+ module Observers
5
+
6
+ module EventsOrActions
7
+ DEFAULTS = [:call]
8
+
9
+ def self.[](value)
10
+ values = Utils.compact_array(value)
11
+
12
+ values.empty? ? DEFAULTS : values
13
+ end
14
+
15
+ def self.fetch_actions(hash)
16
+ return self[hash[:actions] || hash.fetch(:action)] if hash.is_a?(Hash)
17
+
18
+ raise ArgumentError, 'expected a hash with the key :action or :actions'
19
+ end
20
+
21
+ private_constant :DEFAULTS
22
+ end
23
+
24
+ end
25
+ end
@@ -4,7 +4,9 @@ module Micro
4
4
  module Observers
5
5
 
6
6
  class Manager
7
- EMPTY_HASH = {}.freeze
7
+ EqualTo = -> (observer) do
8
+ -> item { item[0] == :observer && item[1] == observer }
9
+ end
8
10
 
9
11
  def self.for(subject)
10
12
  new(subject)
@@ -12,42 +14,79 @@ module Micro
12
14
 
13
15
  def initialize(subject, list = nil)
14
16
  @subject = subject
15
- @list = (list.kind_of?(Array) ? list : []).flatten.tap(&:compact!)
17
+
18
+ @list = Utils.compact_array(list.kind_of?(Array) ? list : [])
19
+ end
20
+
21
+ def included?(observer)
22
+ @list.any?(&EqualTo[observer])
16
23
  end
17
24
 
18
- def attach(observer, options = EMPTY_HASH)
19
- if options[:allow_duplication] || @list.none? { |obs, _data| obs == observer }
20
- @list << [observer, options[:data]]
25
+ def attach(*args)
26
+ options = args.last.is_a?(Hash) ? args.pop : Utils::EMPTY_HASH
27
+
28
+ Utils.compact_array(args).each do |observer|
29
+ if options[:allow_duplication] || !included?(observer)
30
+ @list << [:observer, observer, options[:data]]
31
+ end
21
32
  end
22
33
 
23
34
  self
24
35
  end
25
36
 
26
- def detach(observer)
27
- @list.delete_if { |obs, _data| obs == observer }
37
+ def on(options = Utils::EMPTY_HASH)
38
+ event, callable, with = options[:event], options[:call], options[:with]
39
+
40
+ return self unless event.is_a?(Symbol) && callable.respond_to?(:call)
41
+
42
+ arg = with.is_a?(Proc) ? with.call(@subject) : (arg || subject)
43
+
44
+ @list << [:callable, event, [callable, arg]]
45
+ end
46
+
47
+ def detach(*args)
48
+ Utils.compact_array(args).each do |observer|
49
+ @list.delete_if(&EqualTo[observer])
50
+ end
28
51
 
29
52
  self
30
53
  end
31
54
 
32
- def call(action: :call)
33
- @list.each do |observer, data|
34
- next unless observer.respond_to?(action)
55
+ def notify(*events)
56
+ broadcast(EventsOrActions[events])
35
57
 
36
- handler = observer.method(action)
58
+ self
59
+ end
37
60
 
38
- case handler.arity
39
- when 2 then handler.call(@subject, data)
40
- when 1 then handler.call(@subject)
41
- else raise NotImplementedError
42
- end
43
- end
61
+ def call(options = Utils::EMPTY_HASH)
62
+ broadcast(EventsOrActions.fetch_actions(options))
44
63
 
45
64
  self
46
65
  end
47
66
 
48
- alias notify call
67
+ private
68
+
69
+ def broadcast(evts_or_acts)
70
+ evts_or_acts.each do |evt_or_act|
71
+ @list.each do |strategy, observer, data|
72
+ call!(observer, strategy, data, with: evt_or_act)
73
+ end
74
+ end
75
+ end
76
+
77
+ def call!(observer, strategy, data, with:)
78
+ return data[0].call(data[1]) if strategy == :callable && observer == with
79
+
80
+ if strategy == :observer && observer.respond_to?(with)
81
+ handler = observer.method(with)
82
+
83
+ return handler.call(@subject) if handler.arity == 1
84
+
85
+ handler.call(@subject, data)
86
+ end
87
+ end
49
88
 
50
- private_constant :EMPTY_HASH
89
+ private_constant :EqualTo
51
90
  end
52
91
 
53
92
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro
4
+ module Observers
5
+
6
+ module Utils
7
+ EMPTY_HASH = {}.freeze
8
+
9
+ def self.compact_array(value)
10
+ Array(value).flatten.tap(&:compact!)
11
+ end
12
+ end
13
+
14
+ end
15
+ end
@@ -1,5 +1,5 @@
1
1
  module Micro
2
2
  module Observers
3
- VERSION = '0.2.0'
3
+ VERSION = '0.7.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: u-observers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-09-25 00:00:00.000000000 Z
11
+ date: 2020-09-26 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Simple and powerful implementation of the observer pattern.
14
14
  email:
@@ -27,7 +27,9 @@ files:
27
27
  - bin/console
28
28
  - bin/setup
29
29
  - lib/micro/observers.rb
30
+ - lib/micro/observers/events_or_actions.rb
30
31
  - lib/micro/observers/manager.rb
32
+ - lib/micro/observers/utils.rb
31
33
  - lib/micro/observers/version.rb
32
34
  - lib/u-observers.rb
33
35
  - u-observers.gemspec