u-observers 0.3.0 → 0.8.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: 0fe383e800461aeb658a9b17f2d4799b194b7e70fdf5a545dbe07f69cd9d2642
4
- data.tar.gz: a42fdd9868c43855006b763faa86b0377ae2204f6e9c20893edfbadf49792a60
3
+ metadata.gz: 9b67e1c24feb02de944be44aacb6bba935d9dc1dfac6c53de2ba95dcffbd93ee
4
+ data.tar.gz: aead6fb10e5ada014fed52383f031d140363cbf4f7ef9b21f5ee7c9e9f54c792
5
5
  SHA512:
6
- metadata.gz: af8ce345aec2b28cef954f6de09ce835d1e4236e115877b04c92227121a85ebedd1b1cf422e3cc1645f2b7ad818cfdf81d9b05bcdb41007bca4fd9115d900fc0
7
- data.tar.gz: 45ade4eefd27ae3b8f0aed723681b5c1931cd11c34f78f17a21e59aa745a67de27b32272f4c01377950420f4dd0743c84258b9415cf24dea891d253f9ca1fe4b
6
+ metadata.gz: a77a575068bdee0f9312e25e5623a4031bb1369dee11df5d039121e84cf7cab418b8b37c3c93ff46265528304b64f80fc1be61ca42e78d9436e9e779c390b2bd
7
+ data.tar.gz: f90045332776294e6bc3bf6e70c34b0f24f40551f32a4d9be029ecd5fdfcad4b68d33b6f5c81802e9e257dedf9d1e16395bda434ee2dd48f38f9e291099a8a4e
@@ -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) }
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,9 +4,7 @@ module Micro
4
4
  module Observers
5
5
 
6
6
  class Manager
7
- EMPTY_HASH = {}.freeze
8
-
9
- SameObserver = -> (observer) do
7
+ EqualTo = -> (observer) do
10
8
  -> item { item[0] == :observer && item[1] == observer }
11
9
  end
12
10
 
@@ -17,56 +15,86 @@ module Micro
17
15
  def initialize(subject, list = nil)
18
16
  @subject = subject
19
17
 
20
- @list = (list.kind_of?(Array) ? list : []).flatten.tap(&:compact!)
18
+ @list = Utils.compact_array(list.kind_of?(Array) ? list : [])
21
19
  end
22
20
 
23
21
  def included?(observer)
24
- @list.any?(&SameObserver[observer])
22
+ @list.any?(&EqualTo[observer])
25
23
  end
26
24
 
27
- def attach(observer, options = EMPTY_HASH)
28
- if options[:allow_duplication] || !included?(observer)
29
- @list << [:observer, 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
30
32
  end
31
33
 
32
34
  self
33
35
  end
34
36
 
35
- def on(options=EMPTY_HASH)
36
- action, callable, with = options[:action], options[:call], options[:with]
37
+ def on(options = Utils::EMPTY_HASH)
38
+ event, callable, with = options[:event], options[:call], options[:with]
37
39
 
38
- return self unless action.is_a?(Symbol) && callable.respond_to?(:call)
40
+ return self unless event.is_a?(Symbol) && callable.respond_to?(:call)
39
41
 
40
- arg = with.is_a?(Proc) ? with.call(@subject) : subject
42
+ @list << [:callable, event, [callable, with]]
43
+ end
44
+
45
+ def detach(*args)
46
+ Utils.compact_array(args).each do |observer|
47
+ @list.delete_if(&EqualTo[observer])
48
+ end
41
49
 
42
- @list << [:caller, action, [callable, arg]]
50
+ self
43
51
  end
44
52
 
45
- def detach(observer)
46
- @list.delete_if(&SameObserver[observer])
53
+ def notify(*events)
54
+ broadcast(EventsOrActions[events])
47
55
 
48
56
  self
49
57
  end
50
58
 
51
- def call(action = :call)
52
- @list.each do |type, observer, data|
53
- if type == :caller && observer == action
54
- data[0].call(data[1])
55
- elsif type == :observer && observer.respond_to?(action)
56
- handler = observer.method(action)
59
+ def call(options = Utils::EMPTY_HASH)
60
+ broadcast(EventsOrActions.fetch_actions(options))
57
61
 
58
- return handler.call(@subject) if handler.arity == 1
62
+ self
63
+ end
59
64
 
60
- handler.call(@subject, data)
65
+ private
66
+
67
+ def broadcast(evts_or_acts)
68
+ evts_or_acts.each do |evt_or_act|
69
+ @list.each do |strategy, observer, data|
70
+ call!(observer, strategy, data, with: evt_or_act)
71
+ end
61
72
  end
62
73
  end
63
74
 
64
- self
65
- end
75
+ def call!(observer, strategy, data, with:)
76
+ return call_callable(data) if strategy == :callable && observer == with
77
+
78
+ return call_observer(observer, with, data) if strategy == :observer
79
+ end
80
+
81
+ def call_callable(data)
82
+ callable, arg = data[0], data[1]
83
+
84
+ callable_arg = arg.is_a?(Proc) ? arg.call(@subject) : (arg || @subject)
66
85
 
67
- alias notify call
86
+ callable.call(callable_arg)
87
+ end
88
+
89
+ def call_observer(observer, method_name, data)
90
+ return unless observer.respond_to?(method_name)
91
+
92
+ handler = observer.method(method_name)
93
+
94
+ handler.arity == 1 ? handler.call(@subject) : handler.call(@subject, data)
95
+ end
68
96
 
69
- private_constant :EMPTY_HASH
97
+ private_constant :EqualTo
70
98
  end
71
99
 
72
100
  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.3.0'
3
+ VERSION = '0.8.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.3.0
4
+ version: 0.8.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-28 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