changeset 848:dacbb278d91d

curvecalc port to SyncedGraph. starts up ok, saving is broken Ignore-this: ef920ab36bc7959f94d9154a9f582c27
author drewp@bigasterisk.com
date Tue, 26 Mar 2013 16:50:48 +0000
parents 431ddd043b47
children 8dc33b794924
files bin/curvecalc light9/curvecalc/curve.py light9/curvecalc/curveview.py light9/curvecalc/subterm.py light9/curvecalc/zoomcontrol.py
diffstat 5 files changed, 109 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/bin/curvecalc	Tue Mar 26 08:43:37 2013 +0000
+++ b/bin/curvecalc	Tue Mar 26 16:50:48 2013 +0000
@@ -24,6 +24,7 @@
 
 import run_local
 from light9 import showconfig, prof, networking
+from light9.rdfdb import clientsession
 from light9.curvecalc.curve import Curveset
 from light9.curvecalc import curveview 
 from light9.curvecalc.musicaccess import Music, currentlyPlayingSong
@@ -39,8 +40,8 @@
     pass
 
 class Main(object):
-    def __init__(self, graph, opts, song, curveset, subterms, music):
-        self.graph, self.opts, self.song = graph, opts, song
+    def __init__(self, graph, opts, session, curveset, subterms, music):
+        self.graph, self.opts, self.session = graph, opts, session
         self.curveset, self.subterms, self.music = curveset, subterms, music
         self.lastSeenInputTime = 0
 
@@ -59,7 +60,9 @@
         mainwin.connect("delete-event", lambda *args: reactor.crash())
         def updateTitle():
             # song will soon be a lookup on this curvecalc session
-            mainwin.set_title("curvecalc - %s" % graph.label(song))
+            mainwin.set_title("curvecalc - %s" %
+                              graph.label(
+                                  graph.value(session, L9['currentSong'])))
         graph.addHandler(updateTitle)
         mainwin.parse_geometry("1x1-0+0")
 
@@ -158,8 +161,10 @@
         master = self.wtree.get_object("subterms")
         [master.remove(c) for c in master.get_children()]
 
-        for st in self.graph.objects(self.song, L9['subterm']):
-            log.info("song %s has subterm %s", self.song, st)
+        song = self.graph.value(self.session, L9['currentSong'])
+        
+        for st in self.graph.objects(song, L9['subterm']):
+            log.info("song %s has subterm %s", song, st)
             add_one_subterm(self.graph,
                             self.graph.value(st, L9['sub']),
                             self.curveset,
@@ -215,7 +220,9 @@
         self.music.playOrPause(t=times[0] if times else None)
 
     def onSave(self, *args):
-        savekey(self.song, self.subterms, self.curveset)
+        with self.graph.currentState() as g:
+            savekey(g.value(self.session, L9['currentSong']),
+                    self.subterms, self.curveset)
 
     def makeStatusLines(self, master):
         """various labels that listen for dispatcher signals"""
@@ -284,6 +291,27 @@
             reactor.callLater(1, self.refreshCurveView)
 
 
+class MaxTime(object):
+    """
+    looks up the time in seconds for the session's current song
+    """
+    def __init__(self, graph, session):
+        self.graph, self.session = graph, session
+        graph.addHandler(self.update)
+
+    def update(self):
+        song = self.graph.value(self.session, L9['currentSong'])
+        if song is None:
+            self.maxtime = 0
+            return
+        musicfilename = showconfig.songOnDisk(song)
+        self.maxtime = wavelength(musicfilename)
+        log.info("new max time %r", self.maxtime)
+        dispatcher.send("max time", maxtime=self.maxtime)
+
+    def get(self):
+        return self.maxtime
+
 def main():
     startTime = time.time()
     parser = optparse.OptionParser()
@@ -298,38 +326,51 @@
                       help="live reload of themes and code")
     parser.add_option("--startup-only", action='store_true',
                       help="quit after loading everything (for timing tests)")
+    clientsession.add_option(parser)
     opts, args = parser.parse_args()
 
     logging.basicConfig(format="%(asctime)s %(levelname)-5s %(name)s %(filename)s:%(lineno)d: %(message)s")
     log.setLevel(logging.DEBUG if opts.debug else logging.INFO)
 
     log.debug("startup: music %s", time.time() - startTime)
-    try:
-        song = URIRef(args[0])
-    except IndexError:
-        song = currentlyPlayingSong()
+
+
+    session = clientsession.getUri('curvecalc', opts)
 
     music = Music()
     graph = SyncedGraph("curvecalc")
 
+    try:
+        song = URIRef(args[0])
+        graph.patchObject(context=session,
+                          subject=session,
+                          predicate=L9['currentSong'],
+                          newObject=song)
+    except IndexError:
+        pass
+
     curveset = Curveset(sliders=opts.sliders)
     subterms = []
 
-    curveset.load(basename=os.path.join(
-        showconfig.curvesDir(),
-        showconfig.songFilenameFromURI(song)),
-                  skipMusic=opts.skip_music)
-
+    def curvesetReload():
+        # not sure if this clears right or not yet
+        song = graph.value(session, L9['currentSong'])
+        if song is None:
+            return
+        curveset.load(basename=os.path.join(
+            showconfig.curvesDir(),
+            showconfig.songFilenameFromURI(song)),
+                      skipMusic=opts.skip_music)
+    graph.addHandler(curvesetReload)
+        
     log.debug("startup: output %s", time.time() - startTime)
     out = Output(subterms, music)
 
-    musicfilename = showconfig.songOnDisk(song)
-    maxtime = wavelength(musicfilename)
-    dispatcher.connect(lambda: maxtime, "get max time", weak=False)
+    mt = MaxTime(graph, session)
+    dispatcher.connect(lambda: mt.get(), "get max time", weak=False)
 
-    start = Main(graph, opts, song, curveset, subterms, music)
+    start = Main(graph, opts, session, curveset, subterms, music)
 
-    dispatcher.send("max time", maxtime=maxtime)
     dispatcher.send("show all")
         
     if opts.startup_only:
@@ -346,8 +387,9 @@
                 if not times:
                     request.setResponseCode(404)
                     return "not hovering over any time"
-                
-                return json.dumps({"song":song, "hoverTime" : times[0]})
+                with graph.currentState() as g:
+                    song = g.value(session, L9['currentSong'])
+                    return json.dumps({"song": song, "hoverTime" : times[0]})
             raise NotImplementedError()
 
     reactor.listenTCP(networking.curveCalc.port,
--- a/light9/curvecalc/curve.py	Tue Mar 26 08:43:37 2013 +0000
+++ b/light9/curvecalc/curve.py	Tue Mar 26 16:50:48 2013 +0000
@@ -140,6 +140,7 @@
             self.sliderIgnoreInputUntil = {}
         else:
             self.sliders = None
+        self.markers = Markers()
 
     def sorter(self, name):
         return (not name in ['music', 'smooth_music'], name)
@@ -159,7 +160,6 @@
             curvename = curvename.replace('-','_')
             self.add_curve(curvename,c)
 
-        self.markers = Markers()
         try:
             self.markers.load("%s.markers" % basename)
         except IOError:
--- a/light9/curvecalc/curveview.py	Tue Mar 26 08:43:37 2013 +0000
+++ b/light9/curvecalc/curveview.py	Tue Mar 26 16:50:48 2013 +0000
@@ -617,9 +617,12 @@
                 points=goocanvas.Points([(0,0), (0,0)]),
                 line_width=2, stroke_color='red')
 
-        self.timelineLine.set_property('points', goocanvas.Points([
-            self.screen_from_world((t, 0)),
-            self.screen_from_world((t, 1))]))
+        try:
+            pts = [self.screen_from_world((t, 0)),
+                   self.screen_from_world((t, 1))]
+        except ZeroDivisionError:
+            pts = [(-1, -1), (-1, -1)]
+        self.timelineLine.set_property('points', goocanvas.Points(pts))
         
         self._time = t
         if self.knobEnabled:
@@ -733,11 +736,15 @@
             tic(endtime - postPad, "post %.1f" % (endtime - postPad))
         
     def _draw_one_tic(self,t,label):
-        x = self.screen_from_world((t,0))[0]
+        try:
+            x = self.screen_from_world((t,0))[0]
+            if not 0 <= x < self.size.width:
+                return
+            x = max(5, x) # cheat left-edge stuff onscreen
+        except ZeroDivisionError:
+            x = -100
+            
         ht = self.size.height
-        if not 0 <= x < self.size.width:
-            return
-        x = max(5, x) # cheat left-edge stuff onscreen
         goocanvas.polyline_new_line(self.curveGroup,
                                     x, ht,
                                     x, ht - 20,
@@ -759,7 +766,10 @@
             step = int(len(visible_points) / maxPointsToDraw)
             linewidth = .8
         for p in visible_points[::step]:
-            x,y = self.screen_from_world(p)
+            try:
+                x,y = self.screen_from_world(p)
+            except ZeroDivisionError:
+                x = y = -100
             linepts.append((int(x) + .5, int(y) + .5))
 
         if self.curve.muted:
@@ -768,7 +778,10 @@
             fill = 'white'
 
         if area:
-            base = self.screen_from_world((0, 0))[1]
+            try:
+                base = self.screen_from_world((0, 0))[1]
+            except ZeroDivisionError:
+                base = -100
             base = base + linewidth / 2
             goocanvas.Polyline(parent=self.curveGroup,
                                points=goocanvas.Points(
@@ -791,7 +804,10 @@
         for i,p in zip(visible_idxs,visible_points):
             rad=3
             worldp = p
-            p = self.screen_from_world(p)
+            try:
+                p = self.screen_from_world(p)
+            except ZeroDivisionError:
+                p = (-100, -100)
             dot = goocanvas.Rect(parent=self.curveGroup,
                                  x=int(p[0] - rad) + .5,
                                  y=int(p[1] - rad) + .5,
--- a/light9/curvecalc/subterm.py	Tue Mar 26 08:43:37 2013 +0000
+++ b/light9/curvecalc/subterm.py	Tue Mar 26 16:50:48 2013 +0000
@@ -40,8 +40,8 @@
 
         def chan(name):
             return Submaster.Submaster(
-                leveldict={Patch.get_dmx_channel(name) : 1.0},
-                temporary=True)
+                name=name,
+                levels={Patch.get_dmx_channel(name) : 1.0})
         glo['chan'] = chan
 
         def smooth_random(speed=1):
@@ -126,7 +126,7 @@
                 return self.submaster * subexpr_eval
         except Exception, e:
             dispatcher.send("expr_error", sender=self.subexpr, exc=str(e))
-            return Submaster.Submaster('Error: %s' % str(e), temporary=True)
+            return Submaster.Submaster(name='Error: %s' % str(e), levels={})
 
     def __repr__(self):
         return "<Subterm %s %s>" % (self.submaster, self.subexpr)
@@ -139,7 +139,7 @@
     """rdf graph describing the subterms, readable by add_subterms_for_song"""
     graph = Graph()
     for subterm in subterms:
-        assert subterm.submaster.name, "submaster has no name"
+        assert subterm.submaster.name, "submaster %r has no name" % subterm.submaster
         uri = URIRef(song + "/subterm/" + subterm.submaster.name)
         graph.add((song, L9['subterm'], uri))
         graph.add((uri, RDF.type, L9['Subterm']))
@@ -149,10 +149,10 @@
     return graph
 
 def savekey(song, subterms, curveset):
-    print "saving", song
+    log.info("saving %r", song)
     g = createSubtermGraph(song, subterms)
     g.serialize(graphPathForSubterms(song), format="nt")
 
     curveset.save(basename=os.path.join(showconfig.curvesDir(),
                                         showconfig.songFilenameFromURI(song)))
-    print "saved"
+    log.info("saved")
--- a/light9/curvecalc/zoomcontrol.py	Tue Mar 26 08:43:37 2013 +0000
+++ b/light9/curvecalc/zoomcontrol.py	Tue Mar 26 16:50:48 2013 +0000
@@ -138,9 +138,13 @@
 
         self.redrawzoom()
             
-    def input_time(self,val):
+    def input_time(self, val):
+        """move time cursor to this time"""
         self.lastTime = val
-        x = self.can_for_t(self.lastTime)
+        try:
+            x = self.can_for_t(self.lastTime)
+        except ZeroDivisionError:
+            x = -100
         self.time.set_property("points",
                                goocanvas.Points([(x, 0),
                                                  (x, self.size.height)]))
@@ -182,8 +186,12 @@
             return
         y1, y2 = 3, self.size.height - 3
         lip = 6
-        scan = self.can_for_t(self.start)
-        ecan = self.can_for_t(self.end)
+        try:
+            scan = self.can_for_t(self.start)
+            ecan = self.can_for_t(self.end)
+        except ZeroDivisionError:
+            # todo: set the zoom to some clear null state
+            return
 
         self.leftbrack.set_property("points", goocanvas.Points([
             (scan + lip, y1),