Dispatch read of top-level project XML tags with a table of functions...

... which makes Project.cpp a bit less dependent on some details of other
classes

This puts Tags.cpp back into the big strongly connected component of the
dependency graph.  That will be remedied later when Project.cpp becomes a
low-level file
This commit is contained in:
Paul Licameli 2019-04-29 14:35:52 -04:00
parent a3edf9f6d7
commit 390af96796
15 changed files with 228 additions and 56 deletions

View File

@ -156,6 +156,8 @@ src/Profiler.cpp
src/Profiler.h
src/Project.cpp
src/Project.h
src/ProjectFileIORegistry.cpp
src/ProjectFileIORegistry.h
src/ProjectFSCK.cpp
src/ProjectFSCK.h
src/RealFFTf.cpp

View File

@ -1224,6 +1224,7 @@
5E1512701DB0010C00702E29 /* TrackVRulerControls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E15126B1DB0010C00702E29 /* TrackVRulerControls.cpp */; };
5E16FF4D1FF9CE0B0085E1B8 /* LanguageNames.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5E16FF4C1FF9CE0B0085E1B8 /* LanguageNames.txt */; };
5E18CFF322931D3D00E75250 /* AudacityMessageBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E18CFF222931D3D00E75250 /* AudacityMessageBox.cpp */; };
5E18CFF02291C31000E75250 /* ProjectFileIORegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E18CFEE2291C31000E75250 /* ProjectFileIORegistry.cpp */; };
5E19D655217D51190024D0B1 /* PluginMenus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E19D64C217D51190024D0B1 /* PluginMenus.cpp */; };
5E2A19941EED688500217B58 /* SelectionState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E2A19921EED688500217B58 /* SelectionState.cpp */; };
5E36A0A8217FA2430068E082 /* EditMenus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E36A09F217FA2430068E082 /* EditMenus.cpp */; };
@ -3198,6 +3199,8 @@
5E16FF4C1FF9CE0B0085E1B8 /* LanguageNames.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LanguageNames.txt; path = ../locale/LanguageNames.txt; sourceTree = "<group>"; };
5E18CFF122931CA900E75250 /* AudacityMessageBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudacityMessageBox.h; sourceTree = "<group>"; };
5E18CFF222931D3D00E75250 /* AudacityMessageBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudacityMessageBox.cpp; sourceTree = "<group>"; };
5E18CFEE2291C31000E75250 /* ProjectFileIORegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProjectFileIORegistry.cpp; sourceTree = "<group>"; };
5E18CFEF2291C31000E75250 /* ProjectFileIORegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectFileIORegistry.h; sourceTree = "<group>"; };
5E19D64C217D51190024D0B1 /* PluginMenus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PluginMenus.cpp; path = menus/PluginMenus.cpp; sourceTree = "<group>"; };
5E2A19921EED688500217B58 /* SelectionState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectionState.cpp; sourceTree = "<group>"; };
5E2A19931EED688500217B58 /* SelectionState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectionState.h; sourceTree = "<group>"; };
@ -4353,6 +4356,7 @@
1790B0CE09883BFD008A330A /* Printing.cpp */,
186CCEA30E523C8E00659159 /* Profiler.cpp */,
1790B0D009883BFD008A330A /* Project.cpp */,
5E18CFEE2291C31000E75250 /* ProjectFileIORegistry.cpp */,
5ECF728C228B307E007F2A35 /* ProjectFSCK.cpp */,
28DABFBC0FF19DB100AC7848 /* RealFFTf.cpp */,
EDFCEBA218894B2A00C98E51 /* RealFFTf48x.cpp */,
@ -4465,6 +4469,7 @@
1790B0CF09883BFD008A330A /* Printing.h */,
186CCEA20E523C8D00659159 /* Profiler.h */,
1790B0D109883BFD008A330A /* Project.h */,
5E18CFEF2291C31000E75250 /* ProjectFileIORegistry.h */,
5ECF728B228B307E007F2A35 /* ProjectFSCK.h */,
28DABFBD0FF19DB100AC7848 /* RealFFTf.h */,
EDFCEBA318894B2A00C98E51 /* RealFFTf48x.h */,
@ -8422,6 +8427,7 @@
2897F6F00AB3DB5A003C20C5 /* ControlToolBar.cpp in Sources */,
2897F6F10AB3DB5A003C20C5 /* EditToolBar.cpp in Sources */,
2897F6F20AB3DB5A003C20C5 /* MeterToolBar.cpp in Sources */,
5E18CFF02291C31000E75250 /* ProjectFileIORegistry.cpp in Sources */,
2897F6F30AB3DB5A003C20C5 /* MixerToolBar.cpp in Sources */,
2897F6F40AB3DB5A003C20C5 /* SelectionBar.cpp in Sources */,
2897F6F50AB3DB5A003C20C5 /* ToolBar.cpp in Sources */,

View File

@ -63,6 +63,7 @@ for drawing different aspects of the label and its text box.
#include "AllThemeResources.h"
#include "AColor.h"
#include "Project.h"
#include "ProjectFileIORegistry.h"
#include "TrackArtist.h"
#include "TrackPanel.h"
#include "UndoManager.h"
@ -98,6 +99,15 @@ int LabelTrack::mTextHeight;
int LabelTrack::mFontHeight=-1;
static ProjectFileIORegistry::Entry registerFactory{
wxT( "labeltrack" ),
[]( AudacityProject &project ){
auto &trackFactory = *project.GetTrackFactory();
auto &tracks = *project.GetTracks();
return tracks.Add(trackFactory.NewLabelTrack());
}
};
LabelTrack::Holder TrackFactory::NewLabelTrack()
{
return std::make_shared<LabelTrack>(mDirManager);

View File

@ -207,6 +207,8 @@ audacity_SOURCES = \
Profiler.h \
Project.cpp \
Project.h \
ProjectFileIORegistry.cpp \
ProjectFileIORegistry.h \
ProjectFSCK.cpp \
ProjectFSCK.h \
RealFFTf.cpp \

View File

@ -319,10 +319,11 @@ am__audacity_SOURCES_DIST = BlockFile.cpp BlockFile.h DirManager.cpp \
PitchName.cpp PitchName.h PlatformCompatibility.cpp \
PlatformCompatibility.h PluginManager.cpp PluginManager.h \
Printing.cpp Printing.h Profiler.cpp Profiler.h Project.cpp \
Project.h ProjectFSCK.cpp ProjectFSCK.h RealFFTf.cpp \
RealFFTf.h RealFFTf48x.cpp RealFFTf48x.h RefreshCode.h \
Resample.cpp Resample.h RevisionIdent.h RingBuffer.cpp \
RingBuffer.h Screenshot.cpp Screenshot.h SelectedRegion.cpp \
Project.h ProjectFileIORegistry.cpp ProjectFileIORegistry.h \
ProjectFSCK.cpp ProjectFSCK.h RealFFTf.cpp RealFFTf.h \
RealFFTf48x.cpp RealFFTf48x.h RefreshCode.h Resample.cpp \
Resample.h RevisionIdent.h RingBuffer.cpp RingBuffer.h \
Screenshot.cpp Screenshot.h SelectedRegion.cpp \
SelectedRegion.h SelectionState.cpp SelectionState.h \
Shuttle.cpp Shuttle.h ShuttleGetDefinition.cpp \
ShuttleGetDefinition.h ShuttleGui.cpp ShuttleGui.h \
@ -662,6 +663,7 @@ am_audacity_OBJECTS = $(am__objects_1) audacity-AboutDialog.$(OBJEXT) \
audacity-PlatformCompatibility.$(OBJEXT) \
audacity-PluginManager.$(OBJEXT) audacity-Printing.$(OBJEXT) \
audacity-Profiler.$(OBJEXT) audacity-Project.$(OBJEXT) \
audacity-ProjectFileIORegistry.$(OBJEXT) \
audacity-ProjectFSCK.$(OBJEXT) audacity-RealFFTf.$(OBJEXT) \
audacity-RealFFTf48x.$(OBJEXT) audacity-Resample.$(OBJEXT) \
audacity-RingBuffer.$(OBJEXT) audacity-Screenshot.$(OBJEXT) \
@ -1378,10 +1380,11 @@ audacity_SOURCES = $(libaudacity_la_SOURCES) AboutDialog.cpp \
PitchName.cpp PitchName.h PlatformCompatibility.cpp \
PlatformCompatibility.h PluginManager.cpp PluginManager.h \
Printing.cpp Printing.h Profiler.cpp Profiler.h Project.cpp \
Project.h ProjectFSCK.cpp ProjectFSCK.h RealFFTf.cpp \
RealFFTf.h RealFFTf48x.cpp RealFFTf48x.h RefreshCode.h \
Resample.cpp Resample.h RevisionIdent.h RingBuffer.cpp \
RingBuffer.h Screenshot.cpp Screenshot.h SelectedRegion.cpp \
Project.h ProjectFileIORegistry.cpp ProjectFileIORegistry.h \
ProjectFSCK.cpp ProjectFSCK.h RealFFTf.cpp RealFFTf.h \
RealFFTf48x.cpp RealFFTf48x.h RefreshCode.h Resample.cpp \
Resample.h RevisionIdent.h RingBuffer.cpp RingBuffer.h \
Screenshot.cpp Screenshot.h SelectedRegion.cpp \
SelectedRegion.h SelectionState.cpp SelectionState.h \
Shuttle.cpp Shuttle.h ShuttleGetDefinition.cpp \
ShuttleGetDefinition.h ShuttleGui.cpp ShuttleGui.h \
@ -2553,6 +2556,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-Profiler.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-Project.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-ProjectFSCK.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-ProjectFileIORegistry.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-RealFFTf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-RealFFTf48x.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-Resample.Po@am__quote@
@ -3954,6 +3958,20 @@ audacity-Project.obj: Project.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o audacity-Project.obj `if test -f 'Project.cpp'; then $(CYGPATH_W) 'Project.cpp'; else $(CYGPATH_W) '$(srcdir)/Project.cpp'; fi`
audacity-ProjectFileIORegistry.o: ProjectFileIORegistry.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT audacity-ProjectFileIORegistry.o -MD -MP -MF $(DEPDIR)/audacity-ProjectFileIORegistry.Tpo -c -o audacity-ProjectFileIORegistry.o `test -f 'ProjectFileIORegistry.cpp' || echo '$(srcdir)/'`ProjectFileIORegistry.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/audacity-ProjectFileIORegistry.Tpo $(DEPDIR)/audacity-ProjectFileIORegistry.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ProjectFileIORegistry.cpp' object='audacity-ProjectFileIORegistry.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o audacity-ProjectFileIORegistry.o `test -f 'ProjectFileIORegistry.cpp' || echo '$(srcdir)/'`ProjectFileIORegistry.cpp
audacity-ProjectFileIORegistry.obj: ProjectFileIORegistry.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT audacity-ProjectFileIORegistry.obj -MD -MP -MF $(DEPDIR)/audacity-ProjectFileIORegistry.Tpo -c -o audacity-ProjectFileIORegistry.obj `if test -f 'ProjectFileIORegistry.cpp'; then $(CYGPATH_W) 'ProjectFileIORegistry.cpp'; else $(CYGPATH_W) '$(srcdir)/ProjectFileIORegistry.cpp'; fi`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/audacity-ProjectFileIORegistry.Tpo $(DEPDIR)/audacity-ProjectFileIORegistry.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ProjectFileIORegistry.cpp' object='audacity-ProjectFileIORegistry.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o audacity-ProjectFileIORegistry.obj `if test -f 'ProjectFileIORegistry.cpp'; then $(CYGPATH_W) 'ProjectFileIORegistry.cpp'; else $(CYGPATH_W) '$(srcdir)/ProjectFileIORegistry.cpp'; fi`
audacity-ProjectFSCK.o: ProjectFSCK.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT audacity-ProjectFSCK.o -MD -MP -MF $(DEPDIR)/audacity-ProjectFSCK.Tpo -c -o audacity-ProjectFSCK.o `test -f 'ProjectFSCK.cpp' || echo '$(srcdir)/'`ProjectFSCK.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/audacity-ProjectFSCK.Tpo $(DEPDIR)/audacity-ProjectFSCK.Po

View File

@ -33,6 +33,8 @@
#include "AColor.h"
#include "DirManager.h"
#include "Prefs.h"
#include "Project.h"
#include "ProjectFileIORegistry.h"
#include "InconsistencyException.h"
@ -102,6 +104,15 @@ SONFNS(AutoSave)
static ProjectFileIORegistry::Entry registerFactory{
wxT( "notetrack" ),
[]( AudacityProject &project ){
auto &trackFactory = *project.GetTrackFactory();
auto &tracks = *project.GetTracks();
return tracks.Add(trackFactory.NewNoteTrack());
}
};
NoteTrack::Holder TrackFactory::NewNoteTrack()
{
return std::make_shared<NoteTrack>(mDirManager);

View File

@ -51,6 +51,8 @@ scroll information. It also has some status flags.
#include "Audacity.h" // for USE_* macros
#include "Project.h"
#include "ProjectFileIORegistry.h"
#include "Experimental.h"
#include <stdio.h>
@ -583,6 +585,20 @@ private:
#endif
XMLTagHandler *
AudacityProject::ImportHandlerFactory( AudacityProject &project ) {
auto &ptr = project.mImportXMLTagHandler;
if (!ptr)
ptr =
std::make_unique<ImportXMLTagHandler>( &project );
return ptr.get();
}
ProjectFileIORegistry::Entry
AudacityProject::sImportHandlerFactory{
wxT("import"), ImportHandlerFactory
};
bool ImportXMLTagHandler::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
{
if (wxStrcmp(tag, wxT("import")) || attrs==NULL || (*attrs)==NULL || wxStrcmp(*attrs++, wxT("filename")))
@ -1614,7 +1630,12 @@ bool AudacityProject::IsAudioActive() const
gAudioIO->IsStreamActive(GetAudioIOToken());
}
const Tags *AudacityProject::GetTags()
Tags *AudacityProject::GetTags()
{
return mTags.get();
}
const Tags *AudacityProject::GetTags() const
{
return mTags.get();
}
@ -2744,8 +2765,6 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event)
mTags.reset();
mImportXMLTagHandler.reset();
// Delete all the tracks to free up memory and DirManager references.
mTracks->Clear();
mTracks.reset();
@ -3132,6 +3151,20 @@ auto AudacityProject::ReadProjectFile( const FilePath &fileName )
return { false, bParseSuccess, err, xmlFile.GetErrorStr() };
}
XMLTagHandler *
AudacityProject::RecordingRecoveryFactory( AudacityProject &project ) {
auto &ptr = project.mRecordingRecoveryHandler;
if (!ptr)
ptr =
std::make_unique<RecordingRecoveryHandler>( &project );
return ptr.get();
}
ProjectFileIORegistry::Entry
AudacityProject::sRecoveryFactory{
wxT("recordingrecovery"), RecordingRecoveryFactory
};
// FIXME:? TRAP_ERR This should return a result that is checked.
// See comment in AudacityApp::MRUOpen().
void AudacityProject::OpenFile(const FilePath &fileNameArg, bool addtohistory)
@ -3246,7 +3279,15 @@ void AudacityProject::OpenFile(const FilePath &fileNameArg, bool addtohistory)
return;
}
// The handlers may be created during ReadProjectFile and are not needed
// after this function exits.
auto cleanupHandlers = finally( [this]{
mImportXMLTagHandler.reset();
mRecordingRecoveryHandler.reset();
} );
auto results = ReadProjectFile( fileName );
if ( results.decodeError )
return;
@ -3254,9 +3295,6 @@ void AudacityProject::OpenFile(const FilePath &fileNameArg, bool addtohistory)
const wxString &errorStr = results.errorString;
const bool err = results.trackError;
// Clean up now unused recording recovery handler if any
mRecordingRecoveryHandler.reset();
if (bParseSuccess) {
InitialState();
mTrackPanel->SetFocusedTrack(*GetTracks()->Any().begin());
@ -3278,9 +3316,6 @@ void AudacityProject::OpenFile(const FilePath &fileNameArg, bool addtohistory)
ODManager::UnmarkLoadedODFlag();
if (! closed ) {
// Shouldn't need it any more.
mImportXMLTagHandler.reset();
if ( bParseSuccess ) {
// This is a no-fail:
GetDirManager()->FillBlockfilesCache();
@ -3730,45 +3765,11 @@ bool AudacityProject::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
XMLTagHandler *AudacityProject::HandleXMLChild(const wxChar *tag)
{
if (!wxStrcmp(tag, wxT("tags"))) {
return mTags.get();
}
auto fn = ProjectFileIORegistry::Lookup( tag );
if (fn)
return fn( *this );
// Note that TrackList::Add includes assignment of unique in-session TrackId
// to a reloaded track, though no promise that it equals the id it originally
// had
if (!wxStrcmp(tag, wxT("wavetrack"))) {
return mTracks->Add(mTrackFactory->NewWaveTrack());
}
#ifdef USE_MIDI
if (!wxStrcmp(tag, wxT("notetrack"))) {
return mTracks->Add(mTrackFactory->NewNoteTrack());
}
#endif // USE_MIDI
if (!wxStrcmp(tag, wxT("labeltrack"))) {
return mTracks->Add(mTrackFactory->NewLabelTrack());
}
if (!wxStrcmp(tag, wxT("timetrack"))) {
return mTracks->Add(mTrackFactory->NewTimeTrack());
}
if (!wxStrcmp(tag, wxT("recordingrecovery"))) {
if (!mRecordingRecoveryHandler)
mRecordingRecoveryHandler = std::make_unique<RecordingRecoveryHandler>(this);
return mRecordingRecoveryHandler.get();
}
if (!wxStrcmp(tag, wxT("import"))) {
if (!mImportXMLTagHandler)
mImportXMLTagHandler = std::make_unique<ImportXMLTagHandler>(this);
return mImportXMLTagHandler.get();
}
return NULL;
return nullptr;
}
void AudacityProject::WriteXMLHeader(XMLWriter &xmlFile) const

View File

@ -56,6 +56,7 @@ class Importer;
class ODLock;
class Overlay;
class RecordingRecoveryHandler;
namespace ProjectFileIORegistry{ struct Entry; }
class TrackList;
class Tags;
@ -233,7 +234,8 @@ class AUDACITY_DLL_API AudacityProject final : public wxFrame,
const std::shared_ptr<DirManager> &GetDirManager();
TrackFactory *GetTrackFactory();
AdornedRulerPanel *GetRulerPanel();
const Tags *GetTags();
Tags *GetTags();
const Tags *GetTags() const;
void SetTags( const std::shared_ptr<Tags> &tags );
int GetAudioIOToken() const;
bool IsAudioActive() const;
@ -792,6 +794,12 @@ public:
private:
std::unique_ptr<PlaybackScroller> mPlaybackScroller;
// Declared in this class so that they can have access to private members
static XMLTagHandler *RecordingRecoveryFactory( AudacityProject &project );
static ProjectFileIORegistry::Entry sRecoveryFactory;
static XMLTagHandler *ImportHandlerFactory( AudacityProject &project );
static ProjectFileIORegistry::Entry sImportHandlerFactory;
public:
PlaybackScroller &GetPlaybackScroller() { return *mPlaybackScroller; }
std::shared_ptr<BackgroundCell> GetBackgroundCell() const

View File

@ -0,0 +1,44 @@
/**********************************************************************
Audacity: A Digital Audio Editor
ProjectFileIORegistry.cpp
Paul Licameli
**********************************************************************/
#include "ProjectFileIORegistry.h"
#include "audacity/Types.h"
#include <unordered_map>
#include <wx/string.h>
namespace ProjectFileIORegistry {
namespace {
using TagTable = std::unordered_map< wxString, TagHandlerFactory >;
static TagTable &sTagTable()
{
static TagTable theTable;
return theTable;
}
}
Entry::Entry(
const wxString &tag, const TagHandlerFactory &factory )
{
sTagTable()[ tag ] = factory;
}
TagHandlerFactory Lookup( const wxString &tag )
{
const auto &table = sTagTable();
auto iter = table.find( tag );
if ( iter == table.end() )
return {};
return iter->second;
}
}

View File

@ -0,0 +1,35 @@
/**********************************************************************
Audacity: A Digital Audio Editor
ProjectFileIORegistry.h
Paul Licameli
**********************************************************************/
#ifndef __AUDACITY_PROJECT_FILE_IO_REGISTRY__
#define __AUDACITY_PROJECT_FILE_IO_REGISTRY__
#include <functional>
class AudacityProject;
class XMLTagHandler;
class wxString;
namespace ProjectFileIORegistry {
// Type of functions returning objects that intepret a part of the saved XML
using TagHandlerFactory =
std::function< XMLTagHandler *( AudacityProject & ) >;
// Typically statically constructed
struct Entry{
Entry( const wxString &tag, const TagHandlerFactory &factory );
};
TagHandlerFactory Lookup( const wxString &tag );
}
#endif

View File

@ -45,6 +45,8 @@
#include "FileNames.h"
#include "Prefs.h"
#include "Project.h"
#include "ProjectFileIORegistry.h"
#include "ShuttleGui.h"
#include "TranslatableStringArray.h"
#include "widgets/Grid.h"
@ -224,6 +226,11 @@ static const wxChar *DefaultGenres[] =
wxT("Synthpop")
};
static ProjectFileIORegistry::Entry registerFactory{
wxT( "tags" ),
[]( AudacityProject &project ){ return project.GetTags(); }
};
Tags::Tags()
{
mEditTitle = true;

View File

@ -27,6 +27,7 @@
#include "Envelope.h"
#include "Prefs.h"
#include "Project.h"
#include "ProjectFileIORegistry.h"
#include "TrackArtist.h"
#include "AllThemeResources.h"
@ -39,6 +40,15 @@ std::shared_ptr<TimeTrack> TrackFactory::NewTimeTrack()
return std::make_shared<TimeTrack>(mDirManager, mZoomInfo);
}
static ProjectFileIORegistry::Entry registerFactory{
wxT( "timetrack" ),
[]( AudacityProject &project ){
auto &trackFactory = *project.GetTrackFactory();
auto &tracks = *project.GetTracks();
return tracks.Add(trackFactory.NewTimeTrack());
}
};
TimeTrack::TimeTrack(const std::shared_ptr<DirManager> &projDirManager, const ZoomInfo *zoomInfo):
Track(projDirManager)
, mZoomInfo(zoomInfo)

View File

@ -48,6 +48,7 @@ Track classes.
#include "Spectrum.h"
#include "Project.h"
#include "ProjectFileIORegistry.h"
#include "AudioIO.h"
#include "Prefs.h"
@ -69,6 +70,15 @@ Track classes.
using std::max;
static ProjectFileIORegistry::Entry registerFactory{
wxT( "wavetrack" ),
[]( AudacityProject &project ){
auto &trackFactory = *project.GetTrackFactory();
auto &tracks = *project.GetTracks();
return tracks.Add(trackFactory.NewWaveTrack());
}
};
WaveTrack::Holder TrackFactory::DuplicateWaveTrack(const WaveTrack &orig)
{
return std::static_pointer_cast<WaveTrack>( orig.Duplicate() );

View File

@ -221,6 +221,7 @@
<ClCompile Include="..\..\..\src\Printing.cpp" />
<ClCompile Include="..\..\..\src\Profiler.cpp" />
<ClCompile Include="..\..\..\src\Project.cpp" />
<ClCompile Include="..\..\..\src\ProjectFileIORegistry.cpp" />
<ClCompile Include="..\..\..\src\ProjectFSCK.cpp" />
<ClCompile Include="..\..\..\src\RealFFTf.cpp" />
<ClCompile Include="..\..\..\src\RealFFTf48x.cpp" />
@ -645,6 +646,7 @@
<ClInclude Include="..\..\..\src\Printing.h" />
<ClInclude Include="..\..\..\src\Profiler.h" />
<ClInclude Include="..\..\..\src\Project.h" />
<ClInclude Include="..\..\..\src\ProjectFileIORegistry.h" />
<ClInclude Include="..\..\..\src\ProjectFSCK.h" />
<ClInclude Include="..\..\..\src\RealFFTf.h" />
<ClInclude Include="..\..\..\src\Resample.h" />

View File

@ -260,6 +260,9 @@
<ClCompile Include="..\..\..\src\Project.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\ProjectFileIORegistry.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\ProjectFSCK.cpp">
<Filter>src</Filter>
</ClCompile>
@ -1315,6 +1318,9 @@
<ClInclude Include="..\..\..\src\Project.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\ProjectFileIORegistry.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\ProjectFSCK.h">
<Filter>src</Filter>
</ClInclude>