Changeset - 29a1382de5c8
[Not reviewed]
default
0 5 0
Drew Perttula - 9 years ago 2016-06-09 06:34:28
drewp@bigasterisk.com
introduce autodep handler tree; only rerun highest-level affected handler and let it rerun its children
Ignore-this: dfcc81bbab0d02c40cd79be86c1105d4
5 files changed with 30 insertions and 20 deletions:
0 comments (0 inline, 0 general)
light9/web/edit-choice.coffee
Show inline comments
 
@@ -56,7 +56,7 @@ Polymer
 
        @updateLabel()
 

	
 
    gotGraph: ->
 
      @graph.runHandler(@updateLabel.bind(@))
 
      @graph.runHandler(@updateLabel.bind(@), "edit-choice #{@uri}")
 
        
 
    updateLabel: ->
 
      @label = try
light9/web/graph.coffee
Show inline comments
 
@@ -59,19 +59,20 @@ class GraphWatchers # throw this one awa
 

	
 
class Handler
 
  # a function and the quad patterns it cared about
 
  constructor: (@func) ->
 
    patterns = [] # s,p,o,g quads that should trigger the next run
 
  constructor: (@func, @label) ->
 
    @patterns = [] # s,p,o,g quads that should trigger the next run
 
    @innerHandlers = [] # Handlers requested while this one was running
 
  
 
class AutoDependencies
 
  constructor: () ->
 
    @handlers = [] # all known Handlers (at least those with non-empty patterns)
 
    @handlerStack = [] # currently running
 
    @handlers = new Handler(null) # tree of all known Handlers (at least those with non-empty patterns). Top node is not a handler.
 
    @handlerStack = [@handlers] # currently running
 
    
 
  runHandler: (func) ->
 
  runHandler: (func, label) ->
 
    # what if we have this func already? duplicate is safe?
 
    
 
    h = new Handler(func)
 
    @handlers.push(h)
 

	
 
    h = new Handler(func, label)
 
    @handlerStack[@handlerStack.length - 1].innerHandlers.push(h)
 
    @_rerunHandler(h)
 
    
 
  _rerunHandler: (handler) ->
 
@@ -90,14 +91,19 @@ class AutoDependencies
 
    
 
  graphChanged: (patch) ->
 
    # SyncedGraph is telling us this patch just got applied to the graph.
 
    for h in @handlers
 
      @_rerunHandler(h)
 

	
 
    rerunInners = (cur) =>
 
      toRun = cur.innerHandlers.slice()
 
      for child in toRun
 
        child.innerHandlers = [] # let all children get called again
 
        @_rerunHandler(child)
 
    rerunInners(@handlers)
 

	
 
  askedFor: (s, p, o, g) ->
 
    # SyncedGraph is telling us someone did a query that depended on
 
    # quads in the given pattern.
 
    current = @handlerStack[@handlerStack.length - 1]
 
    if current?
 
    if current? and current != @handlers
 
      current.patterns.push([s, p, o, g])
 
      #log('push', s,p,o,g)
 

	
 
@@ -193,6 +199,7 @@ class window.SyncedGraph
 
  
 

	
 
  subscribe: (s, p, o, onChange) -> # return subscription handle
 
    throw
 
    # onChange is called with a patch that's limited to the quads
 
    # that match your request.
 
    # We call you immediately on existing triples.
 
@@ -205,11 +212,11 @@ class window.SyncedGraph
 
  unsubscribe: (subscription) ->
 
    @_watchers.unsubscribe(subscription)
 

	
 
  runHandler: (func) ->
 
  runHandler: (func, label) ->
 
    # runs your func once, tracking graph calls. if a future patch
 
    # matches what you queried, we runHandler your func again (and
 
    # forget your queries from the first time).
 
    @_autoDeps.runHandler(func)
 
    @_autoDeps.runHandler(func, label)
 

	
 
  _singleValue: (s, p) ->
 
    @_autoDeps.askedFor(s, p, null, null)
light9/web/timeline/adjustable.coffee
Show inline comments
 
@@ -93,7 +93,7 @@ class window.AdjustableFloatObject exten
 
    #   getValueForPos
 

	
 
    super(@config)
 
    @config.graph.runHandler(@_syncValue.bind(@))
 
    @config.graph.runHandler(@_syncValue.bind(@), "adj sync #{@config.subj}")
 

	
 
  _syncValue: () ->
 
    @_currentValue = @config.graph.floatValue(@config.subj, @config.pred)
 
@@ -117,6 +117,7 @@ class window.AdjustableFloatObject exten
 
    # pos is vec2 of pixels relative to the drag start
 
    
 
    newValue = @config.getValueForPos(@_editorCoordinates())
 
    
 
    @config.graph.patchObject(@config.subj, @config.pred,
 
                              @config.graph.LiteralRoundedFloat(newValue),
 
                              @config.ctx)
light9/web/timeline/light9-timeline-audio.html
Show inline comments
 
@@ -62,7 +62,7 @@
 
               }
 
               
 
               this.imgSrc = root + '/' + filename.replace('.wav', '.png');
 
           }.bind(this));
 
           }.bind(this), "timeline-audio " + this.song);
 
       },
 
       _imgWidth: function(zoom) {
 
           if (!zoom.duration) {
light9/web/timeline/timeline.coffee
Show inline comments
 
@@ -292,7 +292,7 @@ Polymer
 
    'update(song)'
 
    ]
 
  onGraph: ->
 
    @graph.runHandler(@update.bind(@))
 
    @graph.runHandler(@update.bind(@), "row notes #{@rowIndex}")
 
  update: ->
 
    U = (x) -> @graph.Uri(x)
 

	
 
@@ -319,7 +319,7 @@ Polymer
 
    @dia.clearElem(@uri)
 

	
 
  onUri: ->
 
    @graph.runHandler(@update.bind(@))
 
    @graph.runHandler(@update.bind(@), "note updates #{@uri}")
 
    
 
  update: ->
 
    # update our note DOM and SVG elements based on the graph
 
@@ -361,7 +361,7 @@ Polymer
 
    'onGraph(graph, song)'
 
    ]
 
  onGraph: (graph, song, zoomInX) ->
 
    graph.runHandler(@update.bind(@))
 
    graph.runHandler(@update.bind(@), "adjuster update")
 
  update: (parentAdjs, graph, song, dia) ->
 
    U = (x) -> @graph.Uri(x)
 
    @adjs = (@parentAdjs || []).slice()
 
@@ -402,10 +402,12 @@ Polymer
 
      value: ''
 

	
 
  onAdj: (adj) ->
 
    # currently I think this subscription never gets to matter since
 
    # we might be rebuilding all adj elements on every update
 
    @adj.subscribe(@updateDisplay.bind(this))
 
    @updateDisplay()
 

	
 
  updateDisplay: () ->
 
    window.adjDragUpdates++ if window.adjDragUpdates?
 
    @spanClass = if @adj.config.emptyBox then 'empty' else ''
 
    @displayValue = @adj.getDisplayValue()
 
    center = @adj.getCenter()
0 comments (0 inline, 0 general)