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
73
74
75
76
# File 'lib/command_handlers/models/observable_model.rb', line 55

def add_property_writer_observers(property_name)
  property_writer_name = "#{property_name}="
  method(property_writer_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\nrescue => e\n  # ignore writing if no property writer exists\n  Glimmer.logger.debug \"No need to observe property writer: \#{property_writer_name}\\n\#{e.message}\\n\#{e.backtrace.join(\"\\n\")}\"\nend\n", __FILE__, __LINE__

#array_object_observer_for(property_name) ⇒ Object



96
97
98
99
100
101
102
# File 'lib/command_handlers/models/observable_model.rb', line 96

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



86
87
88
89
90
91
92
93
94
# File 'lib/command_handlers/models/observable_model.rb', line 86

def ensure_array_object_observer(property_name, object, old_object = nil)
  return unless object.is_a?(Array)
  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



78
79
80
81
82
83
84
# File 'lib/command_handlers/models/observable_model.rb', line 78

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