# HG changeset patch # User Drew Perttula # Date 2014-06-03 05:09:41 # Node ID 52f049d85f961c4913710c8cc9ead110b9efa125 # Parent e6121f8a9f873c30f5305040538077d849829638 less CC crashing. curve points are stored in their own n3 files. fix curve row height edge cases. Ignore-this: 7bd8e0c82d4106d53c24d67b981baf60 diff --git a/light9/curvecalc/curve.py b/light9/curvecalc/curve.py --- a/light9/curvecalc/curve.py +++ b/light9/curvecalc/curve.py @@ -38,6 +38,9 @@ class Curve(object): def toggleMute(self): self.muted = not self.muted + def curvePointsContext(self): + return self.uri + def load(self,filename): self.points[:]=[] for line in file(filename): @@ -227,19 +230,11 @@ class Curveset(object): return for uri in sorted(self.graph.objects(self.currentSong, L9['curve'])): - pts = self.graph.value(uri, L9['points']) - c = Curve(uri, pointsStorage='file' if pts is None else 'graph') - if pts is not None: - c.set_from_string(pts) - else: - diskPts = self.graph.value(uri, L9['pointsFile']) - c.load(os.path.join(showconfig.curvesDir(), diskPts)) - - curvename = self.graph.label(uri) - if not curvename: - raise ValueError("curve %r has no label" % uri) - self.add_curve(curvename, c) - + try: + self.loadCurve(uri) + except Exception as e: + log.error("loading %s failed: %s", uri, e) + basename = os.path.join( showconfig.curvesDir(), showconfig.songFilenameFromURI(self.currentSong)) @@ -247,6 +242,23 @@ class Curveset(object): self.markers.load("%s.markers" % basename) except IOError: print "no marker file found" + + def loadCurve(self, uri): + pts = self.graph.value(uri, L9['points']) + c = Curve(uri, pointsStorage='file' if pts is None else 'graph') + if pts is not None: + c.set_from_string(pts) + else: + diskPts = self.graph.value(uri, L9['pointsFile']) + if diskPts is not None: + c.load(os.path.join(showconfig.curvesDir(), diskPts)) + else: + log.warn("curve %s has no points", c.uri) + + curvename = self.graph.label(uri) + if not curvename: + raise ValueError("curve %r has no label" % uri) + self.add_curve(curvename, c) def save(self): """writes a file for each curve with a name @@ -261,9 +273,8 @@ class Curveset(object): log.warn("not saving file curves anymore- skipping %s" % label) #cur.save("%s-%s" % (basename,name)) elif curve.pointsStorage == 'graph': - ctx = self.currentSong patches.append(self.graph.getObjectPatch( - ctx, + curve.curvePointsContext(), subject=curve.uri, predicate=L9['points'], newObject=Literal(curve.points_as_string()))) @@ -274,7 +285,7 @@ class Curveset(object): # this will cause reloads that will clear our curve list for p in patches: self.graph.patch(p) - + def sorter(self, name): return self.curves[name].uri @@ -320,7 +331,7 @@ class Curveset(object): while name in self.curves: name=name+"-1" - uri = self.currentSong + ('/curve/c-%f' % time.time()) + uri = self.graph.sequentialUri(self.currentSong + '/curve/c-') c = Curve(uri) s, e = self.get_time_range() c.points.extend([(s, 0), (e, 0)]) @@ -329,7 +340,11 @@ class Curveset(object): (self.currentSong, L9['curve'], uri, ctx), (uri, RDF.type, L9['Curve'], ctx), (uri, RDFS.label, Literal(name), ctx), - (uri, L9['points'], Literal(c.points_as_string()), ctx), + ])) + print "pts to", c.curvePointsContext() + self.graph.patch(Patch(addQuads=[ + (uri, L9['points'], Literal(c.points_as_string()), + c.curvePointsContext()), ])) def hw_slider_in(self, num, value): diff --git a/light9/curvecalc/curveview.py b/light9/curvecalc/curveview.py --- a/light9/curvecalc/curveview.py +++ b/light9/curvecalc/curveview.py @@ -672,9 +672,18 @@ class Curveview(object): if self._time == val: return self.update_time_bar(val) + + def alive(self): + # Some handlers still run after a view is destroyed, which + # leads to crashes in somewhere like + # goocanvas_add_item. Workaround is to disable certain methods + # when the widget is gone. Correct solution would be to stop + # and free those handlers when the widget is gone. + return self.canvas.is_visible() def update_time_bar(self, t): - + if not self.alive(): + return if not getattr(self, 'timelineLine', None): self.timelineGroup = GooCanvas.CanvasGroup( parent=self.canvas.get_root_item()) @@ -708,13 +717,17 @@ class Curveview(object): reactor.callLater(.01, self._update_curve) def _update_curve(self): + try: + self._update_curve2() + except Exception: + log.error("in update_curve on %s", self.curve.uri) + raise + + def _update_curve2(self): if not getattr(self, '_pending_update', False): return self._pending_update = False - if not self.canvas.is_visible(): - # this avoids an occasional crash in something like - # goocanvas_add_item when we write objects to a canvas - # that's gone + if not self.alive(): return if not self.redrawsEnabled: print "no redrawsEnabled, skipping", self @@ -810,6 +823,8 @@ class Curveview(object): text=label) def _draw_line(self, visible_points, area=False): + if not visible_points: + return linepts=[] step=1 linewidth = 1.5 @@ -1290,18 +1305,22 @@ class Curvesetview(object): dispatcher.connect(self.setRowHeights, "curve row focus change") def setRowHeights(self): - focusHeight = 100 nRows = len(self.allCurveRows) if not nRows: return anyFocus = any(r.isFocus() for r in self.allCurveRows) + evenHeight = max(14, self.visibleHeight // nRows) - 3 if anyFocus: - h = max(14, (self.visibleHeight - focusHeight) // (nRows - 1)) - 3 + focusHeight = max(100, evenHeight) + if nRows > 1: + otherHeight = max(14, + (self.visibleHeight - focusHeight) // + (nRows - 1)) - 3 else: - h = max(14, self.visibleHeight // nRows) - 3 + otherHeight = evenHeight for row in self.allCurveRows: - row.setHeight(100 if row.isFocus() else h) + row.setHeight(focusHeight if row.isFocus() else otherHeight) def row(self, name): if isinstance(name, Literal):