module Glimmer::DataBinding::ObservableModel
Constants
- PROPERTY_WRITER_FACTORY
Public Instance Methods
add_observer(observer, property_name, options = {})
click to toggle source
# File lib/glimmer/data_binding/observable_model.rb, line 53 def add_observer(observer, property_name, options = {}) initialize_observer_options(options) return observer if has_observer?(observer, property_name) property_observer_list(property_name) << observer # if property writer does not exist, add_property_writer_observers will ensure_array_object_observer only add_property_writer_observers(property_name, options) add_key_writer_observer(property_name, options) unless (['Struct', 'OpenStruct'] & self.class.ancestors.map(&:to_s)).empty? observer end
add_property_writer_observers(property_name, options)
click to toggle source
# File lib/glimmer/data_binding/observable_model.rb, line 115 def add_property_writer_observers(property_name, options) options[:attribute_writer_type].each do |attribute_writer_type| begin property_writer_name = attribute_writer_type.to_s.gsub('attribute', property_name.to_s) ensure_array_object_observer(property_name, send(property_name), nil, options) method(property_writer_name) begin method("__original__#{property_writer_name}") rescue define_singleton_method("__original__#{property_writer_name}", property_writer_method(property_writer_name)) # Note the limitation that the first observe call options apply to all subsequent observations meaning even if unobserve was called, options do not change from initial ones # It is good enough for now. If there is a need to address this in the future, this is where to start the work define_singleton_method(property_writer_name, &PROPERTY_WRITER_FACTORY.call(property_name, property_writer_name, options)) end rescue => e #ignore writing if no property writer exists Glimmer::Config.logger.debug {"No need to observe property writer: #{property_writer_name}\n#{e.message}\n#{e.backtrace.join("\n")}"} end end end
all_property_observer_list()
click to toggle source
# File lib/glimmer/data_binding/observable_model.rb, line 106 def all_property_observer_list property_observer_list(nil) end
Also aliased as: all_key_observer_list
array_object_observer_for(property_name)
click to toggle source
# File lib/glimmer/data_binding/observable_model.rb, line 159 def array_object_observer_for(property_name) @array_object_observers ||= Concurrent::Hash.new @array_object_observers[property_name] = Notifier.new(self, property_name) unless @array_object_observers.has_key?(property_name) @array_object_observers[property_name] end
ensure_array_object_observer(property_name, object, old_object = nil, options = nil)
click to toggle source
# File lib/glimmer/data_binding/observable_model.rb, line 147 def ensure_array_object_observer(property_name, object, old_object = nil, options = nil) options ||= {} return unless object&.is_a?(Array) array_object_observer = array_object_observer_for(property_name) array_observer_registration = array_object_observer.observe(object, options) property_observer_list(property_name).each do |observer| my_registration = observer.registration_for(self, property_name) # TODO eliminate repetition observer.add_dependent(my_registration => array_observer_registration) end array_object_observer_for(property_name).unregister(old_object) if old_object.is_a?(ObservableArray) end
has_observer?(observer, property_name)
click to toggle source
# File lib/glimmer/data_binding/observable_model.rb, line 87 def has_observer?(observer, property_name) property_observer_list(property_name).include?(observer) end
has_observer_for_any_property?(observer)
click to toggle source
# File lib/glimmer/data_binding/observable_model.rb, line 91 def has_observer_for_any_property?(observer) property_observer_hash.values.map(&:to_a).reduce(:+).include?(observer) end
initialize_observer_options(options)
click to toggle source
# File lib/glimmer/data_binding/observable_model.rb, line 165 def initialize_observer_options(options) options[:attribute_writer_type] ||= [:attribute=] options[:attribute_writer_type] = [options[:attribute_writer_type]] if !options[:attribute_writer_type].is_a?(Array) end
notify_observers(property_name)
click to toggle source
# File lib/glimmer/data_binding/observable_model.rb, line 111 def notify_observers(property_name) property_observer_list(property_name).to_a.each { |observer| observer.call(send(property_name)) } end
property_observer_hash()
click to toggle source
# File lib/glimmer/data_binding/observable_model.rb, line 95 def property_observer_hash @property_observers ||= Concurrent::Hash.new end
property_observer_list(property_name)
click to toggle source
# File lib/glimmer/data_binding/observable_model.rb, line 99 def property_observer_list(property_name) property_key = property_name&.to_sym property_observer_hash[property_key] = Concurrent::Set.new unless property_observer_hash[property_key] property_observer_hash[property_key] end
Also aliased as: key_observer_list
property_writer_method(property_writer_name)
click to toggle source
# File lib/glimmer/data_binding/observable_model.rb, line 136 def property_writer_method(property_writer_name) self.class.instance_method(property_writer_name) rescue self.method(property_writer_name) end
remove_all_observers()
click to toggle source
# File lib/glimmer/data_binding/observable_model.rb, line 78 def remove_all_observers all_observers = property_observer_hash.clone property_observer_hash.keys.each do |property_name| remove_observers(property_name) end property_observer_hash.clear all_observers end
remove_observer(observer, property_name, options = {})
click to toggle source
# File lib/glimmer/data_binding/observable_model.rb, line 63 def remove_observer(observer, property_name, options = {}) if has_observer?(observer, property_name) property_observer_list(property_name).delete(observer) observer.unobserve(self, property_name) end end
remove_observers(property_name)
click to toggle source
# File lib/glimmer/data_binding/observable_model.rb, line 70 def remove_observers(property_name) property_key = property_name&.to_sym property_observer_hash[property_key].each do |observer| remove_observer(observer, property_name) end property_observer_hash.delete(property_key) end
unregister_dependent_observers(property_name, old_value)
click to toggle source
# File lib/glimmer/data_binding/observable_model.rb, line 140 def unregister_dependent_observers(property_name, old_value) # TODO look into optimizing this return unless old_value.is_a?(ObservableModel) || old_value.is_a?(ObservableArray) property_observer_list(property_name).each { |observer| observer.unregister_dependents_with_observable(observer.registration_for(self, property_name), old_value) } end
Also aliased as: deregister_dependent_observers