1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-10 09:27:43 +02:00

DirManager.cpp has fewer dependencies...

... To append files during recording or import, it doesn't depend on the
subclasses of BlockFile, instead taking a factory function to which it gives
the filename; and the choice of factory function is also lifted up through the
level of class Sequence which is just above DirManager.

This frees four files from dependency cycles, including DirManager.cpp but not
yet Sequence.cpp
This commit is contained in:
Paul Licameli 2019-05-15 12:12:37 -04:00
parent ca0fb190e6
commit 0832bccc7b
6 changed files with 85 additions and 138 deletions

View File

@ -49,7 +49,7 @@ AliasedFile s.
#include <wx/dataobj.h>
#include <wx/stattext.h>
#include "BlockFile.h"
#include "blockfile/SimpleBlockFile.h"
#include "DirManager.h"
#include "Prefs.h"
#include "Project.h"
@ -204,11 +204,14 @@ static void RemoveDependencies(AudacityProject *project,
BlockFilePtr newBlockFile;
{
SampleBuffer buffer(len, format);
// We tolerate exceptions from NewSimpleBlockFile and so we
// can allow exceptions from ReadData too
// We tolerate exceptions from NewBlockFile
// and so we can allow exceptions from ReadData too
f->ReadData(buffer.ptr(), format, 0, len);
newBlockFile =
dirManager->NewSimpleBlockFile(buffer.ptr(), len, format);
dirManager->NewBlockFile( [&]( wxFileNameWrapper filePath ) {
return make_blockfile<SimpleBlockFile>(
std::move(filePath), buffer.ptr(), len, format);
} );
}
// Update our hash so we know what block files we've done

View File

@ -85,11 +85,9 @@
#include <sys/stat.h>
#endif
#include "BlockFile.h"
#include "FileNames.h"
#include "blockfile/ODPCMAliasBlockFile.h"
#include "blockfile/ODDecodeBlockFile.h"
#include "InconsistencyException.h"
#include "Project.h"
#include "Prefs.h"
#include "widgets/Warning.h"
#include "widgets/ErrorDialog.h"
@ -1182,71 +1180,17 @@ wxFileNameWrapper DirManager::MakeBlockFileName()
return ret;
}
BlockFilePtr DirManager::NewSimpleBlockFile(
samplePtr sampleData, size_t sampleLen,
sampleFormat format,
bool allowDeferredWrite)
BlockFilePtr DirManager::NewBlockFile( const BlockFileFactory &factory )
{
wxFileNameWrapper filePath{ MakeBlockFileName() };
const wxString fileName{ filePath.GetName() };
auto newBlockFile = make_blockfile<SimpleBlockFile>
(std::move(filePath), sampleData, sampleLen, format, allowDeferredWrite);
auto newBlockFile = factory( std::move(filePath) );
mBlockFileHash[fileName] = newBlockFile;
return newBlockFile;
}
BlockFilePtr DirManager::NewAliasBlockFile(
const FilePath &aliasedFile, sampleCount aliasStart,
size_t aliasLen, int aliasChannel)
{
wxFileNameWrapper filePath{ MakeBlockFileName() };
const wxString fileName = filePath.GetName();
auto newBlockFile = make_blockfile<PCMAliasBlockFile>
(std::move(filePath), wxFileNameWrapper{aliasedFile},
aliasStart, aliasLen, aliasChannel);
mBlockFileHash[fileName]=newBlockFile;
aliasList.push_back(aliasedFile);
return newBlockFile;
}
BlockFilePtr DirManager::NewODAliasBlockFile(
const FilePath &aliasedFile, sampleCount aliasStart,
size_t aliasLen, int aliasChannel)
{
wxFileNameWrapper filePath{ MakeBlockFileName() };
const wxString fileName{ filePath.GetName() };
auto newBlockFile = make_blockfile<ODPCMAliasBlockFile>
(std::move(filePath), wxFileNameWrapper{aliasedFile},
aliasStart, aliasLen, aliasChannel);
mBlockFileHash[fileName]=newBlockFile;
aliasList.push_back(aliasedFile);
return newBlockFile;
}
BlockFilePtr DirManager::NewODDecodeBlockFile(
const FilePath &aliasedFile, sampleCount aliasStart,
size_t aliasLen, int aliasChannel, int decodeType)
{
wxFileNameWrapper filePath{ MakeBlockFileName() };
const wxString fileName{ filePath.GetName() };
auto newBlockFile = make_blockfile<ODDecodeBlockFile>
(std::move(filePath), wxFileNameWrapper{ aliasedFile },
aliasStart, aliasLen, aliasChannel, decodeType);
mBlockFileHash[fileName]=newBlockFile;
aliasList.push_back(aliasedFile); //OD TODO: check to see if we need to remove this when done decoding.
//I don't immediately see a place where aliased files remove when a file is closed.
auto &aliasName = newBlockFile->GetExternalFileName();
if ( aliasName.IsOk() )
//OD TODO: check to see if we need to remove this when done decoding.
//I don't immediately see a place where aliased files remove when a file is closed.
aliasList.push_back( aliasName.GetFullPath() );
return newBlockFile;
}

View File

@ -124,23 +124,8 @@ class PROFILE_DLL_API DirManager final : public XMLTagHandler {
wxLongLong GetFreeDiskSpace();
BlockFilePtr
NewSimpleBlockFile(samplePtr sampleData,
size_t sampleLen,
sampleFormat format,
bool allowDeferredWrite = false);
BlockFilePtr
NewAliasBlockFile( const FilePath &aliasedFile, sampleCount aliasStart,
size_t aliasLen, int aliasChannel);
BlockFilePtr
NewODAliasBlockFile( const FilePath &aliasedFile, sampleCount aliasStart,
size_t aliasLen, int aliasChannel);
BlockFilePtr
NewODDecodeBlockFile( const FilePath &aliasedFile, sampleCount aliasStart,
size_t aliasLen, int aliasChannel, int decodeType);
using BlockFileFactory = std::function< BlockFilePtr( wxFileNameWrapper ) >;
BlockFilePtr NewBlockFile( const BlockFileFactory &factory );
/// Returns true if the blockfile pointed to by b is contained by the DirManager
bool ContainsBlockFile(const BlockFile *b) const;

View File

@ -457,6 +457,17 @@ namespace {
{
return numSamples > wxLL(9223372036854775807);
}
BlockFilePtr NewSimpleBlockFile( DirManager &dm,
samplePtr sampleData, size_t sampleLen,
sampleFormat format,
bool allowDeferredWrite = false)
{
return dm.NewBlockFile( [&]( wxFileNameWrapper filePath ) {
return make_blockfile<SimpleBlockFile>(
std::move(filePath), sampleData, sampleLen, format, allowDeferredWrite);
} );
}
}
void Sequence::Paste(sampleCount s, const Sequence *src)
@ -549,7 +560,7 @@ void Sequence::Paste(sampleCount s, const Sequence *src)
splitPoint, length - splitPoint, true);
auto file =
mDirManager->NewSimpleBlockFile(
NewSimpleBlockFile( *mDirManager,
// largerBlockLen is not more than mMaxSamples...
buffer.ptr(), largerBlockLen.as_size_t(), mSampleFormat);
@ -709,41 +720,6 @@ void Sequence::InsertSilence(sampleCount s0, sampleCount len)
Paste(s0, &sTrack);
}
void Sequence::AppendAlias(const FilePath &fullPath,
sampleCount start,
size_t len, int channel, bool useOD)
// STRONG-GUARANTEE
{
// Quick check to make sure that it doesn't overflow
if (Overflows((mNumSamples.as_double()) + ((double)len)))
THROW_INCONSISTENCY_EXCEPTION;
SeqBlock newBlock(
useOD?
mDirManager->NewODAliasBlockFile(fullPath, start, len, channel):
mDirManager->NewAliasBlockFile(fullPath, start, len, channel),
mNumSamples
);
mBlock.push_back(newBlock);
mNumSamples += len;
}
void Sequence::AppendCoded(const FilePath &fName, sampleCount start,
size_t len, int channel, int decodeType)
// STRONG-GUARANTEE
{
// Quick check to make sure that it doesn't overflow
if (Overflows((mNumSamples.as_double()) + ((double)len)))
THROW_INCONSISTENCY_EXCEPTION;
SeqBlock newBlock(
mDirManager->NewODDecodeBlockFile(fName, start, len, channel, decodeType),
mNumSamples
);
mBlock.push_back(newBlock);
mNumSamples += len;
}
void Sequence::AppendBlock
(DirManager &mDirManager,
BlockArray &mBlock, sampleCount &mNumSamples, const SeqBlock &b)
@ -1267,13 +1243,13 @@ void Sequence::SetSamples(samplePtr buffer, sampleFormat format,
else
ClearSamples(scratch.ptr(), mSampleFormat, bstart, blen);
block.f = mDirManager->NewSimpleBlockFile(
block.f = NewSimpleBlockFile( *mDirManager,
scratch.ptr(), fileLength, mSampleFormat);
}
else {
// Avoid reading the disk when the replacement is total
if (useBuffer)
block.f = mDirManager->NewSimpleBlockFile(
block.f = NewSimpleBlockFile( *mDirManager,
useBuffer, fileLength, mSampleFormat);
else
block.f = make_blockfile<SilentBlockFile>(fileLength);
@ -1599,7 +1575,7 @@ void Sequence::Append(samplePtr buffer, sampleFormat format,
const auto newLastBlockLen = length + addLen;
SeqBlock newLastBlock(
mDirManager->NewSimpleBlockFile(
NewSimpleBlockFile( *mDirManager,
buffer2.ptr(), newLastBlockLen, mSampleFormat,
blockFileLog != NULL
),
@ -1625,12 +1601,12 @@ void Sequence::Append(samplePtr buffer, sampleFormat format,
const auto addedLen = std::min(idealSamples, len);
BlockFilePtr pFile;
if (format == mSampleFormat) {
pFile = mDirManager->NewSimpleBlockFile(
pFile = NewSimpleBlockFile( *mDirManager,
buffer, addedLen, mSampleFormat, blockFileLog != NULL);
}
else {
CopySamples(buffer, format, buffer2.ptr(), mSampleFormat, addedLen);
pFile = mDirManager->NewSimpleBlockFile(
pFile = NewSimpleBlockFile( *mDirManager,
buffer2.ptr(), addedLen, mSampleFormat, blockFileLog != NULL);
}
@ -1673,7 +1649,7 @@ void Sequence::Blockify
int newLen = ((i + 1) * len / num) - offset;
samplePtr bufStart = buffer + (offset * SAMPLE_SIZE(mSampleFormat));
b.f = mDirManager.NewSimpleBlockFile(bufStart, newLen, mSampleFormat);
b.f = NewSimpleBlockFile( mDirManager, bufStart, newLen, mSampleFormat );
list.push_back(b);
}
@ -1735,7 +1711,7 @@ void Sequence::Delete(sampleCount start, sampleCount len)
( pos + len ).as_size_t(), newLen - pos, true);
auto newFile =
mDirManager->NewSimpleBlockFile(scratch.ptr(), newLen, mSampleFormat);
NewSimpleBlockFile( *mDirManager, scratch.ptr(), newLen, mSampleFormat );
// Don't make a duplicate array. We can still give STRONG-GUARANTEE
// if we modify only one block in place.
@ -1779,7 +1755,7 @@ void Sequence::Delete(sampleCount start, sampleCount len)
ensureSampleBufferSize(scratch, mSampleFormat, scratchSize, preBufferLen);
Read(scratch.ptr(), mSampleFormat, preBlock, 0, preBufferLen, true);
auto pFile =
mDirManager->NewSimpleBlockFile(scratch.ptr(), preBufferLen, mSampleFormat);
NewSimpleBlockFile( *mDirManager, scratch.ptr(), preBufferLen, mSampleFormat );
newBlock.push_back(SeqBlock(pFile, preBlock.start));
} else {
@ -1825,7 +1801,7 @@ void Sequence::Delete(sampleCount start, sampleCount len)
auto pos = (start + len - postBlock.start).as_size_t();
Read(scratch.ptr(), mSampleFormat, postBlock, pos, postBufferLen, true);
auto file =
mDirManager->NewSimpleBlockFile(scratch.ptr(), postBufferLen, mSampleFormat);
NewSimpleBlockFile( *mDirManager, scratch.ptr(), postBufferLen, mSampleFormat );
newBlock.push_back(SeqBlock(file, start));
} else {
@ -2016,6 +1992,23 @@ size_t Sequence::GetMaxDiskBlockSize()
return sMaxDiskBlockSize;
}
void Sequence::AppendBlockFile( const BlockFileFactory &factory, size_t len )
// STRONG-GUARANTEE
{
// Quick check to make sure that it doesn't overflow
if (Overflows((mNumSamples.as_double()) + ((double)len)))
THROW_INCONSISTENCY_EXCEPTION;
SeqBlock newBlock(
mDirManager->NewBlockFile( [&]( wxFileNameWrapper filePath ){
return factory( std::move( filePath ), len );
} ),
mNumSamples
);
mBlock.push_back(newBlock);
mNumSamples += len;
}
void Sequence::AppendBlockFile(const BlockFilePtr &blockFile)
{
// We assume blockFile has the correct ref count already

View File

@ -23,6 +23,7 @@ class BlockFile;
using BlockFilePtr = std::shared_ptr<BlockFile>;
class DirManager;
class wxFileNameWrapper;
// This is an internal data structure! For advanced use only.
class SeqBlock {
@ -107,12 +108,12 @@ class PROFILE_DLL_API Sequence final : public XMLTagHandler{
void Append(samplePtr buffer, sampleFormat format, size_t len,
XMLWriter* blockFileLog=NULL);
void Delete(sampleCount start, sampleCount len);
void AppendAlias(const FilePath &fullPath,
sampleCount start,
size_t len, int channel, bool useOD);
void AppendCoded(const FilePath &fName, sampleCount start,
size_t len, int channel, int decodeType);
using BlockFileFactory =
std::function< BlockFilePtr( wxFileNameWrapper, size_t /* len */ ) >;
// An overload of AppendBlockFile that passes the factory to DirManager
// which supplies it with a file name
void AppendBlockFile( const BlockFileFactory &factory, size_t len );
///gets an int with OD flags so that we can determine which ODTasks should be run on this track after save/open, etc.
unsigned int GetODFlags();
@ -121,7 +122,7 @@ class PROFILE_DLL_API Sequence final : public XMLTagHandler{
// sequence. This function is used by the recording log crash recovery
// code, but may be useful for other purposes. The blockfile must already
// be registered within the dir manager hash. This is the case
// when the blockfile is created using DirManager::NewSimpleBlockFile or
// when the blockfile is created using SimpleBlockFile or
// loaded from an XML file via DirManager::HandleXMLTag
void AppendBlockFile(const BlockFilePtr &blockFile);

View File

@ -1448,30 +1448,51 @@ void WaveClip::Append(samplePtr buffer, sampleFormat format,
}
}
#include "blockfile/ODPCMAliasBlockFile.h"
void WaveClip::AppendAlias(const FilePath &fName, sampleCount start,
size_t len, int channel,bool useOD)
// STRONG-GUARANTEE
{
// use STRONG-GUARANTEE
mSequence->AppendAlias(fName, start, len, channel,useOD);
mSequence->AppendBlockFile(
[&]( wxFileNameWrapper filePath, size_t len ) {
return useOD
? make_blockfile<ODPCMAliasBlockFile>(
std::move(filePath), wxFileNameWrapper{ fName },
start, len, channel)
: make_blockfile<PCMAliasBlockFile>(
std::move(filePath), wxFileNameWrapper{ fName },
start, len, channel);
},
len
);
// use NOFAIL-GUARANTEE
UpdateEnvelopeTrackLen();
MarkChanged();
}
#include "blockfile/ODDecodeBlockFile.h"
void WaveClip::AppendCoded(const FilePath &fName, sampleCount start,
size_t len, int channel, int decodeType)
// STRONG-GUARANTEE
{
// use STRONG-GUARANTEE
mSequence->AppendCoded(fName, start, len, channel, decodeType);
mSequence->AppendBlockFile(
[&]( wxFileNameWrapper filePath, size_t len ) {
return make_blockfile<ODDecodeBlockFile>(
std::move(filePath), wxFileNameWrapper{ fName },
start, len, channel, decodeType);
},
len
) ;
// use NOFAIL-GUARANTEE
UpdateEnvelopeTrackLen();
MarkChanged();
}
void WaveClip::Flush()
// NOFAIL-GUARANTEE that the clip will be in a flushed state.
// PARTIAL-GUARANTEE in case of exceptions: