class Volt::Computation

Public Class Methods

current() click to toggle source
# File lib/volt/reactive/computation.rb, line 12
def self.current
  @@current
end
current=(val) click to toggle source
# File lib/volt/reactive/computation.rb, line 8
def self.current=(val)
  @@current = val
end
flush!() click to toggle source
# 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
new(computation) click to toggle source

@param [Proc] the code to run when the computation needs to compute

# File lib/volt/reactive/computation.rb, line 17
def initialize(computation)
  @computation   = computation
  @invalidations = []
end
run_without_tracking() { || ... } click to toggle source

Run a block without tracking any dependencies

# 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

Public Instance Methods

compute!(initial_run=false) click to toggle source

Runs the computation, called on initial run and when changed!

# 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!() click to toggle source

Calling invalidate removes the computation from all of its dependencies. This keeps its dependencies from invalidating it again.

# 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) click to toggle source
# 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!() click to toggle source
# 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() { || ... } click to toggle source

Runs in this computation as the current computation, returns the computation

# 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() click to toggle source

Stop re-run of the computations

# File lib/volt/reactive/computation.rb, line 92
def stop
  unless @stopped
    @stopped = true
    invalidate!
  end
end
stopped?() click to toggle source
# File lib/volt/reactive/computation.rb, line 99
def stopped?
  @stopped
end