1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-09-17 16:50:26 +02:00

Merge pull request #1429 from Paul-Licameli/extract-lib-registries

Extract lib registries
This commit is contained in:
Paul Licameli 2021-08-06 08:57:11 -04:00 committed by GitHub
commit 60f0820916
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 153 additions and 99 deletions

View File

@ -13,6 +13,7 @@ set( LIBRARIES
lib-preferences
lib-math
lib-files
lib-registries
)
if ( ${_OPT}has_networking )

View File

@ -72,13 +72,15 @@ AttachedVirtualFunction<
AbstractHost, // class to be switched on by runtime type
int, double // other arguments
>;
// Allow correct linkage for overrides defined in dynamically loaded modules:
DECLARE_EXPORTED_ATTACHED_VIRTUAL(AUDACITY_DLL_API, DoSomething);
```
Definitions needed:
```
//file Client.cpp
// Define the default function body here (as a function returning a function!)
template<> auto DoSomething::Implementation() -> Function {
// Define the default function body here
DEFINE_ATTACHED_VIRTUAL(DoSomething) {
return [](AbstractHost &host, int arg1, double arg2) {
return ErrorCode::Ok;
};
@ -86,9 +88,6 @@ template<> auto DoSomething::Implementation() -> Function {
// at runtime if the virtual function is invoked for a host subclass for which no override
// was defined.
}
// Must also guarantee construction of an instance of class DoSomething at least
// once before any use of DoSomething::Call()
static DoSomething registerMe;
```
Usage of the method somewhere else:
@ -124,7 +123,7 @@ Overrides of the method, defined in any other .cpp file:
// An override of the function, building up a hierarchy of function bodies parallel
// to the host class hierarchy
using DoSomethingSpecial = DoSomething::Override< SpecialHost >;
template<> template<> auto DoSomethingSpecial::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(DoSomethingSpecial) {
// The function can be defined without casting the first argument
return [](SpecialHost &host, int arg1, double arg2) {
return arg1 == 0 ? ErrorCode::Ok : ErrorCode::Bad;
@ -135,8 +134,7 @@ static DoSomethingSpecial registerMe;
// A further override, demonstrating call-through too
using DoSomethingExtraSpecial =
DoSomething::Override< ExtraSpecialHost, DoSomethingSpecial >;
template<> template<>
auto DoSomethingExtraSpecial::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(DoSomethingExtraSpecial) {
return [](ExtraSpecialHost &host, int arg1, double arg2){
// Call the immediately overridden version of the function
auto result = Callthrough( host, arg1, arg2 );
@ -173,11 +171,7 @@ public:
//! At least one static instance must be created; more instances are harmless
/*! (There will be others if there are any overrides.) */
AttachedVirtualFunction()
{
static std::once_flag flag;
std::call_once( flag, []{ Register<This>( Implementation() ); } );
}
AttachedVirtualFunction();
//! For defining overrides of the method
/*!
@ -280,11 +274,33 @@ private:
};
using Registry = std::vector< Entry >;
static Registry &GetRegistry()
{
static Registry registry;
return registry;
}
static Registry &GetRegistry();
};
//! Typically follow the `using` declaration of a new AttachedVirtualFunction with this macro
#define DECLARE_EXPORTED_ATTACHED_VIRTUAL(DECLSPEC, Name) \
template<> DECLSPEC Name::AttachedVirtualFunction(); \
template<> auto DECLSPEC Name::GetRegistry() -> Registry &; \
template<> auto DECLSPEC Name::Implementation() -> Function
//! Used in the companion .cpp file to the .h using the above macro; followed by a function body
#define DEFINE_ATTACHED_VIRTUAL(Name) \
template<> Name::AttachedVirtualFunction() \
{ \
static std::once_flag flag; \
std::call_once( flag, []{ Register<Object>( Implementation() ); } ); \
} \
template<> auto Name::GetRegistry() -> Registry & \
{ \
static Registry registry; \
return registry; \
} \
static Name register ## Name ; \
template<> auto Name::Implementation() -> Function
//! Used to define overriding function; followed by a function body
#define DEFINE_ATTACHED_VIRTUAL_OVERRIDE(Name) \
static Name register ## Name ; \
template<> template<> auto Name::Implementation() -> Function \
#endif

View File

@ -0,0 +1,47 @@
#[[
Some utilities for allowing open-endedness and decoupling of designs, by
maintaining global tables that can be populated at static initialization by
code in scattered places, on which the registry has no build dependency.
AttachedVirtualFunction implements "open methods" -- functions that type-switch
on the first argument, and dispatch to the correct implementation, but without
intrusiveness into the base of the class hierarchy. This allows the set of
methods and the set of subclasses both to be open-ended.
(That is unlike in the "Gang of Four" Visitor pattern, in which the set of
methods becomes open-ended while the set of subclasses is closed-ended: the
Visitor can't handle a new subclass without intrusion into the abstract
Visitor definition.)
ClientData allows a "Site" class to act as a container of attached objects
produced by registered factory functions, and retrieved by the various attaching
modules. The Site's constructor is effectively hookable. This in particular
allows the Project object to be low-level in the graph of file dependencies,
while it is also the top-level object of an ownership tree of various important
sub-structures. This is another "Dependency Inversion" of sorts (the D
principle of SOLID).
Registry implements trees of objects identified by textual paths, and allows
scattered code to insert items or subtrees at specified paths. Registry
computes the merging of trees, and supports visitation. It is used notably
by the tree of menus, allowing insertion of menu items in decoupled code.
]]#
set( SOURCES
AttachedVirtualFunction.h
ClientData.cpp
ClientData.h
ClientDataHelpers.h
Registrar.h
Registry.cpp
Registry.h
)
set( LIBRARIES
lib-preferences-interface
lib-exceptions
PRIVATE
wxBase
)
audacity_library( lib-registries "${SOURCES}" "${LIBRARIES}"
"" ""
)

View File

@ -0,0 +1,15 @@
/*!********************************************************************
Audacity: A Digital Audio Editor
@file ClientData.cpp
Paul Licameli
**********************************************************************/
#include "ClientData.h"
// These are needed out-of-line for the Windows link
ClientData::Base::~Base() = default;
template<> ClientData::Cloneable<>::~Cloneable() = default;

View File

@ -24,9 +24,9 @@ Paul Licameli
namespace ClientData {
//! A convenient default parameter for class template @b Site
struct AUDACITY_DLL_API Base
struct REGISTRIES_API Base
{
virtual ~Base() {}
virtual ~Base();
};
//! A one-argument alias template for the default template-template parameter of ClientData::Site
@ -44,12 +44,12 @@ template< typename Object > using BarePtr = Object*;
*/
template<
template<typename> class Owner = UniquePtr
> struct AUDACITY_DLL_API Cloneable
> struct REGISTRIES_API Cloneable
{
using Base = Cloneable;
using PointerType = Owner< Base >;
virtual ~Cloneable() {}
virtual ~Cloneable();
virtual PointerType Clone() const = 0;
};

View File

@ -29,7 +29,7 @@ class LoadableModule;
class ComponentInterface;
class Effect;
class AUDACITY_DLL_API Registrar
class REGISTRIES_API Registrar
{
public:
Registrar(){

View File

@ -14,7 +14,7 @@ Paul Licameli split from Menus.cpp
#include <wx/log.h>
#include "widgets/AudacityMessageBox.h"
#include "BasicUI.h"
namespace {
@ -174,7 +174,7 @@ using Path = std::vector< Identifier >;
wxLogDebug( msg.Translation() );
#ifdef IS_ALPHA
// user-visible message
AudacityMessageBox( msg );
BasicUI::ShowMessageBox( msg );
#endif
}
}

View File

@ -56,7 +56,7 @@ namespace Registry {
// Most items in the table will be the large ones describing commands, so the
// waste of space in unions for separators and sub-menus should not be
// large.
struct AUDACITY_DLL_API BaseItem {
struct REGISTRIES_API BaseItem {
// declare at least one virtual function so dynamic_cast will work
explicit
BaseItem( const Identifier &internalName )
@ -79,7 +79,7 @@ namespace Registry {
// static tables of items to be computed once and reused
// The name of the delegate is significant for path calculations, but the
// SharedItem's ordering hint is used if the delegate has none
struct AUDACITY_DLL_API SharedItem final : BaseItem {
struct REGISTRIES_API SharedItem final : BaseItem {
explicit SharedItem( const BaseItemSharedPtr &ptr_ )
: BaseItem{ wxEmptyString }
, ptr{ ptr_ }
@ -97,7 +97,7 @@ namespace Registry {
// the ComputedItem is visited
// The name of the substitute is significant for path calculations, but the
// ComputedItem's ordering hint is used if the substitute has none
struct AUDACITY_DLL_API ComputedItem final : BaseItem {
struct REGISTRIES_API ComputedItem final : BaseItem {
// The type of functions that generate descriptions of items.
// Return type is a shared_ptr to let the function decide whether to
// recycle the object or rebuild it on demand each time.
@ -117,13 +117,13 @@ namespace Registry {
};
// Common abstract base class for items that are not groups
struct AUDACITY_DLL_API SingleItem : BaseItem {
struct REGISTRIES_API SingleItem : BaseItem {
using BaseItem::BaseItem;
~SingleItem() override = 0;
};
// Common abstract base class for items that group other items
struct AUDACITY_DLL_API GroupItem : BaseItem {
struct REGISTRIES_API GroupItem : BaseItem {
using BaseItem::BaseItem;
// Construction from an internal name and a previously built-up
@ -231,14 +231,14 @@ namespace Registry {
// The sequence of calls to RegisterItem has no significance for
// determining the visitation ordering. When sequence is important, register
// a GroupItem.
AUDACITY_DLL_API
REGISTRIES_API
void RegisterItem( GroupItem &registry, const Placement &placement,
BaseItemPtr pItem );
// Define actions to be done in Visit.
// Default implementations do nothing
// The supplied path does not include the name of the item
class AUDACITY_DLL_API Visitor
class REGISTRIES_API Visitor
{
public:
virtual ~Visitor();
@ -257,7 +257,7 @@ namespace Registry {
// seen in the registry for the first time is placed somehere, and that
// ordering should be kept the same thereafter in later runs (which may add
// yet other previously unknown items).
void Visit(
REGISTRIES_API void Visit(
Visitor &visitor,
BaseItem *pTopItem,
const GroupItem *pRegistry = nullptr );
@ -269,7 +269,7 @@ namespace Registry {
// registry of plug-ins, and something must be done to preserve old
// behavior. It can be done in the central place using string literal
// identifiers only, not requiring static compilation or linkage dependency.
struct AUDACITY_DLL_API
struct REGISTRIES_API
OrderingPreferenceInitializer : PreferenceInitializer {
using Literal = const wxChar *;
using Pair = std::pair< Literal, Literal >;

View File

@ -84,7 +84,6 @@ list( APPEND SOURCES
AdornedRulerPanel.h
AllThemeResources.cpp
AllThemeResources.h
AttachedVirtualFunction.h
AudacityApp.cpp
AudacityApp.h
$<$<BOOL:${wxIS_MAC}>:AudacityApp.mm>
@ -110,8 +109,6 @@ list( APPEND SOURCES
CellularPanel.cpp
CellularPanel.h
ClassicThemeAsCeeCode.h
ClientData.h
ClientDataHelpers.h
Clipboard.cpp
Clipboard.h
CommonCommandFlags.cpp
@ -217,9 +214,6 @@ list( APPEND SOURCES
ProjectWindowBase.cpp
ProjectWindowBase.h
RefreshCode.h
Registrar.h
Registry.cpp
Registry.h
RingBuffer.cpp
RingBuffer.h
SampleBlock.cpp

View File

@ -23,7 +23,7 @@
#include "ComponentInterface.h"
#include "EffectAutomationParameters.h" // for command automation
#include "../Registrar.h"
#include "Registrar.h"
class ShuttleGui;

View File

@ -14,14 +14,14 @@
#include "Identifier.h"
#include "../ClientData.h"
#include "ClientData.h"
#include "CommandFunctors.h"
#include "CommandFlag.h"
#include "Keyboard.h"
#include "Prefs.h"
#include "../Registry.h"
#include "Registry.h"
#include <vector>

View File

@ -19,7 +19,7 @@
#include "../widgets/wxPanelWrapper.h" // to inherit
#include "FileNames.h" // for FileTypes
#include "../Registry.h"
#include "Registry.h"
class wxArrayString;
class FileDialogWrapper;

View File

@ -19,7 +19,7 @@
#include "../widgets/wxPanelWrapper.h" // to inherit
#include "FileNames.h" // for FileType
#include "../Registry.h"
#include "Registry.h"
class wxArrayString;
class wxListBox;

View File

@ -30,7 +30,7 @@ MousePrefs, QualityPrefs, SpectrumPrefs and ThemePrefs.
#include <functional>
#include "../widgets/wxPanelWrapper.h" // to inherit
#include "ComponentInterface.h"
#include "../Registry.h"
#include "Registry.h"
/* A few constants for an attempt at semi-uniformity */
#define PREFS_FONT_SIZE 8

View File

@ -20,7 +20,7 @@
#include <wx/frame.h> // to inherit
#include <wx/timer.h> // member variable
#include "../ClientData.h"
#include "ClientData.h"
#include "ToolDock.h"
#include "../commands/CommandFunctors.h"

View File

@ -179,16 +179,14 @@ PopupMenuTable *LabelTrackControls::GetMenuExtension(Track *)
}
using DoGetLabelTrackControls = DoGetControls::Override< LabelTrack >;
template<> template<> auto DoGetLabelTrackControls::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(DoGetLabelTrackControls) {
return [](LabelTrack &track) {
return std::make_shared<LabelTrackControls>( track.SharedPointer() );
};
}
static DoGetLabelTrackControls registerDoGetLabelTrackControls;
using GetDefaultLabelTrackHeight = GetDefaultTrackHeight::Override< LabelTrack >;
template<> template<>
auto GetDefaultLabelTrackHeight::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(GetDefaultLabelTrackHeight) {
return [](LabelTrack &) {
// Label tracks are narrow
// Default is to allow two rows so that NEW users get the
@ -196,4 +194,3 @@ auto GetDefaultLabelTrackHeight::Implementation() -> Function {
return 73;
};
}
static GetDefaultLabelTrackHeight registerGetDefaultLabelTrackHeight;

View File

@ -248,9 +248,8 @@ private:
};
using MakeLabelTrackShifter = MakeTrackShifter::Override<LabelTrack>;
template<> template<> auto MakeLabelTrackShifter::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(MakeLabelTrackShifter) {
return [](LabelTrack &track, AudacityProject &project) {
return std::make_unique<LabelTrackShifter>(track, project);
};
}
static MakeLabelTrackShifter registerMakeLabelTrackShifter;

View File

@ -2290,12 +2290,11 @@ int LabelTrackView::DialogForLabelName(
}
using DoGetLabelTrackView = DoGetView::Override< LabelTrack >;
template<> template<> auto DoGetLabelTrackView::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(DoGetLabelTrackView) {
return [](LabelTrack &track) {
return std::make_shared<LabelTrackView>( track.SharedPointer() );
};
}
static DoGetLabelTrackView registerDoGetLabelTrackView;
std::shared_ptr<TrackVRulerControls> LabelTrackView::DoGetVRulerControls()
{

View File

@ -321,22 +321,19 @@ void NoteTrackControls::ReCreateVelocitySlider( wxEvent &evt )
}
using DoGetNoteTrackControls = DoGetControls::Override< NoteTrack >;
template<> template<> auto DoGetNoteTrackControls::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(DoGetNoteTrackControls) {
return [](NoteTrack &track) {
return std::make_shared<NoteTrackControls>( track.SharedPointer() );
};
}
static DoGetNoteTrackControls registerDoGetNoteTrackControls;
#include "../../../ui/TrackView.h"
using GetDefaultNoteTrackHeight = GetDefaultTrackHeight::Override< NoteTrack >;
template<> template<>
auto GetDefaultNoteTrackHeight::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(GetDefaultNoteTrackHeight) {
return [](NoteTrack &) {
return NoteTrackControls::DefaultNoteTrackHeight();
};
}
static GetDefaultNoteTrackHeight registerGetDefaultNoteTrackHeight;
#endif

View File

@ -54,9 +54,8 @@ private:
};
using MakeNoteTrackShifter = MakeTrackShifter::Override<NoteTrack>;
template<> template<> auto MakeNoteTrackShifter::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(MakeNoteTrackShifter) {
return [](NoteTrack &track, AudacityProject&) {
return std::make_unique<NoteTrackShifter>(track);
};
}
static MakeNoteTrackShifter registerMakeNoteTrackShifter;

View File

@ -60,12 +60,11 @@ std::vector<UIHandlePtr> NoteTrackView::DetailedHitTest
}
using DoGetNoteTrackView = DoGetView::Override< NoteTrack >;
template<> template<> auto DoGetNoteTrackView::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(DoGetNoteTrackView) {
return [](NoteTrack &track) {
return std::make_shared<NoteTrackView>( track.SharedPointer() );
};
}
static DoGetNoteTrackView registerDoGetNoteTrackView;
std::shared_ptr<TrackVRulerControls> NoteTrackView::DoGetVRulerControls()
{

View File

@ -1253,19 +1253,16 @@ void WaveTrackControls::ReCreatePanSlider( wxEvent &event )
}
using DoGetWaveTrackControls = DoGetControls::Override< WaveTrack >;
template<> template<> auto DoGetWaveTrackControls::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(DoGetWaveTrackControls) {
return [](WaveTrack &track) {
return std::make_shared<WaveTrackControls>( track.SharedPointer() );
};
}
static DoGetWaveTrackControls registerDoGetWaveTrackControls;
using GetDefaultWaveTrackHeight = GetDefaultTrackHeight::Override< WaveTrack >;
template<> template<>
auto GetDefaultWaveTrackHeight::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(GetDefaultWaveTrackHeight) {
return [](WaveTrack &) {
return WaveTrackControls::DefaultWaveTrackHeight();
};
}
static GetDefaultWaveTrackHeight registerGetDefaultWaveTrackHeight;

View File

@ -188,9 +188,8 @@ private:
};
using MakeWaveTrackShifter = MakeTrackShifter::Override<WaveTrack>;
template<> template<> auto MakeWaveTrackShifter::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(MakeWaveTrackShifter) {
return [](WaveTrack &track, AudacityProject&) {
return std::make_unique<WaveTrackShifter>(track);
};
}
static MakeWaveTrackShifter registerMakeWaveTrackShifter;

View File

@ -1043,12 +1043,11 @@ void WaveTrackView::DoSetMinimized( bool minimized )
}
using DoGetWaveTrackView = DoGetView::Override< WaveTrack >;
template<> template<> auto DoGetWaveTrackView::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(DoGetWaveTrackView) {
return [](WaveTrack &track) {
return std::make_shared<WaveTrackView>( track.SharedPointer() );
};
}
static DoGetWaveTrackView registerDoGetWaveTrackView;
std::shared_ptr<TrackVRulerControls> WaveTrackView::DoGetVRulerControls()
{

View File

@ -12,7 +12,7 @@ Paul Licameli split from class WaveTrack
#define __AUDACITY_WAVE_TRACK_VIEW__
#include "../../../ui/CommonTrackView.h"
#include "../../../../ClientData.h"
#include "ClientData.h"
#include "SampleCount.h"
namespace WaveTrackViewConstants{ enum Display : int; }
struct WaveTrackSubViewType;

View File

@ -170,20 +170,17 @@ PopupMenuTable *TimeTrackControls::GetMenuExtension(Track *)
}
using DoGetTimeTrackControls = DoGetControls::Override< TimeTrack >;
template<> template<> auto DoGetTimeTrackControls::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(DoGetTimeTrackControls) {
return [](TimeTrack &track) {
return std::make_shared<TimeTrackControls>( track.SharedPointer() );
};
}
static DoGetTimeTrackControls registerDoGetTimeTrackControls;
#include "../../ui/TrackView.h"
using GetDefaultTimeTrackHeight = GetDefaultTrackHeight::Override< TimeTrack >;
template<> template<>
auto GetDefaultTimeTrackHeight::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(GetDefaultTimeTrackHeight) {
return [](TimeTrack &) {
return 100;
};
}
static GetDefaultTimeTrackHeight registerGetDefaultTimeTrackHeight;

View File

@ -53,12 +53,11 @@ std::vector<UIHandlePtr> TimeTrackView::DetailedHitTest
}
using DoGetTimeTrackView = DoGetView::Override< TimeTrack >;
template<> template<> auto DoGetTimeTrackView::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(DoGetTimeTrackView) {
return [](TimeTrack &track) {
return std::make_shared<TimeTrackView>( track.SharedPointer() );
};
}
static DoGetTimeTrackView registerDoGetTimeTrackView;
std::shared_ptr<TrackVRulerControls> TimeTrackView::DoGetVRulerControls()
{

View File

@ -11,7 +11,7 @@ Paul Licameli split from TrackPanel.cpp
#ifndef __AUDACITY_BACKGROUND_CELL__
#define __AUDACITY_BACKGROUND_CELL__
#include "../../ClientData.h"
#include "ClientData.h"
#include "CommonTrackPanelCell.h"
class AudacityProject;

View File

@ -12,7 +12,7 @@ Paul Licameli split from TrackPanel.cpp
#define __AUDACITY_EDIT_CURSOR_OVERLAY__
#include <memory>
#include "../../ClientData.h" // to inherit
#include "ClientData.h" // to inherit
#include "../../widgets/Overlay.h" // to inherit
class AudacityProject;

View File

@ -13,7 +13,7 @@ Paul Licameli split from TrackPanel.cpp
#include <wx/event.h> // to inherit
#include <memory>
#include "../../ClientData.h"
#include "ClientData.h"
#include "../../widgets/Overlay.h" // to inherit
class AudacityProject;

View File

@ -12,7 +12,7 @@
#include "Scrubbing.h"
#include "../../widgets/Overlay.h"
#include "../../ClientData.h"
#include "ClientData.h"
#include "../../AdornedRulerPanel.h"
#include "../../Project.h"
#include "../../ProjectWindow.h"

View File

@ -17,7 +17,7 @@ Paul Licameli split from TrackPanel.cpp
#include <wx/longlong.h>
#include "../../AudioIOBase.h" // for ScrubbingOptions
#include "../../ClientData.h" // to inherit
#include "ClientData.h" // to inherit
#include "Prefs.h" // to inherit
#include "../../widgets/Overlay.h" // to inherit
#include "../../commands/CommandContext.h"

View File

@ -272,12 +272,11 @@ bool CoarseTrackShifter::SyncLocks()
return false;
}
template<> auto MakeTrackShifter::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL(MakeTrackShifter) {
return [](Track &track, AudacityProject&) {
return std::make_unique<CoarseTrackShifter>(track);
};
}
static MakeTrackShifter registerMakeTrackShifter;
void ClipMoveState::Init(
AudacityProject &project,

View File

@ -15,7 +15,7 @@ Paul Licameli
#include <unordered_map>
#include <vector>
#include "../../AttachedVirtualFunction.h"
#include "AttachedVirtualFunction.h"
#include "../../UIHandle.h"
class SnapManager;
@ -198,6 +198,7 @@ private:
struct MakeTrackShifterTag;
using MakeTrackShifter = AttachedVirtualFunction<
MakeTrackShifterTag, std::unique_ptr<TrackShifter>, Track, AudacityProject&>;
DECLARE_EXPORTED_ATTACHED_VIRTUAL(AUDACITY_DLL_API, MakeTrackShifter);
class ViewInfo;

View File

@ -37,7 +37,6 @@ const TrackControls &TrackControls::Get( const Track &track )
return Get( const_cast< Track& >( track ) );
}
template<> auto DoGetControls::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL(DoGetControls) {
return nullptr;
}
static DoGetControls registerDoGetControls;

View File

@ -28,7 +28,7 @@ public:
virtual ~TrackControls() = 0;
};
#include "../../AttachedVirtualFunction.h"
#include "AttachedVirtualFunction.h"
struct DoGetControlsTag;
@ -38,5 +38,6 @@ AttachedVirtualFunction<
std::shared_ptr< TrackControls >,
Track
>;
DECLARE_EXPORTED_ATTACHED_VIRTUAL(AUDACITY_DLL_API, DoGetControls);
#endif

View File

@ -11,7 +11,7 @@ Paul Licameli split from TrackPanel.cpp
#include "TrackView.h"
#include "../../Track.h"
#include "../../ClientData.h"
#include "ClientData.h"
#include "../../Project.h"
#include "../../xml/XMLTagHandler.h"
#include "../../xml/XMLWriter.h"
@ -229,12 +229,10 @@ static const AudacityProject::AttachedObjects::RegisteredFactory key{
}
template<> auto DoGetView::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL(DoGetView) {
return nullptr;
}
static DoGetView registerDoGetView;
template<> auto GetDefaultTrackHeight::Implementation() -> Function {
DEFINE_ATTACHED_VIRTUAL(GetDefaultTrackHeight) {
return nullptr;
}
static GetDefaultTrackHeight registerGetDefaultTrackHeight;

View File

@ -103,7 +103,7 @@ private:
int mHeight{ DefaultHeight };
};
#include "../../AttachedVirtualFunction.h"
#include "AttachedVirtualFunction.h"
struct DoGetViewTag;
@ -113,6 +113,7 @@ AttachedVirtualFunction<
std::shared_ptr< TrackView >,
Track
>;
DECLARE_EXPORTED_ATTACHED_VIRTUAL(AUDACITY_DLL_API, DoGetView);
struct GetDefaultTrackHeightTag;
@ -122,5 +123,6 @@ AttachedVirtualFunction<
int,
Track
>;
DECLARE_EXPORTED_ATTACHED_VIRTUAL(AUDACITY_DLL_API, GetDefaultTrackHeight);
#endif