summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/editor_ops.cc76
-rw-r--r--gtk2_ardour/route_time_axis.cc29
-rw-r--r--gtk2_ardour/strip_silence_dialog.cc17
-rw-r--r--libs/ardour/ardour/playlist.h4
-rw-r--r--libs/ardour/playlist.cc25
-rw-r--r--libs/pbd/pbd/property_basics.h1
-rw-r--r--libs/pbd/pbd/stateful.h2
-rw-r--r--libs/pbd/stateful.cc11
8 files changed, 108 insertions, 57 deletions
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index b2174d1933..2866f82e61 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -155,7 +155,13 @@ Editor::split_regions_at (nframes64_t where, RegionSelection& regions)
boost::shared_ptr<Playlist> pl = (*a)->region()->playlist();
- if (! pl->frozen()) {
+ if (!pl) {
+ cerr << "region " << (*a)->region()->name() << " has no playlist!\n";
+ a = tmp;
+ continue;
+ }
+
+ if (!pl->frozen()) {
/* we haven't seen this playlist before */
/* remember used playlists so we can thaw them later */
@@ -3934,17 +3940,6 @@ Editor::cut_copy_midi (CutCopyOp op)
}
}
-struct PlaylistState {
- boost::shared_ptr<Playlist> playlist;
- XMLNode* before;
-};
-
-struct lt_playlist {
- bool operator () (const PlaylistState& a, const PlaylistState& b) {
- return a.playlist < b.playlist;
- }
-};
-
struct PlaylistMapping {
TimeAxisView* tv;
boost::shared_ptr<Playlist> pl;
@@ -4057,8 +4052,8 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
nframes64_t first_position = max_frames;
- set<PlaylistState, lt_playlist> freezelist;
- pair<set<PlaylistState, lt_playlist>::iterator,bool> insert_result;
+ typedef set<boost::shared_ptr<Playlist> > FreezeList;
+ FreezeList freezelist;
/* get ordering correct before we cut/copy */
@@ -4072,21 +4067,19 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
boost::shared_ptr<Playlist> pl = (*x)->region()->playlist();
if (pl) {
- set<PlaylistState, lt_playlist>::iterator fl;
+ FreezeList::iterator fl;
//only take state if this is a new playlist.
for (fl = freezelist.begin(); fl != freezelist.end(); ++fl) {
- if ((*fl).playlist == pl) {
+ if ((*fl) == pl) {
break;
}
}
if (fl == freezelist.end()) {
- PlaylistState before;
- before.playlist = pl;
- before.before = &pl->get_state();
+ pl->clear_history();
pl->freeze ();
- insert_result = freezelist.insert (before);
+ freezelist.insert (pl);
}
}
}
@@ -4177,10 +4170,10 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
if (!foo.empty()) {
cut_buffer->set (foo);
}
-
- for (set<PlaylistState, lt_playlist>::iterator pl = freezelist.begin(); pl != freezelist.end(); ++pl) {
- (*pl).playlist->thaw ();
- _session->add_command (new MementoCommand<Playlist>(*(*pl).playlist, (*pl).before, &(*pl).playlist->get_state()));
+
+ for (FreezeList::iterator pl = freezelist.begin(); pl != freezelist.end(); ++pl) {
+ (*pl)->thaw ();
+ _session->add_command (new StatefulDiffCommand (*pl));
}
}
@@ -4440,13 +4433,20 @@ Editor::nudge_track (bool use_edit, bool forwards)
continue;
}
- /* XXX STATEFUL this won't capture region moves if don't as a stateful diff
- */
+ playlist->clear_history ();
+ playlist->clear_owned_history ();
- XMLNode &before = playlist->get_state();
playlist->nudge_after (start, distance, forwards);
- XMLNode &after = playlist->get_state();
- _session->add_command (new MementoCommand<Playlist>(*playlist, &before, &after));
+
+ vector<StatefulDiffCommand*> cmds;
+
+ playlist->rdiff (cmds);
+
+ for (vector<StatefulDiffCommand*>::iterator c = cmds.begin(); c != cmds.end(); ++c) {
+ _session->add_command (*c);
+ }
+
+ _session->add_command (new StatefulDiffCommand (playlist));
}
commit_reversible_command ();
@@ -6290,10 +6290,8 @@ Editor::insert_time (nframes64_t pos, nframes64_t frames, InsertTimeOption opt,
if (pl) {
- /* XXX STATEFUL this won't capture region motion if done as stateful diff
- */
-
- XMLNode &before = pl->get_state();
+ pl->clear_history ();
+ pl->clear_owned_history ();
if (opt == SplitIntersected) {
pl->split (pos);
@@ -6301,9 +6299,17 @@ Editor::insert_time (nframes64_t pos, nframes64_t frames, InsertTimeOption opt,
pl->shift (pos, frames, (opt == MoveIntersected), ignore_music_glue);
- XMLNode &after = pl->get_state();
+ vector<StatefulDiffCommand*> cmds;
+
+ pl->rdiff (cmds);
+
+ cerr << "Shift generated " << cmds.size() << " sdc's\n";
- _session->add_command (new MementoCommand<Playlist> (*pl, &before, &after));
+ for (vector<StatefulDiffCommand*>::iterator c = cmds.begin(); c != cmds.end(); ++c) {
+ _session->add_command (*c);
+ }
+
+ _session->add_command (new StatefulDiffCommand (pl));
commit = true;
}
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index 39bb1847a1..62a2b2b8a0 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -33,7 +33,7 @@
#include "pbd/whitespace.h"
#include "pbd/memento_command.h"
#include "pbd/enumwriter.h"
-#include "pbd/stacktrace.h"
+#include "pbd/stateful_diff_command.h"
#include <gtkmm/menu.h>
#include <gtkmm/menuitem.h>
@@ -1385,12 +1385,22 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
}
}
- XMLNode &before = playlist->get_state();
+ playlist->clear_history ();
+ playlist->clear_owned_history ();
+
switch (op) {
case Cut:
if ((what_we_got = playlist->cut (time)) != 0) {
_editor.get_cut_buffer().add (what_we_got);
- _session->add_command( new MementoCommand<Playlist>(*playlist.get(), &before, &playlist->get_state()));
+
+ vector<StatefulDiffCommand*> cmds;
+
+ playlist->rdiff (cmds);
+
+ for (vector<StatefulDiffCommand*>::iterator c = cmds.begin(); c != cmds.end(); ++c) {
+ _session->add_command (*c);
+ }
+ _session->add_command (new StatefulDiffCommand (playlist));
ret = true;
}
break;
@@ -1402,7 +1412,14 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
case Clear:
if ((what_we_got = playlist->cut (time)) != 0) {
- _session->add_command( new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
+ vector<StatefulDiffCommand*> cmds;
+
+ playlist->rdiff (cmds);
+
+ for (vector<StatefulDiffCommand*>::iterator c = cmds.begin(); c != cmds.end(); ++c) {
+ _session->add_command (*c);
+ }
+ _session->add_command (new StatefulDiffCommand (playlist));
what_we_got->release ();
ret = true;
}
@@ -1432,9 +1449,9 @@ RouteTimeAxisView::paste (nframes_t pos, float times, Selection& selection, size
pos = session_frame_to_track_frame(pos, get_diskstream()->speed() );
}
- XMLNode &before = playlist->get_state();
+ playlist->clear_history ();
playlist->paste (*p, pos, times);
- _session->add_command( new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
+ _session->add_command (new StatefulDiffCommand (playlist));
return true;
}
diff --git a/gtk2_ardour/strip_silence_dialog.cc b/gtk2_ardour/strip_silence_dialog.cc
index 56210c9373..4dd8f225f2 100644
--- a/gtk2_ardour/strip_silence_dialog.cc
+++ b/gtk2_ardour/strip_silence_dialog.cc
@@ -270,7 +270,7 @@ StripSilenceDialog::_detection_done (void* arg)
bool
StripSilenceDialog::detection_done ()
{
- get_window()->set_cursor (Gdk::Cursor (Gdk::LEFT_PTR));
+ // get_window()->set_cursor (Gdk::Cursor (Gdk::LEFT_PTR));
update_silence_rects ();
return false;
}
@@ -287,22 +287,15 @@ StripSilenceDialog::detection_thread_work ()
{
ARDOUR_UI::instance()->register_thread ("gui", pthread_self(), "silence", 32);
- cerr << pthread_self() << ": thread exists\n";
-
while (1) {
run_lock.lock ();
- cerr << pthread_self() << ": thread notes that its waiting\n";
thread_waiting->signal ();
- cerr << pthread_self() << ": thread waits to run\n";
thread_run->wait (run_lock);
- cerr << pthread_self() << ": silence thread active\n";
-
if (thread_should_exit) {
thread_waiting->signal ();
run_lock.unlock ();
- cerr << pthread_self() << ": silence thread exited\n";
break;
}
@@ -319,7 +312,6 @@ StripSilenceDialog::detection_thread_work ()
}
}
- cerr << pthread_self() << ": silence iteration done\n";
}
return 0;
@@ -349,9 +341,7 @@ StripSilenceDialog::start_silence_detection ()
pthread_create (&itt.thread, 0, StripSilenceDialog::_detection_thread_work, this);
/* wait for it to get started */
- cerr << "Wait for new thread to be ready\n";
thread_waiting->wait (run_lock);
- cerr << "\tits ready\n";
} else {
@@ -361,11 +351,8 @@ StripSilenceDialog::start_silence_detection ()
current = 0;
while (!itt.done) {
- cerr << "tell existing thread to stop\n";
thread_run->signal ();
- cerr << "wait for existing thread to stop\n";
thread_waiting->wait (run_lock);
- cerr << "its stopped\n";
}
}
@@ -377,7 +364,6 @@ StripSilenceDialog::start_silence_detection ()
/* and start it up (again) */
- cerr << "signal thread to run again\n";
thread_run->signal ();
/* change cursor */
@@ -398,4 +384,5 @@ StripSilenceDialog::stop_thread ()
thread_should_exit = true;
thread_run->signal ();
thread_waiting->wait (run_lock);
+ itt.thread = 0;
}
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index 3c79ec0ec4..bc896f35a4 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -35,6 +35,7 @@
#include "pbd/undo.h"
#include "pbd/stateful.h"
+#include "pbd/stateful_owner.h"
#include "pbd/statefuldestructible.h"
#include "pbd/sequence_property.h"
@@ -83,6 +84,7 @@ class RegionListProperty : public PBD::SequenceProperty<std::list<boost::shared_
};
class Playlist : public SessionObject
+ , public PBD::StatefulOwner
, public boost::enable_shared_from_this<Playlist> {
public:
typedef std::list<boost::shared_ptr<Region> > RegionList;
@@ -97,6 +99,8 @@ class Playlist : public SessionObject
bool set_property (const PBD::PropertyBase&);
void update (const RegionListProperty::ChangeRecord&);
+ void clear_owned_history ();
+ void rdiff (std::vector<PBD::StatefulDiffCommand*>&) const;
PBD::PropertyList* property_factory (const XMLNode&) const;
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 8d3b59427d..2b9ce7824f 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -26,9 +26,9 @@
#include <climits>
#include "pbd/failed_constructor.h"
+#include "pbd/stateful_diff_command.h"
#include "pbd/stl_delete.h"
#include "pbd/xml++.h"
-#include "pbd/stacktrace.h"
#include "ardour/debug.h"
#include "ardour/playlist.h"
@@ -2026,6 +2026,29 @@ Playlist::set_property (const PropertyBase& prop)
}
void
+Playlist::rdiff (vector<StatefulDiffCommand*>& cmds) const
+{
+ RegionLock rlock (const_cast<Playlist *> (this));
+
+ for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
+ if ((*i)->changed ()) {
+ StatefulDiffCommand* sdc = new StatefulDiffCommand (*i);
+ cmds.push_back (sdc);
+ }
+ }
+}
+
+void
+Playlist::clear_owned_history ()
+{
+ RegionLock rlock (this);
+
+ for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
+ (*i)->clear_history ();
+ }
+}
+
+void
Playlist::update (const RegionListProperty::ChangeRecord& change)
{
DEBUG_TRACE (DEBUG::Properties, string_compose ("Playlist %1 updates from a change record with %2 adds %3 removes\n",
diff --git a/libs/pbd/pbd/property_basics.h b/libs/pbd/pbd/property_basics.h
index c99fee1961..e818e36e90 100644
--- a/libs/pbd/pbd/property_basics.h
+++ b/libs/pbd/pbd/property_basics.h
@@ -95,6 +95,7 @@ public:
const gchar*property_name () const { return g_quark_to_string (_property_id); }
PropertyID property_id () const { return _property_id; }
+ bool changed() const { return _have_old; }
bool operator==(PropertyID pid) const {
return _property_id == pid;
diff --git a/libs/pbd/pbd/stateful.h b/libs/pbd/pbd/stateful.h
index 93f353a095..5585b5c13b 100644
--- a/libs/pbd/pbd/stateful.h
+++ b/libs/pbd/pbd/stateful.h
@@ -71,6 +71,8 @@ class Stateful {
void clear_history ();
void diff (PropertyList&, PropertyList&) const;
+ bool changed() const;
+
/* create a property list from an XMLNode
*/
virtual PropertyList* property_factory(const XMLNode&) const { return 0; }
diff --git a/libs/pbd/stateful.cc b/libs/pbd/stateful.cc
index 1bf8c17d83..89b22edd24 100644
--- a/libs/pbd/stateful.cc
+++ b/libs/pbd/stateful.cc
@@ -287,5 +287,16 @@ Stateful::resume_property_changes ()
send_change (what_changed);
}
+bool
+Stateful::changed() const
+{
+ for (OwnedPropertyList::const_iterator i = _properties->begin(); i != _properties->end(); ++i) {
+ if (i->second->changed()) {
+ return true;
+ }
+ }
+
+ return false;
+}
} // namespace PBD