1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-10 09:01:13 +02:00

Registry::Visit doesn't require an AudacityProject

This commit is contained in:
Paul Licameli 2020-01-26 16:10:26 -05:00
parent c7bfa7a2a6
commit 103a6050a0
4 changed files with 44 additions and 37 deletions

View File

@ -195,15 +195,15 @@ struct CollectedItems
// alternate as the entire tree is recursively visited.
// forward declaration for mutually recursive functions
void CollectItem( AudacityProject &project,
void CollectItem( Registry::Visitor &visitor,
CollectedItems &collection, BaseItem *Item );
void CollectItems( AudacityProject &project,
void CollectItems( Registry::Visitor &visitor,
CollectedItems &collection, const BaseItemPtrs &items )
{
for ( auto &item : items )
CollectItem( project, collection, item.get() );
CollectItem( visitor, collection, item.get() );
}
void CollectItem( AudacityProject &project,
void CollectItem( Registry::Visitor &visitor,
CollectedItems &collection, BaseItem *pItem )
{
if (!pItem)
@ -214,17 +214,17 @@ void CollectItem( AudacityProject &project,
dynamic_cast<SharedItem*>( pItem )) {
auto &delegate = pShared->ptr;
// recursion
CollectItem( project, collection, delegate.get() );
CollectItem( visitor, collection, delegate.get() );
}
else
if (const auto pComputed =
dynamic_cast<ComputedItem*>( pItem )) {
auto result = pComputed->factory( project );
auto result = pComputed->factory( visitor );
if (result) {
// Guarantee long enough lifetime of the result
collection.computedItems.push_back( result );
// recursion
CollectItem( project, collection, result.get() );
CollectItem( visitor, collection, result.get() );
}
}
else
@ -232,7 +232,7 @@ void CollectItem( AudacityProject &project,
if (pGroup->Transparent() && pItem->name.empty())
// nameless grouping item is transparent to path calculations
// recursion
CollectItems( project, collection, pGroup->items );
CollectItems( visitor, collection, pGroup->items );
else
// all other group items
collection.items.push_back( pItem );
@ -248,29 +248,26 @@ using Path = std::vector< Identifier >;
// forward declaration for mutually recursive functions
void VisitItem(
Registry::Visitor &visitor,
AudacityProject &project, CollectedItems &collection,
Registry::Visitor &visitor, CollectedItems &collection,
Path &path, BaseItem *pItem );
void VisitItems(
Registry::Visitor &visitor,
AudacityProject &project, CollectedItems &collection,
Registry::Visitor &visitor, CollectedItems &collection,
Path &path, GroupItem *pGroup )
{
// Make a new collection for this subtree, sharing the memo cache
CollectedItems newCollection{ {}, collection.computedItems };
// Gather items at this level
CollectItems( project, newCollection, pGroup->items );
CollectItems( visitor, newCollection, pGroup->items );
// Now visit them
path.push_back( pGroup->name );
for ( const auto &pSubItem : newCollection.items )
VisitItem( visitor, project, collection, path, pSubItem );
VisitItem( visitor, collection, path, pSubItem );
path.pop_back();
}
void VisitItem(
Registry::Visitor &visitor,
AudacityProject &project, CollectedItems &collection,
Registry::Visitor &visitor, CollectedItems &collection,
Path &path, BaseItem *pItem )
{
if (!pItem)
@ -285,7 +282,7 @@ void VisitItem(
dynamic_cast<GroupItem*>( pItem )) {
visitor.BeginGroup( *pGroup, path );
// recursion
VisitItems( visitor, project, collection, path, pGroup );
VisitItems( visitor, collection, path, pGroup );
visitor.EndGroup( *pGroup, path );
}
else
@ -296,14 +293,12 @@ void VisitItem(
namespace Registry {
void Visit(
Visitor &visitor, AudacityProject &project,
BaseItem *pTopItem )
void Visit( Visitor &visitor, BaseItem *pTopItem )
{
std::vector< BaseItemSharedPtr > computedItems;
CollectedItems collection{ {}, computedItems };
Path emptyPath;
VisitItem( visitor, project, collection, emptyPath, pTopItem );
VisitItem( visitor, collection, emptyPath, pTopItem );
}
}
@ -354,10 +349,10 @@ static const auto menuTree = MenuTable::Items( MenuPathStart
);
namespace {
struct MenuItemVisitor : Registry::Visitor
struct MenuItemVisitor : MenuVisitor
{
MenuItemVisitor( AudacityProject &proj, CommandManager &man )
: project(proj), manager( man ) {}
: MenuVisitor(proj), manager( man ) {}
void BeginGroup( GroupItem &item, const Path& ) override
{
@ -440,7 +435,6 @@ struct MenuItemVisitor : Registry::Visitor
wxASSERT( false );
}
AudacityProject &project;
CommandManager &manager;
std::vector<bool> flags;
};
@ -458,7 +452,7 @@ void MenuCreator::CreateMenusAndCommands(AudacityProject &project)
wxASSERT(menubar);
MenuItemVisitor visitor{ project, commandManager };
MenuManager::Visit( visitor, project );
MenuManager::Visit( visitor );
GetProjectFrame( project ).SetMenuBar(menubar.release());
@ -469,9 +463,9 @@ void MenuCreator::CreateMenusAndCommands(AudacityProject &project)
#endif
}
void MenuManager::Visit( Registry::Visitor &visitor, AudacityProject &project )
void MenuManager::Visit( MenuVisitor &visitor )
{
Registry::Visit( visitor, project, menuTree.get() );
Registry::Visit( visitor, menuTree.get() );
}
// TODO: This surely belongs in CommandManager?

View File

@ -54,6 +54,8 @@ public:
PluginID mLastEffect{};
};
struct MenuVisitor;
class MenuManager final
: public MenuCreator
, public ClientData::Base
@ -70,8 +72,7 @@ public:
MenuManager &operator=( const MenuManager & ) PROHIBITED;
~MenuManager();
static void Visit(
Registry::Visitor &visitor, AudacityProject &project );
static void Visit( MenuVisitor &visitor );
static void ModifyUndoMenuItems(AudacityProject &project);
static void ModifyToolbarMenus(AudacityProject &project);

View File

@ -427,6 +427,8 @@ namespace Registry {
using BaseItemPtr = std::unique_ptr<BaseItem>;
using BaseItemSharedPtr = std::shared_ptr<BaseItem>;
using BaseItemPtrs = std::vector<BaseItemPtr>;
struct Visitor;
// An item that delegates to another held in a shared pointer; this allows
@ -457,7 +459,7 @@ namespace Registry {
template< typename VisitorType >
using Factory = std::function< BaseItemSharedPtr( VisitorType & ) >;
using DefaultVisitor = AudacityProject;
using DefaultVisitor = Visitor;
explicit ComputedItem( const Factory< DefaultVisitor > &factory_ )
: BaseItem( wxEmptyString )
@ -531,7 +533,10 @@ namespace Registry {
// appled implicitly.)
void AppendOne( const ComputedItem::Factory<VisitorType> &factory )
{
AppendOne( std::make_unique<ComputedItem>( factory ) );
auto adaptedFactory = [factory]( Registry::Visitor &visitor ){
return factory( dynamic_cast< VisitorType& >( visitor ) );
};
AppendOne( std::make_unique<ComputedItem>( adaptedFactory ) );
}
// This overload lets you supply a shared pointer to an item, directly
template<typename Subtype>
@ -572,11 +577,16 @@ namespace Registry {
};
// Top-down visitation of all items and groups in a tree
void Visit(
Visitor &visitor, AudacityProject &project, BaseItem *pTopItem );
void Visit( Visitor &visitor, BaseItem *pTopItem );
}
using MenuVisitor = Registry::ComputedItem::DefaultVisitor;
struct MenuVisitor : Registry::Visitor
{
explicit MenuVisitor( AudacityProject &p ) : project{ p } {}
operator AudacityProject & () const { return project; }
AudacityProject &project;
};
// Define items that populate tables that specifically describe menu trees
namespace MenuTable {

View File

@ -380,8 +380,10 @@ void OnMenuTree(const CommandContext &context)
auto &project = context.project;
using namespace MenuTable;
struct MyVisitor : Visitor
struct MyVisitor : MenuVisitor
{
using MenuVisitor::MenuVisitor;
enum : unsigned { TAB = 3 };
void BeginGroup( GroupItem &item, const Path& ) override
{
@ -415,9 +417,9 @@ void OnMenuTree(const CommandContext &context)
unsigned level{};
wxString indentation;
wxString info;
} visitor;
} visitor{ project };
MenuManager::Visit( visitor, project );
MenuManager::Visit( visitor );
ShowDiagnostics( project, visitor.info,
XO("Menu Tree"), wxT("menutree.txt"), true );