changeset 1386:29a1382de5c8

introduce autodep handler tree; only rerun highest-level affected handler and let it rerun its children Ignore-this: dfcc81bbab0d02c40cd79be86c1105d4
author Drew Perttula <drewp@bigasterisk.com>
date Thu, 09 Jun 2016 06:34:28 +0000
parents 748a2e8afd30
children 26fabcf3a0a8
files light9/web/edit-choice.coffee light9/web/graph.coffee light9/web/timeline/adjustable.coffee light9/web/timeline/light9-timeline-audio.html light9/web/timeline/timeline.coffee
diffstat 5 files changed, 30 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/light9/web/edit-choice.coffee	Thu Jun 09 05:16:32 2016 +0000
+++ b/light9/web/edit-choice.coffee	Thu Jun 09 06:34:28 2016 +0000
@@ -56,7 +56,7 @@
         @updateLabel()
 
     gotGraph: ->
-      @graph.runHandler(@updateLabel.bind(@))
+      @graph.runHandler(@updateLabel.bind(@), "edit-choice #{@uri}")
         
     updateLabel: ->
       @label = try
--- a/light9/web/graph.coffee	Thu Jun 09 05:16:32 2016 +0000
+++ b/light9/web/graph.coffee	Thu Jun 09 06:34:28 2016 +0000
@@ -59,19 +59,20 @@
 
 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 @@
     
   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 @@
   
 
   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 @@
   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)
--- a/light9/web/timeline/adjustable.coffee	Thu Jun 09 05:16:32 2016 +0000
+++ b/light9/web/timeline/adjustable.coffee	Thu Jun 09 06:34:28 2016 +0000
@@ -93,7 +93,7 @@
     #   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 @@
     # 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)
--- a/light9/web/timeline/light9-timeline-audio.html	Thu Jun 09 05:16:32 2016 +0000
+++ b/light9/web/timeline/light9-timeline-audio.html	Thu Jun 09 06:34:28 2016 +0000
@@ -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) {
--- a/light9/web/timeline/timeline.coffee	Thu Jun 09 05:16:32 2016 +0000
+++ b/light9/web/timeline/timeline.coffee	Thu Jun 09 06:34:28 2016 +0000
@@ -292,7 +292,7 @@
     'update(song)'
     ]
   onGraph: ->
-    @graph.runHandler(@update.bind(@))
+    @graph.runHandler(@update.bind(@), "row notes #{@rowIndex}")
   update: ->
     U = (x) -> @graph.Uri(x)
 
@@ -319,7 +319,7 @@
     @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 @@
     '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 @@
       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()