From 367b2c10115a847aeebbf2d28803200ee8670fdc Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sat, 23 Apr 2016 00:50:27 -0400 Subject: [PATCH] Move command functors to a new header file, and generalize with templates... ... so that member functions of other than AudacityProject may be called. Will use this new generality soon for scrubbing menu items. --- mac/Audacity.xcodeproj/project.pbxproj | 56 ++++---- src/Makefile.am | 1 + src/Menus.cpp | 71 +--------- src/commands/CommandFunctors.h | 128 ++++++++++++++++++ src/commands/CommandManager.h | 12 +- win/Projects/Audacity/Audacity.vcxproj | 5 +- .../Audacity/Audacity.vcxproj.filters | 7 +- 7 files changed, 169 insertions(+), 111 deletions(-) create mode 100644 src/commands/CommandFunctors.h diff --git a/mac/Audacity.xcodeproj/project.pbxproj b/mac/Audacity.xcodeproj/project.pbxproj index d638d4621..cc540ee6f 100644 --- a/mac/Audacity.xcodeproj/project.pbxproj +++ b/mac/Audacity.xcodeproj/project.pbxproj @@ -2971,6 +2971,7 @@ 28FE4A060ABF4E960056F5C4 /* mmx_optimized.cpp */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = mmx_optimized.cpp; sourceTree = ""; tabWidth = 3; }; 28FE4A070ABF4E960056F5C4 /* sse_optimized.cpp */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = sse_optimized.cpp; sourceTree = ""; tabWidth = 3; }; 28FEC1B21A12B6FB00FACE48 /* EffectAutomationParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EffectAutomationParameters.h; path = ../include/audacity/EffectAutomationParameters.h; sourceTree = SOURCE_ROOT; }; + 5E4685F81CCA9D84008741F2 /* CommandFunctors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CommandFunctors.h; sourceTree = ""; }; 5E61EE0C1CBAA6BB0009FCF1 /* MemoryX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryX.h; sourceTree = ""; }; 5E74D2D61CC4425D00D88B0B /* TrackPanelOverlay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrackPanelOverlay.cpp; sourceTree = ""; }; 5E74D2D71CC4425D00D88B0B /* TrackPanelOverlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackPanelOverlay.h; sourceTree = ""; }; @@ -3569,58 +3570,59 @@ isa = PBXGroup; children = ( 28D53FFA0FD1912A00FA7C75 /* AppCommandEvent.cpp */, - 28D53FFB0FD1912A00FA7C75 /* AppCommandEvent.h */, 28BD8AA9101DF4C600686679 /* BatchEvalCommand.cpp */, - 28D53FFC0FD1912A00FA7C75 /* BatchEvalCommand.h */, 28851F9C1027F16400152EE1 /* Command.cpp */, - 28D53FFD0FD1912A00FA7C75 /* Command.h */, 28D53FFE0FD1912A00FA7C75 /* CommandBuilder.cpp */, - 28D53FFF0FD1912A00FA7C75 /* CommandBuilder.h */, 28BD8AAA101DF4C600686679 /* CommandDirectory.cpp */, - 28BD8AAB101DF4C600686679 /* CommandDirectory.h */, 28D540000FD1912A00FA7C75 /* CommandHandler.cpp */, - 28D540010FD1912A00FA7C75 /* CommandHandler.h */, 174D9026098C78AF00D5909F /* CommandManager.cpp */, - 174D9027098C78AF00D5909F /* CommandManager.h */, - 1818558F0FFE916C0026D190 /* CommandMisc.h */, 28851F9D1027F16400152EE1 /* CommandSignature.cpp */, - 28851F9E1027F16400152EE1 /* CommandSignature.h */, 28851F9F1027F16400152EE1 /* CommandType.cpp */, - 28851FA01027F16400152EE1 /* CommandType.h */, - 181855900FFE916C0026D190 /* CommandTargets.h */, 28851FA11027F16400152EE1 /* CompareAudioCommand.cpp */, - 28851FA21027F16400152EE1 /* CompareAudioCommand.h */, 28BD8AAC101DF4C600686679 /* ExecMenuCommand.cpp */, - 28BD8AAD101DF4C600686679 /* ExecMenuCommand.h */, 28BD8AAE101DF4C600686679 /* GetAllMenuCommands.cpp */, - 28BD8AAF101DF4C600686679 /* GetAllMenuCommands.h */, 284249EA10D337CE004330A6 /* GetProjectInfoCommand.cpp */, - 284249EB10D337CE004330A6 /* GetProjectInfoCommand.h */, 28851FA31027F16400152EE1 /* GetTrackInfoCommand.cpp */, - 28851FA41027F16400152EE1 /* GetTrackInfoCommand.h */, 28851FA51027F16400152EE1 /* HelpCommand.cpp */, - 28851FA61027F16400152EE1 /* HelpCommand.h */, EDD94ED9103CB520000873F1 /* ImportExportCommands.cpp */, - EDD94EDA103CB520000873F1 /* ImportExportCommands.h */, 174D902A098C78AF00D5909F /* Keyboard.cpp */, - 174D902B098C78AF00D5909F /* Keyboard.h */, 28851FA71027F16400152EE1 /* MessageCommand.cpp */, - 28851FA81027F16400152EE1 /* MessageCommand.h */, EDFCEB9A18894AE600C98E51 /* OpenSaveCommands.cpp */, - EDFCEB9B18894AE600C98E51 /* OpenSaveCommands.h */, 28DE72AA10388583007E18EC /* PreferenceCommands.cpp */, - 28DE72AB10388583007E18EC /* PreferenceCommands.h */, - 28DB34770FDC2C5D0011F589 /* ResponseQueue.h */, 28DB34780FDC2C5D0011F589 /* ResponseQueue.cpp */, 181855950FFE916C0026D190 /* ScreenshotCommand.cpp */, - 181855960FFE916C0026D190 /* ScreenshotCommand.h */, 28D540030FD1912A00FA7C75 /* ScriptCommandRelay.cpp */, - 28D540040FD1912A00FA7C75 /* ScriptCommandRelay.h */, 28851FA91027F16400152EE1 /* SelectCommand.cpp */, - 28851FAA1027F16400152EE1 /* SelectCommand.h */, 284249EC10D337CE004330A6 /* SetProjectInfoCommand.cpp */, - 284249ED10D337CE004330A6 /* SetProjectInfoCommand.h */, 28DE72AC10388583007E18EC /* SetTrackInfoCommand.cpp */, + 28D53FFB0FD1912A00FA7C75 /* AppCommandEvent.h */, + 28D53FFC0FD1912A00FA7C75 /* BatchEvalCommand.h */, + 28D53FFD0FD1912A00FA7C75 /* Command.h */, + 28D53FFF0FD1912A00FA7C75 /* CommandBuilder.h */, + 28BD8AAB101DF4C600686679 /* CommandDirectory.h */, + 5E4685F81CCA9D84008741F2 /* CommandFunctors.h */, + 28D540010FD1912A00FA7C75 /* CommandHandler.h */, + 174D9027098C78AF00D5909F /* CommandManager.h */, + 1818558F0FFE916C0026D190 /* CommandMisc.h */, + 28851F9E1027F16400152EE1 /* CommandSignature.h */, + 181855900FFE916C0026D190 /* CommandTargets.h */, + 28851FA01027F16400152EE1 /* CommandType.h */, + 28851FA21027F16400152EE1 /* CompareAudioCommand.h */, + 28BD8AAD101DF4C600686679 /* ExecMenuCommand.h */, + 28BD8AAF101DF4C600686679 /* GetAllMenuCommands.h */, + 284249EB10D337CE004330A6 /* GetProjectInfoCommand.h */, + 28851FA41027F16400152EE1 /* GetTrackInfoCommand.h */, + 28851FA61027F16400152EE1 /* HelpCommand.h */, + EDD94EDA103CB520000873F1 /* ImportExportCommands.h */, + 174D902B098C78AF00D5909F /* Keyboard.h */, + 28851FA81027F16400152EE1 /* MessageCommand.h */, + EDFCEB9B18894AE600C98E51 /* OpenSaveCommands.h */, + 28DE72AB10388583007E18EC /* PreferenceCommands.h */, + 28DB34770FDC2C5D0011F589 /* ResponseQueue.h */, + 181855960FFE916C0026D190 /* ScreenshotCommand.h */, + 28D540040FD1912A00FA7C75 /* ScriptCommandRelay.h */, + 28851FAA1027F16400152EE1 /* SelectCommand.h */, + 284249ED10D337CE004330A6 /* SetProjectInfoCommand.h */, 28DE72AD10388583007E18EC /* SetTrackInfoCommand.h */, 28BD8AB0101DF4C600686679 /* Validators.h */, ); diff --git a/src/Makefile.am b/src/Makefile.am index 6fa576381..5df0e7656 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -263,6 +263,7 @@ audacity_SOURCES = \ commands/CommandBuilder.h \ commands/CommandDirectory.cpp \ commands/CommandDirectory.h \ + commands/CommandFunctors.h \ commands/CommandHandler.cpp \ commands/CommandHandler.h \ commands/CommandManager.cpp \ diff --git a/src/Menus.cpp b/src/Menus.cpp index 0d899e84d..760e4164a 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -158,76 +158,7 @@ enum { POST_TIMER_RECORD_SHUTDOWN }; -// Define functor subclasses that dispatch to the correct call sequence on -// member functions of AudacityProject - -using audCommandFunction = void (AudacityProject::*)(); -class VoidFunctor final : public CommandFunctor -{ -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; -}; - -using audCommandKeyFunction = void (AudacityProject::*)(const wxEvent *); -class KeyFunctor final : public CommandFunctor -{ -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; -}; - -using audCommandListFunction = void (AudacityProject::*)(int); -class ListFunctor final : public CommandFunctor -{ -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; -}; - -using audCommandPluginFunction = bool (AudacityProject::*)(const PluginID &, int); -class PluginFunctor final : public CommandFunctor -{ -public: - explicit PluginFunctor(AudacityProject *project, const PluginID &id, audCommandPluginFunction pfn) - : mPluginID{ id }, mProject{ project }, mCommandPluginFunction{ pfn } {} - void operator () (int, const wxEvent *) override - { (mProject->*mCommandPluginFunction) (mPluginID, AudacityProject::OnEffectFlags::kNone); } -private: - const PluginID mPluginID; - AudacityProject *const mProject; - const audCommandPluginFunction mCommandPluginFunction; -}; - -// 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 } }; } - -// 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 )) - +#include "commands/CommandFunctors.h" // // Effects menu arrays // diff --git a/src/commands/CommandFunctors.h b/src/commands/CommandFunctors.h new file mode 100644 index 000000000..5df2b27a2 --- /dev/null +++ b/src/commands/CommandFunctors.h @@ -0,0 +1,128 @@ +// +// CommandFunctors.h +// Audacity +// +// Created by Paul Licameli on 4/22/16. +// +// + +#ifndef __AUDACITY_COMMAND_FUNCTORS__ +#define __AUDACITY_COMMAND_FUNCTORS__ + +#include +#include "../MemoryX.h" + +class wxEvent; +typedef wxString PluginID; + +class AUDACITY_DLL_API CommandFunctor /* not final */ +{ +public: + CommandFunctor(){}; + virtual ~CommandFunctor(){}; + virtual void operator()(int index, const wxEvent *e) = 0; +}; + +using CommandFunctorPointer = std::shared_ptr ; + + +// Define functor subclasses that dispatch to the correct call sequence on +// member functions of AudacityProject (or other class!) + +template +using audCommandFunction = void (THIS::*)(); + +template +class VoidFunctor final : public CommandFunctor +{ +public: + explicit VoidFunctor(THIS *This, audCommandFunction pfn) + : mThis{ This }, mCommandFunction{ pfn } {} + void operator () (int, const wxEvent *) override + { (mThis->*mCommandFunction) (); } +private: + THIS *const mThis; + const audCommandFunction mCommandFunction; +}; + +template +using audCommandKeyFunction = void (THIS::*)(const wxEvent *); + +template +class KeyFunctor final : public CommandFunctor +{ +public: + explicit KeyFunctor(THIS *This, audCommandKeyFunction pfn) + : mThis{ This }, mCommandKeyFunction{ pfn } {} + void operator () (int, const wxEvent *evt) override + { (mThis->*mCommandKeyFunction) (evt); } +private: + THIS *const mThis; + const audCommandKeyFunction mCommandKeyFunction; +}; + +template +using audCommandListFunction = void (THIS::*)(int); + +template +class ListFunctor final : public CommandFunctor +{ +public: + explicit ListFunctor(THIS *This, audCommandListFunction pfn) + : mThis{ This }, mCommandListFunction{ pfn } {} + void operator () (int index, const wxEvent *) override + { (mThis->*mCommandListFunction)(index); } +private: + THIS *const mThis; + const audCommandListFunction mCommandListFunction; +}; + +template +using audCommandPluginFunction = bool (THIS::*)(const PluginID &, int); + +template +class PluginFunctor final : public CommandFunctor +{ +public: + explicit PluginFunctor(THIS *This, const PluginID &id, audCommandPluginFunction pfn) + : mPluginID{ id }, mThis{ This }, mCommandPluginFunction{ pfn } {} + void operator () (int, const wxEvent *) override + { (mThis->*mCommandPluginFunction) + (mPluginID, + 0 // AudacityProject::OnEffectFlags::kNone + ); } +private: + const PluginID mPluginID; + THIS *const mThis; + const audCommandPluginFunction mCommandPluginFunction; +}; + +// Now define an overloaded factory function +template +inline CommandFunctorPointer MakeFunctor(THIS *This, + audCommandFunction pfn) +{ return CommandFunctorPointer{ safenew VoidFunctor{ This, pfn } }; } + +template +inline CommandFunctorPointer MakeFunctor(THIS *This, + audCommandKeyFunction pfn) +{ return CommandFunctorPointer{ safenew KeyFunctor{ This, pfn } }; } + +template +inline CommandFunctorPointer MakeFunctor(THIS *This, + audCommandListFunction pfn) +{ return CommandFunctorPointer{ safenew ListFunctor{ This, pfn } }; } + +template +inline CommandFunctorPointer MakeFunctor(THIS *This, const PluginID &id, + audCommandPluginFunction pfn) +{ return CommandFunctorPointer{ safenew PluginFunctor{ This, id, pfn } }; } + +// Now define the macro abbreviations that call the factory +#define FNT(THIS, This, X) (MakeFunctor(This, X )) +#define FNTS(THIS, This, X, S) (MakeFunctor(This, (S), X )) + +#define FN(X) FNT(AudacityProject, this, & AudacityProject :: X) +#define FNS(X, S) FNTS(AudacityProject, this, & AudacityProject :: X, S) + +#endif diff --git a/src/commands/CommandManager.h b/src/commands/CommandManager.h index 7b5c83929..80c6a178a 100644 --- a/src/commands/CommandManager.h +++ b/src/commands/CommandManager.h @@ -14,6 +14,8 @@ #include "../Experimental.h" +#include "CommandFunctors.h" + #include "../MemoryX.h" #include #include @@ -26,14 +28,6 @@ #include "audacity/Types.h" -class AUDACITY_DLL_API CommandFunctor /* not final */ -{ -public: - CommandFunctor(){}; - virtual ~CommandFunctor(){}; - virtual void operator()(int index, const wxEvent *e) = 0; -}; - struct MenuBarListEntry { MenuBarListEntry(const wxString &name_, wxMenuBar *menubar_) @@ -54,8 +48,6 @@ struct SubMenuListEntry wxMenu *menu; }; -using CommandFunctorPointer = std::shared_ptr ; - struct CommandListEntry { int id; diff --git a/win/Projects/Audacity/Audacity.vcxproj b/win/Projects/Audacity/Audacity.vcxproj index 923d36a64..b99c18c40 100755 --- a/win/Projects/Audacity/Audacity.vcxproj +++ b/win/Projects/Audacity/Audacity.vcxproj @@ -1,4 +1,4 @@ - + @@ -414,6 +414,7 @@ + @@ -1107,4 +1108,4 @@ - + \ No newline at end of file diff --git a/win/Projects/Audacity/Audacity.vcxproj.filters b/win/Projects/Audacity/Audacity.vcxproj.filters index aea512d60..ed9d306ad 100755 --- a/win/Projects/Audacity/Audacity.vcxproj.filters +++ b/win/Projects/Audacity/Audacity.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -1768,6 +1768,9 @@ src + + src\commands + @@ -1988,4 +1991,4 @@ plug-ins - + \ No newline at end of file