1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-02 00:49:33 +02:00

Use events to break dependency cycle introduced at 3978e8c

This commit is contained in:
Paul Licameli 2020-11-25 12:18:09 -05:00
parent 7a1ca42109
commit 6944ba564c
6 changed files with 40 additions and 16 deletions

View File

@ -21,10 +21,6 @@ Paul Licameli -- split from ProjectFileIO.cpp
#include "FileException.h"
#include "wxFileNameWrapper.h"
#include "./commands/CommandContext.h"
#include "./ProjectAudioManager.h"
// Configuration to provide "safe" connections
static const char *SafeConfig =
"PRAGMA <schema>.locking_mode = SHARED;"
@ -40,9 +36,11 @@ static const char *FastConfig =
DBConnection::DBConnection(
const std::weak_ptr<AudacityProject> &pProject,
const std::shared_ptr<DBConnectionErrors> &pErrors)
const std::shared_ptr<DBConnectionErrors> &pErrors,
CheckpointFailureCallback callback)
: mpProject{ pProject }
, mpErrors{ pErrors }
, mCallback{ std::move(callback) }
{
mDB = nullptr;
mBypass = false;
@ -284,12 +282,6 @@ sqlite3_stmt *DBConnection::GetStatement(enum StatementID id)
}
void OnStopAudio()
{
ProjectAudioManager::Get( *GetActiveProject() ).Stop();
}
void DBConnection::CheckpointThread()
{
// Open another connection to the DB to prevent blocking the main thread.
@ -367,9 +359,10 @@ void DBConnection::CheckpointThread()
throw SimpleMessageBoxException{
message, XO("Warning"), "Error:_Disk_full_or_not_writable" }; },
SimpleGuard<void>{},
[&](AudacityException * e) {
[this](AudacityException * e) {
// This executes in the main thread.
OnStopAudio();
if (mCallback)
mCallback();
if (e)
e->DelayedHandlerAction();
}

View File

@ -14,6 +14,7 @@ Paul Licameli -- split from ProjectFileIO.h
#include <atomic>
#include <condition_variable>
#include <functional>
#include <map>
#include <memory>
#include <mutex>
@ -35,10 +36,14 @@ struct DBConnectionErrors
class DBConnection
{
public:
// Type of function invoked in the main thread after detection of
// checkpoint failure, which might have been in a worker thread
using CheckpointFailureCallback = std::function<void()>;
DBConnection(
const std::weak_ptr<AudacityProject> &pProject,
const std::shared_ptr<DBConnectionErrors> &pErrors);
const std::shared_ptr<DBConnectionErrors> &pErrors,
CheckpointFailureCallback callback);
~DBConnection();
bool Open(const char *fileName);
@ -107,6 +112,7 @@ private:
std::map<enum StatementID, sqlite3_stmt *> mStatements;
std::shared_ptr<DBConnectionErrors> mpErrors;
CheckpointFailureCallback mCallback;
// Bypass transactions if database will be deleted after close
bool mBypass;

View File

@ -65,6 +65,8 @@ ProjectAudioManager::ProjectAudioManager( AudacityProject &project )
{
static ProjectStatus::RegisteredStatusWidthFunction
registerStatusWidthFunction{ StatusWidthFunction };
project.Bind( EVT_CHECKPOINT_FAILURE,
&ProjectAudioManager::OnCheckpointFailure, this );
}
ProjectAudioManager::~ProjectAudioManager() = default;
@ -953,6 +955,12 @@ void ProjectAudioManager::OnSoundActivationThreshold()
}
}
void ProjectAudioManager::OnCheckpointFailure(wxCommandEvent &evt)
{
evt.Skip();
Stop();
}
bool ProjectAudioManager::Playing() const
{
auto gAudioIO = AudioIO::Get();

View File

@ -140,6 +140,8 @@ private:
void OnCommitRecording() override;
void OnSoundActivationThreshold() override;
void OnCheckpointFailure(wxCommandEvent &evt);
AudacityProject &mProject;
std::shared_ptr<TrackList> mCutPreviewTracks;

View File

@ -43,6 +43,7 @@ Paul Licameli split from AudacityProject.cpp
#endif
wxDEFINE_EVENT(EVT_PROJECT_TITLE_CHANGE, wxCommandEvent);
wxDEFINE_EVENT( EVT_CHECKPOINT_FAILURE, wxCommandEvent);
static const int ProjectFileID = ('A' << 24 | 'U' << 16 | 'D' << 8 | 'Y');
static const int ProjectFileVersion = 1;
@ -320,7 +321,7 @@ bool ProjectFileIO::OpenConnection(FilePath fileName /* = {} */)
// Pass weak_ptr to project into DBConnection constructor
curConn = std::make_unique<DBConnection>(
mProject.shared_from_this(), mpErrors);
mProject.shared_from_this(), mpErrors, [this]{ OnCheckpointFailure(); } );
if (!curConn->Open(fileName))
{
curConn.reset();
@ -1423,6 +1424,12 @@ XMLTagHandler *ProjectFileIO::HandleXMLChild(const wxChar *tag)
return nullptr;
}
void ProjectFileIO::OnCheckpointFailure()
{
wxCommandEvent evt{ EVT_CHECKPOINT_FAILURE };
mProject.ProcessEvent(evt);
}
void ProjectFileIO::WriteXMLHeader(XMLWriter &xmlFile) const
{
xmlFile.Write(wxT("<?xml "));
@ -2062,7 +2069,8 @@ bool ProjectFileIO::SaveProject(
// Open the newly created database
Connection newConn = std::make_unique<DBConnection>(
mProject.shared_from_this(), mpErrors);
mProject.shared_from_this(), mpErrors,
[this]{ OnCheckpointFailure(); });
// NOTE: There is a noticeable delay here when dealing with large multi-hour
// projects that we just created. The delay occurs in Open() when it

View File

@ -40,6 +40,11 @@ using Connection = std::unique_ptr<DBConnection>;
using BlockIDs = std::unordered_set<SampleBlockID>;
// An event processed by the project in the main thread after a checkpoint
// failure was detected in a worker thread
wxDECLARE_EXPORTED_EVENT( AUDACITY_DLL_API,
EVT_CHECKPOINT_FAILURE, wxCommandEvent );
///\brief Object associated with a project that manages reading and writing
/// of Audacity project file formats, and autosave
class ProjectFileIO final
@ -177,6 +182,8 @@ public:
DBConnection &GetConnection();
private:
void OnCheckpointFailure();
void WriteXMLHeader(XMLWriter &xmlFile) const;
void WriteXML(XMLWriter &xmlFile, bool recording = false,
const TrackList *tracks = nullptr) /* not override */;