1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-21 14:50:06 +02:00

Register factory functions with DirManager to interpret XML tags...

... Removes direct dependency on ODManager.h and some BlockFile subclasses,
but does not yet break any dependency cycles
This commit is contained in:
Paul Licameli 2019-05-14 14:49:47 -04:00
parent 81d4c217e6
commit ca0fb190e6
8 changed files with 113 additions and 53 deletions

View File

@ -86,9 +86,6 @@
#endif #endif
#include "FileNames.h" #include "FileNames.h"
#include "blockfile/LegacyBlockFile.h"
#include "blockfile/LegacyAliasBlockFile.h"
#include "blockfile/SilentBlockFile.h"
#include "blockfile/ODPCMAliasBlockFile.h" #include "blockfile/ODPCMAliasBlockFile.h"
#include "blockfile/ODDecodeBlockFile.h" #include "blockfile/ODDecodeBlockFile.h"
#include "InconsistencyException.h" #include "InconsistencyException.h"
@ -98,8 +95,6 @@
#include "widgets/ErrorDialog.h" #include "widgets/ErrorDialog.h"
#include "widgets/ProgressDialog.h" #include "widgets/ProgressDialog.h"
#include "ondemand/ODManager.h"
#if defined(__WXMAC__) #if defined(__WXMAC__)
#include <mach/mach.h> #include <mach/mach.h>
#include <mach/vm_statistics.h> #include <mach/vm_statistics.h>
@ -1340,6 +1335,24 @@ BlockFilePtr DirManager::CopyBlockFile(const BlockFilePtr &b)
return b2; return b2;
} }
namespace {
using Deserializers =
std::unordered_map< wxString, DirManager::BlockFileDeserializer >;
Deserializers &GetDeserializers()
{
static Deserializers sDeserializers;
return sDeserializers;
}
}
DirManager::RegisteredBlockFileDeserializer::RegisteredBlockFileDeserializer(
const wxString &tag, BlockFileDeserializer function )
{
GetDeserializers()[tag] = function;
}
bool DirManager::HandleXMLTag(const wxChar *tag, const wxChar **attrs) bool DirManager::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
{ {
if( !mLoadingTarget ) if( !mLoadingTarget )
@ -1350,60 +1363,21 @@ bool DirManager::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
BlockFilePtr &target = mLoadingTarget(); BlockFilePtr &target = mLoadingTarget();
mLoadingTarget = nullptr; mLoadingTarget = nullptr;
if (!wxStricmp(tag, wxT("silentblockfile"))) { auto &table = GetDeserializers();
// Silent blocks don't actually have a file associated, so auto iter = table.find( tag );
// we don't need to worry about the hash table at all if ( iter == table.end() )
target = SilentBlockFile::BuildFromXML(*this, attrs);
return true;
}
else if ( !wxStricmp(tag, wxT("simpleblockfile")) )
pBlockFile = SimpleBlockFile::BuildFromXML(*this, attrs);
else if( !wxStricmp(tag, wxT("pcmaliasblockfile")) )
pBlockFile = PCMAliasBlockFile::BuildFromXML(*this, attrs);
else if( !wxStricmp(tag, wxT("odpcmaliasblockfile")) )
{
pBlockFile = ODPCMAliasBlockFile::BuildFromXML(*this, attrs);
//in the case of loading an OD file, we need to schedule the ODManager to begin OD computing of summary
//However, because we don't have access to the track or even the Sequence from this call, we mark a flag
//in the ODMan and check it later.
ODManager::MarkLoadedODFlag();
}
else if( !wxStricmp(tag, wxT("oddecodeblockfile")) )
{
pBlockFile = ODDecodeBlockFile::BuildFromXML(*this, attrs);
ODManager::MarkLoadedODFlag();
}
else if( !wxStricmp(tag, wxT("blockfile")) ||
!wxStricmp(tag, wxT("legacyblockfile")) ) {
// Support Audacity version 1.1.1 project files
int i=0;
bool alias = false;
while(attrs[i]) {
if (!wxStricmp(attrs[i], wxT("alias"))) {
if (wxAtoi(attrs[i+1])==1)
alias = true;
}
i++;
if (attrs[i])
i++;
}
if (alias)
pBlockFile = LegacyAliasBlockFile::BuildFromXML(projFull, attrs);
else
pBlockFile = LegacyBlockFile::BuildFromXML(projFull, attrs,
mLoadingBlockLen,
mLoadingFormat);
}
else
return false; return false;
pBlockFile = iter->second( *this, attrs );
if (!pBlockFile) if (!pBlockFile)
// BuildFromXML failed, or we didn't find a valid blockfile tag. // BuildFromXML failed, or we didn't find a valid blockfile tag.
return false; return false;
if (!pBlockFile->GetFileName().name.IsOk())
// Silent blocks don't actually have a file associated, so
// we don't need to worry about the hash table at all
return true;
// Check the length here so we don't have to do it in each BuildFromXML method. // Check the length here so we don't have to do it in each BuildFromXML method.
if ((mMaxSamples != ~size_t(0)) && // is initialized if ((mMaxSamples != ~size_t(0)) && // is initialized
(pBlockFile->GetLength() > mMaxSamples)) (pBlockFile->GetLength() > mMaxSamples))

View File

@ -68,6 +68,16 @@ class PROFILE_DLL_API DirManager final : public XMLTagHandler {
static void RecursivelyRemove(const FilePaths& filePathArray, int count, int bias, static void RecursivelyRemove(const FilePaths& filePathArray, int count, int bias,
int flags, const wxChar* message = nullptr); int flags, const wxChar* message = nullptr);
// Type of a function that builds a block file, using attributes from XML
using BlockFileDeserializer =
std::function< BlockFilePtr( DirManager&, const wxChar ** ) >;
// Typically a statically declared object,
// registers a function for an XML tag
struct RegisteredBlockFileDeserializer {
RegisteredBlockFileDeserializer(
const wxString &tag, BlockFileDeserializer function );
};
private: private:
// MM: Construct DirManager // MM: Construct DirManager
// Don't call this directly but use Create() instead // Don't call this directly but use Create() instead
@ -162,7 +172,9 @@ class PROFILE_DLL_API DirManager final : public XMLTagHandler {
{ {
mLoadingTarget = loadingTarget; mLoadingTarget = loadingTarget;
} }
sampleFormat GetLoadingFormat() const { return mLoadingFormat; }
void SetLoadingFormat(sampleFormat format) { mLoadingFormat = format; } void SetLoadingFormat(sampleFormat format) { mLoadingFormat = format; }
size_t GetLoadingBlockLength() const { return mLoadingBlockLen; }
void SetLoadingBlockLength(size_t len) { mLoadingBlockLen = len; } void SetLoadingBlockLength(size_t len) { mLoadingBlockLen = len; }
// Note: following affects only the loading of block files when opening a project // Note: following affects only the loading of block files when opening a project

View File

@ -17,6 +17,7 @@
#include <sndfile.h> #include <sndfile.h>
#include "LegacyBlockFile.h" #include "LegacyBlockFile.h"
#include "../DirManager.h"
#include "../FileFormats.h" #include "../FileFormats.h"
#include "../xml/XMLTagHandler.h" #include "../xml/XMLTagHandler.h"
@ -147,3 +148,36 @@ BlockFilePtr LegacyAliasBlockFile::BuildFromXML(const FilePath &projDir, const w
void LegacyAliasBlockFile::Recover(){ void LegacyAliasBlockFile::Recover(){
WriteSummary(); WriteSummary();
} }
static const auto sFactory = []( DirManager &dm, const wxChar **attrs ){
// Support Audacity version 1.1.1 project files
int i=0;
bool alias = false;
while(attrs[i]) {
if (!wxStricmp(attrs[i], wxT("alias"))) {
if (wxAtoi(attrs[i+1])==1)
alias = true;
}
i++;
if (attrs[i])
i++;
}
if (alias)
return LegacyAliasBlockFile::BuildFromXML(
dm.GetProjectDataDir(), attrs);
else
return LegacyBlockFile::BuildFromXML(dm.GetProjectDataDir(), attrs,
dm.GetLoadingBlockLength(),
dm.GetLoadingFormat());
};
static DirManager::RegisteredBlockFileDeserializer sRegistration1 {
"blockfile", sFactory
};
static DirManager::RegisteredBlockFileDeserializer sRegistration2 {
"legacyblockfile", sFactory
};

View File

@ -29,6 +29,7 @@ The summary is eventually computed and written to a file in a background thread.
#include "../DirManager.h" #include "../DirManager.h"
#include "../FileFormats.h" #include "../FileFormats.h"
#include "../ondemand/ODManager.h"
#include "NotYetAvailableException.h" #include "NotYetAvailableException.h"
const int bheaderTagLen = 20; const int bheaderTagLen = 20;
@ -524,3 +525,11 @@ void ODDecodeBlockFile::ChangeAudioFile(wxFileNameWrapper &&newAudioFile)
static DirManager::RegisteredBlockFileDeserializer sRegistration {
"oddecodeblockfile",
[]( DirManager &dm, const wxChar **attrs ){
auto result = ODDecodeBlockFile::BuildFromXML( dm, attrs );
ODManager::MarkLoadedODFlag();
return result;
}
};

View File

@ -561,4 +561,15 @@ void ODPCMAliasBlockFile::UnlockRead() const
mReadDataMutex.Unlock(); mReadDataMutex.Unlock();
} }
static DirManager::RegisteredBlockFileDeserializer sRegistration {
"odpcmaliasblockfile",
[]( DirManager &dm, const wxChar **attrs ){
auto result = ODPCMAliasBlockFile::BuildFromXML( dm, attrs );
//in the case of loading an OD file, we need to schedule the ODManager to begin OD computing of summary
//However, because we don't have access to the track or even the Sequence from this call, we mark a flag
//in the ODMan and check it later.
ODManager::MarkLoadedODFlag();
return result;
}
};

View File

@ -200,3 +200,9 @@ void PCMAliasBlockFile::Recover(void)
WriteSummary(); WriteSummary();
} }
static DirManager::RegisteredBlockFileDeserializer sRegistration {
"pcmaliasblockfile",
[]( DirManager &dm, const wxChar **attrs ){
return PCMAliasBlockFile::BuildFromXML( dm, attrs );
}
};

View File

@ -12,6 +12,7 @@
#include "SilentBlockFile.h" #include "SilentBlockFile.h"
#include "../FileFormats.h" #include "../FileFormats.h"
#include "../DirManager.h"
#include "../xml/XMLTagHandler.h" #include "../xml/XMLTagHandler.h"
SilentBlockFile::SilentBlockFile(size_t sampleLen): SilentBlockFile::SilentBlockFile(size_t sampleLen):
@ -91,3 +92,9 @@ auto SilentBlockFile::GetSpaceUsage() const -> DiskByteCount
return 0; return 0;
} }
static DirManager::RegisteredBlockFileDeserializer sRegistration {
"silentblockfile",
[]( DirManager &dm, const wxChar **attrs ){
return SilentBlockFile::BuildFromXML( dm, attrs );
}
};

View File

@ -610,3 +610,10 @@ bool SimpleBlockFile::GetCache()
return false; return false;
#endif #endif
} }
static DirManager::RegisteredBlockFileDeserializer sRegistration {
"simpleblockfile",
[]( DirManager &dm, const wxChar **attrs ){
return SimpleBlockFile::BuildFromXML( dm, attrs );
}
};