Module: Glimmer::DataBinding::Observer
Overview
Mixin representing Observer trait from Observer Design Pattern Allows classes to include without interfering with their inheritance hierarchy.
Includes a default implementation that can receive an observer block Example: Observer.proc {|new_value| puts new_value} Subclasses may override
Defined Under Namespace
Classes: Proc, Registration
Class Method Summary
collapse
Instance Method Summary
collapse
-
#add_dependent(parent_to_dependent_hash) ⇒ Object
add dependent observer to unregister when unregistering observer.
-
#call(new_value = nil, *extra_args) ⇒ Object
-
#compact_args(args) ⇒ Object
-
#dependents ⇒ Object
mapping of registrations to dependents property] => [[dependent, dependent_observable, dependent_property], …].
-
#dependents_for(registration) ⇒ Object
-
#observe(observable, *args) ⇒ Object
(also: #register)
registers observer in an observable on args usually containing a property and options (optional) observer maintains registration list to unregister later.
-
#registration_for(observable, *args) ⇒ Object
(also: #ensure_registration_for!)
-
#registrations ⇒ Object
-
#remove_dependent(parent_to_dependent_hash) ⇒ Object
-
#unobserve(observable, *args) ⇒ Object
(also: #unregister, #deregister)
-
#unobserve_all_observables ⇒ Object
(also: #unregister_all_observables, #deregister_all_observables)
cleans up all registrations in observables.
-
#unobserve_dependents_with_observable(registration, dependent_observable) ⇒ Object
(also: #unregister_dependents_with_observable, #deregister_dependents_with_observable)
Class Method Details
.proc(&observer_block) ⇒ Object
58
59
60
|
# File 'lib/glimmer/data_binding/observer.rb', line 58
def proc(&observer_block)
Proc.new(&observer_block)
end
|
Instance Method Details
#add_dependent(parent_to_dependent_hash) ⇒ Object
add dependent observer to unregister when unregistering observer
141
142
143
144
145
|
# File 'lib/glimmer/data_binding/observer.rb', line 141
def add_dependent(parent_to_dependent_hash)
registration = parent_to_dependent_hash.keys.first
dependent = parent_to_dependent_hash.values.first
dependents_for(registration) << dependent
end
|
#call(new_value = nil, *extra_args) ⇒ Object
155
156
157
|
# File 'lib/glimmer/data_binding/observer.rb', line 155
def call(new_value = nil, *)
raise Error, 'Not implemented!'
end
|
#compact_args(args) ⇒ Object
159
160
161
162
163
|
# File 'lib/glimmer/data_binding/observer.rb', line 159
def compact_args(args)
args = args[0...-1] if args.last == {}
args = args[0...-1] if args.last == []
args.compact
end
|
#dependents ⇒ Object
mapping of registrations to dependents property] => [[dependent, dependent_observable, dependent_property], …]
75
76
77
|
# File 'lib/glimmer/data_binding/observer.rb', line 75
def dependents
@dependents ||= Concurrent::Hash.new
end
|
#dependents_for(registration) ⇒ Object
79
80
81
|
# File 'lib/glimmer/data_binding/observer.rb', line 79
def dependents_for(registration)
dependents[registration.object_id] ||= Concurrent::Set.new
end
|
#observe(observable, *args) ⇒ Object
Also known as:
register
registers observer in an observable on args usually containing a property and options (optional) observer maintains registration list to unregister later
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
# File 'lib/glimmer/data_binding/observer.rb', line 85
def observe(observable, *args)
options = args.last.is_a?(Hash) ? args.last : {}
return if observable.nil?
return if options[:ignore_frozen] && observable.frozen?
unless observable.is_a?(Observable)
if observable.is_a?(Array)
observable.extend(ObservableArray)
elsif observable.is_a?(Hash)
observable.extend(ObservableHash)
else
observable.extend(ObservableModel)
end
end
args = compact_args(args)
observable.add_observer(self, *args)
ensure_registration_for!(observable, *args)
end
|
#registration_for(observable, *args) ⇒ Object
Also known as:
ensure_registration_for!
67
68
69
70
|
# File 'lib/glimmer/data_binding/observer.rb', line 67
def registration_for(observable, *args)
args = compact_args(args)
registrations[[observable.object_id, args]] ||= Registration.new(observer: self, observable: observable, args: args)
end
|
#registrations ⇒ Object
63
64
65
|
# File 'lib/glimmer/data_binding/observer.rb', line 63
def registrations
@registrations ||= Concurrent::Hash.new
end
|
#remove_dependent(parent_to_dependent_hash) ⇒ Object
147
148
149
150
151
152
153
|
# File 'lib/glimmer/data_binding/observer.rb', line 147
def remove_dependent(parent_to_dependent_hash)
registration = parent_to_dependent_hash.keys.first
dependent = parent_to_dependent_hash.values.first
dependents_for(registration).delete(dependent).tap do
dependents.delete([registration.object_id]) if dependents_for(registration).empty?
end
end
|
#unobserve(observable, *args) ⇒ Object
Also known as:
unregister, deregister
105
106
107
108
109
110
111
112
113
114
115
116
117
|
# File 'lib/glimmer/data_binding/observer.rb', line 105
def unobserve(observable, *args)
return unless observable.is_a?(Observable)
args = compact_args(args)
registration = registration_for(observable, *args)
registrations.delete([observable.object_id, args])
registration.tap do |registration|
dependents_for(registration).each do |dependent|
remove_dependent(registration => dependent)
dependent.deregister if dependent != registration
end
observable.remove_observer(self, *args)
end
end
|
#unobserve_all_observables ⇒ Object
Also known as:
unregister_all_observables, deregister_all_observables
cleans up all registrations in observables
131
132
133
134
135
136
|
# File 'lib/glimmer/data_binding/observer.rb', line 131
def unobserve_all_observables
registrations.values.dup.each do |registration|
registration.deregister
registrations.delete([registration.observable.object_id, registration.args])
end
end
|
#unobserve_dependents_with_observable(registration, dependent_observable) ⇒ Object
Also known as:
unregister_dependents_with_observable, deregister_dependents_with_observable
121
122
123
124
125
126
|
# File 'lib/glimmer/data_binding/observer.rb', line 121
def unobserve_dependents_with_observable(registration, dependent_observable)
thedependents = dependents_for(registration).select do |thedependent|
thedependent.observable == dependent_observable
end
thedependents.each(&:deregister)
end
|