Module: Glimmer::SWT::ObservableModel

Includes:
Observable
Defined in:
lib/glimmer/swt/observable_model.rb

Overview

TODO prefix utility methods with double-underscore

Defined Under Namespace

Classes: Notifier

Instance Method Summary collapse

Instance Method Details

#add_observer(observer, property_name) ⇒ Object



23
24
25
26
27
28
# File 'lib/glimmer/swt/observable_model.rb', line 23

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)



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/glimmer/swt/observable_model.rb', line 57

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 <<-end_eval, __FILE__, __LINE__
    def #{property_writer_name}(value)
      old_value = self.#{property_name}
      unregister_dependent_observers('#{property_name}', old_value)
      self.__original_#{property_writer_name}(value)
      notify_observers('#{property_name}')
      ensure_array_object_observer('#{property_name}', value, old_value)
    end
    end_eval
  end
rescue => e
  # ignore writing if no property writer exists
  Glimmer.logger.debug "No need to observe property writer: #{property_writer_name}\n#{e.message}\n#{e.backtrace.join("\n")}"
end

#array_object_observer_for(property_name) ⇒ Object



98
99
100
101
102
103
104
# File 'lib/glimmer/swt/observable_model.rb', line 98

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

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



88
89
90
91
92
93
94
95
96
# File 'lib/glimmer/swt/observable_model.rb', line 88

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)


34
35
36
# File 'lib/glimmer/swt/observable_model.rb', line 34

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

#has_observer_for_any_property?(observer) ⇒ Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/glimmer/swt/observable_model.rb', line 38

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

#notify_observers(property_name) ⇒ Object



52
53
54
# File 'lib/glimmer/swt/observable_model.rb', line 52

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

#property_observer_hashObject



42
43
44
45
# File 'lib/glimmer/swt/observable_model.rb', line 42

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

#property_observer_list(property_name) ⇒ Object



47
48
49
50
# File 'lib/glimmer/swt/observable_model.rb', line 47

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



30
31
32
# File 'lib/glimmer/swt/observable_model.rb', line 30

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

#unregister_dependent_observers(property_name, old_value) ⇒ Object



80
81
82
83
84
85
86
# File 'lib/glimmer/swt/observable_model.rb', line 80

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