Do orphan block checking differently... (#655)

... Don't have special knowledge of "blockid" in ProjectSerializer, which should
be very low-level.

Instead, we can deserialize the project first, and use the block ids collected
by the sample block factory since f137a1e.
This commit is contained in:
Paul Licameli 2020-09-01 11:54:36 -04:00 committed by GitHub
parent 1e3885730f
commit 92d7ee38e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 30 deletions

View File

@ -1539,10 +1539,8 @@ bool ProjectFileIO::ImportProject(const FilePath &fileName)
}
wxString project;
BlockIDs blockids;
// Decode it while capturing the associated sample blockids
project = ProjectSerializer::Decode(buffer, blockids);
project = ProjectSerializer::Decode(buffer);
if (project.size() == 0)
{
SetError(XO("Unable to decode project document"));
@ -1788,7 +1786,6 @@ bool ProjectFileIO::LoadProject(const FilePath &fileName)
return false;
}
BlockIDs blockids;
wxString project;
wxMemoryBuffer buffer;
bool usedAutosave = true;
@ -1821,8 +1818,7 @@ bool ProjectFileIO::LoadProject(const FilePath &fileName)
}
else
{
// Decode it while capturing the associated sample blockids
project = ProjectSerializer::Decode(buffer, blockids);
project = ProjectSerializer::Decode(buffer);
if (project.empty())
{
SetError(XO("Unable to decode project document"));
@ -1830,15 +1826,6 @@ bool ProjectFileIO::LoadProject(const FilePath &fileName)
return false;
}
// Check for orphans blocks...sets mRecovered if any were deleted
if (blockids.size() > 0)
{
if (!DeleteBlocks(blockids, true))
{
return false;
}
}
XMLFileReader xmlFile;
// Load 'er up
@ -1852,6 +1839,19 @@ bool ProjectFileIO::LoadProject(const FilePath &fileName)
return false;
}
// Check for orphans blocks...sets mRecovered if any were deleted
auto blockids = WaveTrackFactory::Get( mProject )
.GetSampleBlockFactory()
->GetActiveBlockIDs();
if (blockids.size() > 0)
{
if (!DeleteBlocks(blockids, true))
{
return false;
}
}
// Remember if we used autosave or not
if (usedAutosave)
{

View File

@ -383,7 +383,7 @@ bool ProjectSerializer::DictChanged() const
}
// See ProjectFileIO::LoadProject() for explanation of the blockids arg
wxString ProjectSerializer::Decode(const wxMemoryBuffer &buffer, BlockIDs &blockids)
wxString ProjectSerializer::Decode(const wxMemoryBuffer &buffer)
{
wxMemoryInputStream in(buffer.GetData(), buffer.GetDataLen());
@ -549,16 +549,6 @@ wxString ProjectSerializer::Decode(const wxMemoryBuffer &buffer, BlockIDs &block
{
id = ReadUShort( in );
long long val = ReadLongLong( in );
// Look for and save the "blockid" values to support orphan
// block checking. This should be removed once serialization
// and related blocks become part of the same transaction.
const wxString &name = Lookup(id);
if (name.IsSameAs(wxT("blockid")))
{
blockids.insert(val);
}
out.WriteAttr(Lookup(id), val);
}
break;

View File

@ -22,9 +22,6 @@
// From SampleBlock.h
using SampleBlockID = long long;
// From ProjectFileiIO.h
using BlockIDs = std::unordered_set<SampleBlockID>;
///
/// ProjectSerializer
///
@ -69,7 +66,7 @@ public:
bool DictChanged() const;
// Returns empty string if decoding fails
static wxString Decode(const wxMemoryBuffer &buffer, BlockIDs &blockids);
static wxString Decode(const wxMemoryBuffer &buffer);
private:
void WriteName(const wxString & name);

View File

@ -13,6 +13,7 @@ SampleBlock.h
#include <functional>
#include <memory>
#include <unordered_set>
class AudacityProject;
class ProjectFileIO;
@ -133,6 +134,10 @@ public:
sampleFormat srcformat,
const wxChar **attrs);
using SampleBlockIDs = std::unordered_set<SampleBlockID>;
/*! @return ids of all sample blocks created by this factory and still extant */
virtual SampleBlockIDs GetActiveBlockIDs() = 0;
protected:
// The override should throw more informative exceptions on error than the
// default InconsistencyException thrown by Create

View File

@ -129,6 +129,8 @@ public:
~SqliteSampleBlockFactory() override;
SampleBlockIDs GetActiveBlockIDs() override;
SampleBlockPtr DoGet(SampleBlockID sbid) override;
SampleBlockPtr DoCreate(samplePtr src,
@ -171,6 +173,21 @@ SampleBlockPtr SqliteSampleBlockFactory::DoCreate(
return sb;
}
auto SqliteSampleBlockFactory::GetActiveBlockIDs() -> SampleBlockIDs
{
SampleBlockIDs result;
for (auto end = mAllBlocks.end(), it = mAllBlocks.begin(); it != end;) {
if (it->second.expired())
// Tighten up the map
it = mAllBlocks.erase(it);
else {
result.insert( it->first );
++it;
}
}
return result;
}
SampleBlockPtr SqliteSampleBlockFactory::DoCreateSilent(
size_t numsamples, sampleFormat srcformat )
{