[pitivi: 3/16] Make TrackObjects reusable once they have been removed from a Track.
- From: Edward Hervey <edwardrv src gnome org>
- To: svn-commits-list gnome org
- Subject: [pitivi: 3/16] Make TrackObjects reusable once they have been removed from a Track.
- Date: Wed, 8 Jul 2009 14:37:11 +0000 (UTC)
commit 9122088baac0e760567c3c931c9ed6580c852a85
Author: Alessandro Decina <alessandro d gmail com>
Date: Fri Jul 3 16:44:35 2009 +0200
Make TrackObjects reusable once they have been removed from a Track.
This change makes TrackObjects reusable by decoupling construction and
initialization. Now you can call makeBin() and releaseBin() in pairs on the same
object to create/destroy bins keeping the same track object instance (with the
associated data, eg keyframes).
With this change, bins are now created when objects are added to a Track
(Track.addTrackObject) and destroyed when removed from a track
(Track.removeTrackObject)
The first visible benefit of this change is that it simplifies TimelineObject
do/undo operations a lot.
pitivi/formatters/etree.py | 7 +++----
pitivi/timeline/timeline.py | 1 -
pitivi/timeline/timeline_undo.py | 35 ++++++-----------------------------
pitivi/timeline/track.py | 16 +++++++++-------
tests/test_etree_formatter.py | 24 ++++++++++++++++--------
tests/test_timeline_undo.py | 2 +-
tests/test_track.py | 3 +++
7 files changed, 38 insertions(+), 50 deletions(-)
---
diff --git a/pitivi/formatters/etree.py b/pitivi/formatters/etree.py
index 45ca28f..99b1e16 100644
--- a/pitivi/formatters/etree.py
+++ b/pitivi/formatters/etree.py
@@ -339,7 +339,7 @@ class ElementTreeFormatter(Formatter):
return element
- def _loadTrackObject(self, element):
+ def _loadTrackObject(self, track, element):
self.debug("%r", element)
klass = namedAny(element.attrib["type"])
@@ -353,6 +353,7 @@ class ElementTreeFormatter(Formatter):
for name, value_string in self._filterElementProperties(element):
value = self._parsePropertyValue(value_string)
setattr(track_object, name, value)
+ track.addTrackObject(track_object)
curves_element = element.find("curves")
if curves_element:
for curve in curves_element.getchildren():
@@ -389,7 +390,6 @@ class ElementTreeFormatter(Formatter):
def _loadInterpolator(self, element, trackobject):
interpolator = trackobject.getInterpolator(element.attrib["property"])
-
start = element.find("start")
interpolator.start.value = self._parsePropertyValue(
start.attrib["value"])
@@ -455,8 +455,7 @@ class ElementTreeFormatter(Formatter):
track_objects_element = element.find("track-objects")
for track_object_element in track_objects_element:
- track_object = self._loadTrackObject(track_object_element)
- track.addTrackObject(track_object)
+ self._loadTrackObject(track, track_object_element)
return track
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index 8863811..2adb1c0 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -355,7 +355,6 @@ class TimelineObject(Signallable, Loggable):
raise TimelineError(str(e))
other.addTrackObject(other_track_object)
- track_object.track.addTrackObject(other_track_object)
if self.timeline is not None:
# if self is not yet in a timeline, the caller needs to add "other"
diff --git a/pitivi/timeline/timeline_undo.py b/pitivi/timeline/timeline_undo.py
index cefb64d..273cae3 100644
--- a/pitivi/timeline/timeline_undo.py
+++ b/pitivi/timeline/timeline_undo.py
@@ -75,16 +75,12 @@ class TimelineObjectAdded(UndoableAction):
def __init__(self, timeline, timeline_object):
self.timeline = timeline
self.timeline_object = timeline_object
- self.timeline_object_copy = self._copyTimelineObject(timeline_object)
+ self.tracks = dict((track_object, track_object.track)
+ for track_object in timeline_object.track_objects)
def do(self):
- temporary_timeline_object = \
- self._copyTimelineObject(self.timeline_object_copy)
- self.timeline_object.track_objects = []
- for track_object in temporary_timeline_object.track_objects:
- track, track_object.track = track_object.track, None
+ for track_object, track in self.tracks.iteritems():
track.addTrackObject(track_object)
- self.timeline_object.addTrackObject(track_object)
self.timeline.addTimelineObject(self.timeline_object)
self._done()
@@ -93,43 +89,24 @@ class TimelineObjectAdded(UndoableAction):
self.timeline.removeTimelineObject(self.timeline_object, deep=True)
self._undone()
- def _copyTimelineObject(self, timeline_object):
- copy = timeline_object.copy()
- for (track_object_copy, track_object) in \
- zip(copy.track_objects, timeline_object.track_objects):
- track_object_copy.track = track_object.track
-
- return copy
-
class TimelineObjectRemoved(UndoableAction):
def __init__(self, timeline, timeline_object):
self.timeline = timeline
self.timeline_object = timeline_object
- self.timeline_object_copy = self._copyTimelineObject(timeline_object)
+ self.tracks = dict((track_object, track_object.track)
+ for track_object in timeline_object.track_objects)
def do(self):
self.timeline.removeTimelineObject(self.timeline_object, deep=True)
self._done()
def undo(self):
- temporary_timeline_object = \
- self._copyTimelineObject(self.timeline_object_copy)
- for track_object in temporary_timeline_object.track_objects:
- track, track_object.track = track_object.track, None
+ for track_object, track in self.tracks.iteritems():
track.addTrackObject(track_object)
- self.timeline_object.track_objects = temporary_timeline_object.track_objects
self.timeline.addTimelineObject(self.timeline_object)
self._undone()
- def _copyTimelineObject(self, timeline_object):
- copy = timeline_object.copy()
- for (track_object_copy, track_object) in \
- zip(copy.track_objects, timeline_object.track_objects):
- track_object_copy.track = track_object.track
-
- return copy
-
class TimelineLogObserver(object):
propertyChangedAction = TimelineObjectPropertyChanged
timelineObjectAddedAction = TimelineObjectAdded
diff --git a/pitivi/timeline/track.py b/pitivi/timeline/track.py
index 2b899ba..183c7dd 100644
--- a/pitivi/timeline/track.py
+++ b/pitivi/timeline/track.py
@@ -275,7 +275,6 @@ class TrackObject(Signallable, Loggable):
self.interpolators = {}
self._rebuild_interpolators = True
self.gnl_object = obj = self._makeGnlObject()
- self.makeBin()
self.trimmed_start = 0
self.keyframes = []
@@ -344,6 +343,9 @@ class TrackObject(Signallable, Loggable):
media_duration=self.media_duration, priority=self.priority)
other.trimmed_start = self.trimmed_start
+ if self.track is not None:
+ self.track.addTrackObject(other)
+
interpolators = self.getInterpolators()
for property, interpolator in interpolators.itervalues():
other_interpolator = other.getInterpolator(property.name)
@@ -507,18 +509,16 @@ class TrackObject(Signallable, Loggable):
def makeBin(self):
if self.stream is None:
- raise TrackError
+ raise TrackError()
if self.gnl_object is None:
- raise TrackError
+ raise TrackError()
bin = self.factory.makeBin(self.stream)
self.gnl_object.add(bin)
self._maybeBuildInterpolators()
def releaseBin(self):
- elts = list(self.gnl_object.elements())
- if elts:
- bin = elts[0]
+ for bin in list(self.gnl_object.elements()):
self.gnl_object.remove(bin)
bin.set_state(gst.STATE_NULL)
self.factory.releaseBin(bin)
@@ -684,6 +684,8 @@ class Track(Signallable):
except gst.AddError:
raise TrackError()
+ track_object.makeBin()
+
track_object.track = weakref.proxy(self)
self.track_objects.append(track_object)
@@ -705,7 +707,7 @@ class Track(Signallable):
raise TrackError()
self._disconnectFromTrackObject(track_object)
- track_object.release()
+ track_object.releaseBin()
self.track_objects.remove(track_object)
track_object.track = None
diff --git a/tests/test_etree_formatter.py b/tests/test_etree_formatter.py
index 21e6aba..f46db02 100644
--- a/tests/test_etree_formatter.py
+++ b/tests/test_etree_formatter.py
@@ -123,6 +123,8 @@ class TestFormatterSave(TestCase):
start=10 * gst.SECOND, duration=20 * gst.SECOND,
in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
priority=10)
+ track = Track(video_stream)
+ track.addTrackObject(track_object)
# create an interpolator and insert it into the track object
fakevol = gst.element_factory_make("volume")
@@ -185,6 +187,8 @@ class TestFormatterSave(TestCase):
start=10 * gst.SECOND, duration=20 * gst.SECOND,
in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
priority=10)
+ track = Track(video_stream)
+ track.addTrackObject(track_object)
element = self.formatter._saveTrackObject(track_object)
element_ref = self.formatter._saveTrackObjectRef(track_object)
@@ -229,6 +233,8 @@ class TestFormatterSave(TestCase):
start=10 * gst.SECOND, duration=20 * gst.SECOND,
in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
priority=10)
+ track = Track(video_stream)
+ track.addTrackObject(track_object)
self.formatter._saveTrackObject(track_object)
@@ -256,7 +262,8 @@ class TestFormatterSave(TestCase):
start=10 * gst.SECOND, duration=20 * gst.SECOND,
in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
priority=10)
-
+ track = Track(video_stream)
+ track.addTrackObject(track_object)
self.formatter._saveTrackObject(track_object)
timeline_object = TimelineObject(source1)
@@ -279,11 +286,11 @@ class TestFormatterSave(TestCase):
in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
priority=10)
- self.formatter._saveTrackObject(track_object)
-
track = Track(video_stream)
track.addTrackObject(track_object)
+ self.formatter._saveTrackObject(track_object)
+
timeline_object = TimelineObject(source1)
timeline_object.addTrackObject(track_object)
@@ -316,11 +323,11 @@ class TestFormatterSave(TestCase):
in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
priority=10)
- self.formatter._saveTrackObject(track_object)
-
track = Track(video_stream)
track.addTrackObject(track_object)
+ self.formatter._saveTrackObject(track_object)
+
timeline_object = TimelineObject(source1)
timeline_object.addTrackObject(track_object)
@@ -425,8 +432,9 @@ class TestFormatterLoad(TestCase):
mode=str(mode))
end = SubElement(curve, "end", value=str(10 % 2), mode="2")
+ track = Track(stream)
# point gun at foot; pull trigger
- track_object = self.formatter._loadTrackObject(element)
+ track_object = self.formatter._loadTrackObject(track, element)
self.failUnless(isinstance(track_object, SourceTrackObject))
self.failUnlessEqual(track_object.factory, factory)
self.failUnlessEqual(track_object.stream, stream)
@@ -557,11 +565,11 @@ class TestFormatterLoad(TestCase):
in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
priority=10)
- self.formatter._saveTrackObject(track_object)
-
track = Track(video_stream)
track.addTrackObject(track_object)
+ self.formatter._saveTrackObject(track_object)
+
timeline_object = TimelineObject(source1)
timeline_object.addTrackObject(track_object)
diff --git a/tests/test_timeline_undo.py b/tests/test_timeline_undo.py
index bca4ccf..1db741f 100644
--- a/tests/test_timeline_undo.py
+++ b/tests/test_timeline_undo.py
@@ -142,7 +142,7 @@ class TestTimelineUndo(TestCase):
self.timeline.addTimelineObject(self.timeline_object1)
self.action_log.begin("remove clip")
- self.timeline.removeTimelineObject(self.timeline_object1)
+ self.timeline.removeTimelineObject(self.timeline_object1, deep=True)
self.action_log.commit()
self.failUnlessEqual(len(stacks), 1)
diff --git a/tests/test_track.py b/tests/test_track.py
index 47129bf..8647f13 100644
--- a/tests/test_track.py
+++ b/tests/test_track.py
@@ -219,10 +219,13 @@ class TestTrackObject(TestCase):
factory.duration = DURATION
stream_ = AudioStream(gst.Caps("audio/x-raw-int"))
obj = SourceTrackObject(factory, stream_)
+ track = Track(stream_)
+ track.addTrackObject(obj)
obj.start = 3 * gst.SECOND
obj.duration = DURATION
+
# create a zig-zag volume curve
interpolator = obj.getInterpolator("volume")
expected = dict(((t * gst.SECOND, (t % 2, gst.INTERPOLATE_LINEAR))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]