Class: Volt::Computation
Constant Summary collapse
- @@current =
nil
- @@flush_queue =
Set.new
Class Method Summary collapse
- .current ⇒ Object
- .current=(val) ⇒ Object
- .flush! ⇒ Object
-
.run_without_tracking ⇒ Object
Run a block without tracking any dependencies.
Instance Method Summary collapse
-
#compute!(initial_run = false) ⇒ Object
Runs the computation, called on initial run and when changed!.
-
#initialize(computation) ⇒ Computation
constructor
A new instance of Computation.
-
#invalidate! ⇒ Object
Calling invalidate removes the computation from all of its dependencies.
- #on_invalidate(&callback) ⇒ Object
- #queue_flush! ⇒ Object
-
#run_in ⇒ Object
Runs in this computation as the current computation, returns the computation.
-
#stop ⇒ Object
Stop re-run of the computations.
- #stopped? ⇒ Boolean
Constructor Details
#initialize(computation) ⇒ Computation
Returns a new instance of Computation.
17 18 19 20 |
# File 'lib/volt/reactive/computation.rb', line 17 def initialize(computation) @computation = computation @invalidations = [] end |
Class Method Details
.current ⇒ Object
12 13 14 |
# File 'lib/volt/reactive/computation.rb', line 12 def self.current @@current end |
.current=(val) ⇒ Object
8 9 10 |
# File 'lib/volt/reactive/computation.rb', line 8 def self.current=(val) @@current = val end |
.flush! ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/volt/reactive/computation.rb', line 128 def self.flush! fail "Can't flush while in a flush" if @flushing @flushing = true # clear any timers @@timer = nil computations = @@flush_queue @@flush_queue = Set.new computations.each(&:compute!) @flushing = false end |
.run_without_tracking ⇒ Object
Run a block without tracking any dependencies
117 118 119 120 121 122 123 124 125 126 |
# File 'lib/volt/reactive/computation.rb', line 117 def self.run_without_tracking previous = Computation.current Computation.current = nil begin return_value = yield ensure Computation.current = previous end return_value end |
Instance Method Details
#compute!(initial_run = false) ⇒ Object
Runs the computation, called on initial run and when changed!
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/volt/reactive/computation.rb', line 24 def compute!(initial_run=false) @invalidated = false unless @stopped @computing = true begin run_in do if @computation.arity > 0 # Pass in the Computation so it can be canceled from within @computation.call(self) else @computation.call end end rescue => e if initial_run # Re-raise if we are in the initial run raise else # Sometimes we get nil as the exception, not sure if thats an opal # issue or what. if e msg = "Exception During Compute: " + e.inspect msg += "\n" + e.backtrace.join("\n") if e.respond_to?(:backtrace) Volt.logger.error(msg) if RUBY_PLATFORM == 'opal' `console.log(e);` end end end ensure @computing = false end end end |
#invalidate! ⇒ Object
Calling invalidate removes the computation from all of its dependencies. This keeps its dependencies from invalidating it again.
78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/volt/reactive/computation.rb', line 78 def invalidate! unless @invalidated @invalidated = true queue_flush! unless @stopped invalidations = @invalidations @invalidations = [] invalidations.each(&:call) end end |
#on_invalidate(&callback) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/volt/reactive/computation.rb', line 62 def on_invalidate(&callback) if @invalidated # Call invalidate now, since its already invalidated # Computation.run_without_tracking do queue_flush! callback.call # end else # Store the invalidation @invalidations << callback end end |
#queue_flush! ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/volt/reactive/computation.rb', line 143 def queue_flush! @@flush_queue << self # If we are in the browser, we queue a flush for the next tick # If we are not in the browser, the user must manually flush if Volt.in_browser? unless @@timer # Flush once everything else has finished running @@timer = `setImmediate(function() { self.$class()['$flush!'](); })` end end end |
#run_in ⇒ Object
Runs in this computation as the current computation, returns the computation
104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/volt/reactive/computation.rb', line 104 def run_in previous = Computation.current Computation.current = self begin yield ensure Computation.current = previous end self end |
#stop ⇒ Object
Stop re-run of the computations
92 93 94 95 96 97 |
# File 'lib/volt/reactive/computation.rb', line 92 def stop unless @stopped @stopped = true invalidate! end end |
#stopped? ⇒ Boolean
99 100 101 |
# File 'lib/volt/reactive/computation.rb', line 99 def stopped? @stopped end |