module RuGUI::ObservablePropertySupport
Adds support to observable properties.
Public Class Methods
# File lib/rugui/observable_property_support.rb, line 225 def self.included(base) base.extend(ClassMethods) base.create_class_inheritable_attributes end
Initializes the observable properties. If you override this method, make sure that you call the initialize_observable_property_support
method, so that the observable properties are initialized.
# File lib/rugui/observable_property_support.rb, line 9 def initialize(observable_properties_values = {}) initialize_observable_property_support(observable_properties_values) end
Public Instance Methods
Returns true
if obj
is equals to self
.
This method checks if obj
is of the same type of self
and if all core observable_properties
are equals.
# File lib/rugui/observable_property_support.rb, line 82 def ==(obj) if obj.is_a?(self.class) self.class.core_observable_properties.each do |property| return false unless obj.respond_to?(property) and respond_to?(property) return false unless send(property) == obj.send(property) end return true end end
Copies all observable properties from other_observable to self
# File lib/rugui/observable_property_support.rb, line 93 def copy_observable_properties_from(other_observable, deep = true) self.class.observable_properties.each do |property| if other_observable.respond_to?(property) other_property_value = other_observable.send(property) if other_property_value.class.include?(ObservablePropertySupport) if deep send("#{property}=", other_property_value.class.new) if send(property).nil? # Creates an instance of the same class send(property).copy_observable_properties_from(other_property_value) end else send("#{property}=", other_property_value) end end end end
Initializes observable properties, setting their initial value.
# File lib/rugui/observable_property_support.rb, line 14 def initialize_observable_property_support(observable_properties_values = {}) self.class.observable_properties_options.each do |property, options| value = (observable_properties_values.with_indifferent_access[property] || clone_if_possible(options[:initial_value])) send("#{property}=", value) end end
Returns a map of all observable properties with theirs values.
# File lib/rugui/observable_property_support.rb, line 110 def observable_properties self.class.observable_properties.inject({}) { |properties, property| properties.merge!({ property => send(property) }) } end
Called whenver the a property has changed.
# File lib/rugui/observable_property_support.rb, line 42 def property_changed(property, new_value, old_value) initialize_observers_if_needed @observers.each do |observer| observer.property_updated(self, property, new_value, old_value) if observer.respond_to?(:property_updated) end @named_observers.each do |observable_name, observer| observer.named_observable_property_updated(observable_name, self, property, new_value, old_value) if observer.respond_to?(:named_observable_property_updated) end end
Registers an observer for this model.
The observer must implement a method with this signature:
property_updated(observable, property, new_value, old_value)
This method is called whenever a property has changed its value. One option is to include the PropertyObserver
module in the observer class.
Optionally, if observable_name
can be given, a method with this signature will also be called:
named_observable_property_updated(observable_name, observable, property, new_value, old_value)
# File lib/rugui/observable_property_support.rb, line 35 def register_observer(observer, observable_name = nil) initialize_observers_if_needed @observers << observer @named_observers[observable_name] = observer unless observable_name.nil? end
Resets all observable properties for this observer.
Since an observable property may be another observable there may exist some observers observing this other observable. In this scenario one should not attempt to set a new object into the observable property, because the observers would still be looking for the old observable.
By calling reset!
all observable properties are reset to the values specified when creating it. Also if the property respond to reset the method will be called, unless a reset_value is configured, i.e., it is not nil
. Also, if prevent_reset is true, that property will not be reseted, even if it has a reset_value configured.
# File lib/rugui/observable_property_support.rb, line 64 def reset! self.class.observable_properties_options.each do |property, options| unless options[:prevent_reset] property_value = send(property) if options[:reset_value].nil? and property_value.respond_to?(:reset!) property_value.reset! else send("#{property}=", clone_if_possible(options[:reset_value])) end end end end
Update observable properties values given a map of values
# File lib/rugui/observable_property_support.rb, line 115 def update_observable_properties(values = {}) values.each { |property, value| send("#{property}=", value) if self.respond_to?("#{property}=") } end
Private Instance Methods
# File lib/rugui/observable_property_support.rb, line 240 def clone_if_possible(value) value.clone unless value.nil? rescue TypeError value end
# File lib/rugui/observable_property_support.rb, line 236 def has_changed?(new_value, old_value) !(new_value.kind_of?(old_value.class) && old_value == new_value) end
# File lib/rugui/observable_property_support.rb, line 231 def initialize_observers_if_needed @observers = [] if not defined?(@observers) or @observers.nil? @named_observers = {} if not defined?(@named_observers) or @named_observers.nil? end