Module: ObservableModel

Includes:
Observable
Defined in:
lib/command_handlers/models/observable_model.rb

Overview

TODO prefix utility methods with double-underscore

Defined Under Namespace

Classes: Updater

Instance Method Summary collapse

Instance Method Details

#add_observer(observer, property_name) ⇒ Object



21
22
23
24
25
26
# File 'lib/command_handlers/models/observable_model.rb', line 21

def add_observer(observer, property_name)
  return observer if has_observer?(observer, property_name)
  property_observer_list(property_name) << observer
  add_property_writer_observers(property_name)
  observer
end

#add_property_writer_observers(property_name) ⇒ Object

TODO upon updating values, make sure dependent observers are cleared (not added as dependents here)



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/command_handlers/models/observable_model.rb', line 55

def add_property_writer_observers(property_name)
  property_writer_name = "#{property_name}="
  ensure_array_object_observer(property_name, send(property_name))
  begin
    method("__original_#{property_writer_name}")
  rescue
    instance_eval "alias __original_#{property_writer_name} #{property_writer_name}"
    instance_eval "      def \#{property_writer_name}(value)\n        old_value = self.\#{property_name}\n        unregister_dependent_observers('\#{property_name}', old_value)\n        self.__original_\#{property_writer_name}(value)\n        notify_observers('\#{property_name}')\n        ensure_array_object_observer('\#{property_name}', value, old_value)\n      end\n    end_eval\n  end\nend\n", __FILE__, __LINE__

#array_object_observer_for(property_name) ⇒ Object



93
94
95
96
97
98
99
# File 'lib/command_handlers/models/observable_model.rb', line 93

def array_object_observer_for(property_name)
  @array_object_observers ||= {}
  unless @array_object_observers.has_key?(property_name)
    @array_object_observers[property_name] = ObservableModel::Updater.new(self, property_name)
  end
  @array_object_observers[property_name]
end

#ensure_array_object_observer(property_name, object, old_object = nil) ⇒ Object



82
83
84
85
86
87
88
89
90
91
# File 'lib/command_handlers/models/observable_model.rb', line 82

def ensure_array_object_observer(property_name, object, old_object = nil)
  return unless object.is_a?(Array)
  object.extend(ObservableArray) unless object.is_a?(ObservableArray)
  array_object_observer = array_object_observer_for(property_name)
  array_object_observer.observe(object)
  property_observer_list(property_name).each do |observer|
    observer.add_dependent([self, property_name] => [array_object_observer, object, nil])
  end
  array_object_observer_for(property_name).unregister(old_object) if old_object.is_a?(ObservableArray)
end

#has_observer?(observer, property_name) ⇒ Boolean

Returns:

  • (Boolean)


32
33
34
# File 'lib/command_handlers/models/observable_model.rb', line 32

def has_observer?(observer, property_name)
  property_observer_list(property_name).include?(observer)
end

#has_observer_for_any_property?(observer) ⇒ Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/command_handlers/models/observable_model.rb', line 36

def has_observer_for_any_property?(observer)
  property_observer_hash.values.map(&:to_a).sum.include?(observer)
end

#notify_observers(property_name) ⇒ Object



50
51
52
# File 'lib/command_handlers/models/observable_model.rb', line 50

def notify_observers(property_name)
  property_observer_list(property_name).each {|observer| observer.update(send(property_name))}
end

#property_observer_hashObject



40
41
42
43
# File 'lib/command_handlers/models/observable_model.rb', line 40

def property_observer_hash
  @property_observers = Hash.new unless @property_observers
  @property_observers
end

#property_observer_list(property_name) ⇒ Object



45
46
47
48
# File 'lib/command_handlers/models/observable_model.rb', line 45

def property_observer_list(property_name)
  property_observer_hash[property_name.to_sym] = Set.new unless property_observer_hash[property_name.to_sym]
  property_observer_hash[property_name.to_sym]
end

#remove_observer(observer, property_name) ⇒ Object



28
29
30
# File 'lib/command_handlers/models/observable_model.rb', line 28

def remove_observer(observer, property_name)
  property_observer_list(property_name).delete(observer)
end

#unregister_dependent_observers(property_name, old_value) ⇒ Object



74
75
76
77
78
79
80
# File 'lib/command_handlers/models/observable_model.rb', line 74

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 do |observer|
    observer.unregister_dependents_with_observable([self, property_name], old_value)
  end
end