Session IS-A history owner

This commit is contained in:
Paul Davis
2024-06-27 21:40:24 -06:00
parent d30c8a1286
commit e8fdbb8cd9
3 changed files with 10 additions and 237 deletions

View File

@@ -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*);

View File

@@ -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 ()
{

View File

@@ -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*/)
{