[pitivi: 7/41] Fix mass-deletion bug, #634723



commit 5842bb66188257eb645639dc9d566db4eec6f399
Author: Benjamin M. Schwartz <bens alum mit edu>
Date:   Sat Jul 9 19:15:37 2011 -0400

    Fix mass-deletion bug, #634723
    
    The patch works by adding explicit methods for mass deletion, and delaying
    cleanup until after all the objects have been deleted.  I must admit that,
    since I have not diagnosed the cause of the hang, I am not sure why this
    resolves it, and a race condition may still be lurking.  However, I believe
    that this design is more sensible, and indeed the code seems to have been
    designed with the expectation that cleanup would be delayed until after
    many objects have been deleted.

 pitivi/timeline/timeline.py |   30 ++++++++++++++++++++++++++----
 pitivi/timeline/track.py    |   20 ++++++++++++++++----
 2 files changed, 42 insertions(+), 8 deletions(-)
---
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index e94214f..27f2cc1 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -1634,14 +1634,37 @@ class Timeline(Signallable, Loggable):
                 track = track_object.track
                 track.removeTrackObject(track_object)
 
+    def removeMultipleTimelineObjects(self, objs, deep=False):
+        """
+        Remove multiple objects from the Timeline.
+
+        @param objs: The collection of objects to remove
+        @type obj: collection(L{TimelineObject})
+        @param deep: If C{True}, remove the L{TrackObject}s associated with
+             these objects.
+        @type deep: C{bool}
+        @raises TimelineError: If the object doesn't belong to the timeline.
+        """
+        for obj in objs:
+            self.removeTimelineObject(obj, False)
+
+        # If we are going to remove the associated track objects, first
+        # group them by track so we can use the track's removeMultiple method.
+        if deep:
+            track_aggregate = collections.defaultdict(list)
+            for obj in objs:
+                for track_object in obj.track_objects:
+                    track_aggregate[track_object.track].append(track_object)
+            for track, objects_to_remove in track_aggregate.items():
+                track.removeMultipleTrackObjects(objects_to_remove)
+
     def removeFactory(self, factory):
         """Remove every instance factory in the timeline
         @param factory: the factory to remove from the timeline
         """
         objs = [obj for obj in self.timeline_objects if obj.factory is
             factory]
-        for obj in objs:
-            self.removeTimelineObject(obj, deep=True)
+        self.removeMultipleTimelineObjects(objs, deep=True)
 
     def usesFactory(self, factory):
         """
@@ -1979,8 +2002,7 @@ class Timeline(Signallable, Loggable):
         Removes all the currently selected L{TimelineObject}s from the Timeline.
         """
         self.unlinkSelection()
-        for timeline_object in self.selection:
-            self.removeTimelineObject(timeline_object, deep=True)
+        self.removeMultipleTimelineObjects(self.selection, deep=True)
         self.selection.setSelection(set([]), SELECT)
 
     def split(self, time):
diff --git a/pitivi/timeline/track.py b/pitivi/timeline/track.py
index f52bcaf..1cc2a07 100644
--- a/pitivi/timeline/track.py
+++ b/pitivi/timeline/track.py
@@ -1180,7 +1180,7 @@ class Track(Signallable, Loggable):
         if self._update_transitions:
             self.updateTransitions()
 
-    def removeTrackObject(self, track_object):
+    def _justRemoveTrackObject(self, track_object):
         if track_object.track is None:
             raise TrackError()
 
@@ -1197,17 +1197,29 @@ class Track(Signallable, Loggable):
         track_object.track = None
 
         self._disconnectTrackObjectSignals(track_object)
+        self.emit('track-object-removed', track_object)
+
+    def removeTrackObject(self, track_object):
+        self._justRemoveTrackObject(track_object)
+
+        self._updateMaxPriority()
+        self.updateDefaultSources()
+
+        if self._update_transitions:
+            self.updateTransitions()
+
+    def removeMultipleTrackObjects(self, track_objects):
+        for track_object in track_objects:
+            self._justRemoveTrackObject(track_object)
 
         self._updateMaxPriority()
         self.updateDefaultSources()
 
-        self.emit('track-object-removed', track_object)
         if self._update_transitions:
             self.updateTransitions()
 
     def removeAllTrackObjects(self):
-        for track_object in list(self.track_objects):
-            self.removeTrackObject(track_object)
+        self.removeMultipleTrackObjects(list(self.track_objects))
 
     def _updateMaxPriority(self):
         priorities = [track_object.priority for track_object in



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]