summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2010-03-02 18:05:26 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2010-03-02 18:05:26 +0000
commit17088ee3ea5af1e6174b098bb5bcfdaec6ebf9b0 (patch)
treecbf9fe8fb94212f9a50c6b760ebaac3b4a1bcec6
parenta5ab2e99e19d5f5d4c1f91f38cd774fefdf257dc (diff)
(1) remove most uses of MementoCommand for Playlist and Region (2) move frozen state from Region into Stateful, renamed "suspend property changes" (3) successive changes to a Property (scalar) after clear_history() do not keep resetting the old value (fixes region trim)
git-svn-id: svn://localhost/ardour2/branches/3.0@6720 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/audio_region_editor.cc26
-rw-r--r--gtk2_ardour/audio_region_view.cc10
-rw-r--r--gtk2_ardour/audio_streamview.cc8
-rw-r--r--gtk2_ardour/editor_audio_import.cc5
-rw-r--r--gtk2_ardour/editor_drag.cc14
-rw-r--r--gtk2_ardour/editor_keyboard.cc19
-rw-r--r--gtk2_ardour/editor_mouse.cc41
-rw-r--r--gtk2_ardour/editor_ops.cc235
-rw-r--r--gtk2_ardour/editor_timefx.cc11
-rw-r--r--gtk2_ardour/midi_region_view.cc5
-rw-r--r--gtk2_ardour/midi_streamview.cc8
-rw-r--r--gtk2_ardour/midi_time_axis.cc6
-rw-r--r--gtk2_ardour/region_gain_line.cc8
-rw-r--r--libs/ardour/ardour/audio_track.h2
-rw-r--r--libs/ardour/ardour/automation_list.h1
-rw-r--r--libs/ardour/ardour/midi_track.h2
-rw-r--r--libs/ardour/ardour/region.h11
-rw-r--r--libs/ardour/ardour/session.h2
-rw-r--r--libs/ardour/ardour/track.h2
-rw-r--r--libs/ardour/audio_diskstream.cc7
-rw-r--r--libs/ardour/audio_track.cc2
-rw-r--r--libs/ardour/audioregion.cc34
-rw-r--r--libs/ardour/automation_list.cc18
-rw-r--r--libs/ardour/midi_diskstream.cc6
-rw-r--r--libs/ardour/midi_track.cc2
-rw-r--r--libs/ardour/playlist.cc18
-rw-r--r--libs/ardour/region.cc77
-rw-r--r--libs/ardour/region_factory.cc12
-rw-r--r--libs/ardour/session.cc4
-rw-r--r--libs/evoral/evoral/ControlList.hpp5
-rw-r--r--libs/pbd/pbd/properties.h6
-rw-r--r--libs/pbd/pbd/stateful.h19
-rw-r--r--libs/pbd/stateful.cc52
-rw-r--r--libs/surfaces/osc/osc_controllable.cc6
-rw-r--r--libs/surfaces/osc/osc_controllable.h4
35 files changed, 326 insertions, 362 deletions
diff --git a/gtk2_ardour/audio_region_editor.cc b/gtk2_ardour/audio_region_editor.cc
index e246c04391..adbb1e04ea 100644
--- a/gtk2_ardour/audio_region_editor.cc
+++ b/gtk2_ardour/audio_region_editor.cc
@@ -18,6 +18,7 @@
*/
#include "pbd/memento_command.h"
+#include "pbd/stateful_diff_command.h"
#include "ardour/session.h"
#include "ardour/audioregion.h"
@@ -256,10 +257,9 @@ AudioRegionEditor::position_clock_changed ()
boost::shared_ptr<Playlist> pl = _region->playlist();
if (pl) {
- XMLNode &before = pl->get_state();
+ _region->clear_history ();
_region->set_position (position_clock.current_time(), this);
- XMLNode &after = pl->get_state();
- _session->add_command(new MementoCommand<Playlist>(*pl, &before, &after));
+ _session->add_command(new StatefulDiffCommand (_region));
}
_session->commit_reversible_command ();
@@ -273,10 +273,9 @@ AudioRegionEditor::end_clock_changed ()
boost::shared_ptr<Playlist> pl = _region->playlist();
if (pl) {
- XMLNode &before = pl->get_state();
+ _region->clear_history ();
_region->trim_end (end_clock.current_time(), this);
- XMLNode &after = pl->get_state();
- _session->add_command(new MementoCommand<Playlist>(*pl, &before, &after));
+ _session->add_command(new StatefulDiffCommand (_region));
}
_session->commit_reversible_command ();
@@ -294,10 +293,9 @@ AudioRegionEditor::length_clock_changed ()
boost::shared_ptr<Playlist> pl = _region->playlist();
if (pl) {
- XMLNode &before = pl->get_state();
+ _region->clear_history ();
_region->trim_end (_region->position() + frames - 1, this);
- XMLNode &after = pl->get_state();
- _session->add_command(new MementoCommand<Playlist>(*pl, &before, &after));
+ _session->add_command(new StatefulDiffCommand (_region));
}
_session->commit_reversible_command ();
@@ -404,10 +402,9 @@ AudioRegionEditor::sync_offset_absolute_clock_changed ()
{
_session->begin_reversible_command (_("change region sync point"));
- XMLNode& before = _region->get_state ();
+ _region->clear_history ();
_region->set_sync_position (sync_offset_absolute_clock.current_time());
- XMLNode& after = _region->get_state ();
- _session->add_command (new MementoCommand<AudioRegion> (*_region.get(), &before, &after));
+ _session->add_command (new StatefulDiffCommand (_region));
_session->commit_reversible_command ();
}
@@ -417,10 +414,9 @@ AudioRegionEditor::sync_offset_relative_clock_changed ()
{
_session->begin_reversible_command (_("change region sync point"));
- XMLNode& before = _region->get_state ();
+ _region->clear_history ();
_region->set_sync_position (sync_offset_relative_clock.current_time() + _region->position ());
- XMLNode& after = _region->get_state ();
- _session->add_command (new MementoCommand<AudioRegion> (*_region.get(), &before, &after));
+ _session->add_command (new StatefulDiffCommand (_region));
_session->commit_reversible_command ();
}
diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc
index 438867c9dc..7a0e76606e 100644
--- a/gtk2_ardour/audio_region_view.cc
+++ b/gtk2_ardour/audio_region_view.cc
@@ -267,8 +267,8 @@ AudioRegionView::audio_region() const
void
AudioRegionView::region_changed (const PropertyChange& what_changed)
{
- ENSURE_GUI_THREAD (*this, &AudioRegionView::region_changed, what_changed)
- //cerr << "AudioRegionView::region_changed() called" << endl;
+ ENSURE_GUI_THREAD (*this, &AudioRegionView::region_changed, what_changed);
+ // cerr << "AudioRegionView::region_changed() called" << endl;
RegionView::region_changed (what_changed);
@@ -276,7 +276,7 @@ AudioRegionView::region_changed (const PropertyChange& what_changed)
region_scale_amplitude_changed ();
}
if (what_changed.contains (ARDOUR::Properties::fade_in)) {
- fade_in_changed ();
+ fade_in_changed ();
}
if (what_changed.contains (ARDOUR::Properties::fade_out)) {
fade_out_changed ();
@@ -1022,6 +1022,10 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev)
gain_line->view_to_model_coord (x, y);
+ /* XXX STATEFUL: can't convert to stateful diff until we
+ can represent automation data with it.
+ */
+
trackview.session()->begin_reversible_command (_("add gain control point"));
XMLNode &before = audio_region()->envelope()->get_state();
diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc
index 640120516c..ac95bf63c2 100644
--- a/gtk2_ardour/audio_streamview.cc
+++ b/gtk2_ardour/audio_streamview.cc
@@ -660,10 +660,10 @@ AudioStreamView::update_rec_regions ()
if (nlen != region->length()) {
- region->freeze ();
+ region->suspend_property_changes ();
region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
region->set_length (nlen, this);
- region->thaw ();
+ region->resume_property_changes ();
if (origlen == 1) {
/* our special initial length */
@@ -685,10 +685,10 @@ AudioStreamView::update_rec_regions ()
if (region->source_length(0) >= region->start() + nlen) {
- region->freeze ();
+ region->suspend_property_changes ();
region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
region->set_length (nlen, this);
- region->thaw ();
+ region->resume_property_changes ();
if (origlen == 1) {
/* our special initial length */
diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc
index 05056f3829..201659d7b4 100644
--- a/gtk2_ardour/editor_audio_import.cc
+++ b/gtk2_ardour/editor_audio_import.cc
@@ -29,6 +29,7 @@
#include "pbd/pthread_utils.h"
#include "pbd/basename.h"
#include "pbd/shortpath.h"
+#include "pbd/stateful_diff_command.h"
#include <gtkmm2ext/choice.h>
@@ -840,9 +841,9 @@ Editor::finish_bringing_in_material (boost::shared_ptr<Region> region, uint32_t
boost::shared_ptr<Playlist> playlist = existing_track->diskstream()->playlist();
boost::shared_ptr<Region> copy (RegionFactory::create (region, region->properties()));
begin_reversible_command (_("insert file"));
- XMLNode &before = playlist->get_state();
+ playlist->clear_history ();
playlist->add_region (copy, pos);
- _session->add_command (new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
+ _session->add_command (new StatefulDiffCommand (playlist));
commit_reversible_command ();
break;
}
diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc
index 2922ad19bb..cd6e5148f6 100644
--- a/gtk2_ardour/editor_drag.cc
+++ b/gtk2_ardour/editor_drag.cc
@@ -1425,9 +1425,9 @@ RegionInsertDrag::finished (GdkEvent* /*event*/, bool /*movement_occurred*/)
boost::shared_ptr<Playlist> playlist = dest_rtv->playlist();
_editor->begin_reversible_command (_("insert region"));
- XMLNode& before = playlist->get_state ();
+ playlist->clear_history ();
playlist->add_region (_primary->region (), _last_frame_position);
- _editor->session()->add_command (new MementoCommand<Playlist> (*playlist, &before, &playlist->get_state()));
+ _editor->session()->add_command (new StatefulDiffCommand (playlist));
_editor->commit_reversible_command ();
delete _primary;
@@ -1772,7 +1772,8 @@ TrimDrag::motion (GdkEvent* event, bool first_move)
for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
(*i)->fake_set_opaque(false);
- (*i)->region()->freeze ();
+ (*i)->region()->clear_history ();
+ (*i)->region()->suspend_property_changes ();
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
@@ -1784,7 +1785,6 @@ TrimDrag::motion (GdkEvent* event, bool first_move)
insert_result = _editor->motion_frozen_playlists.insert (pl);
if (insert_result.second) {
- _editor->session()->add_command(new MementoCommand<Playlist>(*pl, &pl->get_state(), 0));
pl->freeze();
}
}
@@ -1867,13 +1867,13 @@ TrimDrag::finished (GdkEvent* event, bool movement_occurred)
for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
_editor->thaw_region_after_trim (**i);
(*i)->fake_set_opaque (true);
+ if (_have_transaction) {
+ _editor->session()->add_command (new StatefulDiffCommand ((*i)->region()));
+ }
}
}
for (set<boost::shared_ptr<Playlist> >::iterator p = _editor->motion_frozen_playlists.begin(); p != _editor->motion_frozen_playlists.end(); ++p) {
(*p)->thaw ();
- if (_have_transaction) {
- _editor->session()->add_command (new MementoCommand<Playlist>(*(*p).get(), 0, &(*p)->get_state()));
- }
}
_editor->motion_frozen_playlists.clear ();
diff --git a/gtk2_ardour/editor_keyboard.cc b/gtk2_ardour/editor_keyboard.cc
index ea40b43f50..e6936232cd 100644
--- a/gtk2_ardour/editor_keyboard.cc
+++ b/gtk2_ardour/editor_keyboard.cc
@@ -17,13 +17,14 @@
*/
+#include "pbd/memento_command.h"
+#include "pbd/stateful_diff_command.h"
+
#include "ardour/audioregion.h"
#include "ardour/playlist.h"
#include "ardour/session.h"
#include "ardour/location.h"
-#include "pbd/memento_command.h"
-
#include "editor.h"
#include "region_view.h"
#include "selection.h"
@@ -33,6 +34,7 @@
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
void
Editor::kbd_driver (sigc::slot<void,GdkEvent*> theslot, bool use_track_canvas, bool use_time_canvas, bool can_select)
@@ -89,11 +91,9 @@ Editor::kbd_mute_unmute_region ()
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
- XMLNode &before = (*i)->region()->playlist()->get_state ();
+ (*i)->region()->playlist()->clear_history ();
(*i)->region()->set_muted (!(*i)->region()->muted ());
- XMLNode &after = (*i)->region()->playlist()->get_state ();
-
- _session->add_command (new MementoCommand<ARDOUR::Playlist>(*((*i)->region()->playlist()), &before, &after));
+ _session->add_command (new StatefulDiffCommand ((*i)->region()->playlist()));
}
@@ -102,12 +102,9 @@ Editor::kbd_mute_unmute_region ()
} else if (entered_regionview) {
begin_reversible_command (_("mute region"));
- XMLNode &before = entered_regionview->region()->playlist()->get_state();
-
+ entered_regionview->region()->playlist()->clear_history ();
entered_regionview->region()->set_muted (!entered_regionview->region()->muted());
-
- XMLNode &after = entered_regionview->region()->playlist()->get_state();
- _session->add_command (new MementoCommand<ARDOUR::Playlist>(*(entered_regionview->region()->playlist()), &before, &after));
+ _session->add_command (new StatefulDiffCommand (entered_regionview->region()->playlist()));
commit_reversible_command();
}
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 5820218a2a..ee28ff6804 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -31,6 +31,7 @@
#include <gtkmm2ext/tearoff.h>
#include "pbd/memento_command.h"
#include "pbd/basename.h"
+#include "pbd/stateful_diff_command.h"
#include "ardour_ui.h"
#include "actions.h"
@@ -2287,23 +2288,17 @@ Editor::point_trim (GdkEvent* event, nframes64_t new_bound)
}
if (!(*i)->region()->locked()) {
- boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
- XMLNode &before = pl->get_state();
-
+ (*i)->region()->clear_history ();
(*i)->region()->trim_front (new_bound, this);
-
- XMLNode &after = pl->get_state();
- _session->add_command(new MementoCommand<Playlist>(*pl.get(), &before, &after));
+ _session->add_command(new StatefulDiffCommand ((*i)->region()));
}
}
} else {
if (!rv->region()->locked()) {
- boost::shared_ptr<Playlist> pl = rv->region()->playlist();
- XMLNode &before = pl->get_state();
+ rv->region()->clear_history ();
rv->region()->trim_front (new_bound, this);
- XMLNode &after = pl->get_state();
- _session->add_command(new MementoCommand<Playlist>(*pl.get(), &before, &after));
+ _session->add_command(new StatefulDiffCommand (rv->region()));
}
}
@@ -2318,22 +2313,18 @@ Editor::point_trim (GdkEvent* event, nframes64_t new_bound)
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i)
{
if (!(*i)->region()->locked()) {
- boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
- XMLNode &before = pl->get_state();
+ (*i)->region()->clear_history();
(*i)->region()->trim_end (new_bound, this);
- XMLNode &after = pl->get_state();
- _session->add_command(new MementoCommand<Playlist>(*pl.get(), &before, &after));
+ _session->add_command(new StatefulDiffCommand ((*i)->region()));
}
}
} else {
if (!rv->region()->locked()) {
- boost::shared_ptr<Playlist> pl = rv->region()->playlist();
- XMLNode &before = pl->get_state();
+ rv->region()->clear_history ();
rv->region()->trim_end (new_bound, this);
- XMLNode &after = pl->get_state();
- _session->add_command (new MementoCommand<Playlist>(*pl.get(), &before, &after));
+ _session->add_command (new StatefulDiffCommand (rv->region()));
}
}
@@ -2354,7 +2345,7 @@ Editor::thaw_region_after_trim (RegionView& rv)
return;
}
- region->thaw ();
+ region->resume_property_changes ();
AudioRegionView* arv = dynamic_cast<AudioRegionView*>(&rv);
@@ -2453,11 +2444,10 @@ Editor::mouse_brush_insert_region (RegionView* rv, nframes64_t pos)
boost::shared_ptr<Playlist> playlist = rtv->playlist();
double speed = rtv->get_diskstream()->speed();
- XMLNode &before = playlist->get_state();
+ playlist->clear_history ();
boost::shared_ptr<Region> new_region (RegionFactory::create (rv->region()));
- playlist->add_region (new_region, (nframes64_t) (pos * speed));
- XMLNode &after = playlist->get_state();
- _session->add_command(new MementoCommand<Playlist>(*playlist.get(), &before, &after));
+ playlist->add_region (new_region, (nframes64_t) (pos * speed));
+ _session->add_command (new StatefulDiffCommand (playlist));
// playlist is frozen, so we have to update manually XXX this is disgusting
@@ -2560,10 +2550,9 @@ Editor::start_selection_grab (ArdourCanvas::Item* /*item*/, GdkEvent* event)
boost::shared_ptr<Playlist> playlist = clicked_axisview->playlist();
- XMLNode *before = &(playlist->get_state());
+ playlist->clear_history ();
clicked_routeview->playlist()->add_region (region, selection->time[clicked_selection].start);
- XMLNode *after = &(playlist->get_state());
- _session->add_command(new MementoCommand<Playlist>(*playlist, before, after));
+ _session->add_command(new StatefulDiffCommand (playlist));
commit_reversible_command ();
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index c3800b21fb..6eaf1fb41a 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -323,10 +323,9 @@ Editor::nudge_forward (bool next, bool force_playhead)
distance = next_distance;
}
- XMLNode &before = r->playlist()->get_state();
+ r->clear_history ();
r->set_position (r->position() + distance, this);
- XMLNode &after = r->playlist()->get_state();
- _session->add_command (new MementoCommand<Playlist>(*(r->playlist()), &before, &after));
+ _session->add_command (new StatefulDiffCommand (r));
}
commit_reversible_command ();
@@ -403,16 +402,15 @@ Editor::nudge_backward (bool next, bool force_playhead)
if (next) {
distance = next_distance;
}
-
- XMLNode &before = r->playlist()->get_state();
+
+ r->clear_history ();
if (r->position() > distance) {
r->set_position (r->position() - distance, this);
} else {
r->set_position (0, this);
}
- XMLNode &after = r->playlist()->get_state();
- _session->add_command(new MementoCommand<Playlist>(*(r->playlist()), &before, &after));
+ _session->add_command (new StatefulDiffCommand (r));
}
commit_reversible_command ();
@@ -493,10 +491,9 @@ Editor::nudge_forward_capture_offset ()
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
boost::shared_ptr<Region> r ((*i)->region());
- XMLNode &before = r->playlist()->get_state();
+ r->clear_history ();
r->set_position (r->position() + distance, this);
- XMLNode &after = r->playlist()->get_state();
- _session->add_command(new MementoCommand<Playlist>(*(r->playlist()), &before, &after));
+ _session->add_command(new StatefulDiffCommand (r));
}
commit_reversible_command ();
@@ -523,15 +520,14 @@ Editor::nudge_backward_capture_offset ()
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
boost::shared_ptr<Region> r ((*i)->region());
- XMLNode &before = r->playlist()->get_state();
+ r->clear_history ();
if (r->position() > distance) {
r->set_position (r->position() - distance, this);
} else {
r->set_position (0, this);
}
- XMLNode &after = r->playlist()->get_state();
- _session->add_command(new MementoCommand<Playlist>(*(r->playlist()), &before, &after));
+ _session->add_command(new StatefulDiffCommand (r));
}
commit_reversible_command ();
@@ -2225,9 +2221,9 @@ Editor::insert_region_list_drag (boost::shared_ptr<Region> region, int x, int y)
snap_to (where);
begin_reversible_command (_("insert dragged region"));
- XMLNode &before = playlist->get_state();
+ playlist->clear_history ();
playlist->add_region (RegionFactory::create (region), where, 1.0);
- _session->add_command(new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
+ _session->add_command(new StatefulDiffCommand (playlist));
commit_reversible_command ();
}
@@ -2303,9 +2299,9 @@ Editor::insert_region_list_selection (float times)
}
begin_reversible_command (_("insert region"));
- XMLNode &before = playlist->get_state();
+ playlist->clear_history ();
playlist->add_region ((RegionFactory::create (region)), get_preferred_edit_position(), times);
- _session->add_command(new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
+ _session->add_command(new StatefulDiffCommand (playlist));
commit_reversible_command ();
}
@@ -2818,11 +2814,7 @@ Editor::separate_regions_between (const TimeSelection& ts)
if ((playlist = rtv->playlist()) != 0) {
- XMLNode *before;
- bool got_some;
-
- before = &(playlist->get_state());
- got_some = false;
+ playlist->clear_history ();
/* XXX need to consider musical time selections here at some point */
@@ -2842,25 +2834,18 @@ Editor::separate_regions_between (const TimeSelection& ts)
if (!latest_regionviews.empty()) {
- got_some = true;
-
rtv->view()->foreach_regionview (sigc::bind (
sigc::ptr_fun (add_if_covered),
&(*t), &new_selection));
-
+
if (!in_command) {
begin_reversible_command (_("separate"));
in_command = true;
}
- _session->add_command(new MementoCommand<Playlist>(
- *playlist, before, &playlist->get_state()));
+ _session->add_command(new StatefulDiffCommand (playlist));
}
}
-
- if (!got_some) {
- delete before;
- }
}
}
}
@@ -3022,10 +3007,9 @@ Editor::crop_region_to (nframes64_t start, nframes64_t end)
the_end = min (end, the_end);
cnt = the_end - the_start + 1;
- XMLNode &before = (*i)->get_state();
+ region->clear_history ();
region->trim_to (the_start, cnt, this);
- XMLNode &after = (*i)->get_state();
- _session->add_command (new MementoCommand<Playlist>(*(*i), &before, &after));
+ _session->add_command (new StatefulDiffCommand (region));
}
commit_reversible_command ();
@@ -3063,9 +3047,9 @@ Editor::region_fill_track ()
return;
}
- XMLNode &before = pl->get_state();
+ pl->clear_history ();
pl->add_region (RegionFactory::create (region), region->last_frame(), times);
- _session->add_command (new MementoCommand<Playlist>(*pl, &before, &pl->get_state()));
+ _session->add_command (new StatefulDiffCommand (pl));
}
commit_reversible_command ();
@@ -3107,9 +3091,9 @@ Editor::region_fill_selection ()
continue;
}
- XMLNode &before = playlist->get_state();
+ playlist->clear_history ();
playlist->add_region (RegionFactory::create (region), start, times);
- _session->add_command (new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
+ _session->add_command (new StatefulDiffCommand (playlist));
}
commit_reversible_command ();
@@ -3142,10 +3126,9 @@ Editor::set_sync_point (nframes64_t where, const RegionSelection& rs)
in_command = true;
}
- XMLNode &before = region->playlist()->get_state();
+ region->clear_history ();
region->set_sync_position (where);
- XMLNode &after = region->playlist()->get_state();
- _session->add_command(new MementoCommand<Playlist>(*(region->playlist()), &before, &after));
+ _session->add_command(new StatefulDiffCommand (region));
}
if (in_command) {
@@ -3168,10 +3151,9 @@ Editor::remove_region_sync ()
begin_reversible_command (_("remove sync"));
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
- XMLNode &before = (*i)->region()->playlist()->get_state();
+ (*i)->region()->clear_history ();
(*i)->region()->clear_sync_position ();
- XMLNode &after = (*i)->region()->playlist()->get_state();
- _session->add_command(new MementoCommand<Playlist>(*((*i)->region()->playlist()), &before, &after));
+ _session->add_command(new StatefulDiffCommand ((*i)->region()));
}
commit_reversible_command ();
}
@@ -3290,10 +3272,9 @@ Editor::align_selection_relative (RegionPoint point, nframes64_t position, const
/* move first one specially */
- XMLNode &before = r->playlist()->get_state();
+ r->clear_history ();
r->set_position (pos, this);
- XMLNode &after = r->playlist()->get_state();
- _session->add_command(new MementoCommand<Playlist>(*(r->playlist()), &before, &after));
+ _session->add_command(new StatefulDiffCommand (r));
/* move rest by the same amount */
@@ -3303,16 +3284,15 @@ Editor::align_selection_relative (RegionPoint point, nframes64_t position, const
boost::shared_ptr<Region> region ((*i)->region());
- XMLNode &before = region->playlist()->get_state();
+ region->clear_history ();
if (dir > 0) {
region->set_position (region->position() + distance, this);
} else {
region->set_position (region->position() - distance, this);
}
-
- XMLNode &after = region->playlist()->get_state();
- _session->add_command(new MementoCommand<Playlist>(*(region->playlist()), &before, &after));
+
+ _session->add_command(new StatefulDiffCommand (region));
}
@@ -3346,7 +3326,7 @@ Editor::align_region (boost::shared_ptr<Region> region, RegionPoint point, nfram
void
Editor::align_region_internal (boost::shared_ptr<Region> region, RegionPoint point, nframes64_t position)
{
- XMLNode &before = region->playlist()->get_state();
+ region->clear_history ();
switch (point) {
case SyncPoint:
@@ -3364,8 +3344,7 @@ Editor::align_region_internal (boost::shared_ptr<Region> region, RegionPoint poi
break;
}
- XMLNode &after = region->playlist()->get_state();
- _session->add_command(new MementoCommand<Playlist>(*(region->playlist()), &before, &after));
+ _session->add_command(new StatefulDiffCommand (region));
}
void
@@ -3396,15 +3375,13 @@ Editor::trim_region (bool front)
for (list<RegionView*>::const_iterator i = rs.by_layer().begin(); i != rs.by_layer().end(); ++i) {
if (!(*i)->region()->locked()) {
- boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
- XMLNode &before = pl->get_state();
+ (*i)->region()->clear_history ();
if (front) {
(*i)->region()->trim_front (where, this);
} else {
(*i)->region()->trim_end (where, this);
}
- XMLNode &after = pl->get_state();
- _session->add_command(new MementoCommand<Playlist>(*pl.get(), &before, &after));
+ _session->add_command (new StatefulDiffCommand ((*i)->region()));
}
}
@@ -3466,12 +3443,10 @@ Editor::trim_region_to_location (const Location& loc, const char* str)
start = session_frame_to_track_frame (loc.start(), speed);
end = session_frame_to_track_frame (loc.end(), speed);
-
- XMLNode &before = rv->region()->playlist()->get_state();
+
+ rv->region()->clear_history ();
rv->region()->trim_to (start, (end - start), this);
- XMLNode &after = rv->region()->playlist()->get_state();
- _session->add_command(new MementoCommand<Playlist>(
- *(rv->region()->playlist()), &before, &after));
+ _session->add_command(new StatefulDiffCommand (rv->region()));
}
commit_reversible_command ();
@@ -3507,11 +3482,9 @@ Editor::trim_region_to_edit_point ()
speed = tav->get_diskstream()->speed();
}
- XMLNode &before = rv->region()->playlist()->get_state();
+ rv->region()->clear_history ();
rv->region()->trim_end (session_frame_to_track_frame(where, speed), this);
- XMLNode &after = rv->region()->playlist()->get_state();
- _session->add_command(new MementoCommand<Playlist>(
- *(rv->region()->playlist()), &before, &after));
+ _session->add_command(new StatefulDiffCommand (rv->region()));
}
commit_reversible_command ();
@@ -3547,11 +3520,9 @@ Editor::trim_region_from_edit_point ()
speed = tav->get_diskstream()->speed();
}
- XMLNode &before = rv->region()->playlist()->get_state();
+ rv->region()->clear_history ();
rv->region()->trim_front (session_frame_to_track_frame(where, speed), this);
- XMLNode &after = rv->region()->playlist()->get_state();
- _session->add_command(new MementoCommand<Playlist>(
- *(rv->region()->playlist()), &before, &after));
+ _session->add_command(new StatefulDiffCommand (rv->region()));
}
commit_reversible_command ();
@@ -3604,7 +3575,7 @@ Editor::trim_to_region(bool forward)
boost::shared_ptr<Region> region = arv->region();
boost::shared_ptr<Playlist> playlist (region->playlist());
- XMLNode &before = playlist->get_state();
+ region->clear_history ();
if(forward){
@@ -3630,8 +3601,7 @@ Editor::trim_to_region(bool forward)
arv->region_changed (ARDOUR::bounds_change);
}
- XMLNode &after = playlist->get_state();
- _session->add_command(new MementoCommand<Playlist>(*playlist, &before, &after));
+ _session->add_command(new StatefulDiffCommand (region));
}
commit_reversible_command ();
@@ -3658,7 +3628,7 @@ Editor::_freeze_thread (void* arg)
void*
Editor::freeze_thread ()
{
- clicked_routeview->audio_track()->freeze (*current_interthread_info);
+ clicked_routeview->audio_track()->freeze_me (*current_interthread_info);
current_interthread_info->done = true;
return 0;
}
@@ -3747,7 +3717,7 @@ Editor::bounce_range_selection (bool replace, bool enable_processing)
itt.cancel = false;
itt.progress = false;
- XMLNode &before = playlist->get_state();
+ playlist->clear_history ();
boost::shared_ptr<Region> r = rtv->track()->bounce_range (start, start+cnt, itt, enable_processing);
if (replace) {
@@ -3757,8 +3727,7 @@ Editor::bounce_range_selection (bool replace, bool enable_processing)
playlist->add_region (r, start);
}
- XMLNode &after = playlist->get_state();
- _session->add_command (new MementoCommand<Playlist> (*playlist, &before, &after));
+ _session->add_command (new StatefulDiffCommand (playlist));
}
commit_reversible_command ();
@@ -3994,10 +3963,9 @@ Editor::remove_clicked_region ()
boost::shared_ptr<Playlist> playlist = clicked_routeview->playlist();
begin_reversible_command (_("remove region"));
- XMLNode &before = playlist->get_state();
+ playlist->clear_history ();
playlist->remove_region (clicked_regionview->region());
- XMLNode &after = playlist->get_state();
- _session->add_command(new MementoCommand<Playlist>(*playlist, &before, &after));
+ _session->add_command(new StatefulDiffCommand (playlist));
commit_reversible_command ();
}
@@ -4034,7 +4002,7 @@ Editor::remove_selected_regions ()
regions_to_remove.push_back ((*i)->region());
}
- vector<PlaylistState> playlists;
+ vector<boost::shared_ptr<Playlist> > playlists;
for (list<boost::shared_ptr<Region> >::iterator rl = regions_to_remove.begin(); rl != regions_to_remove.end(); ++rl) {
@@ -4045,33 +4013,31 @@ Editor::remove_selected_regions ()
continue;
}
- vector<PlaylistState>::iterator i;
+ vector<boost::shared_ptr<Playlist> >::iterator i;
- //only take state if this is a new playlist.
+ //only prep history if this is a new playlist.
for (i = playlists.begin(); i != playlists.end(); ++i) {
- if ((*i).playlist == playlist) {
+ if ((*i) == playlist) {
break;
}
}
if (i == playlists.end()) {
- PlaylistState before;
- before.playlist = playlist;
- before.before = &playlist->get_state();
-
+ playlist->clear_history ();
playlist->freeze ();
- playlists.push_back(before);
+
+ playlists.push_back (playlist);
}
playlist->remove_region (*rl);
}
- vector<PlaylistState>::iterator pl;
+ vector<boost::shared_ptr<Playlist> >::iterator pl;
for (pl = playlists.begin(); pl != playlists.end(); ++pl) {
- (*pl).playlist->thaw ();
- _session->add_command(new MementoCommand<Playlist>(*(*pl).playlist, (*pl).before, &(*pl).playlist->get_state()));
+ (*pl)->thaw ();
+ _session->add_command(new StatefulDiffCommand (*pl));
}
commit_reversible_command ();
@@ -4351,9 +4317,9 @@ Editor::duplicate_some_regions (RegionSelection& regions, float times)
sigc::connection c = rtv->view()->RegionViewAdded.connect (sigc::mem_fun(*this, &Editor::collect_new_region_view));
playlist = (*i)->region()->playlist();
- XMLNode &before = playlist->get_state();
+ playlist->clear_history ();
playlist->duplicate (r, end_frame + (r->first_frame() - start_frame) + 1, times);
- _session->add_command(new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
+ _session->add_command(new StatefulDiffCommand (playlist));
c.disconnect ();
@@ -4392,10 +4358,9 @@ Editor::duplicate_selection (float times)
if ((playlist = (*i)->playlist()) == 0) {
continue;
}
- XMLNode &before = playlist->get_state();
+ playlist->clear_history ();
playlist->duplicate (*ri, selection->time[clicked_selection].end, times);
- XMLNode &after = playlist->get_state();
- _session->add_command (new MementoCommand<Playlist>(*playlist, &before, &after));
+ _session->add_command (new StatefulDiffCommand (playlist));
++ri;
if (ri == new_regions.end()) {
@@ -4439,10 +4404,9 @@ void
Editor::clear_playlist (boost::shared_ptr<Playlist> playlist)
{
begin_reversible_command (_("clear playlist"));
- XMLNode &before = playlist->get_state();
+ playlist->clear_history ();
playlist->clear ();
- XMLNode &after = playlist->get_state();
- _session->add_command (new MementoCommand<Playlist>(*playlist.get(), &before, &after));
+ _session->add_command (new StatefulDiffCommand (playlist));
commit_reversible_command ();
}
@@ -4476,6 +4440,9 @@ Editor::nudge_track (bool use_edit, bool forwards)
continue;
}
+ /* XXX STATEFUL this won't capture region moves if don't as a stateful diff
+ */
+
XMLNode &before = playlist->get_state();
playlist->nudge_after (start, distance, forwards);
XMLNode &after = playlist->get_state();
@@ -4555,9 +4522,10 @@ Editor::normalize_region ()
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
if (!arv)
continue;
- XMLNode &before = arv->region()->get_state();
+ arv->region()->clear_history ();
arv->audio_region()->normalize_to (spin.get_value());
- _session->add_command (new MementoCommand<Region>(*(arv->region().get()), &before, &arv->region()->get_state()));
+ _session->add_command (new StatefulDiffCommand (arv->region()));
+
}
commit_reversible_command ();
@@ -4588,9 +4556,9 @@ Editor::reset_region_scale_amplitude ()
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
if (!arv)
continue;
- XMLNode &before = arv->region()->get_state();
+ arv->region()->clear_history ();
arv->audio_region()->set_scale_amplitude (1.0f);
- _session->add_command (new MementoCommand<Region>(*(arv->region().get()), &before, &arv->region()->get_state()));
+ _session->add_command (new StatefulDiffCommand (arv->region()));
}
commit_reversible_command ();
@@ -4615,10 +4583,12 @@ Editor::adjust_region_scale_amplitude (bool up)
for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
- if (!arv)
+ if (!arv) {
continue;
- XMLNode &before = arv->region()->get_state();
+ }
+ arv->region()->clear_history ();
+
double fraction = gain_to_slider_position (arv->audio_region()->scale_amplitude ());
if (up) {
@@ -4640,7 +4610,7 @@ Editor::adjust_region_scale_amplitude (bool up)
}
arv->audio_region()->set_scale_amplitude (fraction);
- _session->add_command (new MementoCommand<Region>(*(arv->region().get()), &before, &arv->region()->get_state()));
+ _session->add_command (new StatefulDiffCommand (arv->region()));
}
commit_reversible_command ();
@@ -4786,8 +4756,8 @@ Editor::apply_filter (Filter& filter, string command)
if (arv->audio_region()->apply (filter) == 0) {
- XMLNode &before = playlist->get_state();
-
+ playlist->clear_history ();
+
if (filter.results.empty ()) {
/* no regions returned; remove the old one */
@@ -4809,8 +4779,7 @@ Editor::apply_filter (Filter& filter, string command)
}
- XMLNode &after = playlist->get_state();
- _session->add_command(new MementoCommand<Playlist>(*playlist, &before, &after));
+ _session->add_command(new StatefulDiffCommand (playlist));
} else {
goto out;
}
@@ -4918,10 +4887,9 @@ Editor::toggle_gain_envelope_visibility ()
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
if (arv) {
- XMLNode &before = arv->region()->get_state ();
+ arv->region()->clear_history ();
arv->set_envelope_visible (!arv->envelope_visible());
- XMLNode &after = arv->region()->get_state ();
- _session->add_command (new MementoCommand<Region> (*(arv->region().get()), &before, &after));
+ _session->add_command (new StatefulDiffCommand (arv->region()));
}
}
@@ -4983,10 +4951,9 @@ Editor::set_region_lock_style (Region::PositionLockStyle ps)
_session->begin_reversible_command (_("region lock style"));
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
- XMLNode &before = (*i)->region()->get_state ();
+ (*i)->region()->clear_history ();
(*i)->region()->set_position_lock_style (ps);
- XMLNode &after = (*i)->region()->get_state ();
- _session->add_command (new MementoCommand<Region> (*((*i)->region().get()), &before, &after));
+ _session->add_command (new StatefulDiffCommand ((*i)->region()));
}
_session->commit_reversible_command ();
@@ -5165,14 +5132,15 @@ Editor::toggle_fade_active (bool in)
have_switch = true;
}
- XMLNode &before = region->get_state();
+ region->clear_history ();
+
if (in) {
region->set_fade_in_active (!yn);
} else {
region->set_fade_out_active (!yn);
}
- XMLNode &after = region->get_state();
- _session->add_command(new MementoCommand<AudioRegion>(*region.get(), &before, &after));
+
+ _session->add_command(new StatefulDiffCommand (region));
}
commit_reversible_command ();
@@ -5265,13 +5233,10 @@ Editor::set_fade_in_active (bool yn)
boost::shared_ptr<AudioRegion> ar (tmp->audio_region());
-
- XMLNode &before = ar->get_state();
-
+
+ ar->clear_history ();
ar->set_fade_in_active (yn);
-
- XMLNode &after = ar->get_state();
- _session->add_command(new MementoCommand<AudioRegion>(*ar, &before, &after));
+ _session->add_command (new StatefulDiffCommand (ar));
}
commit_reversible_command ();
@@ -5299,12 +5264,9 @@ Editor::set_fade_out_active (bool yn)
boost::shared_ptr<AudioRegion> ar (tmp->audio_region());
- XMLNode &before = ar->get_state();
-
+ ar->clear_history ();
ar->set_fade_out_active (yn);
-
- XMLNode &after = ar->get_state();
- _session->add_command(new MementoCommand<AudioRegion>(*ar, &before, &after));
+ _session->add_command(new StatefulDiffCommand (ar));
}
commit_reversible_command ();
@@ -5925,7 +5887,7 @@ Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList
nframes64_t pos = r->position();
- XMLNode& before (pl->get_state());
+ pl->clear_history ();
x = positions.begin();
@@ -6007,9 +5969,7 @@ Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList
pl->thaw ();
- XMLNode& after (pl->get_state());
-
- _session->add_command (new MementoCommand<Playlist>(*pl, &before, &after));
+ _session->add_command (new StatefulDiffCommand (pl));
}
void
@@ -6330,6 +6290,9 @@ 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();
if (opt == SplitIntersected) {
diff --git a/gtk2_ardour/editor_timefx.cc b/gtk2_ardour/editor_timefx.cc
index aab6b67658..fcd7e9baf4 100644
--- a/gtk2_ardour/editor_timefx.cc
+++ b/gtk2_ardour/editor_timefx.cc
@@ -26,6 +26,7 @@
#include "pbd/error.h"
#include "pbd/pthread_utils.h"
#include "pbd/memento_command.h"
+#include "pbd/stateful_diff_command.h"
#include <gtkmm2ext/utils.h>
@@ -80,11 +81,10 @@ Editor::time_stretch (RegionSelection& regions, float fraction)
MidiStretch stretch(*_session, request);
begin_reversible_command ("midi stretch");
stretch.run(regions.front()->region());
- XMLNode &before = playlist->get_state();
+ playlist->clear_history ();
playlist->replace_region (regions.front()->region(), stretch.results[0],
regions.front()->region()->position());
- XMLNode &after = playlist->get_state();
- _session->add_command (new MementoCommand<Playlist>(*playlist, &before, &after));
+ _session->add_command (new StatefulDiffCommand (playlist));
commit_reversible_command ();
}
@@ -315,10 +315,9 @@ Editor::do_timefx (TimeFXDialog& dialog)
in_command = true;
}
- XMLNode &before = playlist->get_state();
+ playlist->clear_history ();
playlist->replace_region (region, new_region, region->position());
- XMLNode &after = playlist->get_state();
- _session->add_command (new MementoCommand<Playlist>(*playlist, &before, &after));
+ _session->add_command (new StatefulDiffCommand (playlist));
}
i = tmp;
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc
index 4ea7aba4fa..aec77df8c0 100644
--- a/gtk2_ardour/midi_region_view.cc
+++ b/gtk2_ardour/midi_region_view.cc
@@ -29,6 +29,7 @@
#include <sigc++/signal.h>
#include "pbd/memento_command.h"
+#include "pbd/stateful_diff_command.h"
#include "ardour/playlist.h"
#include "ardour/tempo.h"
@@ -2530,9 +2531,9 @@ MidiRegionView::paste (nframes64_t pos, float times, const MidiCutBuffer& mcb)
trackview.session()->begin_reversible_command (_("paste"));
- XMLNode& before (_region->get_state());
+ _region->clear_history ();
_region->set_length (end_frame, this);
- trackview.session()->add_command (new MementoCommand<Region>(*_region, &before, &_region->get_state()));
+ trackview.session()->add_command (new StatefulDiffCommand (_region));
}
apply_delta ();
diff --git a/gtk2_ardour/midi_streamview.cc b/gtk2_ardour/midi_streamview.cc
index 19c1a53b39..1ca63d0f53 100644
--- a/gtk2_ardour/midi_streamview.cc
+++ b/gtk2_ardour/midi_streamview.cc
@@ -558,10 +558,10 @@ MidiStreamView::update_rec_regions (boost::shared_ptr<MidiModel> data, nframes_t
if (nlen != region->length()) {
- region->freeze ();
+ region->suspend_property_changes ();
region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
region->set_length (start + dur - region->position(), this);
- region->thaw ();
+ region->resume_property_changes ();
if (origlen == 1) {
/* our special initial length */
@@ -622,10 +622,10 @@ MidiStreamView::update_rec_regions (boost::shared_ptr<MidiModel> data, nframes_t
if (region->source_length(0) >= region->position() + nlen) {
- region->freeze ();
+ region->suspend_property_changes ();
region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
region->set_length (nlen, this);
- region->thaw ();
+ region->resume_property_changes ();
if (origlen == 1) {
/* our special initial length */
diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc
index b1adb7c67e..5949541e56 100644
--- a/gtk2_ardour/midi_time_axis.cc
+++ b/gtk2_ardour/midi_time_axis.cc
@@ -31,6 +31,7 @@
#include "pbd/basename.h"
#include "pbd/enumwriter.h"
#include "pbd/memento_command.h"
+#include "pbd/stateful_diff_command.h"
#include <gtkmm2ext/gtk_ui.h>
#include <gtkmm2ext/selector.h>
@@ -966,7 +967,7 @@ MidiTimeAxisView::add_region (nframes64_t pos)
Editor* real_editor = dynamic_cast<Editor*> (&_editor);
real_editor->begin_reversible_command (_("create region"));
- XMLNode &before = playlist()->get_state();
+ playlist()->clear_history ();
framepos_t start = pos;
real_editor->snap_to (start, -1);
@@ -988,8 +989,7 @@ MidiTimeAxisView::add_region (nframes64_t pos)
boost::shared_ptr<Region> region = (RegionFactory::create (src, plist));
playlist()->add_region (region, start);
- XMLNode &after = playlist()->get_state();
- _session->add_command (new MementoCommand<Playlist> (*playlist().get(), &before, &after));
+ _session->add_command (new StatefulDiffCommand (playlist()));
real_editor->commit_reversible_command();
diff --git a/gtk2_ardour/region_gain_line.cc b/gtk2_ardour/region_gain_line.cc
index 827562524e..30e19ec24a 100644
--- a/gtk2_ardour/region_gain_line.cc
+++ b/gtk2_ardour/region_gain_line.cc
@@ -19,6 +19,7 @@
#include "evoral/Curve.hpp"
#include "pbd/memento_command.h"
+#include "pbd/stateful_diff_command.h"
#include "ardour/audioregion.h"
#include "ardour/session.h"
@@ -53,6 +54,8 @@ void
AudioRegionGainLine::start_drag_single (ControlPoint* cp, double x, float fraction)
{
AutomationLine::start_drag_single (cp, x, fraction);
+
+ // XXX Stateful need to capture automation curve data
if (!rv.audio_region()->envelope_active()) {
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(rv.audio_region().get()), &rv.audio_region()->get_state(), 0));
@@ -72,10 +75,9 @@ AudioRegionGainLine::remove_point (ControlPoint& cp)
XMLNode &before = alist->get_state();
if (!rv.audio_region()->envelope_active()) {
- XMLNode &region_before = rv.audio_region()->get_state();
+ rv.audio_region()->clear_history ();
rv.audio_region()->set_envelope_active(true);
- XMLNode &region_after = rv.audio_region()->get_state();
- trackview.session()->add_command(new MementoCommand<AudioRegion>(*(rv.audio_region().get()), &region_before, &region_after));
+ trackview.session()->add_command(new StatefulDiffCommand (rv.audio_region()));
}
alist->erase (mr.start, mr.end);
diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h
index fc5b4255b3..be8d988a41 100644
--- a/libs/ardour/ardour/audio_track.h
+++ b/libs/ardour/ardour/audio_track.h
@@ -49,7 +49,7 @@ class AudioTrack : public Track
int export_stuff (BufferSet& bufs, sframes_t start_frame, nframes_t nframes, bool enable_processing = true);
- void freeze (InterThreadInfo&);
+ void freeze_me (InterThreadInfo&);
void unfreeze ();
boost::shared_ptr<Region> bounce (InterThreadInfo&);
diff --git a/libs/ardour/ardour/automation_list.h b/libs/ardour/ardour/automation_list.h
index 1778771c5f..79acedebf3 100644
--- a/libs/ardour/ardour/automation_list.h
+++ b/libs/ardour/ardour/automation_list.h
@@ -50,7 +50,6 @@ class AutomationList : public PBD::StatefulDestructible, public Evoral::ControlL
AutomationList& operator= (const AutomationList&);
bool operator== (const AutomationList&);
- void freeze();
void thaw ();
void mark_dirty () const;
diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h
index bc636eea83..6f8fda78da 100644
--- a/libs/ardour/ardour/midi_track.h
+++ b/libs/ardour/ardour/midi_track.h
@@ -53,7 +53,7 @@ public:
int export_stuff (BufferSet& bufs, nframes_t nframes, sframes_t end_frame);
- void freeze (InterThreadInfo&);
+ void freeze_me (InterThreadInfo&);
void unfreeze ();
boost::shared_ptr<Region> bounce (InterThreadInfo&);
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h
index 1da185c6f2..09dd8f203c 100644
--- a/libs/ardour/ardour/region.h
+++ b/libs/ardour/ardour/region.h
@@ -93,9 +93,6 @@ class Region
PBD::PropertyList* property_factory (const XMLNode&) const;
- void unlock_property_changes () { _no_property_changes = false; }
- void block_property_changes () { _no_property_changes = true; }
-
virtual ~Region();
/** Note: changing the name of a Region does not constitute an edit */
@@ -156,8 +153,7 @@ class Region
void set_position_lock_style (PositionLockStyle ps);
void recompute_position_from_lock_style ();
- void freeze ();
- void thaw ();
+ void suspend_property_changes ();
bool covers (framepos_t frame) const {
return first_frame() <= frame && frame <= last_frame();
@@ -288,6 +284,7 @@ class Region
protected:
void send_change (const PBD::PropertyChange&);
+ void mid_thaw (const PBD::PropertyChange&);
void trim_to_internal (framepos_t position, framecnt_t length, void *src);
virtual void set_position_internal (framepos_t pos, bool allow_bbt_recompute);
@@ -304,7 +301,6 @@ class Region
virtual void recompute_at_end () = 0;
DataType _type;
- bool _no_property_changes;
PBD::Property<bool> _muted;
PBD::Property<bool> _opaque;
@@ -332,14 +328,11 @@ class Region
framepos_t _last_position;
PositionLockStyle _positional_lock_style;
mutable RegionEditState _first_edit;
- int _frozen;
BBT_Time _bbt_time;
AnalysisFeatureList _transients;
bool _valid_transients;
mutable uint64_t _read_data_count; ///< modified in read()
- PBD::PropertyChange _pending_changed;
uint64_t _last_layer_op; ///< timestamp
- Glib::Mutex _lock;
SourceList _sources;
/** Used when timefx are applied, so we can always use the original source */
SourceList _master_sources;
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index d26c84a795..cf88f2e6bd 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -603,7 +603,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
boost::shared_ptr<Region> write_one_track (AudioTrack&, nframes_t start, nframes_t end,
bool overwrite, std::vector<boost::shared_ptr<Source> >&, InterThreadInfo& wot,
bool enable_processing = true);
- int freeze (InterThreadInfo&);
+ int freeze_all (InterThreadInfo&);
/* session-wide solo/mute/rec-enable */
diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h
index 0ed4b8c70b..eee9f03fe5 100644
--- a/libs/ardour/ardour/track.h
+++ b/libs/ardour/ardour/track.h
@@ -74,7 +74,7 @@ class Track : public Route
FreezeState freeze_state() const;
- virtual void freeze (InterThreadInfo&) = 0;
+ virtual void freeze_me (InterThreadInfo&) = 0;
virtual void unfreeze () = 0;
virtual boost::shared_ptr<Region> bounce (InterThreadInfo&) = 0;
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index f7a1240bdd..1f77964d0d 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -35,7 +35,7 @@
#include "pbd/xml++.h"
#include "pbd/memento_command.h"
#include "pbd/enumwriter.h"
-#include "pbd/stacktrace.h"
+#include "pbd/stateful_diff_command.h"
#include "ardour/analyser.h"
#include "ardour/ardour.h"
@@ -1497,7 +1497,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
// cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
- XMLNode &before = _playlist->get_state();
+ _playlist->clear_history ();
_playlist->freeze ();
for (buffer_position = c->front()->write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
@@ -1537,8 +1537,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
}
_playlist->thaw ();
- XMLNode &after = _playlist->get_state();
- _session.add_command (new MementoCommand<Playlist>(*_playlist, &before, &after));
+ _session.add_command (new StatefulDiffCommand (_playlist));
}
mark_write_completed = true;
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index ebc7a9be66..245b122c18 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -692,7 +692,7 @@ AudioTrack::bounce_range (nframes_t start, nframes_t end, InterThreadInfo& itt,
}
void
-AudioTrack::freeze (InterThreadInfo& itt)
+AudioTrack::freeze_me (InterThreadInfo& itt)
{
vector<boost::shared_ptr<Source> > srcs;
string new_playlist_name;
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index e30a3a5994..abddffc12e 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -589,7 +589,7 @@ AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_
LocaleGuard lg (X_("POSIX"));
boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
- freeze ();
+ suspend_property_changes ();
if (the_playlist) {
the_playlist->freeze ();
@@ -612,7 +612,7 @@ AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_
/* Now find envelope description and other related child items */
- _envelope->freeze ();
+ _envelope->freeze ();
for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
XMLNode *child;
@@ -677,9 +677,9 @@ AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_
}
}
- _envelope->thaw ();
- thaw ();
-
+ _envelope->thaw ();
+ resume_property_changes ();
+
if (send) {
send_change (what_changed);
}
@@ -761,9 +761,9 @@ AudioRegion::set_fade_out_shape (FadeShape shape)
void
AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
{
- _fade_in->freeze ();
+ _fade_in->freeze ();
*_fade_in = *f;
- _fade_in->thaw ();
+ _fade_in->thaw ();
send_change (PropertyChange (Properties::fade_in));
}
@@ -771,7 +771,7 @@ AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
void
AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
{
- _fade_in->freeze ();
+ _fade_in->freeze ();
_fade_in->clear ();
switch (shape) {
@@ -822,15 +822,15 @@ AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
break;
}
- _fade_in->thaw ();
+ _fade_in->thaw ();
}
void
AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
{
- _fade_out->freeze ();
+ _fade_out->freeze ();
*_fade_out = *f;
- _fade_out->thaw ();
+ _fade_out->thaw ();
send_change (PropertyChange (Properties::fade_in));
}
@@ -838,7 +838,7 @@ AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
void
AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
{
- _fade_out->freeze ();
+ _fade_out->freeze ();
_fade_out->clear ();
switch (shape) {
@@ -887,7 +887,7 @@ AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
break;
}
- _fade_out->thaw ();
+ _fade_out->thaw ();
}
void
@@ -977,11 +977,11 @@ AudioRegion::set_default_fades ()
void
AudioRegion::set_default_envelope ()
{
- _envelope->freeze ();
+ _envelope->freeze ();
_envelope->clear ();
_envelope->fast_simple_add (0, 1.0f);
_envelope->fast_simple_add (_length, 1.0f);
- _envelope->thaw ();
+ _envelope->thaw ();
}
void
@@ -991,10 +991,10 @@ AudioRegion::recompute_at_end ()
based on the the existing curve.
*/
- _envelope->freeze ();
+ _envelope->freeze ();
_envelope->truncate_end (_length);
_envelope->set_max_xval (_length);
- _envelope->thaw ();
+ _envelope->thaw ();
if (_fade_in->back()->when > _length) {
_fade_in->extend_to (_length);
diff --git a/libs/ardour/automation_list.cc b/libs/ardour/automation_list.cc
index 479674aee6..92a3d167da 100644
--- a/libs/ardour/automation_list.cc
+++ b/libs/ardour/automation_list.cc
@@ -170,7 +170,7 @@ AutomationList::maybe_signal_changed ()
{
ControlList::maybe_signal_changed ();
- if (!_frozen) {
+ if (!ControlList::frozen()) {
StateChanged (); /* EMIT SIGNAL */
}
}
@@ -208,12 +208,6 @@ AutomationList::stop_touch ()
}
void
-AutomationList::freeze ()
-{
- _frozen++;
-}
-
-void
AutomationList::thaw ()
{
ControlList::thaw();
@@ -313,7 +307,7 @@ AutomationList::deserialize_events (const XMLNode& node)
return -1;
}
- freeze ();
+ ControlList::freeze ();
clear ();
stringstream str (content_node->content());
@@ -344,8 +338,8 @@ AutomationList::deserialize_events (const XMLNode& node)
maybe_signal_changed ();
}
- thaw ();
-
+ ControlList::thaw ();
+
return 0;
}
@@ -377,7 +371,7 @@ AutomationList::set_state (const XMLNode& node, int version)
nframes_t x;
double y;
- freeze ();
+ ControlList::freeze ();
clear ();
for (i = elist.begin(); i != elist.end(); ++i) {
@@ -397,7 +391,7 @@ AutomationList::set_state (const XMLNode& node, int version)
fast_simple_add (x, y);
}
- thaw ();
+ ControlList::thaw ();
return 0;
}
diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc
index ccfaeaa5cd..836fb05c8b 100644
--- a/libs/ardour/midi_diskstream.cc
+++ b/libs/ardour/midi_diskstream.cc
@@ -35,6 +35,7 @@
#include "pbd/xml++.h"
#include "pbd/memento_command.h"
#include "pbd/enumwriter.h"
+#include "pbd/stateful_diff_command.h"
#include "ardour/ardour.h"
#include "ardour/audioengine.h"
@@ -1011,7 +1012,7 @@ MidiDiskstream::transport_stopped (struct tm& /*when*/, time_t /*twhen*/, bool a
// cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
- XMLNode &before = _playlist->get_state();
+ _playlist->clear_history ();
_playlist->freeze ();
uint32_t buffer_position = 0;
@@ -1053,8 +1054,7 @@ MidiDiskstream::transport_stopped (struct tm& /*when*/, time_t /*twhen*/, bool a
}
_playlist->thaw ();
- XMLNode &after = _playlist->get_state();
- _session.add_command (new MementoCommand<Playlist>(*_playlist, &before, &after));
+ _session.add_command (new StatefulDiffCommand(_playlist));
}
diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc
index af66f2f40c..9409e9f143 100644
--- a/libs/ardour/midi_track.cc
+++ b/libs/ardour/midi_track.cc
@@ -556,7 +556,7 @@ MidiTrack::bounce_range (nframes_t /*start*/, nframes_t /*end*/, InterThreadInfo
}
void
-MidiTrack::freeze (InterThreadInfo& /*itt*/)
+MidiTrack::freeze_me (InterThreadInfo& /*itt*/)
{
}
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 6169df8f03..eb21cdcde6 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -855,7 +855,7 @@ Playlist::partition (framepos_t start, framepos_t end, bool cut)
partition_internal (start, end, cut, thawlist);
for (RegionList::iterator i = thawlist.begin(); i != thawlist.end(); ++i) {
- (*i)->thaw ();
+ (*i)->resume_property_changes ();
}
}
@@ -972,7 +972,7 @@ Playlist::partition_internal (framepos_t start, framepos_t end, bool cutting, Re
/* "front" ***** */
- current->freeze ();
+ current->suspend_property_changes ();
thawlist.push_back (current);
current->trim_end (pos2, this);
@@ -1011,7 +1011,7 @@ Playlist::partition_internal (framepos_t start, framepos_t end, bool cutting, Re
/* front ****** */
- current->freeze ();
+ current->suspend_property_changes ();
thawlist.push_back (current);
current->trim_end (pos2, this);
@@ -1054,7 +1054,7 @@ Playlist::partition_internal (framepos_t start, framepos_t end, bool cutting, Re
/* end */
- current->freeze ();
+ current->suspend_property_changes ();
thawlist.push_back (current);
current->trim_front (pos3, this);
} else if (overlap == OverlapExternal) {
@@ -1157,7 +1157,7 @@ Playlist::cut (framepos_t start, framecnt_t cnt, bool result_is_hidden)
partition_internal (start, start+cnt-1, true, thawlist);
for (RegionList::iterator i = thawlist.begin(); i != thawlist.end(); ++i) {
- (*i)->thaw ();
+ (*i)->resume_property_changes();
}
return the_copy;
@@ -2123,15 +2123,15 @@ Playlist::set_state (const XMLNode& node, int version)
if ((region = region_by_id (id))) {
- region->freeze ();
+ region->suspend_property_changes ();
if (region->set_state (*child, version)) {
- region->thaw ();
+ region->resume_property_changes ();
continue;
}
} else if ((region = RegionFactory::create (_session, *child, true)) != 0) {
- region->freeze ();
+ region->suspend_property_changes ();
} else {
error << _("Playlist: cannot create region from XML") << endmsg;
continue;
@@ -2141,7 +2141,7 @@ Playlist::set_state (const XMLNode& node, int version)
// So that layer_op ordering doesn't get screwed up
region->set_last_layer_op( region->layer());
- region->thaw ();
+ region->resume_property_changes ();
}
}
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index f59d076c59..b89ad2854b 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -199,13 +199,11 @@ Region::register_properties ()
Region::Region (Session& s, framepos_t start, framecnt_t length, const string& name, DataType type)
: SessionObject(s, name)
, _type(type)
- , _no_property_changes (true)
, REGION_DEFAULT_STATE(start,length)
, _last_length (length)
, _last_position (0)
, _positional_lock_style(AudioTime)
, _first_edit (EditChangesNothing)
- , _frozen(0)
, _read_data_count(0)
, _last_layer_op(0)
, _pending_explicit_relayer (false)
@@ -219,13 +217,11 @@ Region::Region (Session& s, framepos_t start, framecnt_t length, const string& n
Region::Region (const SourceList& srcs)
: SessionObject(srcs.front()->session(), "toBeRenamed")
, _type (srcs.front()->type())
- , _no_property_changes (true)
, REGION_DEFAULT_STATE(0,0)
, _last_length (0)
, _last_position (0)
, _positional_lock_style (_type == DataType::AUDIO ? AudioTime : MusicTime)
, _first_edit (EditChangesNothing)
- , _frozen (0)
, _valid_transients(false)
, _read_data_count(0)
, _last_layer_op (0)
@@ -251,13 +247,11 @@ Region::Region (const SourceList& srcs)
Region::Region (boost::shared_ptr<const Region> other, frameoffset_t offset, bool offset_relative)
: SessionObject(other->session(), other->name())
, _type (other->data_type())
- , _no_property_changes (true)
, REGION_COPY_STATE (other)
, _last_length (other->_last_length)
, _last_position(other->_last_position) \
, _positional_lock_style(other->_positional_lock_style) \
, _first_edit (EditChangesNothing)
- , _frozen (0)
, _valid_transients(false)
, _read_data_count(0)
, _last_layer_op (0)
@@ -360,13 +354,11 @@ Region::Region (boost::shared_ptr<const Region> other, frameoffset_t offset, boo
Region::Region (boost::shared_ptr<const Region> other, const SourceList& srcs)
: SessionObject (other->session(), other->name())
, _type (srcs.front()->type())
- , _no_property_changes (true)
, REGION_COPY_STATE (other)
, _last_length (other->_last_length)
, _last_position (other->_last_position)
, _positional_lock_style (other->_positional_lock_style)
, _first_edit (EditChangesID)
- , _frozen (0)
, _valid_transients (false)
, _read_data_count (0)
, _last_layer_op (other->_last_layer_op)
@@ -393,13 +385,11 @@ Region::Region (boost::shared_ptr<const Region> other, const SourceList& srcs)
Region::Region (boost::shared_ptr<const Region> other)
: SessionObject(other->session(), other->name())
, _type(other->data_type())
- , _no_property_changes (true)
, REGION_COPY_STATE (other)
, _last_length (other->_last_length)
, _last_position (other->_last_position)
, _positional_lock_style (other->_positional_lock_style)
, _first_edit (EditChangesID)
- , _frozen(0)
, _valid_transients(false)
, _read_data_count(0)
, _last_layer_op(other->_last_layer_op)
@@ -475,7 +465,7 @@ Region::set_length (framecnt_t len, void */*src*/)
maybe_uncopy ();
invalidate_transients ();
- if (!_frozen) {
+ if (!property_changes_suspended()) {
recompute_at_end ();
}
@@ -803,7 +793,7 @@ Region::trim_front (framepos_t new_position, void *src)
}
trim_to_internal (new_position, newlen, src);
- if (!_frozen) {
+ if (!property_changes_suspended()) {
recompute_at_start ();
}
}
@@ -822,7 +812,7 @@ Region::trim_end (framepos_t new_endpoint, void */*src*/)
if (new_endpoint > _position) {
trim_to_internal (_position, new_endpoint - _position + 1, this);
- if (!_frozen) {
+ if (!property_changes_suspended()) {
recompute_at_end ();
}
}
@@ -837,7 +827,7 @@ Region::trim_to (framepos_t position, framecnt_t length, void *src)
trim_to_internal (position, length, src);
- if (!_frozen) {
+ if (!property_changes_suspended()) {
recompute_at_start ();
recompute_at_end ();
}
@@ -890,14 +880,14 @@ Region::trim_to_internal (framepos_t position, framecnt_t length, void */*src*/)
what_changed.add (Properties::start);
}
if (_length != length) {
- if (!_frozen) {
+ if (!property_changes_suspended()) {
_last_length = _length;
}
_length = length;
what_changed.add (Properties::length);
}
if (_position != position) {
- if (!_frozen) {
+ if (!property_changes_suspended()) {
_last_position = _position;
}
_position = position;
@@ -987,7 +977,7 @@ Region::set_sync_position (framepos_t absolute_pos)
if (file_pos != _sync_position) {
_sync_marked = true;
_sync_position = file_pos;
- if (!_frozen) {
+ if (!property_changes_suspended()) {
maybe_uncopy ();
}
send_change (Properties::sync_position);
@@ -999,7 +989,7 @@ Region::clear_sync_position ()
{
if (sync_marked()) {
_sync_marked = false;
- if (!_frozen) {
+ if (!property_changes_suspended()) {
maybe_uncopy ();
}
send_change (Properties::sync_position);
@@ -1229,43 +1219,22 @@ Region::_set_state (const XMLNode& node, int version, PropertyChange& what_chang
}
void
-Region::freeze ()
+Region::suspend_property_changes ()
{
- _frozen++;
+ Stateful::suspend_property_changes ();
_last_length = _length;
_last_position = _position;
}
void
-Region::thaw ()
+Region::mid_thaw (const PropertyChange& what_changed)
{
- PropertyChange what_changed;
-
- {
- Glib::Mutex::Lock lm (_lock);
-
- if (_frozen && --_frozen > 0) {
- return;
- }
-
- if (!_pending_changed.empty()) {
- what_changed = _pending_changed;
- _pending_changed.clear ();
- }
- }
-
- if (what_changed.empty()) {
- return;
- }
-
if (what_changed.contains (Properties::length)) {
if (what_changed.contains (Properties::position)) {
recompute_at_start ();
}
recompute_at_end ();
}
-
- send_change (what_changed);
}
void
@@ -1275,15 +1244,7 @@ Region::send_change (const PropertyChange& what_changed)
return;
}
- {
- Glib::Mutex::Lock lm (_lock);
- if (_frozen) {
- _pending_changed.add (what_changed);
- return;
- }
- }
-
- PropertyChanged (what_changed);
+ Stateful::send_change (what_changed);
if (!_no_property_changes) {
@@ -1294,12 +1255,10 @@ Region::send_change (const PropertyChange& what_changed)
try {
boost::shared_ptr<Region> rptr = shared_from_this();
RegionPropertyChanged (rptr, what_changed);
-
} catch (...) {
/* no shared_ptr available, relax; */
}
}
-
}
void
@@ -1584,16 +1543,26 @@ Region::set_property (const PropertyBase& prop)
} else if (prop == Properties::position_locked.property_id) {
_position_locked = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
} else if (prop == Properties::start.property_id) {
- _start = dynamic_cast<const PropertyTemplate<framepos_t>*>(&prop)->val();
+ framepos_t val = dynamic_cast<const PropertyTemplate<framepos_t>*>(&prop)->val();
+ if (val != _start) {
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("region %1 start changed from %2 to %3",
+ _name.val(), _start, val));
+ _start = val;
+ return true;
+ }
} else if (prop == Properties::length.property_id) {
framecnt_t val = dynamic_cast<const PropertyTemplate<framecnt_t>* > (&prop)->val();
if (val != _length) {
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("region %1 length changed from %2 to %3",
+ _name.val(), _length, val));
_length = val;
return true;
}
} else if (prop == Properties::position.property_id) {
framepos_t val = dynamic_cast<const PropertyTemplate<framepos_t>*>(&prop)->val();
if (val != _position) {
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("region %1 position changed from %2 to %3",
+ _name.val(), _position, val));
_position = val;
return true;
}
diff --git a/libs/ardour/region_factory.cc b/libs/ardour/region_factory.cc
index d2c5fa1b22..3f4af2462c 100644
--- a/libs/ardour/region_factory.cc
+++ b/libs/ardour/region_factory.cc
@@ -67,7 +67,6 @@ RegionFactory::create (boost::shared_ptr<const Region> region)
}
if (ret) {
- ret->unlock_property_changes ();
map_add (ret);
/* pure copy constructor - no property list */
@@ -106,10 +105,7 @@ RegionFactory::create (boost::shared_ptr<Region> region, frameoffset_t offset, c
}
if (ret) {
-
ret->set_properties (plist);
- ret->unlock_property_changes ();
-
map_add (ret);
if (announce) {
@@ -149,10 +145,7 @@ RegionFactory::create (boost::shared_ptr<Region> region, const PropertyList& pli
}
if (ret) {
-
ret->set_properties (plist);
- ret->unlock_property_changes ();
-
map_add (ret);
if (announce) {
@@ -195,8 +188,6 @@ RegionFactory::create (boost::shared_ptr<Region> region, const SourceList& srcs,
if (ret) {
ret->set_properties (plist);
- ret->unlock_property_changes ();
-
map_add (ret);
if (announce) {
@@ -242,8 +233,6 @@ RegionFactory::create (const SourceList& srcs, const PropertyList& plist, bool a
if (ret) {
ret->set_properties (plist);
- ret->unlock_property_changes ();
-
map_add (ret);
if (announce) {
@@ -290,7 +279,6 @@ RegionFactory::create (SourceList& srcs, const XMLNode& node)
if (ret->set_state (node, Stateful::loading_state_version)) {
ret.reset ();
} else {
- ret->unlock_property_changes ();
map_add (ret);
CheckNewRegion (ret);
}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 0c2f12d91d..53c8ea2350 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -3847,7 +3847,7 @@ Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, b
}
int
-Session::freeze (InterThreadInfo& itt)
+Session::freeze_all (InterThreadInfo& itt)
{
shared_ptr<RouteList> r = routes.reader ();
@@ -3859,7 +3859,7 @@ Session::freeze (InterThreadInfo& itt)
/* XXX this is wrong because itt.progress will keep returning to zero at the start
of every track.
*/
- t->freeze (itt);
+ t->freeze_me (itt);
}
}
diff --git a/libs/evoral/evoral/ControlList.hpp b/libs/evoral/evoral/ControlList.hpp
index b4c8590cb6..d68b6a3e5f 100644
--- a/libs/evoral/evoral/ControlList.hpp
+++ b/libs/evoral/evoral/ControlList.hpp
@@ -94,8 +94,9 @@ public:
ControlList& operator= (const ControlList&);
bool operator== (const ControlList&);
- void freeze();
- void thaw ();
+ virtual void freeze();
+ virtual void thaw ();
+ bool frozen() const { return _frozen; }
const Parameter& parameter() const { return _parameter; }
void set_parameter(const Parameter& p) { _parameter = p; }
diff --git a/libs/pbd/pbd/properties.h b/libs/pbd/pbd/properties.h
index 274dfffd9c..8d2f465ebf 100644
--- a/libs/pbd/pbd/properties.h
+++ b/libs/pbd/pbd/properties.h
@@ -122,8 +122,10 @@ protected:
{}
void set (T const& v) {
- _old = _current;
- _have_old = true;
+ if (!_have_old) {
+ _old = _current;
+ _have_old = true;
+ }
_current = v;
}
diff --git a/libs/pbd/pbd/stateful.h b/libs/pbd/pbd/stateful.h
index 78b9eb7b3b..93f353a095 100644
--- a/libs/pbd/pbd/stateful.h
+++ b/libs/pbd/pbd/stateful.h
@@ -82,6 +82,12 @@ class Stateful {
static int current_state_version;
static int loading_state_version;
+ virtual void suspend_property_changes ();
+ virtual void resume_property_changes ();
+
+ void unlock_property_changes () { _no_property_changes = false; }
+ void block_property_changes () { _no_property_changes = true; }
+
protected:
void add_instant_xml (XMLNode&, const sys::path& directory_path);
@@ -100,10 +106,21 @@ class Stateful {
XMLNode *_extra_xml;
XMLNode *_instant_xml;
- PBD::ID _id;
+ PBD::ID _id;
+ int32_t _frozen;
+ bool _no_property_changes;
+ PBD::PropertyChange _pending_changed;
+ Glib::Mutex _lock;
std::string _xml_node_name; ///< name of node to use for this object in XML
OwnedPropertyList* _properties;
+
+ virtual void send_change (const PropertyChange&);
+ /** derived classes can implement this in order to process a property change
+ within thaw() just before send_change() is called.
+ */
+ virtual void mid_thaw (const PropertyChange&) { }
+ bool property_changes_suspended() const { return g_atomic_int_get (&_frozen) > 0; }
};
} // namespace PBD
diff --git a/libs/pbd/stateful.cc b/libs/pbd/stateful.cc
index f2d9f9ee12..1bf8c17d83 100644
--- a/libs/pbd/stateful.cc
+++ b/libs/pbd/stateful.cc
@@ -39,7 +39,9 @@ int Stateful::current_state_version = 0;
int Stateful::loading_state_version = 0;
Stateful::Stateful ()
- : _properties (new OwnedPropertyList)
+ : _frozen (0)
+ , _no_property_changes (false)
+ , _properties (new OwnedPropertyList)
{
_extra_xml = 0;
_instant_xml = 0;
@@ -238,4 +240,52 @@ Stateful::add_property (PropertyBase& s)
_properties->add (s);
}
+void
+Stateful::send_change (const PropertyChange& what_changed)
+{
+ if (what_changed.empty()) {
+ return;
+ }
+
+ {
+ Glib::Mutex::Lock lm (_lock);
+ if (_frozen) {
+ _pending_changed.add (what_changed);
+ return;
+ }
+ }
+
+ PropertyChanged (what_changed);
+}
+
+void
+Stateful::suspend_property_changes ()
+{
+ _frozen++;
+}
+
+void
+Stateful::resume_property_changes ()
+{
+ PropertyChange what_changed;
+
+ {
+ Glib::Mutex::Lock lm (_lock);
+
+ if (_frozen && --_frozen > 0) {
+ return;
+ }
+
+ if (!_pending_changed.empty()) {
+ what_changed = _pending_changed;
+ _pending_changed.clear ();
+ }
+ }
+
+ mid_thaw (what_changed);
+
+ send_change (what_changed);
+}
+
+
} // namespace PBD
diff --git a/libs/surfaces/osc/osc_controllable.cc b/libs/surfaces/osc/osc_controllable.cc
index baf888667e..001eca6f3e 100644
--- a/libs/surfaces/osc/osc_controllable.cc
+++ b/libs/surfaces/osc/osc_controllable.cc
@@ -36,7 +36,7 @@ OSCControllable::OSCControllable (lo_address a, const std::string& p, boost::sha
, addr (a)
, path (p)
{
- c->Changed.connect (changed_connection, boost::bind (&OSCControllable::send_change, this), OSC::instance());
+ c->Changed.connect (changed_connection, boost::bind (&OSCControllable::send_change_message, this), OSC::instance());
}
OSCControllable::~OSCControllable ()
@@ -58,7 +58,7 @@ OSCControllable::set_state (const XMLNode& /*node*/, int /*version*/)
}
void
-OSCControllable::send_change ()
+OSCControllable::send_change_message ()
{
lo_message msg = lo_message_new ();
@@ -84,7 +84,7 @@ OSCRouteControllable::~OSCRouteControllable ()
}
void
-OSCRouteControllable::send_change ()
+OSCRouteControllable::send_change_message ()
{
lo_message msg = lo_message_new ();
diff --git a/libs/surfaces/osc/osc_controllable.h b/libs/surfaces/osc/osc_controllable.h
index 55e2815d35..828c3769f5 100644
--- a/libs/surfaces/osc/osc_controllable.h
+++ b/libs/surfaces/osc/osc_controllable.h
@@ -50,7 +50,7 @@ class OSCControllable : public PBD::Stateful
lo_address addr;
std::string path;
- virtual void send_change ();
+ virtual void send_change_message ();
};
class OSCRouteControllable : public OSCControllable
@@ -67,7 +67,7 @@ class OSCRouteControllable : public OSCControllable
private:
boost::shared_ptr<ARDOUR::Route> _route;
- void send_change ();
+ void send_change_message ();
};
#endif /* __osc_osccontrollable_h__ */