From 0c182c3c0bc9382b3837c168c8b621154f5c65ac Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Wed, 24 Feb 2016 15:17:06 -0500 Subject: [PATCH] Shrink the command functor objects by using more subclasses... ... Let virtual function dispatch do the work, don't write our own dispatch! --- src/Menus.cpp | 107 +++++++++++++++++++--------------- src/Project.h | 31 ---------- src/commands/CommandManager.h | 2 +- 3 files changed, 60 insertions(+), 80 deletions(-) diff --git a/src/Menus.cpp b/src/Menus.cpp index 217de5a28..202f51dce 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -143,64 +143,75 @@ enum { kAlignTogether }; +// Define functor subclasses that dispatch to the correct call sequence on +// member functions of AudacityProject -AudacityProjectCommandFunctor::AudacityProjectCommandFunctor(AudacityProject *project, - audCommandFunction commandFunction) +using audCommandFunction = void (AudacityProject::*)(); +class VoidFunctor : public CommandFunctor { - mProject = project; - mCommandFunction = commandFunction; - mCommandKeyFunction = NULL; - mCommandListFunction = NULL; - mCommandPluginFunction = NULL; -} +public: + explicit VoidFunctor(AudacityProject *project, audCommandFunction pfn) + : mProject{ project }, mCommandFunction{ pfn } {} + void operator () (int, const wxEvent *) override + { (mProject->*mCommandFunction) (); } +private: + AudacityProject *const mProject; + const audCommandFunction mCommandFunction; +}; -AudacityProjectCommandFunctor::AudacityProjectCommandFunctor(AudacityProject *project, - audCommandKeyFunction commandFunction) +using audCommandKeyFunction = void (AudacityProject::*)(const wxEvent *); +class KeyFunctor : public CommandFunctor { - mProject = project; - mCommandFunction = NULL; - mCommandKeyFunction = commandFunction; - mCommandListFunction = NULL; - mCommandPluginFunction = NULL; -} +public: + explicit KeyFunctor(AudacityProject *project, audCommandKeyFunction pfn) + : mProject{ project }, mCommandKeyFunction{ pfn } {} + void operator () (int, const wxEvent *evt) override + { (mProject->*mCommandKeyFunction) (evt); } +private: + AudacityProject *const mProject; + const audCommandKeyFunction mCommandKeyFunction; +}; -AudacityProjectCommandFunctor::AudacityProjectCommandFunctor(AudacityProject *project, - audCommandListFunction commandFunction) +using audCommandListFunction = void (AudacityProject::*)(int); +class ListFunctor : public CommandFunctor { - mProject = project; - mCommandFunction = NULL; - mCommandKeyFunction = NULL; - mCommandListFunction = commandFunction; - mCommandPluginFunction = NULL; -} +public: + explicit ListFunctor(AudacityProject *project, audCommandListFunction pfn) + : mProject{ project }, mCommandListFunction{ pfn } {} + void operator () (int index, const wxEvent *) override + { (mProject->*mCommandListFunction)(index); } +private: + AudacityProject *const mProject; + const audCommandListFunction mCommandListFunction; +}; -AudacityProjectCommandFunctor::AudacityProjectCommandFunctor(AudacityProject *project, - audCommandPluginFunction commandFunction, - const PluginID & pluginID) +using audCommandPluginFunction = bool (AudacityProject::*)(const PluginID &, int); +class PluginFunctor : public CommandFunctor { - mProject = project; - mCommandFunction = NULL; - mCommandKeyFunction = NULL; - mCommandListFunction = NULL; - mCommandPluginFunction = commandFunction; - mPluginID = pluginID; -} +public: + explicit PluginFunctor(AudacityProject *project, const PluginID &id, audCommandPluginFunction pfn) + : mPluginID{ id }, mProject{ project }, mCommandPluginFunction{ pfn } {} + void operator () (int index, const wxEvent *) override + { (mProject->*mCommandPluginFunction) (mPluginID, AudacityProject::OnEffectFlags::kNone); } +private: + const PluginID mPluginID; + AudacityProject *const mProject; + const audCommandPluginFunction mCommandPluginFunction; +}; -void AudacityProjectCommandFunctor::operator()(int index, const wxEvent * evt) -{ - if (mCommandPluginFunction) - (mProject->*(mCommandPluginFunction)) (mPluginID, AudacityProject::OnEffectFlags::kNone); - else if (mCommandListFunction) - (mProject->*(mCommandListFunction)) (index); - else if (mCommandKeyFunction) - (mProject->*(mCommandKeyFunction)) (evt); - else - (mProject->*(mCommandFunction)) (); -} +// Now define an overloaded factory function +inline CommandFunctorPointer MakeFunctor(AudacityProject *project, audCommandFunction pfn) +{ return CommandFunctorPointer{ safenew VoidFunctor{ project, pfn } }; } +inline CommandFunctorPointer MakeFunctor(AudacityProject *project, audCommandKeyFunction pfn) +{ return CommandFunctorPointer{ safenew KeyFunctor{ project, pfn } }; } +inline CommandFunctorPointer MakeFunctor(AudacityProject *project, audCommandListFunction pfn) +{ return CommandFunctorPointer{ safenew ListFunctor{ project, pfn } }; } +inline CommandFunctorPointer MakeFunctor(AudacityProject *project, const PluginID &id, audCommandPluginFunction pfn) +{ return CommandFunctorPointer{ safenew PluginFunctor{ project, id, pfn } }; } -#define FN(X) CommandFunctorPointer{safenew AudacityProjectCommandFunctor(this, &AudacityProject:: X )} -#define FNI(X, I) CommandFunctorPointer{safenew AudacityProjectCommandFunctor(this, &AudacityProject:: X, I)} -#define FNS(X, S) CommandFunctorPointer{safenew AudacityProjectCommandFunctor(this, &AudacityProject:: X, S)} +// Now define the macro abbreviations that call the factory +#define FN(X) (MakeFunctor(this, &AudacityProject:: X )) +#define FNS(X, S) (MakeFunctor(this, (S), &AudacityProject:: X )) // // Effects menu arrays diff --git a/src/Project.h b/src/Project.h index 81397fad4..4dbca4d7b 100644 --- a/src/Project.h +++ b/src/Project.h @@ -685,36 +685,5 @@ public: DECLARE_EVENT_TABLE() }; -typedef void (AudacityProject::*audCommandFunction)(); -typedef void (AudacityProject::*audCommandKeyFunction)(const wxEvent *); -typedef void (AudacityProject::*audCommandListFunction)(int); -typedef bool (AudacityProject::*audCommandPluginFunction)(const PluginID &, int); - -// Previously this was in menus.cpp, and the declaration of the -// command functor was not visible anywhere else. -class AUDACITY_DLL_API AudacityProjectCommandFunctor : public CommandFunctor -{ -public: - AudacityProjectCommandFunctor(AudacityProject *project, - audCommandFunction commandFunction); - AudacityProjectCommandFunctor(AudacityProject *project, - audCommandKeyFunction commandFunction); - AudacityProjectCommandFunctor(AudacityProject *project, - audCommandListFunction commandFunction); - AudacityProjectCommandFunctor(AudacityProject *project, - audCommandPluginFunction commandFunction, - const PluginID & pluginID); - - virtual void operator()(int index = 0, const wxEvent *evt = NULL); - -private: - AudacityProject *mProject; - audCommandFunction mCommandFunction; - audCommandKeyFunction mCommandKeyFunction; - audCommandListFunction mCommandListFunction; - audCommandPluginFunction mCommandPluginFunction; - PluginID mPluginID; -}; - #endif diff --git a/src/commands/CommandManager.h b/src/commands/CommandManager.h index 3aa8ea370..78216a86e 100644 --- a/src/commands/CommandManager.h +++ b/src/commands/CommandManager.h @@ -30,7 +30,7 @@ class AUDACITY_DLL_API CommandFunctor public: CommandFunctor(){}; virtual ~CommandFunctor(){}; - virtual void operator()(int index = 0, const wxEvent *e = NULL) = 0; + virtual void operator()(int index, const wxEvent *e) = 0; }; struct MenuBarListEntry