Minor net navigator improvements.

Ignore bus member connection subgraphs.  They do not have a valid net
name nor do they contain schematic items.  This prevents empty nodes
from being added to the tree.  They can be reintroduced in the future
if someone wants to pursue it.

Freeze the wxTreeCtrl while populating it and thaw when done to prevent
any unnecessary repainting.

Add profiling to test how long it takes to rebuild the net navigator.
The recently added populate the navigator with all nets when no net
is highlighted has exposed some potential performances issues with some
versions of wxWidgets on certain platforms.  Namely wxWidgets 3.2.4 on
Linux GTK.

Fix an issue where a sheet name change would not update the highlighted
net navigator resulting in a stale human readable sheet path.

Prevent the highlighted net navigator from being rebuilt twice when
loading a schematic.  SCH_EDIT_FRAME::RefreshNetNavigator() was being
called from both SCH_EDIT_FRAME::UpdateHierarchyNavigator() and
SCH_EDIT_FRAME::RecalculateConnectivity().

Add a new trace helper "KICAD_UI_PROFILE" to show trace output when
profiling user interface performance.  It's used in the net navigator
profiling mentioned above.

Reuse PROF_TIMER::Show() to generate string for PROF_TIMER::to_string().
This commit is contained in:
Wayne Stambaugh 2024-04-17 14:31:50 -04:00
parent a4073c2ace
commit d79619edd1
7 changed files with 66 additions and 18 deletions

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2018-2021 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2018-2024 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -55,6 +55,7 @@ const wxChar* const traceSchSheetPaths = wxT( "KICAD_SCH_SHEET_PATHS" );
const wxChar* const traceEnvVars = wxT( "KICAD_ENV_VARS" );
const wxChar* const traceGalProfile = wxT( "KICAD_GAL_PROFILE" );
const wxChar* const traceKiCad2Step = wxT( "KICAD2STEP" );
const wxChar* const traceUiProfile = wxT( "KICAD_UI_PROFILE" );
wxString dump( const wxArrayString& aArray )

View File

@ -4,7 +4,7 @@
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2013-2023 CERN (www.cern.ch)
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -555,7 +555,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
TestDanglingEnds();
UpdateHierarchyNavigator();
UpdateHierarchyNavigator( false );
wxCommandEvent changedEvt( EDA_EVT_SCHEMATIC_CHANGED );
ProcessEventLocally( changedEvt );

View File

@ -21,6 +21,7 @@
*/
#include <wx/log.h>
#include <core/profile.h>
#include <tool/tool_manager.h>
#include <kiface_base.h>
#include <sch_edit_frame.h>
@ -31,6 +32,7 @@
#include <sch_sheet_pin.h>
#include <schematic.h>
#include <string_utils.h>
#include <trace_helpers.h>
#include <connection_graph.h>
#include <widgets/wx_aui_utils.h>
#include <tools/ee_actions.h>
@ -251,6 +253,12 @@ void SCH_EDIT_FRAME::RefreshNetNavigator( const NET_NAVIGATOR_ITEM_DATA* aSelect
{
wxCHECK( m_netNavigator, /* void */ );
size_t nodeCnt = 0;
m_netNavigator->Freeze();
PROF_TIMER timer;
if( m_highlightedConn.IsEmpty() )
{
m_netNavigator->DeleteAllItems();
@ -262,16 +270,19 @@ void SCH_EDIT_FRAME::RefreshNetNavigator( const NET_NAVIGATOR_ITEM_DATA* aSelect
for( const auto& net : netMap )
{
wxTreeItemId netId = m_netNavigator->AppendItem( rootId, UnescapeString( net.first.Name ) );
// Skip bus member subgraphs for the moment.
if( net.first.Name.IsEmpty() )
continue;
nodeCnt++;
wxTreeItemId netId = m_netNavigator->AppendItem( rootId,
UnescapeString( net.first.Name ) );
MakeNetNavigatorNode( net.first.Name, netId, aSelection );
}
m_netNavigator->Expand( rootId );
return;
}
if( !m_netNavigator->IsEmpty() )
else if( !m_netNavigator->IsEmpty() )
{
const wxString shownNetName = m_netNavigator->GetItemText( m_netNavigator->GetRootItem() );
@ -279,6 +290,8 @@ void SCH_EDIT_FRAME::RefreshNetNavigator( const NET_NAVIGATOR_ITEM_DATA* aSelect
{
m_netNavigator->DeleteAllItems();
nodeCnt++;
wxTreeItemId rootId = m_netNavigator->AddRoot( UnescapeString( m_highlightedConn ), 0 );
MakeNetNavigatorNode( m_highlightedConn, rootId, aSelection );
@ -293,6 +306,8 @@ void SCH_EDIT_FRAME::RefreshNetNavigator( const NET_NAVIGATOR_ITEM_DATA* aSelect
itemData = dynamic_cast<NET_NAVIGATOR_ITEM_DATA*>( m_netNavigator->GetItemData( selection ) );
m_netNavigator->DeleteAllItems();
nodeCnt++;
wxTreeItemId rootId = m_netNavigator->AddRoot( UnescapeString( m_highlightedConn ), 0 );
MakeNetNavigatorNode( m_highlightedConn, rootId, itemData );
@ -300,10 +315,19 @@ void SCH_EDIT_FRAME::RefreshNetNavigator( const NET_NAVIGATOR_ITEM_DATA* aSelect
}
else
{
nodeCnt++;
wxTreeItemId rootId = m_netNavigator->AddRoot( UnescapeString( m_highlightedConn ), 0 );
MakeNetNavigatorNode( m_highlightedConn, rootId, aSelection );
}
timer.Stop();
wxLogTrace( traceUiProfile, wxS( "Adding %zu nodes to net navigator took %s." ),
nodeCnt, timer.to_string() );
m_netNavigator->Thaw();
}

View File

@ -1172,11 +1172,13 @@ void SCH_EDIT_FRAME::OnUpdatePCB( wxCommandEvent& event )
}
void SCH_EDIT_FRAME::UpdateHierarchyNavigator()
void SCH_EDIT_FRAME::UpdateHierarchyNavigator( bool aRefreshNetNavigator )
{
m_toolManager->GetTool<SCH_NAVIGATE_TOOL>()->CleanHistory();
m_hierarchy->UpdateHierarchyTree();
RefreshNetNavigator();
if( aRefreshNetNavigator )
RefreshNetNavigator();
}
@ -1743,9 +1745,13 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_COMMIT* aCommit, SCH_CLEANUP_FL
if( m_highlightedConnChanged )
return;
else if( !hasHighlightedConn )
// No highlighted connection, but connectivity has changed, so refresh the list of all nets
if( !hasHighlightedConn )
{
// No highlighted connection, but connectivity has changed, so refresh
// the list of all nets
m_highlightedConnChanged = true;
}
else if( connection
&& ( connection->Name() == highlightedConn
|| connection->HasDriverChanged() ) )

View File

@ -232,7 +232,7 @@ public:
/**
* Update the hierarchy navigation tree and history
*/
void UpdateHierarchyNavigator();
void UpdateHierarchyNavigator( bool aRefreshNetNavigator = true );
/**
* Update the hierarchy navigation tree labels.

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2018-2021 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2018-2024 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -220,6 +220,13 @@ extern KICOMMON_API const wxChar* const traceGalProfile;
*/
extern KICOMMON_API const wxChar* const traceKiCad2Step;
/**
* Flag to enable user interface profile tracing.
*
* Use "KICAD_UI_PROFILE" to enable.
*/
extern KICOMMON_API const wxChar* const traceUiProfile;
///@}
/**

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* Copyright (C) 2019-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2020, 2024 KiCad Developers, see AUTHORS.txt for contributors.
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@ -33,6 +33,7 @@
#include <atomic>
#include <chrono>
#include <sstream>
#include <string>
#include <iostream>
#include <iomanip>
@ -153,9 +154,18 @@ public:
std::string to_string()
{
char tmp[1024];
snprintf( tmp, sizeof( tmp ), "%s: %-6.1fms", m_name.c_str(), msecs() );
return tmp;
std::string retv;
if( !m_name.empty() )
retv = m_name + ": ";
std::stringstream time;
Show( time );
retv += time.get();
return retv;
}
private: