Class: ReactiveArray

Inherits:
Object show all
Includes:
Eventable
Defined in:
lib/volt/reactive/reactive_array.rb

Overview

< Array

Direct Known Subclasses

ArrayModel

Instance Method Summary collapse

Methods included from Eventable

#on, #remove_listener, #trigger!

Constructor Details

#initialize(array = []) ⇒ ReactiveArray

Returns a new instance of ReactiveArray.



6
7
8
9
10
11
# File 'lib/volt/reactive/reactive_array.rb', line 6

def initialize(array=[])
  @array = array
  @array_deps = []
  @size_dep = Dependency.new
  @old_size = 0
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &block) ⇒ Object

Forward any missing methods to the array



14
15
16
# File 'lib/volt/reactive/reactive_array.rb', line 14

def method_missing(method_name, *args, &block)
  @array.send(method_name, *args, &block)
end

Instance Method Details

#+(array) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/volt/reactive/reactive_array.rb', line 145

def +(array)
  raise "not implemented yet"
  old_size = self.size

  # TODO: += is funky here, might need to make a .plus! method
  result = ReactiveArray.new(@array.dup + array)

  old_size.upto(result.size-1) do |index|
    trigger_for_index!('changed', index)
    trigger_added!(old_size + index)
  end

  trigger_size_change!

  return result
end

#<<(value) ⇒ Object

alias :__old_append :<<



134
135
136
137
138
139
140
141
142
# File 'lib/volt/reactive/reactive_array.rb', line 134

def <<(value)
  result = (@array << value)

  trigger_for_index!(self.size-1)
  trigger_added!(self.size-1)
  trigger_size_change!

  return result
end

#==(*args) ⇒ Object



18
19
20
# File 'lib/volt/reactive/reactive_array.rb', line 18

def ==(*args)
  @array.==(*args)
end

#[](index) ⇒ Object

TODO: Handle a range



43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/volt/reactive/reactive_array.rb', line 43

def [](index)
  # Handle a negative index
  index = size + index if index < 0

  # Get or create the dependency
  dep = (@array_deps[index] ||= Dependency.new)

  # Track the dependency
  dep.depend

  # Return the index
  return @array[index]
end

#[]=(index, value) ⇒ Object



57
58
59
60
61
62
63
64
65
# File 'lib/volt/reactive/reactive_array.rb', line 57

def []=(index, value)

  # Assign the new value
  @array[index] = value

  trigger_for_index!(index)

  trigger_size_change!
end

#clearObject



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/volt/reactive/reactive_array.rb', line 111

def clear
  old_size = @array.size

  deps = @array_deps
  @array_deps = []

  # Trigger remove for each cell
  old_size.times do |index|
    trigger_removed!(old_size - index - 1)
  end

  # Trigger on each cell since we are clearing out the array
  if deps
    deps.each do |dep|
      dep.changed! if dep
    end
  end

  # clear the array
  @array = []
end

#count(&block) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/volt/reactive/reactive_array.rb', line 27

def count(&block)
  if block
    count = 0
    size.times do |index|
      if block.call(self[index]).true?
        count += 1
      end
    end

    return count
  else
    return size
  end
end

#delete(val) ⇒ Object



100
101
102
103
104
105
106
107
108
109
# File 'lib/volt/reactive/reactive_array.rb', line 100

def delete(val)
  index = @array.index(val)
  if index
    self.delete_at(index)
  else
    # Sometimes the model isn't loaded at the right state yet, so we
    # just remove it from the persistor
    @persistor.removed(val) if @persistor
  end
end

#delete_at(index) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/volt/reactive/reactive_array.rb', line 74

def delete_at(index)
  # Handle a negative index
  index = size + index if index < 0

  model = @array.delete_at(index)

  # Remove the dependency for that cell, and #remove it
  index_deps = @array_deps.delete_at(index)
  index_deps.remove if index_deps

  trigger_removed!(index)

  # Trigger a changed event for each element in the zone where the
  # delete would change
  index.upto(self.size+1) do |position|
    trigger_for_index!(position)
  end

  trigger_size_change!

  @persistor.removed(model) if @persistor

  return model
end

#each(&block) ⇒ Object

At the moment, each just passes through.



23
24
25
# File 'lib/volt/reactive/reactive_array.rb', line 23

def each(&block)
  @array.each(&block)
end

#insert(index, *objects) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/volt/reactive/reactive_array.rb', line 162

def insert(index, *objects)
  result = @array.insert(index, *objects)

  # All objects from index to the end have "changed"
  index.upto(result.size) do |index|
    trigger_for_index!(index)
  end

  objects.size.times do |count|
    trigger_added!(index+count)
  end

  trigger_size_change!

  return result
end

#inspectObject



180
181
182
# File 'lib/volt/reactive/reactive_array.rb', line 180

def inspect
  "#<#{self.class.to_s}:#{object_id} #{@array.inspect}>"
end

#sizeObject Also known as: length



67
68
69
70
71
# File 'lib/volt/reactive/reactive_array.rb', line 67

def size
  @size_dep.depend

  return @array.size
end