Session IS-A history owner
This commit is contained in:
@@ -57,6 +57,7 @@
|
||||
#include "pbd/error.h"
|
||||
#include "pbd/event_loop.h"
|
||||
#include "pbd/file_archive.h"
|
||||
#include "pbd/history_owner.h"
|
||||
#include "pbd/rcu.h"
|
||||
#include "pbd/statefuldestructible.h"
|
||||
#include "pbd/signals.h"
|
||||
@@ -203,10 +204,13 @@ private:
|
||||
};
|
||||
|
||||
/** Ardour Session */
|
||||
class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionList, public SessionEventManager, public TransportAPI, public Temporal::TimeDomainProvider
|
||||
class LIBARDOUR_API Session : public PBD::StatefulDestructible,
|
||||
public PBD::ScopedConnectionList,
|
||||
public SessionEventManager,
|
||||
public TransportAPI,
|
||||
public Temporal::TimeDomainProvider,
|
||||
public PBD::HistoryOwner
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
enum RecordState {
|
||||
Disabled = 0,
|
||||
@@ -404,7 +408,7 @@ public:
|
||||
}
|
||||
|
||||
RecordState record_status() const {
|
||||
return _record_status.load();
|
||||
return _record_status.load();
|
||||
}
|
||||
|
||||
bool actively_recording () const {
|
||||
@@ -1085,70 +1089,6 @@ public:
|
||||
std::string next_undo() const { return _history.next_undo(); }
|
||||
std::string next_redo() const { return _history.next_redo(); }
|
||||
|
||||
/** begin collecting undo information
|
||||
*
|
||||
* This call must always be followed by either
|
||||
* begin_reversible_command() or commit_reversible_command()
|
||||
*
|
||||
* @param cmd_name human readable name for the undo operation
|
||||
*/
|
||||
void begin_reversible_command (const std::string& cmd_name);
|
||||
void begin_reversible_command (GQuark);
|
||||
/** abort an open undo command
|
||||
* This must only be called after begin_reversible_command ()
|
||||
*/
|
||||
void abort_reversible_command ();
|
||||
/** finalize an undo command and commit pending transactions
|
||||
*
|
||||
* This must only be called after begin_reversible_command ()
|
||||
* @param cmd (additional) command to add
|
||||
*/
|
||||
void commit_reversible_command (PBD::Command* cmd = 0);
|
||||
|
||||
void add_command (PBD::Command *const cmd);
|
||||
|
||||
/** create an StatefulDiffCommand from the given object and add it to the stack.
|
||||
*
|
||||
* This function must only be called after begin_reversible_command.
|
||||
* Failing to do so may lead to a crash.
|
||||
*
|
||||
* @param sfd the object to diff
|
||||
* @returns the allocated StatefulDiffCommand (already added via add_command)
|
||||
*/
|
||||
PBD::StatefulDiffCommand* add_stateful_diff_command (std::shared_ptr<PBD::StatefulDestructible> sfd);
|
||||
|
||||
/** @return The list of operations that are currently in progress */
|
||||
std::list<GQuark> const & current_operations () {
|
||||
return _current_trans_quarks;
|
||||
}
|
||||
|
||||
bool operation_in_progress (GQuark) const;
|
||||
|
||||
/**
|
||||
* Test if any undo commands were added since the
|
||||
* call to begin_reversible_command ()
|
||||
*
|
||||
* This is useful to determine if an undoable
|
||||
* action was performed before adding additional
|
||||
* information (e.g. selection changes) to the
|
||||
* undo transaction.
|
||||
*
|
||||
* @return true if undo operation is valid but empty
|
||||
*/
|
||||
bool collected_undo_commands () const {
|
||||
return _current_trans && !_current_trans->empty ();
|
||||
}
|
||||
|
||||
PBD::UndoTransaction* current_reversible_command() { return _current_trans; }
|
||||
|
||||
/**
|
||||
* Abort reversible command IFF no undo changes
|
||||
* have been collected.
|
||||
* @return true if undo operation was aborted.
|
||||
*/
|
||||
bool abort_empty_reversible_command ();
|
||||
|
||||
void add_commands (std::vector<PBD::Command*> const & cmds);
|
||||
|
||||
std::map<PBD::ID,PBD::StatefulDestructible*> registry;
|
||||
|
||||
@@ -2141,15 +2081,6 @@ private:
|
||||
XMLNode* _bundle_xml_node;
|
||||
int load_bundles (XMLNode const &);
|
||||
|
||||
PBD::UndoHistory _history;
|
||||
/** current undo transaction, or 0 */
|
||||
PBD::UndoTransaction* _current_trans;
|
||||
/** GQuarks to describe the reversible commands that are currently in progress.
|
||||
* These may be nested, in which case more recently-started commands are toward
|
||||
* the front of the list.
|
||||
*/
|
||||
std::list<GQuark> _current_trans_quarks;
|
||||
|
||||
int backend_sync_callback (TransportState, samplepos_t);
|
||||
|
||||
void process_rtop (SessionEvent*);
|
||||
|
||||
@@ -195,7 +195,8 @@ Session::Session (AudioEngine &eng,
|
||||
string mix_template,
|
||||
bool unnamed,
|
||||
samplecnt_t sr)
|
||||
: _playlists (new SessionPlaylists)
|
||||
: HistoryOwner (X_("editor"))
|
||||
, _playlists (new SessionPlaylists)
|
||||
, _engine (eng)
|
||||
, process_function (&Session::process_with_events)
|
||||
, _bounce_processing_active (false)
|
||||
@@ -320,7 +321,6 @@ Session::Session (AudioEngine &eng,
|
||||
, no_questions_about_missing_files (false)
|
||||
, _bundles (new BundleList)
|
||||
, _bundle_xml_node (0)
|
||||
, _current_trans (0)
|
||||
, _clicking (false)
|
||||
, _click_rec_only (false)
|
||||
, click_data (0)
|
||||
@@ -7516,12 +7516,6 @@ Session::recently_touched_controllable () const
|
||||
return _recently_touched_controllable.lock ();
|
||||
}
|
||||
|
||||
bool
|
||||
Session::operation_in_progress (GQuark op) const
|
||||
{
|
||||
return (find (_current_trans_quarks.begin(), _current_trans_quarks.end(), op) != _current_trans_quarks.end());
|
||||
}
|
||||
|
||||
void
|
||||
Session::reconnect_ltc_output ()
|
||||
{
|
||||
|
||||
@@ -3337,158 +3337,6 @@ Session::all_route_group() const
|
||||
return *_all_route_group;
|
||||
}
|
||||
|
||||
void
|
||||
Session::add_commands (vector<Command*> const & cmds)
|
||||
{
|
||||
for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
|
||||
add_command (*i);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Session::add_command (Command* const cmd)
|
||||
{
|
||||
assert (_current_trans);
|
||||
if (!_current_trans) {
|
||||
error << "Attempted to add an UNDO command without a current transaction. ignoring command (" << cmd->name() << ")" << endl;
|
||||
return;
|
||||
}
|
||||
DEBUG_TRACE (DEBUG::UndoHistory,
|
||||
string_compose ("Current Undo Transaction %1, adding command: %2\n",
|
||||
_current_trans->name (),
|
||||
cmd->name ()));
|
||||
_current_trans->add_command (cmd);
|
||||
}
|
||||
|
||||
PBD::StatefulDiffCommand*
|
||||
Session::add_stateful_diff_command (std::shared_ptr<PBD::StatefulDestructible> sfd)
|
||||
{
|
||||
PBD::StatefulDiffCommand* cmd = new PBD::StatefulDiffCommand (sfd);
|
||||
add_command (cmd);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void
|
||||
Session::begin_reversible_command (const string& name)
|
||||
{
|
||||
begin_reversible_command (g_quark_from_string (name.c_str ()));
|
||||
}
|
||||
|
||||
/** Begin a reversible command using a GQuark to identify it.
|
||||
* begin_reversible_command() and commit_reversible_command() calls may be nested,
|
||||
* but there must be as many begin...()s as there are commit...()s.
|
||||
*/
|
||||
void
|
||||
Session::begin_reversible_command (GQuark q)
|
||||
{
|
||||
if (_current_trans) {
|
||||
#ifndef NDEBUG
|
||||
cerr << "An UNDO transaction was started while a prior command was underway. Aborting command (" << g_quark_to_string (q) << ") and prior (" << _current_trans->name() << ")" << "\n";
|
||||
#else
|
||||
PBD::warning << "An UNDO transaction was started while a prior command was underway. Aborting command (" << g_quark_to_string (q) << ") and prior (" << _current_trans->name() << ")" << endmsg;
|
||||
#endif
|
||||
abort_reversible_command();
|
||||
assert (false);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If nested begin/commit pairs are used, we create just one UndoTransaction
|
||||
to hold all the commands that are committed. This keeps the order of
|
||||
commands correct in the history.
|
||||
*/
|
||||
|
||||
if (_current_trans == 0) {
|
||||
DEBUG_TRACE (DEBUG::UndoHistory, string_compose ("Begin Reversible Command, new transaction: %1\n", g_quark_to_string (q)));
|
||||
|
||||
/* start a new transaction */
|
||||
assert (_current_trans_quarks.empty ());
|
||||
_current_trans = new UndoTransaction();
|
||||
_current_trans->set_name (g_quark_to_string (q));
|
||||
} else {
|
||||
DEBUG_TRACE (DEBUG::UndoHistory, string_compose ("Begin Reversible Command, current transaction: %1\n", _current_trans->name ()));
|
||||
}
|
||||
|
||||
_current_trans_quarks.push_front (q);
|
||||
}
|
||||
|
||||
void
|
||||
Session::abort_reversible_command ()
|
||||
{
|
||||
if (!_current_trans) {
|
||||
return;
|
||||
}
|
||||
DEBUG_TRACE (DEBUG::UndoHistory, string_compose ("Abort Reversible Command: %1\n", _current_trans->name ()));
|
||||
_current_trans->clear();
|
||||
delete _current_trans;
|
||||
_current_trans = nullptr;
|
||||
_current_trans_quarks.clear();
|
||||
}
|
||||
|
||||
bool
|
||||
Session::abort_empty_reversible_command ()
|
||||
{
|
||||
if (!collected_undo_commands ()) {
|
||||
abort_reversible_command ();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Session::commit_reversible_command (Command *cmd)
|
||||
{
|
||||
assert (_current_trans);
|
||||
assert (!_current_trans_quarks.empty ());
|
||||
if (!_current_trans) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct timeval now;
|
||||
|
||||
if (cmd) {
|
||||
DEBUG_TRACE (DEBUG::UndoHistory,
|
||||
string_compose ("Current Undo Transaction %1, adding command: %2\n",
|
||||
_current_trans->name (),
|
||||
cmd->name ()));
|
||||
_current_trans->add_command (cmd);
|
||||
}
|
||||
|
||||
DEBUG_TRACE (DEBUG::UndoHistory,
|
||||
string_compose ("Commit Reversible Command, current transaction: %1\n",
|
||||
_current_trans->name ()));
|
||||
|
||||
_current_trans_quarks.pop_front ();
|
||||
|
||||
if (!_current_trans_quarks.empty ()) {
|
||||
DEBUG_TRACE (DEBUG::UndoHistory,
|
||||
string_compose ("Commit Reversible Command, transaction is not "
|
||||
"top-level, current transaction: %1\n",
|
||||
_current_trans->name ()));
|
||||
/* the transaction we're committing is not the top-level one */
|
||||
return;
|
||||
}
|
||||
|
||||
if (_current_trans->empty()) {
|
||||
/* no commands were added to the transaction, so just get rid of it */
|
||||
DEBUG_TRACE (DEBUG::UndoHistory,
|
||||
string_compose ("Commit Reversible Command, No commands were "
|
||||
"added to current transaction: %1\n",
|
||||
_current_trans->name ()));
|
||||
delete _current_trans;
|
||||
_current_trans = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
gettimeofday (&now, 0);
|
||||
_current_trans->set_timestamp (now);
|
||||
|
||||
DEBUG_TRACE (DEBUG::UndoHistory,
|
||||
string_compose ("Commit Reversible Command, add to history %1\n",
|
||||
_current_trans->name ()));
|
||||
_history.add (_current_trans);
|
||||
_current_trans = nullptr;
|
||||
}
|
||||
|
||||
static bool
|
||||
accept_all_audio_files (const string& path, void* /*arg*/)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user