module Glimmer::DataBinding::ObservableArray

Public Instance Methods

<<(element) click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 153
def <<(element)
  super(element).tap do
    add_element_observers(element)
    notify_observers
  end
end
Also aliased as: push, append
[]=(index, value) click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 162
def []=(index, value)
  old_value = self[index]
  unregister_dependent_observers(old_value)
  remove_element_observers(old_value)
  add_element_observers(value)
  super(index, value).tap do
    notify_observers
  end
end
add_element_observer(element, observer, options = {}) click to toggle source
# File lib/glimmer/data_binding/observable_array.rb, line 68
def add_element_observer(element, observer, options = {})
  element_properties_for(observer).each do |property|
    observer.observe(element, property, options)
  end
  if element.is_a?(Array) && (options[:recursive] == true || (options[:recursive].is_a?(Integer) && options[:recursive] >= 0))
    ensure_array_object_observer(element, options)
  end
end
add_element_observers(element, general_options = {}) click to toggle source
# File lib/glimmer/data_binding/observable_array.rb, line 62
def add_element_observers(element, general_options = {})
  property_observer_list.each do |observer, options|
    add_element_observer(element, observer, options.merge(general_options))
  end
end
add_observer(observer, *args) click to toggle source
# File lib/glimmer/data_binding/observable_array.rb, line 48
def add_observer(observer, *args)
  options = args.last.is_a?(Hash) ? args.pop : {}
  element_properties = args.flatten.compact.uniq
  return observer if has_observer?(observer) && has_observer_element_properties?(observer, element_properties)
  property_observer_list[observer] = options
  observer_element_properties[observer] = Concurrent::Set.new(Concurrent::Array.new(element_properties_for(observer).to_a) + Concurrent::Array.new(element_properties)) # converting to Array as a workaround to jruby-9.3.2.0 issue TODO remove this workaround when no longer needed
  if !options.empty? && options[:recursive].is_a?(Integer)
    options = options.clone
    options[:recursive] = options[:recursive] - 1
  end
  each { |element| add_element_observer(element, observer, options) }
  observer
end
append(element)
Alias for: <<
array_object_observer_for(object) click to toggle source
# File lib/glimmer/data_binding/observable_array.rb, line 87
def array_object_observer_for(object)
  @array_object_observers ||= Concurrent::Hash.new
  @array_object_observers[object] = Notifier.new(self) unless @array_object_observers.has_key?(object)
  @array_object_observers[object]
end
clear() click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 222
def clear
  each do |old_value|
    unregister_dependent_observers(old_value)
    remove_element_observers(old_value)
  end
  super.tap do
    notify_observers
  end
end
collect!(&block) click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 238
def collect!(&block)
  if block_given?
    each do |old_value|
      unregister_dependent_observers(old_value)
      remove_element_observers(old_value)
    end
    super(&block).tap do
      each { |element| add_element_observers(element) }
      notify_observers
    end
  else
    super
  end
end
Also aliased as: map!
compact!() click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 254
def compact!
  # TODO consider checking which exact indices changed and only notifying if there is a change
  super.tap { notify_observers }
end
delete(element) click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 190
def delete(element)
  unregister_dependent_observers(element)
  remove_element_observers(element)
  super(element).tap do
    notify_observers
  end
end
delete_at(index) click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 198
def delete_at(index)
  old_value = self[index]
  unregister_dependent_observers(old_value)
  remove_element_observers(old_value)
  super(index).tap do
    notify_observers
  end
end
delete_if(&block) click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 207
def delete_if(&block)
  if block_given?
    old_array = Array.new(self)
    super(&block).tap do |new_array|
      (old_array - new_array).each do |element|
        unregister_dependent_observers(element)
        remove_element_observers(element)
      end
      notify_observers
    end
  else
    super
  end
end
deregister_dependent_observers(old_value)
element_properties_for(observer) click to toggle source
# File lib/glimmer/data_binding/observable_array.rb, line 145
def element_properties_for(observer)
  observer_element_properties[observer] ||= Concurrent::Set.new
end
ensure_array_object_observer(object, options) click to toggle source
# File lib/glimmer/data_binding/observable_array.rb, line 77
def ensure_array_object_observer(object, options)
  return unless object&.is_a?(Array)
  array_object_observer = array_object_observer_for(object)
  array_observer_registration = array_object_observer.observe(object, options)
  property_observer_list.each do |observer, options|
    my_registration = observer.registration_for(self)
    observer.add_dependent(my_registration => array_observer_registration)
  end
end
filter!(&block) click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 289
def filter!(&block)
  if block_given?
    old_array = Array.new(self)
    super(&block).tap do
      (old_array - self).each do |old_value|
        unregister_dependent_observers(old_value)
        remove_element_observers(old_value)
      end
      notify_observers
    end
  else
    super
  end
end
flatten!(level=nil) click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 259
def flatten!(level=nil)
  each do |old_value|
    unregister_dependent_observers(old_value)
    remove_element_observers(old_value)
  end
  (level.nil? ? super() : super(level)).tap do
    each { |element| add_element_observers(element) }
    notify_observers
  end
end
has_observer?(observer) click to toggle source
# File lib/glimmer/data_binding/observable_array.rb, line 129
def has_observer?(observer)
  property_observer_list.keys.include?(observer)
end
has_observer_element_properties?(observer, element_properties) click to toggle source
# File lib/glimmer/data_binding/observable_array.rb, line 133
def has_observer_element_properties?(observer, element_properties)
  element_properties_for(observer).to_a.include_all?(*element_properties)
end
map!(&block)
Alias for: collect!
notify_observers() click to toggle source
# File lib/glimmer/data_binding/observable_array.rb, line 149
def notify_observers
  property_observer_list.to_a.each { |obs, opt| obs.call(self) }
end
observer_element_properties() click to toggle source
# File lib/glimmer/data_binding/observable_array.rb, line 141
def observer_element_properties
  @observer_element_properties ||= Concurrent::Hash.new
end
pop() click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 172
def pop
  popped_element = last
  unregister_dependent_observers(popped_element)
  remove_element_observers(popped_element)
  super.tap do
    notify_observers
  end
end
prepend(element)
Alias for: unshift
property_observer_list() click to toggle source
# File lib/glimmer/data_binding/observable_array.rb, line 137
def property_observer_list
  @property_observer_list ||= Concurrent::Hash.new
end
push(element)
Alias for: <<
reject!(&block) click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 346
def reject!(&block)
  if block.nil?
    super
  else
    old_array = Array.new(self)
    super(&block).tap do
      (old_array - self).each do |old_value|
        unregister_dependent_observers(old_value)
        remove_element_observers(old_value)
      end
      notify_observers
    end
  end
end
remove_element_observer(element, observer) click to toggle source
# File lib/glimmer/data_binding/observable_array.rb, line 116
def remove_element_observer(element, observer)
  element_properties_for(observer).each do |property|
    observer.unobserve(element, property)
  end
  if element.is_a?(ObservableArray)
    array_object_observer_for(element).unobserve(element)
    element.property_observer_list.select {|obs, opt| obs.respond_to?(:observable_array) && obs.observable_array == self}.each do |o|
      o.deregister_all_observables if o.respond_to?(:deregister_all_observables)
      @array_object_observers.reject! {|k, v| v == o}
    end
  end
end
remove_element_observers(element) click to toggle source
# File lib/glimmer/data_binding/observable_array.rb, line 110
def remove_element_observers(element)
  property_observer_list.each do |observer, options|
    remove_element_observer(element, observer)
  end
end
remove_observer(observer, *args) click to toggle source
# File lib/glimmer/data_binding/observable_array.rb, line 93
def remove_observer(observer, *args)
  options = args.last.is_a?(Hash) ? args.pop : {}
  element_properties = args
  element_properties = element_properties.flatten.compact.uniq
  if !element_properties.empty?
    old_element_properties = element_properties_for(observer)
    observer_element_properties[observer] = Concurrent::Set.new(Concurrent::Array.new(element_properties_for(observer).to_a) - Concurrent::Array.new(element_properties)) # TODO remove this workaround when no longer needed (it is for jruby-9.3.2.0 issue)
    each { |element| element_properties.each { |property| observer.unobserve(element, property) } }
  end
  if element_properties_for(observer).empty?
    property_observer_list.delete(observer)
    observer_element_properties.delete(observer)
    each { |element| remove_element_observer(element, observer) }
  end
  observer
end
replace(other_array) click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 361
def replace(other_array)
  old_array = Array.new(self)
  super(other_array).tap do
    (old_array - self).each do |old_value|
      unregister_dependent_observers(old_value)
      remove_element_observers(old_value)
    end
    notify_observers
  end
end
reverse!() click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 232
def reverse!
  super.tap do
    notify_observers
  end
end
rotate!(count=1) click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 270
def rotate!(count=1)
  super(count).tap { notify_observers }
end
select!(&block) click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 274
def select!(&block)
  if block_given?
    old_array = Array.new(self)
    super(&block).tap do
      (old_array - self).each do |old_value|
        unregister_dependent_observers(old_value)
        remove_element_observers(old_value)
      end
      notify_observers
    end
  else
    super
  end
end
shift() click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 181
def shift
  shifted_element = first
  unregister_dependent_observers(shifted_element)
  remove_element_observers(shifted_element)
  super.tap do
    notify_observers
  end
end
shuffle!(hash = nil) click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 304
def shuffle!(hash = nil)
  (hash.nil? ? super() : super(random: hash[:random])).tap { notify_observers }
end
slice!(arg1, arg2=nil) click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 308
def slice!(arg1, arg2=nil)
  old_array = Array.new(self)
  (arg2.nil? ? super(arg1) : super(arg1, arg2)).tap do
    (old_array - self).each do |old_value|
      unregister_dependent_observers(old_value)
      remove_element_observers(old_value)
    end
    notify_observers
  end
end
sort!(&block) click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 319
def sort!(&block)
  (block.nil? ? super() : super(&block)).tap { notify_observers }
end
sort_by!(&block) click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 323
def sort_by!(&block)
  (block.nil? ? super() : super(&block)).tap { notify_observers }
end
uniq!(&block) click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 327
def uniq!(&block)
  each do |old_value|
    unregister_dependent_observers(old_value)
    remove_element_observers(old_value)
  end
  (block.nil? ? super() : super(&block)).tap do
    each { |element| add_element_observers(element) }
    notify_observers
  end
end
unregister_dependent_observers(old_value) click to toggle source
# File lib/glimmer/data_binding/observable_array.rb, line 372
def unregister_dependent_observers(old_value)
  return unless old_value.is_a?(ObservableModel) || old_value.is_a?(ObservableArray)
  property_observer_list.each { |observer, options| observer.unregister_dependents_with_observable(observer.registration_for(self), old_value) }
end
unshift(element) click to toggle source
Calls superclass method
# File lib/glimmer/data_binding/observable_array.rb, line 338
def unshift(element)
  super(element).tap do
    add_element_observers(element)
    notify_observers
  end
end
Also aliased as: prepend