mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 08:36:32 +01:00
goodbye to MementoCommand for playlists
git-svn-id: svn://localhost/ardour2/branches/3.0@6726 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
c2c224727e
commit
6dde6c5a8f
8 changed files with 108 additions and 57 deletions
|
|
@ -155,6 +155,12 @@ Editor::split_regions_at (nframes64_t where, RegionSelection& regions)
|
||||||
|
|
||||||
boost::shared_ptr<Playlist> pl = (*a)->region()->playlist();
|
boost::shared_ptr<Playlist> pl = (*a)->region()->playlist();
|
||||||
|
|
||||||
|
if (!pl) {
|
||||||
|
cerr << "region " << (*a)->region()->name() << " has no playlist!\n";
|
||||||
|
a = tmp;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!pl->frozen()) {
|
if (!pl->frozen()) {
|
||||||
/* we haven't seen this playlist before */
|
/* we haven't seen this playlist before */
|
||||||
|
|
||||||
|
|
@ -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 {
|
struct PlaylistMapping {
|
||||||
TimeAxisView* tv;
|
TimeAxisView* tv;
|
||||||
boost::shared_ptr<Playlist> pl;
|
boost::shared_ptr<Playlist> pl;
|
||||||
|
|
@ -4057,8 +4052,8 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
|
||||||
|
|
||||||
nframes64_t first_position = max_frames;
|
nframes64_t first_position = max_frames;
|
||||||
|
|
||||||
set<PlaylistState, lt_playlist> freezelist;
|
typedef set<boost::shared_ptr<Playlist> > FreezeList;
|
||||||
pair<set<PlaylistState, lt_playlist>::iterator,bool> insert_result;
|
FreezeList freezelist;
|
||||||
|
|
||||||
/* get ordering correct before we cut/copy */
|
/* 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();
|
boost::shared_ptr<Playlist> pl = (*x)->region()->playlist();
|
||||||
|
|
||||||
if (pl) {
|
if (pl) {
|
||||||
set<PlaylistState, lt_playlist>::iterator fl;
|
FreezeList::iterator fl;
|
||||||
|
|
||||||
//only take state if this is a new playlist.
|
//only take state if this is a new playlist.
|
||||||
for (fl = freezelist.begin(); fl != freezelist.end(); ++fl) {
|
for (fl = freezelist.begin(); fl != freezelist.end(); ++fl) {
|
||||||
if ((*fl).playlist == pl) {
|
if ((*fl) == pl) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fl == freezelist.end()) {
|
if (fl == freezelist.end()) {
|
||||||
PlaylistState before;
|
pl->clear_history();
|
||||||
before.playlist = pl;
|
|
||||||
before.before = &pl->get_state();
|
|
||||||
pl->freeze ();
|
pl->freeze ();
|
||||||
insert_result = freezelist.insert (before);
|
freezelist.insert (pl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4178,9 +4171,9 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
|
||||||
cut_buffer->set (foo);
|
cut_buffer->set (foo);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (set<PlaylistState, lt_playlist>::iterator pl = freezelist.begin(); pl != freezelist.end(); ++pl) {
|
for (FreezeList::iterator pl = freezelist.begin(); pl != freezelist.end(); ++pl) {
|
||||||
(*pl).playlist->thaw ();
|
(*pl)->thaw ();
|
||||||
_session->add_command (new MementoCommand<Playlist>(*(*pl).playlist, (*pl).before, &(*pl).playlist->get_state()));
|
_session->add_command (new StatefulDiffCommand (*pl));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4440,13 +4433,20 @@ Editor::nudge_track (bool use_edit, bool forwards)
|
||||||
continue;
|
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);
|
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 ();
|
commit_reversible_command ();
|
||||||
|
|
@ -6290,10 +6290,8 @@ Editor::insert_time (nframes64_t pos, nframes64_t frames, InsertTimeOption opt,
|
||||||
|
|
||||||
if (pl) {
|
if (pl) {
|
||||||
|
|
||||||
/* XXX STATEFUL this won't capture region motion if done as stateful diff
|
pl->clear_history ();
|
||||||
*/
|
pl->clear_owned_history ();
|
||||||
|
|
||||||
XMLNode &before = pl->get_state();
|
|
||||||
|
|
||||||
if (opt == SplitIntersected) {
|
if (opt == SplitIntersected) {
|
||||||
pl->split (pos);
|
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);
|
pl->shift (pos, frames, (opt == MoveIntersected), ignore_music_glue);
|
||||||
|
|
||||||
XMLNode &after = pl->get_state();
|
vector<StatefulDiffCommand*> cmds;
|
||||||
|
|
||||||
_session->add_command (new MementoCommand<Playlist> (*pl, &before, &after));
|
pl->rdiff (cmds);
|
||||||
|
|
||||||
|
cerr << "Shift generated " << cmds.size() << " sdc's\n";
|
||||||
|
|
||||||
|
for (vector<StatefulDiffCommand*>::iterator c = cmds.begin(); c != cmds.end(); ++c) {
|
||||||
|
_session->add_command (*c);
|
||||||
|
}
|
||||||
|
|
||||||
|
_session->add_command (new StatefulDiffCommand (pl));
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@
|
||||||
#include "pbd/whitespace.h"
|
#include "pbd/whitespace.h"
|
||||||
#include "pbd/memento_command.h"
|
#include "pbd/memento_command.h"
|
||||||
#include "pbd/enumwriter.h"
|
#include "pbd/enumwriter.h"
|
||||||
#include "pbd/stacktrace.h"
|
#include "pbd/stateful_diff_command.h"
|
||||||
|
|
||||||
#include <gtkmm/menu.h>
|
#include <gtkmm/menu.h>
|
||||||
#include <gtkmm/menuitem.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) {
|
switch (op) {
|
||||||
case Cut:
|
case Cut:
|
||||||
if ((what_we_got = playlist->cut (time)) != 0) {
|
if ((what_we_got = playlist->cut (time)) != 0) {
|
||||||
_editor.get_cut_buffer().add (what_we_got);
|
_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;
|
ret = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -1402,7 +1412,14 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
|
||||||
|
|
||||||
case Clear:
|
case Clear:
|
||||||
if ((what_we_got = playlist->cut (time)) != 0) {
|
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 ();
|
what_we_got->release ();
|
||||||
ret = true;
|
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() );
|
pos = session_frame_to_track_frame(pos, get_diskstream()->speed() );
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLNode &before = playlist->get_state();
|
playlist->clear_history ();
|
||||||
playlist->paste (*p, pos, times);
|
playlist->paste (*p, pos, times);
|
||||||
_session->add_command( new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
|
_session->add_command (new StatefulDiffCommand (playlist));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,7 @@ StripSilenceDialog::_detection_done (void* arg)
|
||||||
bool
|
bool
|
||||||
StripSilenceDialog::detection_done ()
|
StripSilenceDialog::detection_done ()
|
||||||
{
|
{
|
||||||
get_window()->set_cursor (Gdk::Cursor (Gdk::LEFT_PTR));
|
// get_window()->set_cursor (Gdk::Cursor (Gdk::LEFT_PTR));
|
||||||
update_silence_rects ();
|
update_silence_rects ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -287,22 +287,15 @@ StripSilenceDialog::detection_thread_work ()
|
||||||
{
|
{
|
||||||
ARDOUR_UI::instance()->register_thread ("gui", pthread_self(), "silence", 32);
|
ARDOUR_UI::instance()->register_thread ("gui", pthread_self(), "silence", 32);
|
||||||
|
|
||||||
cerr << pthread_self() << ": thread exists\n";
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
run_lock.lock ();
|
run_lock.lock ();
|
||||||
cerr << pthread_self() << ": thread notes that its waiting\n";
|
|
||||||
thread_waiting->signal ();
|
thread_waiting->signal ();
|
||||||
cerr << pthread_self() << ": thread waits to run\n";
|
|
||||||
thread_run->wait (run_lock);
|
thread_run->wait (run_lock);
|
||||||
|
|
||||||
cerr << pthread_self() << ": silence thread active\n";
|
|
||||||
|
|
||||||
if (thread_should_exit) {
|
if (thread_should_exit) {
|
||||||
thread_waiting->signal ();
|
thread_waiting->signal ();
|
||||||
run_lock.unlock ();
|
run_lock.unlock ();
|
||||||
cerr << pthread_self() << ": silence thread exited\n";
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -319,7 +312,6 @@ StripSilenceDialog::detection_thread_work ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cerr << pthread_self() << ": silence iteration done\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -349,9 +341,7 @@ StripSilenceDialog::start_silence_detection ()
|
||||||
|
|
||||||
pthread_create (&itt.thread, 0, StripSilenceDialog::_detection_thread_work, this);
|
pthread_create (&itt.thread, 0, StripSilenceDialog::_detection_thread_work, this);
|
||||||
/* wait for it to get started */
|
/* wait for it to get started */
|
||||||
cerr << "Wait for new thread to be ready\n";
|
|
||||||
thread_waiting->wait (run_lock);
|
thread_waiting->wait (run_lock);
|
||||||
cerr << "\tits ready\n";
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
@ -361,11 +351,8 @@ StripSilenceDialog::start_silence_detection ()
|
||||||
current = 0;
|
current = 0;
|
||||||
|
|
||||||
while (!itt.done) {
|
while (!itt.done) {
|
||||||
cerr << "tell existing thread to stop\n";
|
|
||||||
thread_run->signal ();
|
thread_run->signal ();
|
||||||
cerr << "wait for existing thread to stop\n";
|
|
||||||
thread_waiting->wait (run_lock);
|
thread_waiting->wait (run_lock);
|
||||||
cerr << "its stopped\n";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -377,7 +364,6 @@ StripSilenceDialog::start_silence_detection ()
|
||||||
|
|
||||||
/* and start it up (again) */
|
/* and start it up (again) */
|
||||||
|
|
||||||
cerr << "signal thread to run again\n";
|
|
||||||
thread_run->signal ();
|
thread_run->signal ();
|
||||||
|
|
||||||
/* change cursor */
|
/* change cursor */
|
||||||
|
|
@ -398,4 +384,5 @@ StripSilenceDialog::stop_thread ()
|
||||||
thread_should_exit = true;
|
thread_should_exit = true;
|
||||||
thread_run->signal ();
|
thread_run->signal ();
|
||||||
thread_waiting->wait (run_lock);
|
thread_waiting->wait (run_lock);
|
||||||
|
itt.thread = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
#include "pbd/undo.h"
|
#include "pbd/undo.h"
|
||||||
#include "pbd/stateful.h"
|
#include "pbd/stateful.h"
|
||||||
|
#include "pbd/stateful_owner.h"
|
||||||
#include "pbd/statefuldestructible.h"
|
#include "pbd/statefuldestructible.h"
|
||||||
#include "pbd/sequence_property.h"
|
#include "pbd/sequence_property.h"
|
||||||
|
|
||||||
|
|
@ -83,6 +84,7 @@ class RegionListProperty : public PBD::SequenceProperty<std::list<boost::shared_
|
||||||
};
|
};
|
||||||
|
|
||||||
class Playlist : public SessionObject
|
class Playlist : public SessionObject
|
||||||
|
, public PBD::StatefulOwner
|
||||||
, public boost::enable_shared_from_this<Playlist> {
|
, public boost::enable_shared_from_this<Playlist> {
|
||||||
public:
|
public:
|
||||||
typedef std::list<boost::shared_ptr<Region> > RegionList;
|
typedef std::list<boost::shared_ptr<Region> > RegionList;
|
||||||
|
|
@ -97,6 +99,8 @@ class Playlist : public SessionObject
|
||||||
|
|
||||||
bool set_property (const PBD::PropertyBase&);
|
bool set_property (const PBD::PropertyBase&);
|
||||||
void update (const RegionListProperty::ChangeRecord&);
|
void update (const RegionListProperty::ChangeRecord&);
|
||||||
|
void clear_owned_history ();
|
||||||
|
void rdiff (std::vector<PBD::StatefulDiffCommand*>&) const;
|
||||||
|
|
||||||
PBD::PropertyList* property_factory (const XMLNode&) const;
|
PBD::PropertyList* property_factory (const XMLNode&) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,9 @@
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
|
||||||
#include "pbd/failed_constructor.h"
|
#include "pbd/failed_constructor.h"
|
||||||
|
#include "pbd/stateful_diff_command.h"
|
||||||
#include "pbd/stl_delete.h"
|
#include "pbd/stl_delete.h"
|
||||||
#include "pbd/xml++.h"
|
#include "pbd/xml++.h"
|
||||||
#include "pbd/stacktrace.h"
|
|
||||||
|
|
||||||
#include "ardour/debug.h"
|
#include "ardour/debug.h"
|
||||||
#include "ardour/playlist.h"
|
#include "ardour/playlist.h"
|
||||||
|
|
@ -2025,6 +2025,29 @@ Playlist::set_property (const PropertyBase& prop)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
void
|
||||||
Playlist::update (const RegionListProperty::ChangeRecord& change)
|
Playlist::update (const RegionListProperty::ChangeRecord& change)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ public:
|
||||||
|
|
||||||
const gchar*property_name () const { return g_quark_to_string (_property_id); }
|
const gchar*property_name () const { return g_quark_to_string (_property_id); }
|
||||||
PropertyID property_id () const { return _property_id; }
|
PropertyID property_id () const { return _property_id; }
|
||||||
|
bool changed() const { return _have_old; }
|
||||||
|
|
||||||
bool operator==(PropertyID pid) const {
|
bool operator==(PropertyID pid) const {
|
||||||
return _property_id == pid;
|
return _property_id == pid;
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,8 @@ class Stateful {
|
||||||
|
|
||||||
void clear_history ();
|
void clear_history ();
|
||||||
void diff (PropertyList&, PropertyList&) const;
|
void diff (PropertyList&, PropertyList&) const;
|
||||||
|
bool changed() const;
|
||||||
|
|
||||||
/* create a property list from an XMLNode
|
/* create a property list from an XMLNode
|
||||||
*/
|
*/
|
||||||
virtual PropertyList* property_factory(const XMLNode&) const { return 0; }
|
virtual PropertyList* property_factory(const XMLNode&) const { return 0; }
|
||||||
|
|
|
||||||
|
|
@ -287,5 +287,16 @@ Stateful::resume_property_changes ()
|
||||||
send_change (what_changed);
|
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
|
} // namespace PBD
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue