Module: RuGUI::ObservablePropertySupport

Included in:
BaseModel, BaseViewHelper
Defined in:
lib/rugui/observable_property_support.rb

Overview

Adds support to observable properties.

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



225
226
227
228
# File 'lib/rugui/observable_property_support.rb', line 225

def self.included(base)
  base.extend(ClassMethods)
  base.create_class_inheritable_attributes
end

Instance Method Details

#==(obj) ⇒ Object

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.



82
83
84
85
86
87
88
89
90
# 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) ⇒ Object

Copies all observable properties from other_observable to self



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# 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_properties_values = {}) ⇒ Object

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.



9
10
11
# File 'lib/rugui/observable_property_support.rb', line 9

def initialize(observable_properties_values = {})
  initialize_observable_property_support(observable_properties_values)
end

#initialize_observable_property_support(observable_properties_values = {}) ⇒ Object

Initializes observable properties, setting their initial value.



14
15
16
17
18
19
# 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_propertiesObject

Returns a map of all observable properties with theirs values.



110
111
112
# 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) ⇒ Object

Called whenver the a property has changed.



42
43
44
45
46
47
48
49
50
# 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) ⇒ Object

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)


35
36
37
38
39
# 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!Object

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.



64
65
66
67
68
69
70
71
72
73
74
75
# 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 = {}) ⇒ Object

Update observable properties values given a map of values



115
116
117
# 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