mirror of
https://github.com/cookiengineer/audacity
synced 2025-11-23 17:30:17 +01:00
Cross project copy data loss (#604)
* Need only CloseLock now, not old Lock and Unlock... ... which were for cross-project cut and paste, but they no longer work and we need another solution. So delete much old code. * Fix dangling reference to AudacityProject completely! ... ... in SqliteSampleBlockFactory: retain ONLY the shared pointer to ProjectFileIO, then pass that, not project, to constructors of blocks. completing the work of127696879d* Restore part of the Bug2436 fix... ... which needs the non-default arguments to WaveTrack::EmptyCopy that got lost atd39590cf41So that pasted WaveTracks refer to the correct SampleBlockFactory and database for their project But this is not yet a sufficient re-fix for the bug * Complete the fix for cross-project copies and 2436... ... by duplicating sample blocks, in Sequence.cpp, when it is wrong just to share them. And to determine which case it is, see whether source and destination Sequences have the same sample block factories when doing Copy or Paste. Duplicate when the factories are different. Otherwise sharing is safe and more space efficient. This does the analogous to what DirManager::CopyBlockFile did before commitd39590c.
This commit is contained in:
@@ -22,11 +22,9 @@ class SqliteSampleBlock final : public SampleBlock
|
||||
{
|
||||
public:
|
||||
|
||||
explicit SqliteSampleBlock(AudacityProject *project);
|
||||
explicit SqliteSampleBlock(ProjectFileIO &io);
|
||||
~SqliteSampleBlock() override;
|
||||
|
||||
void Lock() override;
|
||||
void Unlock() override;
|
||||
void CloseLock() override;
|
||||
|
||||
void SetSamples(samplePtr src, size_t numsamples, sampleFormat srcformat);
|
||||
@@ -83,7 +81,7 @@ private:
|
||||
bool mValid;
|
||||
bool mDirty;
|
||||
bool mSilent;
|
||||
int mRefCnt;
|
||||
bool mLocked = false;
|
||||
|
||||
SampleBlockID mBlockID;
|
||||
|
||||
@@ -131,13 +129,11 @@ public:
|
||||
const wxChar **attrs) override;
|
||||
|
||||
private:
|
||||
AudacityProject &mProject;
|
||||
std::shared_ptr<ProjectFileIO> mpIO;
|
||||
};
|
||||
|
||||
SqliteSampleBlockFactory::SqliteSampleBlockFactory( AudacityProject &project )
|
||||
: mProject{ project }
|
||||
, mpIO{ ProjectFileIO::Get(project).shared_from_this() }
|
||||
: mpIO{ ProjectFileIO::Get(project).shared_from_this() }
|
||||
{
|
||||
|
||||
}
|
||||
@@ -147,7 +143,7 @@ SqliteSampleBlockFactory::~SqliteSampleBlockFactory() = default;
|
||||
SampleBlockPtr SqliteSampleBlockFactory::DoCreate(
|
||||
samplePtr src, size_t numsamples, sampleFormat srcformat )
|
||||
{
|
||||
auto sb = std::make_shared<SqliteSampleBlock>(&mProject);
|
||||
auto sb = std::make_shared<SqliteSampleBlock>(*mpIO);
|
||||
sb->SetSamples(src, numsamples, srcformat);
|
||||
return sb;
|
||||
}
|
||||
@@ -155,7 +151,7 @@ SampleBlockPtr SqliteSampleBlockFactory::DoCreate(
|
||||
SampleBlockPtr SqliteSampleBlockFactory::DoCreateSilent(
|
||||
size_t numsamples, sampleFormat srcformat )
|
||||
{
|
||||
auto sb = std::make_shared<SqliteSampleBlock>(&mProject);
|
||||
auto sb = std::make_shared<SqliteSampleBlock>(*mpIO);
|
||||
sb->SetSilent(numsamples, srcformat);
|
||||
return sb;
|
||||
}
|
||||
@@ -164,7 +160,7 @@ SampleBlockPtr SqliteSampleBlockFactory::DoCreateSilent(
|
||||
SampleBlockPtr SqliteSampleBlockFactory::DoCreateFromXML(
|
||||
sampleFormat srcformat, const wxChar **attrs )
|
||||
{
|
||||
auto sb = std::make_shared<SqliteSampleBlock>(&mProject);
|
||||
auto sb = std::make_shared<SqliteSampleBlock>(*mpIO);
|
||||
sb->mSampleFormat = srcformat;
|
||||
|
||||
int found = 0;
|
||||
@@ -230,17 +226,16 @@ SampleBlockPtr SqliteSampleBlockFactory::DoCreateFromXML(
|
||||
|
||||
SampleBlockPtr SqliteSampleBlockFactory::DoGet( SampleBlockID sbid )
|
||||
{
|
||||
auto sb = std::make_shared<SqliteSampleBlock>(&mProject);
|
||||
auto sb = std::make_shared<SqliteSampleBlock>(*mpIO);
|
||||
sb->Load(sbid);
|
||||
return sb;
|
||||
}
|
||||
|
||||
SqliteSampleBlock::SqliteSampleBlock(AudacityProject *project)
|
||||
: mIO(ProjectFileIO::Get(*project))
|
||||
SqliteSampleBlock::SqliteSampleBlock(ProjectFileIO &io)
|
||||
: mIO(io)
|
||||
{
|
||||
mValid = false;
|
||||
mSilent = false;
|
||||
mRefCnt = 0;
|
||||
|
||||
mBlockID = 0;
|
||||
|
||||
@@ -258,7 +253,7 @@ SqliteSampleBlock::SqliteSampleBlock(AudacityProject *project)
|
||||
SqliteSampleBlock::~SqliteSampleBlock()
|
||||
{
|
||||
// See ProjectFileIO::Bypass() for a description of mIO.mBypass
|
||||
if (mRefCnt == 0 && !mIO.ShouldBypass())
|
||||
if (!mLocked && !mIO.ShouldBypass())
|
||||
{
|
||||
// In case Delete throws, don't let an exception escape a destructor,
|
||||
// but we can still enqueue the delayed handler so that an error message
|
||||
@@ -269,19 +264,9 @@ SqliteSampleBlock::~SqliteSampleBlock()
|
||||
}
|
||||
}
|
||||
|
||||
void SqliteSampleBlock::Lock()
|
||||
{
|
||||
++mRefCnt;
|
||||
}
|
||||
|
||||
void SqliteSampleBlock::Unlock()
|
||||
{
|
||||
--mRefCnt;
|
||||
}
|
||||
|
||||
void SqliteSampleBlock::CloseLock()
|
||||
{
|
||||
Lock();
|
||||
mLocked = true;
|
||||
}
|
||||
|
||||
SampleBlockID SqliteSampleBlock::GetBlockID()
|
||||
|
||||
Reference in New Issue
Block a user