mirror of
https://github.com/cookiengineer/audacity
synced 2025-07-25 08:58:06 +02:00
Some machinery to add more menu handler object classes...
...without adding linkage dependencies to AudacityProject constructor
This commit is contained in:
parent
b7f35609ad
commit
280e8d9bac
@ -171,8 +171,23 @@ static void AddEffectMenuItemGroup(
|
||||
|
||||
constexpr size_t kAlignLabelsCount = 5;
|
||||
|
||||
static const AudacityProject::RegisteredAttachedObjectFactory factory{ []{
|
||||
return std::make_unique< MenuCommandHandler >();
|
||||
} };
|
||||
|
||||
PrefsListener::~PrefsListener()
|
||||
{
|
||||
}
|
||||
|
||||
void PrefsListener::UpdatePrefs()
|
||||
{
|
||||
}
|
||||
|
||||
MenuCommandHandler &GetMenuCommandHandler(AudacityProject &project)
|
||||
{ return *project.mMenuCommandHandler; }
|
||||
{
|
||||
return static_cast<MenuCommandHandler&>(
|
||||
project.GetAttachedObject( factory ) );
|
||||
}
|
||||
|
||||
MenuManager &GetMenuManager(AudacityProject &project)
|
||||
{ return *project.mMenuManager; }
|
||||
|
10
src/Menus.h
10
src/Menus.h
@ -35,8 +35,16 @@ enum EffectType : int;
|
||||
typedef wxString PluginID;
|
||||
typedef wxArrayString PluginIDList;
|
||||
|
||||
class PrefsListener
|
||||
{
|
||||
public:
|
||||
virtual ~PrefsListener();
|
||||
virtual void UpdatePrefs(); // default is no-op
|
||||
};
|
||||
|
||||
struct MenuCommandHandler final
|
||||
: public CommandHandlerObject // MUST be the first base class!
|
||||
, public PrefsListener
|
||||
{
|
||||
MenuCommandHandler();
|
||||
~MenuCommandHandler();
|
||||
@ -592,7 +600,7 @@ public:
|
||||
bool mCircularTrackNavigation{};
|
||||
wxLongLong mLastSelectionAdjustment;
|
||||
|
||||
void UpdatePrefs();
|
||||
void UpdatePrefs() override;
|
||||
};
|
||||
|
||||
class MenuCreator
|
||||
|
@ -98,6 +98,7 @@ scroll information. It also has some status flags.
|
||||
#include "Dependencies.h"
|
||||
#include "Diags.h"
|
||||
#include "HistoryWindow.h"
|
||||
#include "InconsistencyException.h"
|
||||
#include "Lyrics.h"
|
||||
#include "LyricsWindow.h"
|
||||
#include "MixerBoard.h"
|
||||
@ -888,6 +889,64 @@ static wxString CreateUniqueName()
|
||||
wxString::Format(wxT(" N-%i"), ++count);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
#if 0
|
||||
std::mutex sObjectFactoriesMutex;
|
||||
struct ObjectFactorySetLocker : private std::unique_lock< std::mutex >
|
||||
{
|
||||
ObjectFactorySetLocker()
|
||||
: std::unique_lock< std::mutex > { sObjectFactoriesMutex }
|
||||
{}
|
||||
};
|
||||
#else
|
||||
struct ObjectFactorySetLocker {};
|
||||
#endif
|
||||
|
||||
std::vector<AudacityProject::AttachedObjectFactory> &sObjectFactories()
|
||||
{
|
||||
// Put this declaration inside a function to avoid problems of undefined
|
||||
// sequence of initialization of file-scope statics in different
|
||||
// compilation units.
|
||||
// Note that mutex locking is not needed for constructing a static object
|
||||
// in C++11:
|
||||
//https://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables
|
||||
static std::vector<AudacityProject::AttachedObjectFactory> factories;
|
||||
return factories;
|
||||
}
|
||||
}
|
||||
|
||||
AudacityProject::
|
||||
RegisteredAttachedObjectFactory::RegisteredAttachedObjectFactory(
|
||||
const AttachedObjectFactory &factory )
|
||||
{
|
||||
ObjectFactorySetLocker locker;
|
||||
mIndex = sObjectFactories().size();
|
||||
sObjectFactories().push_back( factory );
|
||||
|
||||
// In case registration happens while projects exist:
|
||||
for (const auto &pProject : gAudacityProjects) {
|
||||
if (pProject->mAttachedObjects.size() == mIndex) {
|
||||
auto pObject = factory();
|
||||
wxASSERT( pObject );
|
||||
pProject->mAttachedObjects.push_back( std::move( pObject ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AudacityProject::
|
||||
AttachedObject &AudacityProject::GetAttachedObject(
|
||||
const RegisteredAttachedObjectFactory &factory )
|
||||
{
|
||||
ObjectFactorySetLocker locker;
|
||||
if ( factory.mIndex >= mAttachedObjects.size() )
|
||||
THROW_INCONSISTENCY_EXCEPTION;
|
||||
auto &pObject = mAttachedObjects[ factory.mIndex ];
|
||||
if ( !pObject )
|
||||
THROW_INCONSISTENCY_EXCEPTION;
|
||||
return *pObject;
|
||||
}
|
||||
|
||||
enum {
|
||||
FirstID = 1000,
|
||||
|
||||
@ -982,7 +1041,15 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
|
||||
// Initialize view info (shared with TrackPanel)
|
||||
//
|
||||
|
||||
mMenuCommandHandler = std::make_unique<MenuCommandHandler>();
|
||||
{
|
||||
ObjectFactorySetLocker locker;
|
||||
for (const auto &factory : sObjectFactories()) {
|
||||
auto pObject = factory();
|
||||
wxASSERT( pObject );
|
||||
mAttachedObjects.push_back( std::move( pObject ) );
|
||||
}
|
||||
}
|
||||
|
||||
mMenuManager = std::make_unique<MenuManager>();
|
||||
|
||||
UpdatePrefs();
|
||||
@ -1364,7 +1431,12 @@ void AudacityProject::UpdatePrefs()
|
||||
|
||||
SetProjectTitle();
|
||||
|
||||
GetMenuCommandHandler(*this).UpdatePrefs();
|
||||
{
|
||||
ObjectFactorySetLocker locker;
|
||||
for( const auto &pObject : mAttachedObjects )
|
||||
pObject->UpdatePrefs();
|
||||
}
|
||||
|
||||
GetMenuManager(*this).UpdatePrefs();
|
||||
|
||||
if (mTrackPanel) {
|
||||
|
@ -172,6 +172,8 @@ class WaveTrack;
|
||||
struct MenuCommandHandler;
|
||||
class MenuManager;
|
||||
|
||||
class PrefsListener;
|
||||
|
||||
class AUDACITY_DLL_API AudacityProject final : public wxFrame,
|
||||
public TrackPanelListener,
|
||||
public SelectionBarListener,
|
||||
@ -184,6 +186,24 @@ class AUDACITY_DLL_API AudacityProject final : public wxFrame,
|
||||
const wxPoint & pos, const wxSize & size);
|
||||
virtual ~AudacityProject();
|
||||
|
||||
using AttachedObject = PrefsListener;
|
||||
using AttachedObjectFactory =
|
||||
std::function< std::unique_ptr<AttachedObject>() >;
|
||||
|
||||
// Typically a static object. Allows various application code to
|
||||
// attach per-project state, without Project.cpp needing to include a header
|
||||
// file or know the details.
|
||||
class RegisteredAttachedObjectFactory {
|
||||
public:
|
||||
RegisteredAttachedObjectFactory( const AttachedObjectFactory &factory );
|
||||
|
||||
private:
|
||||
friend AudacityProject;
|
||||
size_t mIndex {};
|
||||
};
|
||||
AttachedObject &
|
||||
GetAttachedObject( const RegisteredAttachedObjectFactory& factory );
|
||||
|
||||
virtual void ApplyUpdatedTheme();
|
||||
|
||||
AudioIOStartStreamOptions GetDefaultPlayOptions();
|
||||
@ -807,7 +827,7 @@ private:
|
||||
#endif
|
||||
|
||||
private:
|
||||
std::unique_ptr<MenuCommandHandler> mMenuCommandHandler;
|
||||
std::vector< std::unique_ptr<AttachedObject> > mAttachedObjects;
|
||||
std::unique_ptr<MenuManager> mMenuManager;
|
||||
|
||||
public:
|
||||
|
Loading…
x
Reference in New Issue
Block a user