module RuGUI::ObservablePropertySupport

Adds support to observable properties.

Public Class Methods

included(base) click to toggle source
# File lib/rugui/observable_property_support.rb, line 225
def self.included(base)
  base.extend(ClassMethods)
  base.create_class_inheritable_attributes
end
new(observable_properties_values = {}) click to toggle source

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

==(obj) click to toggle source

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
copy_observable_properties_from(other_observable, deep = true) click to toggle source

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
initialize_observable_property_support(observable_properties_values = {}) click to toggle source

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
observable_properties() click to toggle source

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
property_changed(property, new_value, old_value) click to toggle source

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
register_observer(observer, observable_name = nil) click to toggle source

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
reset!() click to toggle source

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 = {}) click to toggle source

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

clone_if_possible(value) click to toggle source
# File lib/rugui/observable_property_support.rb, line 240
def clone_if_possible(value)
  value.clone unless value.nil?
rescue TypeError
  value
end
has_changed?(new_value, old_value) click to toggle source
# 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
initialize_observers_if_needed() click to toggle source
# 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